summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Norbye <tnorbye@google.com>2014-09-04 20:44:00 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2014-09-04 20:44:01 +0000
commitfb5a02906f644d044eb0286bf27d413ba0e05216 (patch)
treebca7d49005d81d10c70bc3f547df041c636b4300
parent9cde0e3c015174898df8b8f3672185941fad4786 (diff)
parentd245f58efbfc26b13b9b9d5e52e6a83a0d76216c (diff)
downloadidea-fb5a02906f644d044eb0286bf27d413ba0e05216.tar.gz
Merge "Merge remote-tracking branch 'aosp/upstream-master' into merge"
-rw-r--r--.idea/compiler.xml1
-rw-r--r--.idea/libraries/Netty.xml4
-rw-r--r--bin/win/runnerw.exebin99840 -> 106600 bytes
-rw-r--r--build/conf/classVersions.txt2
-rw-r--r--build/scripts/libLicenses.gant2
-rw-r--r--community-main.iml1
-rw-r--r--java/compiler/impl/src/com/intellij/compiler/impl/CompileContextImpl.java12
-rw-r--r--java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java61
-rw-r--r--java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java102
-rw-r--r--java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java46
-rw-r--r--java/compiler/impl/src/com/intellij/compiler/server/DefaultMessageHandler.java59
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/actions/AdjustArrayRangeAction.java41
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/actions/CustomizeThreadsViewAction.java16
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/actions/JavaReferringObjectsValue.java172
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/actions/ShowReferringObjectsAction.java131
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/actions/ToggleMethodBreakpointAction.java3
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/JavaDebuggerEvaluator.java10
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java39
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java2
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java43
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java4
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/MethodEvaluator.java40
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/impl/DebuggerContextUtil.java55
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/HotSwapProgressImpl.java2
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java2
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluator.java217
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/EvaluationDescriptor.java23
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/FieldDescriptorImpl.java15
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/LocalVariableDescriptorImpl.java12
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java1
-rw-r--r--java/debugger/openapi/src/com/intellij/debugger/SourcePosition.java82
-rw-r--r--java/execution/impl/src/com/intellij/execution/impl/DefaultJavaProgramRunner.java9
-rw-r--r--java/execution/openapi/src/com/intellij/execution/configurations/JavaParameters.java20
-rw-r--r--java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryOptionsPanel.java2
-rw-r--r--java/idea-ui/src/com/intellij/ide/actions/ImportModuleAction.java13
-rw-r--r--java/idea-ui/src/com/intellij/ide/actions/OpenProjectAction.java84
-rw-r--r--java/idea-ui/src/com/intellij/ide/actions/ShowStructureSettingsAction.java6
-rw-r--r--java/idea-ui/src/com/intellij/ide/actions/TemplateProjectStructureAction.java1
-rw-r--r--java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/DefaultLibraryRootsComponentDescriptor.java40
-rw-r--r--java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/NativeLibraryOrderRootTypeUIFactory.java46
-rw-r--r--java/java-analysis-impl/src/com/intellij/analysis/JavaAnalysisScope.java11
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/JavaHighlightInfoTypes.java4
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Analysis.java145
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisConverter.java458
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisConverterImpl.java206
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisIndex.java198
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/ClassDataIndexer.java425
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Combined.java465
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Contracts.java192
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/ControlFlow.java1030
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Data.java54
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/HData.java311
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Parameters.java472
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/ProjectBytecodeAnalysis.java224
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Solver.java360
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/ASMUtils.java57
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/ControlFlowGraph.java174
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/DFSTree.java134
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/FramelessAnalyzer.java362
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/LeakingParameters.java610
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/LiteAnalyzer.java189
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/LiteFramelessAnalyzer.java56
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/OriginsAnalysis.java193
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/RichControlFlow.java101
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractInference.java38
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java12
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java7
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaExpressionFactory.java2
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java4
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/ImplementedAtRuntimeCondition.java29
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/javaDoc/JavaDocLocalInspectionBase.java4
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/unnecessaryModuleDependency/UnnecessaryModuleDependencyInspection.java2
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/unusedLibraries/UnusedLibrariesInspection.java2
-rw-r--r--java/java-impl/src/com/intellij/analysis/BaseClassesAnalysisAction.java5
-rw-r--r--java/java-impl/src/com/intellij/application/options/JavaIndentOptionsProvider.java109
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/CodeInsightUtil.java42
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsLineMarkerProvider.java23
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java6
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionSorting.java5
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java26
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/JavaGenerateMemberCompletionContributor.java9
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/JavaInheritorsGetter.java5
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/JavaMemberNameCompletionContributor.java2
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java3
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaColorProvider.java8
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateAnnotationMethodFromUsageFix.java2
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreatePropertyFromUsageFix.java2
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/editorActions/JavaTypedHandler.java38
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/folding/impl/JavaElementSignatureProvider.java2
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersHandlerBase.java2
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java2
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightExceptionsHandlerFactory.java10
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightExitPointsHandlerFactory.java10
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightImportedElementsHandlerFactory.java10
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightOverridingMethodsHandlerFactory.java10
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightSuppressedWarningsFactory.java10
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/hint/actions/ShowSiblingsAction.java12
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/hint/api/impls/MethodParameterInfoHandler.java9
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateClassDialog.java3
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateFieldFromParameterDialog.java7
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/lookup/VariableLookupItem.java38
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/unwrap/JavaMethodParameterUnwrapper.java5
-rw-r--r--java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesHandler.java12
-rw-r--r--java/java-impl/src/com/intellij/ide/actions/CreateClassAction.java2
-rw-r--r--java/java-impl/src/com/intellij/ide/actions/CreatePackageInfoAction.java2
-rw-r--r--java/java-impl/src/com/intellij/ide/actions/JavaCreateTemplateInPackageAction.java2
-rw-r--r--java/java-impl/src/com/intellij/ide/util/scopeChooser/HierarchyScopeDescriptorProvider.java6
-rw-r--r--java/java-impl/src/com/intellij/internal/GenerateVisitorByHierarchyAction.java4
-rw-r--r--java/java-impl/src/com/intellij/internal/StaticIconFieldsAction.java33
-rw-r--r--java/java-impl/src/com/intellij/openapi/module/BasePackageParameterFactory.java3
-rw-r--r--java/java-impl/src/com/intellij/packageDependencies/ui/PackagePatternProvider.java7
-rw-r--r--java/java-impl/src/com/intellij/psi/RefResolveServiceImpl.java172
-rw-r--r--java/java-impl/src/com/intellij/psi/impl/file/PsiJavaDirectoryFactory.java2
-rw-r--r--java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReference.java2
-rw-r--r--java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReferenceProvider.java4
-rw-r--r--java/java-impl/src/com/intellij/refactoring/anonymousToInner/AnonymousToInnerDialog.java2
-rw-r--r--java/java-impl/src/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureDialog.java2
-rw-r--r--java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDialog.java4
-rw-r--r--java/java-impl/src/com/intellij/refactoring/copy/CopyClassDialog.java2
-rw-r--r--java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsDialog.java4
-rw-r--r--java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java4
-rw-r--r--java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java2
-rw-r--r--java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectDialog.java2
-rw-r--r--java/java-impl/src/com/intellij/refactoring/extractSuperclass/JavaExtractSuperBaseDialog.java8
-rw-r--r--java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassDialog.java2
-rw-r--r--java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassProcessor.java4
-rw-r--r--java/java-impl/src/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationDialog.java2
-rw-r--r--java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java7
-rw-r--r--java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceConstantDialog.java4
-rw-r--r--java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldDialog.java4
-rw-r--r--java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractJavaInplaceIntroducer.java2
-rw-r--r--java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterDialog.java2
-rw-r--r--java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableDialog.java3
-rw-r--r--java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectDialog.java3
-rw-r--r--java/java-impl/src/com/intellij/refactoring/makeStatic/MakeParameterizedStaticDialog.java2
-rw-r--r--java/java-impl/src/com/intellij/refactoring/migration/EditMigrationEntryDialog.java4
-rw-r--r--java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesDialog.java4
-rw-r--r--java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesProcessor.java2
-rw-r--r--java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveJavaFileHandler.java2
-rw-r--r--java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerDialog.java4
-rw-r--r--java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodDialog.java2
-rw-r--r--java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMembersDialog.java2
-rw-r--r--java/java-impl/src/com/intellij/refactoring/rename/DirectoryAsPackageRenameHandler.java7
-rw-r--r--java/java-impl/src/com/intellij/refactoring/rename/PsiPackageRenameValidator.java3
-rw-r--r--java/java-impl/src/com/intellij/refactoring/rename/naming/ConstructorParameterOnFieldRenameRenamer.java4
-rw-r--r--java/java-impl/src/com/intellij/refactoring/replaceConstructorWithBuilder/ReplaceConstructorWithBuilderDialog.java2
-rw-r--r--java/java-impl/src/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryDialog.java2
-rw-r--r--java/java-impl/src/com/intellij/refactoring/typeCook/TypeCookProcessor.java11
-rw-r--r--java/java-impl/src/com/intellij/refactoring/typeCook/Util.java6
-rw-r--r--java/java-impl/src/com/intellij/refactoring/typeCook/deductive/PsiTypeVariableFactory.java16
-rw-r--r--java/java-impl/src/com/intellij/refactoring/typeCook/deductive/builder/ReductionSystem.java32
-rw-r--r--java/java-impl/src/com/intellij/refactoring/typeCook/deductive/builder/Result.java16
-rw-r--r--java/java-impl/src/com/intellij/refactoring/typeCook/deductive/builder/SystemBuilder.java23
-rw-r--r--java/java-impl/src/com/intellij/refactoring/typeCook/deductive/resolver/Binding.java6
-rw-r--r--java/java-impl/src/com/intellij/refactoring/typeCook/deductive/resolver/BindingFactory.java19
-rw-r--r--java/java-impl/src/com/intellij/refactoring/typeCook/deductive/resolver/ResolverTree.java69
-rw-r--r--java/java-impl/src/com/intellij/refactoring/typeCook/deductive/util/VictimCollector.java9
-rw-r--r--java/java-impl/src/com/intellij/refactoring/util/ParameterTablePanel.java2
-rw-r--r--java/java-impl/src/com/intellij/refactoring/util/duplicates/MethodDuplicatesHandler.java20
-rw-r--r--java/java-impl/src/com/intellij/refactoring/wrapreturnvalue/WrapReturnValueDialog.java3
-rw-r--r--java/java-impl/src/com/intellij/slicer/SliceLeafAnalyzer.java29
-rw-r--r--java/java-impl/src/com/intellij/slicer/SliceNullnessAnalyzer.java13
-rw-r--r--java/java-impl/src/com/intellij/slicer/SliceUsage.java10
-rw-r--r--java/java-impl/src/com/intellij/testIntegration/createTest/CreateTestDialog.java2
-rw-r--r--java/java-impl/src/com/intellij/testIntegration/createTest/JavaTestGenerator.java19
-rw-r--r--java/java-indexing-api/src/com/intellij/psi/search/searches/AllOverridingMethodsSearch.java3
-rw-r--r--java/java-indexing-api/src/com/intellij/psi/search/searches/AnnotatedMembersSearch.java3
-rw-r--r--java/java-indexing-api/src/com/intellij/psi/search/searches/AnnotatedPackagesSearch.java3
-rw-r--r--java/java-indexing-api/src/com/intellij/psi/search/searches/AnnotationTargetsSearch.java3
-rw-r--r--java/java-indexing-api/src/com/intellij/psi/search/searches/ClassInheritorsSearch.java9
-rw-r--r--java/java-indexing-api/src/com/intellij/psi/search/searches/DirectClassInheritorsSearch.java5
-rw-r--r--java/java-indexing-api/src/com/intellij/psi/search/searches/FunctionalExpressionSearch.java30
-rw-r--r--java/java-indexing-api/src/com/intellij/psi/search/searches/MethodReferencesSearch.java9
-rw-r--r--java/java-indexing-impl/src/com/intellij/codeInsight/navigation/MethodImplementationsSearch.java11
-rw-r--r--java/java-indexing-impl/src/com/intellij/psi/impl/file/impl/JavaFileManagerImpl.java2
-rw-r--r--java/java-indexing-impl/src/com/intellij/psi/impl/search/AnnotatedElementsSearcher.java8
-rw-r--r--java/java-indexing-impl/src/com/intellij/psi/impl/search/AnnotatedPackagesSearcher.java90
-rw-r--r--java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaAllOverridingMethodsSearcher.java19
-rw-r--r--java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaDirectInheritorsSearcher.java46
-rw-r--r--java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaFunctionalExpressionSearcher.java125
-rw-r--r--java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodDeepestSuperSearcher.java26
-rw-r--r--java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodSuperSearcher.java42
-rw-r--r--java/java-indexing-impl/src/com/intellij/psi/impl/search/PsiAnnotationMethodReferencesSearcher.java39
-rw-r--r--java/java-indexing-impl/src/com/intellij/psi/impl/search/SimpleAccessorReferenceSearcher.java1
-rw-r--r--java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java2
-rw-r--r--java/java-psi-api/src/com/intellij/psi/GenericsUtil.java10
-rw-r--r--java/java-psi-api/src/com/intellij/psi/JVMElementFactory.java1
-rw-r--r--java/java-psi-api/src/com/intellij/psi/PsiCapturedWildcardType.java31
-rw-r--r--java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java4
-rw-r--r--java/java-psi-api/src/com/intellij/psi/PsiNameHelper.java2
-rw-r--r--java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java2
-rw-r--r--java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java8
-rw-r--r--java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java15
-rw-r--r--java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java4
-rw-r--r--java/java-psi-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java18
-rw-r--r--java/java-psi-impl/src/com/intellij/lang/java/parser/ReferenceParser.java4
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowAnalyzer.java2
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowFactory.java29
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java6
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/file/PsiPackageImpl.java3
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/light/LightTypeParameter.java4
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/FunctionalInterfaceParameterizationUtil.java5
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java42
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java314
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariable.java9
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/PsiGraphInferenceHelper.java9
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java65
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/LambdaExpressionCompatibilityConstraint.java4
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java22
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/MethodReferenceResolver.java13
-rw-r--r--java/java-runtime/src/com/intellij/rt/debugger/DefaultMethodInvoker.java39
-rw-r--r--java/java-tests/testData/codeInsight/completion/keywords/finalInCatch.java7
-rw-r--r--java/java-tests/testData/codeInsight/completion/keywords/finalInIncompleteCatch.java7
-rw-r--r--java/java-tests/testData/codeInsight/completion/smartType/SuggestTypeParametersInTypeArgumentList.java8
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/ParameterBoundsWithCapturedWildcard.java5
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/SuperCaptureSubstitutionWhenTypeParameterHasUpperBounds.java30
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA110947.java2
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA128333.java24
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SuperWildcardWithBoundPromotion.java4
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/WildcardsBoundsIntersection.java2
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/CyclicParamsDependency.java18
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/IDEA126163.java29
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/IDEA128101.java4
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/IDEA128766.java21
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/InfiniteTypes.java9
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/SOEDuringInferenceFromParamBounds.java2
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/SameMethodNestedChainedCallsNearFunctionInterfaces.java87
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/AdditionalConstraints3Level.java15
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/WildcardParametrization.java19
-rw-r--r--java/java-tests/testData/codeInsight/typing/fixIfByBraceCompositeCondition_after.java5
-rw-r--r--java/java-tests/testData/codeInsight/typing/fixIfByBraceCompositeCondition_before.java5
-rw-r--r--java/java-tests/testData/codeInsight/typing/fixIfByBraceNewObject_after.java5
-rw-r--r--java/java-tests/testData/codeInsight/typing/fixIfByBraceNewObject_before.java5
-rw-r--r--java/java-tests/testData/codeInsight/typing/fixIfByBrace_after.java7
-rw-r--r--java/java-tests/testData/codeInsight/typing/fixIfByBrace_before.java5
-rw-r--r--java/java-tests/testData/codeInsight/typing/fixWhileByBrace_after.java7
-rw-r--r--java/java-tests/testData/codeInsight/typing/fixWhileByBrace_before.java5
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/awt/annotations.xml228
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/beans/beancontext/annotations.xml3
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/io/annotations.xml125
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/lang/annotations.xml291
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/lang/invoke/annotations.xml177
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/net/annotations.xml216
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/security/annotations.xml48
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/sql/annotations.xml54
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/util/annotations.xml555
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/util/concurrent/atomic/annotations.xml15
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/util/concurrent/locks/annotations.xml12
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/javax/swing/annotations.xml219
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/collections/annotations.xml18
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/collections/iterators/annotations.xml11
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/collections/map/annotations.xml30
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/annotations.xml1395
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/builder/annotations.xml586
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/enum/annotations.xml3
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/enums/annotations.xml3
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/exception/annotations.xml84
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/math/annotations.xml135
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/mutable/annotations.xml24
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/text/annotations.xml299
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/time/annotations.xml90
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/anakia/annotations.xml9
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/annotations.xml8
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/app/event/annotations.xml21
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/app/event/implement/annotations.xml39
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/app/tools/annotations.xml15
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/context/annotations.xml18
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/convert/annotations.xml3
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/exception/annotations.xml6
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/io/annotations.xml9
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/runtime/annotations.xml21
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/runtime/directive/annotations.xml96
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/runtime/log/annotations.xml57
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/runtime/parser/annotations.xml12
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/runtime/parser/node/annotations.xml129
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/runtime/resource/annotations.xml6
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/runtime/resource/loader/annotations.xml48
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/servlet/annotations.xml24
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/texen/annotations.xml27
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/texen/util/annotations.xml3
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/util/annotations.xml11
-rw-r--r--java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/util/introspection/annotations.xml33
-rw-r--r--java/java-tests/testData/inspection/dataFlow/fixture/GetterResultsNotSame.java26
-rw-r--r--java/java-tests/testData/inspection/dataFlow/fixture/SwitchOnNullable.java10
-rw-r--r--java/java-tests/testData/psi/repositoryUse/deepPackages/classes/a/a/a/a/e/f/i.class (renamed from java/java-tests/testData/psi/repositoryUse/scr17094/classes/a/a/a/a/e/f/i.class)bin761 -> 761 bytes
-rw-r--r--java/java-tests/testData/psi/repositoryUse/deepPackages/classes2/com/intellij/internal/a/b/a/i.class (renamed from java/java-tests/testData/psi/repositoryUse/scr17094/classes2/com/intellij/internal/a/b/a/i.class)bin1675 -> 1675 bytes
-rw-r--r--java/java-tests/testData/psi/repositoryUse/scr17094/classes1/com/intellij/util/d/bw.classbin7667 -> 0 bytes
-rw-r--r--java/java-tests/testData/refactoring/inlineMethod/multifile/preserveStaticImportsIfOverloaded/after/Bar.java6
-rw-r--r--java/java-tests/testData/refactoring/inlineMethod/multifile/preserveStaticImportsIfOverloaded/after/Foo.java3
-rw-r--r--java/java-tests/testData/refactoring/inlineMethod/multifile/preserveStaticImportsIfOverloaded/before/Bar.java7
-rw-r--r--java/java-tests/testData/refactoring/inlineMethod/multifile/preserveStaticImportsIfOverloaded/before/Foo.java4
-rw-r--r--java/java-tests/testData/refactoring/inlineMethod/multifile/removeStaticImportsIfOverloadedUnused/after/Bar.java4
-rw-r--r--java/java-tests/testData/refactoring/inlineMethod/multifile/removeStaticImportsIfOverloadedUnused/after/Foo.java3
-rw-r--r--java/java-tests/testData/refactoring/inlineMethod/multifile/removeStaticImportsIfOverloadedUnused/before/Bar.java6
-rw-r--r--java/java-tests/testData/refactoring/inlineMethod/multifile/removeStaticImportsIfOverloadedUnused/before/Foo.java4
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/GenerateGetterSetterTest.groovy4
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/JavaTypingTest.java16
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy42
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/completion/KeywordCompletionTest.java4
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.groovy2
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java5
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java2
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/FindFunctionalInterfaceTest.java3
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlighting8Test.java6
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java23
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java5
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java11
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInspection/ContractInferenceFromSourceTest.groovy51
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java2
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInspection/UnusedLibraryInspectionTest.java8
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisIntegrationTest.java42
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisTest.java26
-rw-r--r--java/java-tests/testSrc/com/intellij/find/FindManagerTest.java22
-rw-r--r--java/java-tests/testSrc/com/intellij/navigation/ChooseByNameTest.groovy10
-rw-r--r--java/java-tests/testSrc/com/intellij/project/LoadProjectTest.java7
-rw-r--r--java/java-tests/testSrc/com/intellij/psi/FindClassInDeepPackagesTest.java (renamed from java/java-tests/testSrc/com/intellij/psi/SCR17094Test.java)19
-rw-r--r--java/java-tests/testSrc/com/intellij/psi/MiscPsiTest.java21
-rw-r--r--java/java-tests/testSrc/com/intellij/psi/impl/cache/impl/ClassFileUnderSourceRootTest.java (renamed from java/java-tests/testSrc/com/intellij/psi/impl/cache/impl/SCR17650Test.java)15
-rw-r--r--java/java-tests/testSrc/com/intellij/psi/impl/cache/impl/FindClassTest.java (renamed from java/java-tests/testSrc/com/intellij/psi/impl/cache/impl/SCR14423Test.java)37
-rw-r--r--java/java-tests/testSrc/com/intellij/psi/impl/cache/impl/SameSourceRootInTwoModulesTest.java (renamed from java/java-tests/testSrc/com/intellij/psi/impl/cache/impl/SCR20733Test.java)9
-rw-r--r--java/java-tests/testSrc/com/intellij/psi/impl/cache/impl/SourceRootAddedAsLibraryRootTest.java (renamed from java/java-tests/testSrc/com/intellij/psi/impl/cache/impl/SCR19174Test.java)15
-rw-r--r--java/java-tests/testSrc/com/intellij/psi/impl/file/impl/PsiEventsTest.java89
-rw-r--r--java/java-tests/testSrc/com/intellij/psi/impl/file/impl/TempFileSystemTest.java43
-rw-r--r--java/java-tests/testSrc/com/intellij/refactoring/inline/InlineMethodMultifileTest.java3
-rw-r--r--java/java-tests/testSrc/com/intellij/roots/libraries/LibraryTest.java119
-rw-r--r--java/jdkAnnotations/org/jdom/annotations.xml6
-rw-r--r--java/openapi/src/com/intellij/lang/refactoring/JavaNamesValidator.java5
-rw-r--r--java/openapi/src/com/intellij/openapi/roots/NativeLibraryOrderRootType.java34
-rw-r--r--java/openapi/src/com/intellij/util/xml/converters/AbstractMemberResolveConverter.java2
-rw-r--r--java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilder.java5
-rw-r--r--java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java2
-rw-r--r--java/testFramework/src/com/intellij/codeInsight/daemon/DaemonAnalyzerTestCase.java4
-rw-r--r--java/testFramework/src/com/intellij/codeInsight/daemon/quickFix/LightQuickFixTestCase.java1
-rw-r--r--java/testFramework/src/com/intellij/debugger/DebuggerTestCase.java11
-rw-r--r--java/testFramework/src/com/intellij/testFramework/CompilerTester.java2
-rw-r--r--java/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ConvertFieldToAtomicIntention.java10
-rw-r--r--java/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ConvertFieldToThreadLocalIntention.java8
-rw-r--r--java/typeMigration/test/com/intellij/refactoring/TypeMigrationTest.java7
-rw-r--r--java/typeMigration/testData/intentions/atomic/afterArrayInitializer.java6
-rw-r--r--java/typeMigration/testData/intentions/atomic/beforeArrayInitializer.java4
-rw-r--r--java/typeMigration/testData/intentions/threadLocal/afterArrayInitializer.java9
-rw-r--r--java/typeMigration/testData/intentions/threadLocal/beforeArrayInitializer.java4
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildMain.java42
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/incremental/FSOperations.java2
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/incremental/fs/BuildFSState.java6
-rw-r--r--jps/model-api/src/org/jetbrains/jps/model/java/JpsNativeLibraryRootType.java28
-rw-r--r--jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/JpsJavaModelSerializerExtension.java3
-rw-r--r--lib/netty-all-4.1.0.Beta3.jar (renamed from lib/netty-all-4.1.0.Beta1.jar)bin1997099 -> 2175247 bytes
-rw-r--r--lib/required_for_dist.txt2
-rw-r--r--lib/src/netty-all-4.1.0.Beta3-sources.jar (renamed from lib/src/netty-all-4.1.0.Beta1-sources.jar)bin1646796 -> 1756376 bytes
-rw-r--r--platform/analysis-api/src/com/intellij/analysis/AnalysisScope.java33
-rw-r--r--platform/analysis-api/src/com/intellij/codeInsight/intention/IntentionManager.java8
-rw-r--r--platform/analysis-api/src/com/intellij/codeInspection/InspectionProfileEntry.java13
-rw-r--r--platform/analysis-api/src/com/intellij/profile/ProfileChangeAdapter.java2
-rw-r--r--platform/analysis-api/src/com/intellij/psi/search/scope/packageSet/FilePatternPackageSet.java5
-rw-r--r--platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java59
-rw-r--r--platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfoType.java4
-rw-r--r--platform/analysis-impl/src/com/intellij/codeInspection/InspectionEngine.java139
-rw-r--r--platform/analysis-impl/src/com/intellij/codeInspection/SmartHashMap.java (renamed from platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/SmartHashMap.java)4
-rw-r--r--platform/analysis-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextBase.java39
-rw-r--r--platform/analysis-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java5
-rw-r--r--platform/analysis-impl/src/com/intellij/profile/codeInspection/InspectionProfileManager.java3
-rw-r--r--platform/annotations/src/org/intellij/lang/annotations/Flow.java6
-rw-r--r--platform/annotations/src/org/intellij/lang/annotations/MagicConstant.java25
-rw-r--r--platform/annotations/src/org/jetbrains/annotations/Contract.java8
-rw-r--r--platform/core-api/src/com/intellij/lang/ASTNode.java5
-rw-r--r--platform/core-api/src/com/intellij/openapi/options/SchemesManagerFactory.java10
-rw-r--r--platform/core-api/src/com/intellij/openapi/progress/EmptyProgressIndicator.java3
-rw-r--r--platform/core-api/src/com/intellij/openapi/progress/ProgressIndicatorProvider.java4
-rw-r--r--platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java2
-rw-r--r--platform/core-api/src/com/intellij/openapi/util/ExecutionCallback.java3
-rw-r--r--platform/core-api/src/com/intellij/psi/util/PsiUtilCore.java11
-rw-r--r--platform/core-api/src/com/intellij/usageView/UsageInfo.java9
-rw-r--r--platform/core-api/src/com/intellij/util/PlatformUtilsCore.java6
-rw-r--r--platform/core-impl/src/com/intellij/core/CoreProjectEnvironment.java27
-rw-r--r--platform/core-impl/src/com/intellij/mock/MockApplicationEx.java3
-rw-r--r--platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationEx.java3
-rw-r--r--platform/core-impl/src/com/intellij/openapi/options/AbstractSchemesManager.java3
-rw-r--r--platform/core-impl/src/com/intellij/openapi/progress/util/AbstractProgressIndicatorBase.java4
-rw-r--r--platform/core-impl/src/com/intellij/psi/SingleRootFileViewProvider.java2
-rw-r--r--platform/core-impl/src/com/intellij/psi/impl/PsiToDocumentSynchronizer.java16
-rw-r--r--platform/core-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java24
-rw-r--r--platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java21
-rw-r--r--platform/core-impl/src/com/intellij/psi/impl/source/tree/CompositeElement.java7
-rw-r--r--platform/core-impl/src/com/intellij/psi/impl/source/tree/FileElement.java12
-rw-r--r--platform/core-impl/src/com/intellij/psi/impl/source/tree/LeafElement.java8
-rw-r--r--platform/core-impl/src/com/intellij/util/DocumentUtil.java4
-rw-r--r--platform/dvcs-api/src/com/intellij/dvcs/push/OutgoingCommitsProvider.java17
-rw-r--r--platform/dvcs-api/src/com/intellij/dvcs/push/PushSpec.java22
-rw-r--r--platform/dvcs-api/src/com/intellij/dvcs/push/PushSupport.java31
-rw-r--r--platform/dvcs-api/src/com/intellij/dvcs/push/PushTarget.java1
-rw-r--r--platform/dvcs-api/src/com/intellij/dvcs/push/Pusher.java17
-rw-r--r--platform/dvcs-api/src/com/intellij/dvcs/push/VcsError.java4
-rw-r--r--platform/dvcs-impl/dvcs-impl.iml2
-rw-r--r--platform/dvcs-impl/src/com/intellij/dvcs/push/PushController.java184
-rw-r--r--platform/dvcs-impl/src/com/intellij/dvcs/push/ui/EditableTreeNode.java4
-rw-r--r--platform/dvcs-impl/src/com/intellij/dvcs/push/ui/PushLog.java53
-rw-r--r--platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryNode.java53
-rw-r--r--platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryWithBranchPanel.java30
-rw-r--r--platform/dvcs-impl/src/com/intellij/dvcs/push/ui/SingleRepositoryNode.java9
-rw-r--r--platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsFullCommitDetailsNode.java12
-rw-r--r--platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsPushDialog.java25
-rw-r--r--platform/dvcs-impl/testFramework/com/intellij/dvcs/test/MockProject.java171
-rw-r--r--platform/dvcs-impl/testFramework/com/intellij/dvcs/test/MockProjectRootManager.java109
-rw-r--r--platform/editor-ui-api/src/com/intellij/ide/ui/UISettings.java3
-rw-r--r--platform/editor-ui-api/src/com/intellij/openapi/actionSystem/ActionManager.java17
-rw-r--r--platform/editor-ui-api/src/com/intellij/openapi/editor/Caret.java32
-rw-r--r--platform/editor-ui-api/src/com/intellij/openapi/editor/CaretModel.java16
-rw-r--r--platform/editor-ui-api/src/com/intellij/openapi/editor/colors/FontPreferences.java7
-rw-r--r--platform/editor-ui-api/src/com/intellij/openapi/editor/event/EditorFactoryListener.java6
-rw-r--r--platform/extensions/src/com/intellij/openapi/extensions/Extensions.java11
-rw-r--r--platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/RemoteExternalSystemCommunicationManager.java6
-rw-r--r--platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskRunner.java8
-rw-r--r--platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/AbstractExternalSystemToolWindowFactory.java7
-rw-r--r--platform/icons/src/actions/GroupByClass.pngbin494 -> 366 bytes
-rw-r--r--platform/icons/src/actions/GroupByFile.pngbin266 -> 176 bytes
-rw-r--r--platform/icons/src/general/projectConfigurable.pngbin1076 -> 988 bytes
-rw-r--r--platform/icons/src/general/projectConfigurable@2x.pngbin1098 -> 1093 bytes
-rw-r--r--platform/icons/src/gutter/extAnnotation.pngbin322 -> 224 bytes
-rw-r--r--platform/icons/src/nodes/nativeLibrariesFolder.pngbin0 -> 295 bytes
-rw-r--r--platform/icons/src/nodes/nativeLibrariesFolder@2x.pngbin0 -> 690 bytes
-rw-r--r--platform/icons/src/nodes/nativeLibrariesFolder@2x_dark.pngbin0 -> 677 bytes
-rw-r--r--platform/icons/src/nodes/nativeLibrariesFolder_dark.pngbin0 -> 410 bytes
-rw-r--r--platform/indexing-api/src/com/intellij/psi/search/searches/ReferencesSearch.java5
-rw-r--r--platform/lang-api/src/com/intellij/execution/RunProfileStarter.java17
-rw-r--r--platform/lang-api/src/com/intellij/execution/configuration/RunConfigurationExtensionsManager.java3
-rw-r--r--platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationsSettings.java3
-rw-r--r--platform/lang-api/src/com/intellij/execution/configurations/SimpleProgramParameters.java4
-rw-r--r--platform/lang-api/src/com/intellij/execution/runners/AsyncGenericProgramRunner.java41
-rw-r--r--platform/lang-api/src/com/intellij/execution/runners/BaseProgramRunner.java7
-rw-r--r--platform/lang-api/src/com/intellij/execution/runners/ExecutionUtil.java17
-rw-r--r--platform/lang-api/src/com/intellij/execution/runners/GenericProgramRunner.java31
-rw-r--r--platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java14
-rw-r--r--platform/lang-api/src/com/intellij/lang/documentation/AbstractDocumentationProvider.java9
-rw-r--r--platform/lang-api/src/com/intellij/lang/documentation/CompositeDocumentationProvider.java86
-rw-r--r--platform/lang-api/src/com/intellij/lang/documentation/DocumentationProviderEx.java6
-rw-r--r--platform/lang-api/src/com/intellij/lexer/CompositeLexer.java12
-rw-r--r--platform/lang-api/src/com/intellij/openapi/roots/ui/OrderRootTypeUIFactory.java2
-rw-r--r--platform/lang-api/src/com/intellij/psi/codeStyle/LegacyCodeStyleSettingsManager.java1
-rw-r--r--platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ArrangementSectionRule.java12
-rw-r--r--platform/lang-api/src/com/intellij/psi/util/PsiUtilBase.java2
-rw-r--r--platform/lang-impl/src/com/intellij/application/options/CodeStyleSchemesConfigurable.java46
-rw-r--r--platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.form6
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/actions/FormatChangedTextUtil.java3
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/actions/OptimizeImportsProcessor.java5
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java51
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java16
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java16
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java3
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/EditorTracker.java4
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/IdentifierHighlighterPass.java32
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java95
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PsiElementListNavigator.java4
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TrafficLightRenderer.java13
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TrafficProgressPanel.java108
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/WholeFileLocalInspectionsPassFactory.java2
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/documentation/DockablePopupManager.java75
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java96
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java248
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/documentation/QuickDocOnMouseOverManager.java2
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/documentation/QuickDocUtil.java72
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java13
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/editorActions/JoinLinesHandler.java59
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/generation/GenerateByPatternDialog.java22
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/highlighting/HighlightUsagesHandlerFactory.java4
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/highlighting/HighlightUsagesHandlerFactoryBase.java40
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java44
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java3
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditAction.java28
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java2
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionManagerImpl.java33
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java18
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/navigation/CtrlMouseHandler.java4
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoTargetHandler.java3
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/navigation/ImplementationSearcher.java8
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateLookupElementImpl.java4
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateSettingsEditor.java23
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateEditorUtil.java68
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateSettings.java2
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/template/postfix/settings/PostfixDescriptionPanel.form15
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixLiveTemplate.java7
-rw-r--r--platform/lang-impl/src/com/intellij/codeInspection/actions/CleanupInspectionIntention.java (renamed from platform/analysis-impl/src/com/intellij/codeInspection/actions/CleanupInspectionIntention.java)11
-rw-r--r--platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java17
-rw-r--r--platform/lang-impl/src/com/intellij/conversion/impl/ui/ConvertProjectDialog.java8
-rw-r--r--platform/lang-impl/src/com/intellij/execution/actions/ChooseRunConfigurationPopup.java128
-rw-r--r--platform/lang-impl/src/com/intellij/execution/configuration/EnvironmentVariablesComponent.java (renamed from platform/lang-api/src/com/intellij/execution/configuration/EnvironmentVariablesComponent.java)22
-rw-r--r--platform/lang-impl/src/com/intellij/execution/configuration/EnvironmentVariablesTextFieldWithBrowseButton.java (renamed from platform/lang-api/src/com/intellij/execution/configuration/EnvironmentVariablesTextFieldWithBrowseButton.java)34
-rw-r--r--platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java11
-rw-r--r--platform/lang-impl/src/com/intellij/execution/impl/EditConfigurationsDialog.java7
-rw-r--r--platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java10
-rw-r--r--platform/lang-impl/src/com/intellij/execution/runners/AbstractConsoleRunnerWithHistory.java10
-rw-r--r--platform/lang-impl/src/com/intellij/execution/runners/DefaultProgramRunner.java10
-rw-r--r--platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java25
-rw-r--r--platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java3
-rw-r--r--platform/lang-impl/src/com/intellij/find/findInProject/FindInProjectManager.java10
-rw-r--r--platform/lang-impl/src/com/intellij/find/impl/FindInProjectTask.java2
-rw-r--r--platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreview.java31
-rw-r--r--platform/lang-impl/src/com/intellij/find/impl/livePreview/ReplacementView.java20
-rw-r--r--platform/lang-impl/src/com/intellij/find/replaceInProject/ReplaceInProjectManager.java31
-rw-r--r--platform/lang-impl/src/com/intellij/formatting/alignment/AlignmentStrategy.java17
-rw-r--r--platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/ExportableFileTemplateSettings.java15
-rw-r--r--platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateConfigurable.java69
-rw-r--r--platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarModel.java7
-rw-r--r--platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPopup.java7
-rw-r--r--platform/lang-impl/src/com/intellij/ide/projectView/ProjectViewSettings.java23
-rw-r--r--platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewPane.java81
-rw-r--r--platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewDirectoryHelper.java33
-rw-r--r--platform/lang-impl/src/com/intellij/ide/todo/ScopeBasedTodosPanel.java129
-rw-r--r--platform/lang-impl/src/com/intellij/ide/todo/ScopeBasedTodosTreeBuilder.java5
-rw-r--r--platform/lang-impl/src/com/intellij/ide/todo/ScopeBasedTodosTreeStructure.java25
-rw-r--r--platform/lang-impl/src/com/intellij/ide/ui/search/TraverseUIStarter.java15
-rw-r--r--platform/lang-impl/src/com/intellij/ide/util/PsiElementListCellRenderer.java2
-rw-r--r--platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java22
-rw-r--r--platform/lang-impl/src/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java9
-rw-r--r--platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java12
-rw-r--r--platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeDescriptorProvider.java1
-rw-r--r--platform/lang-impl/src/com/intellij/injected/editor/CaretModelWindow.java13
-rw-r--r--platform/lang-impl/src/com/intellij/injected/editor/InjectedCaret.java12
-rw-r--r--platform/lang-impl/src/com/intellij/internal/ImageDuplicateResultsDialog.java2
-rw-r--r--platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java106
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ModuleStateStorageManager.java1
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/roots/impl/PushedFilePropertiesUpdaterImpl.java86
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/util/registry/RegistryUi.java31
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/vcs/checkin/CheckinHandlerUtil.java12
-rw-r--r--platform/lang-impl/src/com/intellij/packageDependencies/actions/AnalyzeDependenciesOnSpecifiedTargetHandler.java2
-rw-r--r--platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/InspectionsConfigTreeRenderer.java32
-rw-r--r--platform/lang-impl/src/com/intellij/psi/impl/DocumentCommitThread.java18
-rw-r--r--platform/lang-impl/src/com/intellij/psi/impl/file/impl/PsiVFSListener.java6
-rw-r--r--platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java61
-rw-r--r--platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java3
-rw-r--r--platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleSchemesImpl.java13
-rw-r--r--platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/PersistableCodeStyleSchemes.java22
-rw-r--r--platform/lang-impl/src/com/intellij/psi/stubs/StubIndexState.java6
-rw-r--r--platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java10
-rw-r--r--platform/lang-impl/src/com/intellij/refactoring/rename/RenameProcessor.java23
-rw-r--r--platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java9
-rw-r--r--platform/lang-impl/src/com/intellij/semantic/SemServiceImpl.java12
-rw-r--r--platform/lang-impl/src/com/intellij/tools/ToolConfigurable.java16
-rw-r--r--platform/lang-impl/src/com/intellij/tools/ToolManager.java3
-rw-r--r--platform/lang-impl/src/com/intellij/ui/JBTableWithHintProvider.java67
-rw-r--r--platform/lang-impl/src/com/intellij/ui/JBTreeWithHintProvider.java64
-rw-r--r--platform/lang-impl/src/com/intellij/ui/popup/PopupUpdateProcessor.java17
-rw-r--r--platform/lang-impl/src/com/intellij/usageView/UsageViewUtil.java4
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java2
-rw-r--r--platform/lang-impl/src/com/intellij/webcore/packaging/ManagePackagesDialog.java2
-rw-r--r--platform/platform-api/platform-api.iml2
-rw-r--r--platform/platform-api/src/com/intellij/execution/configurations/GeneralCommandLine.java8
-rw-r--r--platform/platform-api/src/com/intellij/execution/configurations/PathEnvironmentVariableUtil.java50
-rw-r--r--platform/platform-api/src/com/intellij/execution/configurations/PtyCommandLine.java1
-rw-r--r--platform/platform-api/src/com/intellij/execution/process/AnsiEscapeDecoder.java52
-rw-r--r--platform/platform-api/src/com/intellij/ide/UiActivity.java8
-rw-r--r--platform/platform-api/src/com/intellij/ide/UiActivityMonitor.java9
-rw-r--r--platform/platform-api/src/com/intellij/ide/browsers/BrowserLauncherAppless.java25
-rw-r--r--platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java70
-rw-r--r--platform/platform-api/src/com/intellij/mock/MockProgressIndicator.java98
-rw-r--r--platform/platform-api/src/com/intellij/notification/NotificationGroup.java4
-rw-r--r--platform/platform-api/src/com/intellij/openapi/actionSystem/ActionPlaces.java3
-rw-r--r--platform/platform-api/src/com/intellij/openapi/actionSystem/ActionStub.java7
-rw-r--r--platform/platform-api/src/com/intellij/openapi/actionSystem/CommonShortcuts.java12
-rw-r--r--platform/platform-api/src/com/intellij/openapi/application/ApplicationStarter.java27
-rw-r--r--platform/platform-api/src/com/intellij/openapi/application/ApplicationStarterEx.java18
-rw-r--r--platform/platform-api/src/com/intellij/openapi/diff/ActionButtonPresentation.java2
-rw-r--r--platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptor.java54
-rw-r--r--platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptorFactory.java89
-rw-r--r--platform/platform-api/src/com/intellij/openapi/options/ConfigurableBase.java (renamed from platform/platform-impl/src/com/intellij/openapi/options/ConfigurableBase.java)0
-rw-r--r--platform/platform-api/src/com/intellij/openapi/options/ConfigurableEP.java3
-rw-r--r--platform/platform-api/src/com/intellij/openapi/options/ConfigurableUi.java (renamed from platform/platform-impl/src/com/intellij/openapi/options/ConfigurableUi.java)0
-rw-r--r--platform/platform-api/src/com/intellij/openapi/options/ShowSettingsUtil.java8
-rw-r--r--platform/platform-api/src/com/intellij/openapi/options/SimpleConfigurable.java (renamed from platform/platform-impl/src/com/intellij/openapi/options/SimpleConfigurable.java)0
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/Banner.java3
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/DetailsComponent.java88
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/DialogBuilder.java38
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java8
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/DialogWrapperPeerFactory.java21
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/MessageDialogBuilder.java1
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/Messages.java9
-rw-r--r--platform/platform-api/src/com/intellij/openapi/util/PasswordUtil.java14
-rw-r--r--platform/platform-api/src/com/intellij/openapi/util/registry/RegistryState.java14
-rw-r--r--platform/platform-api/src/com/intellij/openapi/wm/ToolWindowId.java1
-rw-r--r--platform/platform-api/src/com/intellij/ui/ColoredListCellRenderer.java11
-rw-r--r--platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java8
-rw-r--r--platform/platform-api/src/com/intellij/ui/GuiUtils.java32
-rw-r--r--platform/platform-api/src/com/intellij/ui/HyperlinkLabel.java25
-rw-r--r--platform/platform-api/src/com/intellij/ui/InplaceButton.java6
-rw-r--r--platform/platform-api/src/com/intellij/ui/JBListWithHintProvider.java64
-rw-r--r--platform/platform-api/src/com/intellij/ui/ScreenUtil.java124
-rw-r--r--platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java4
-rw-r--r--platform/platform-api/src/com/intellij/ui/popup/HintUpdateSupply.java156
-rw-r--r--platform/platform-api/src/com/intellij/ui/table/JBTable.java4
-rw-r--r--platform/platform-api/src/com/intellij/util/PlatformUtils.java8
-rw-r--r--platform/platform-api/src/com/intellij/util/net/AuthenticationDialog.java12
-rw-r--r--platform/platform-api/src/com/intellij/util/net/HTTPProxySettingsDialog.java31
-rw-r--r--platform/platform-api/src/com/intellij/util/net/HTTPProxySettingsPanel.java389
-rw-r--r--platform/platform-api/src/com/intellij/util/net/HttpConfigurable.java296
-rw-r--r--platform/platform-api/src/com/intellij/util/net/HttpProxyConfigurable.java44
-rw-r--r--platform/platform-api/src/com/intellij/util/net/HttpProxySettingsUi.form (renamed from platform/platform-api/src/com/intellij/util/net/HTTPProxySettings.form)47
-rw-r--r--platform/platform-api/src/com/intellij/util/net/HttpProxySettingsUi.java386
-rw-r--r--platform/platform-api/src/com/intellij/util/net/IOExceptionDialog.java22
-rw-r--r--platform/platform-api/src/com/intellij/util/net/IdeaWideAuthenticator.java24
-rw-r--r--platform/platform-api/src/com/intellij/util/net/IdeaWideProxySelector.java4
-rw-r--r--platform/platform-api/src/com/intellij/util/net/NetUtils.java2
-rw-r--r--platform/platform-api/src/com/intellij/util/proxy/CommonProxy.java45
-rw-r--r--platform/platform-api/src/com/intellij/util/ui/ButtonlessScrollBarUI.java14
-rw-r--r--platform/platform-api/src/com/intellij/util/ui/StatusText.java3
-rw-r--r--platform/platform-impl/src/com/intellij/diagnostic/ErrorReportConfigurable.java29
-rw-r--r--platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountDialog.java28
-rw-r--r--platform/platform-impl/src/com/intellij/ide/CommandLineProcessor.java6
-rw-r--r--platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java63
-rw-r--r--platform/platform-impl/src/com/intellij/ide/IdeRepaintManager.java12
-rw-r--r--platform/platform-impl/src/com/intellij/ide/UiActivityMonitorImpl.java170
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actionMacro/actions/EditMacrosAction.java21
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actions/BaseNavigateToSourceAction.java41
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java11
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actions/OpenFileAction.java117
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actions/OpenProjectFileChooserDescriptor.java87
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsUtilImpl.java115
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actions/ViewSourceAction.java12
-rw-r--r--platform/platform-impl/src/com/intellij/ide/customize/AbstractCustomizeWizardStep.java10
-rw-r--r--platform/platform-impl/src/com/intellij/ide/customize/CustomizeDesktopEntryStep.java108
-rw-r--r--platform/platform-impl/src/com/intellij/ide/customize/CustomizeFeaturedPluginsStepPanel.java17
-rw-r--r--platform/platform-impl/src/com/intellij/ide/customize/CustomizeIDEWizardDialog.java22
-rw-r--r--platform/platform-impl/src/com/intellij/ide/customize/CustomizePluginsStepPanel.java4
-rw-r--r--platform/platform-impl/src/com/intellij/ide/customize/CustomizeUIThemeStepPanel.java12
-rw-r--r--platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/MasterKeyPasswordSafe.java65
-rw-r--r--platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java24
-rw-r--r--platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java57
-rw-r--r--platform/platform-impl/src/com/intellij/ide/ui/AppearancePanel.form43
-rw-r--r--platform/platform-impl/src/com/intellij/ide/util/TipUIUtil.java2
-rw-r--r--platform/platform-impl/src/com/intellij/idea/IdeaApplication.java18
-rw-r--r--platform/platform-impl/src/com/intellij/notification/impl/actions/ShowDelayedMessageInternalAction.java58
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/actionSystem/ex/QuickListsManager.java3
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java786
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ChameleonAction.java68
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/config/ActionBean.java4
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java47
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ApplicationStoreImpl.java23
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/BaseFileConfigurableStoreImpl.java4
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java40
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DefaultProjectStoreImpl.java4
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/OldStreamProviderAdapter.java2
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStateStorageManager.java2
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManager.java2
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java7
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StorageUtil.java25
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.java5
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/ApplicationStarterBase.java (renamed from platform/platform-api/src/com/intellij/openapi/diff/ApplicationStarterBase.java)14
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/DiffApplication.java (renamed from platform/platform-api/src/com/intellij/openapi/diff/DiffApplication.java)2
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/MergeApplication.java (renamed from platform/platform-api/src/com/intellij/openapi/diff/MergeApplication.java)2
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/ex/DiffPanelOptions.java2
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffUtil.java12
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/impl/external/BaseExternalTool.java26
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/impl/external/ExtCompareFiles.java3
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/impl/external/ExtCompareFolders.java5
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/impl/external/ExtMergeFiles.java54
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/EditorPlaceHolder.java4
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/impl/util/SyncScrollSupport.java66
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/colors/impl/EditorColorsManagerImpl.java3
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java26
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java22
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java13
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/ContextMenuImpl.java25
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorFactoryImpl.java15
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java6
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java55
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java34
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceManager.java37
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentCaret.java13
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentCaretModel.java5
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java2
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java19
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java54
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/PreviewPanel.java244
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/RemoteFilePanel.java12
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorProvider.java2
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java3
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/keymap/impl/KeymapManagerImpl.java2
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/CompositeConfigurable.java4
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/SchemesManagerFactoryImpl.java20
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/SchemesManagerImpl.java54
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableWrapper.java4
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/ex/GlassPanel.java52
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/ex/MixedConfigurableGroup.java75
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/ex/NodeConfigurable.java12
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/ex/SingleConfigurableEditor.java16
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/newEditor/IdeSettingsDialog.java330
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditor.java442
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java78
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/newEditor/PreferencesDialog.form41
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/newEditor/PreferencesDialog.java159
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsFilter.java211
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsTreeView.java182
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java9
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorBase.java6
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorUtils.java134
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectMacrosUtil.java12
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java24
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginAdvertiserEditorNotificationProvider.java9
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiser.java8
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vcs/changes/issueLinks/LinkMouseListenerBase.java16
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vfs/ex/temp/TempFileSystem.java5
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java13
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PresentationModeProgressPanel.form4
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PresentationModeProgressPanel.java5
-rw-r--r--platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java1
-rw-r--r--platform/platform-impl/src/com/intellij/ui/AppUIUtil.java8
-rw-r--r--platform/platform-impl/src/com/intellij/ui/EditorComboBoxEditor.java12
-rw-r--r--platform/platform-impl/src/com/intellij/ui/EditorNotificationsImpl.java10
-rw-r--r--platform/platform-impl/src/com/intellij/ui/EditorTextField.java10
-rw-r--r--platform/platform-impl/src/com/intellij/ui/FocusTrackback.java10
-rw-r--r--platform/platform-impl/src/com/intellij/ui/LibNotifyWrapper.java15
-rw-r--r--platform/platform-impl/src/com/intellij/ui/SpeedSearchBase.java10
-rwxr-xr-xplatform/platform-impl/src/com/intellij/ui/messages/SheetController.java4
-rwxr-xr-xplatform/platform-impl/src/com/intellij/ui/messages/SheetMessage.java12
-rw-r--r--platform/platform-impl/src/com/intellij/ui/popup/WizardPopup.java6
-rw-r--r--platform/platform-impl/src/net/sf/cglib/proxy/AdvancedEnhancer.java182
-rw-r--r--platform/platform-impl/src/org/jetbrains/io/BuiltInServer.java5
-rw-r--r--platform/platform-resources-en/src/messages/ActionsBundle.properties2
-rw-r--r--platform/platform-resources-en/src/messages/IdeBundle.properties7
-rw-r--r--platform/platform-resources-en/src/messages/InspectionsBundle.properties2
-rw-r--r--platform/platform-resources-en/src/messages/OptionsBundle.properties16
-rw-r--r--platform/platform-resources-en/src/messages/UIBundle.properties2
-rw-r--r--platform/platform-resources-en/src/messages/XDebuggerBundle.properties3
-rw-r--r--platform/platform-resources/src/META-INF/LangExtensions.xml16
-rw-r--r--platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml3
-rw-r--r--platform/platform-resources/src/META-INF/PlatformExtensions.xml15
-rw-r--r--platform/platform-resources/src/META-INF/PlatformLangPlugin.xml2
-rw-r--r--platform/platform-resources/src/META-INF/VcsExtensions.xml2
-rw-r--r--platform/platform-resources/src/META-INF/XmlPlugin.xml3
-rw-r--r--platform/platform-resources/src/META-INF/mime.types4
-rw-r--r--platform/platform-resources/src/META-INF/xdebugger.xml2
-rw-r--r--platform/platform-resources/src/brokenPlugins.txt14
-rw-r--r--platform/platform-resources/src/idea/LangActions.xml3
-rw-r--r--platform/platform-resources/src/idea/PlatformActions.xml2
-rw-r--r--platform/platform-tests/testSrc/com/intellij/codeInsight/actions/ReformatOnlyVcsChangedTextTest.java22
-rw-r--r--platform/platform-tests/testSrc/com/intellij/execution/process/AnsiEscapeDecoderTest.java35
-rw-r--r--platform/platform-tests/testSrc/com/intellij/ide/ActivityMonitorTest.java67
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/components/impl/ApplicationStoreTest.java153
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/components/impl/StateStorageManagerImplTest.java2
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/HeavyFileEditorManagerTestCase.java7
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/keymap/impl/ModifierKeyDoubleClickHandlerTest.java9
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java4
-rw-r--r--platform/platform-tests/testSrc/com/intellij/psi/impl/PsiDocumentManagerImplTest.java68
-rw-r--r--platform/projectModel-api/src/com/intellij/openapi/components/StoragePathMacros.java2
-rw-r--r--platform/projectModel-api/src/com/intellij/openapi/project/DefaultProjectTypeProvider.java35
-rw-r--r--platform/projectModel-api/src/com/intellij/openapi/project/ProjectType.java59
-rw-r--r--platform/projectModel-api/src/com/intellij/openapi/project/ProjectTypeService.java61
-rw-r--r--platform/projectModel-api/src/com/intellij/openapi/roots/OrderRootType.java5
-rw-r--r--platform/projectModel-api/src/com/intellij/openapi/roots/PersistentOrderRootType.java8
-rw-r--r--platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/DefaultStateSerializer.java7
-rw-r--r--platform/projectModel-impl/src/com/intellij/openapi/projectRoots/impl/ProjectRootContainerImpl.java21
-rw-r--r--platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java120
-rw-r--r--platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootIndex.java14
-rw-r--r--platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java15
-rw-r--r--platform/projectModel-impl/src/messages/ProjectBundle.properties2
-rw-r--r--platform/remote-servers/impl/src/META-INF/RemoteServers.xml2
-rw-r--r--platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudAccountSelectionEditor.java9
-rw-r--r--platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/SourceMapDecoder.java40
-rw-r--r--platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/SourceResolver.java23
-rw-r--r--platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerTreeStructure.java14
-rw-r--r--platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/TestComparisionFailedState.java21
-rw-r--r--platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/TestFailedState.java4
-rw-r--r--platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/TestsPresentationUtil.java19
-rw-r--r--platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/DataProvider.java16
-rw-r--r--platform/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ui/ReplaceUsageViewContext.java7
-rw-r--r--platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/DialogBase.java152
-rw-r--r--platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/EditVarConstraintsDialog.java22
-rw-r--r--platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchCommand.java7
-rw-r--r--platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchContext.java3
-rw-r--r--platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchDialog.java18
-rw-r--r--platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/UIUtil.java16
-rw-r--r--platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/UsageViewContext.java34
-rw-r--r--platform/structuralsearch/source/messages/SSRBundle.properties6
-rw-r--r--platform/structure-view-impl/src/com/intellij/ide/util/treeView/smartTree/SmartTreeStructure.java11
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/MockSchemesManagerFactory.java9
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java2
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/PlatformTestUtil.java13
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/PlatformUltraLiteTestFixture.java14
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java3
-rw-r--r--platform/testRunner/src/com/intellij/execution/testframework/TestTreeView.java4
-rw-r--r--platform/usageView/src/com/intellij/usages/impl/GroupNode.java6
-rw-r--r--platform/usageView/src/com/intellij/usages/impl/SearchForUsagesRunnable.java2
-rw-r--r--platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java3
-rw-r--r--platform/util-rt/src/com/intellij/openapi/util/Conditions.java10
-rw-r--r--platform/util/resources/misc/registry.properties18
-rw-r--r--platform/util/src/com/intellij/diagnostic/ThreadDumper.java27
-rw-r--r--platform/util/src/com/intellij/icons/AllIcons.java3
-rw-r--r--platform/util/src/com/intellij/openapi/application/PathManager.java2
-rw-r--r--platform/util/src/com/intellij/openapi/diagnostic/Logger.java1
-rw-r--r--platform/util/src/com/intellij/openapi/util/JDOMUtil.java42
-rw-r--r--platform/util/src/com/intellij/openapi/util/LowMemoryWatcher.java20
-rw-r--r--platform/util/src/com/intellij/openapi/util/NotNullLazyValue.java1
-rw-r--r--platform/util/src/com/intellij/openapi/util/Ref.java2
-rw-r--r--platform/util/src/com/intellij/openapi/util/io/FileUtil.java3
-rw-r--r--platform/util/src/com/intellij/openapi/util/text/StringUtil.java14
-rw-r--r--platform/util/src/com/intellij/util/ArrayUtil.java2
-rw-r--r--platform/util/src/com/intellij/util/EnvironmentUtil.java18
-rw-r--r--platform/util/src/com/intellij/util/concurrency/BoundedTaskExecutor.java13
-rw-r--r--platform/util/src/com/intellij/util/concurrency/SequentialTaskExecutor.java7
-rw-r--r--platform/util/src/com/intellij/util/containers/ConcurrentInstanceMap.java4
-rw-r--r--platform/util/src/com/intellij/util/containers/ContainerUtil.java22
-rw-r--r--platform/util/src/com/intellij/util/containers/FilteringIterator.java17
-rw-r--r--platform/util/src/com/intellij/util/containers/InternalIterator.java4
-rw-r--r--platform/util/src/com/intellij/util/io/storage/HeavyProcessLatch.java9
-rw-r--r--platform/util/src/com/intellij/util/xmlb/MapBinding.java8
-rw-r--r--platform/util/src/com/intellij/util/xmlb/XmlSerializer.java1
-rw-r--r--platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.java21
-rw-r--r--platform/vcs-api/src/com/intellij/openapi/vcs/VcsTaskHandler.java17
-rw-r--r--platform/vcs-api/src/com/intellij/openapi/vcs/changes/ChangeListManagerGate.java8
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/VcsNotifier.java2
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/CallbackData.java6
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesFragmentedDiffPanel.java185
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/PreparedFragmentedContent.java4
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/CompoundShelfFileProcessor.java20
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelfManagerConfigurationMerger.java2
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java14
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/checkin/CodeAnalysisBeforeCheckinHandler.java5
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/checkin/CodeCleanupCheckinHandlerFactory.java5
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java6
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/ui/VcsBalloonProblemNotifier.java2
-rw-r--r--platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogFilterCollection.java3
-rw-r--r--platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogHashFilter.java5
-rw-r--r--platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/AbstractVisibleGraph.java2
-rw-r--r--platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/AbstractPrintElementsManager.java8
-rw-r--r--platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/FilterPrintElementsManager.java6
-rw-r--r--platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/visible/DottedEdges.java73
-rw-r--r--platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/visible/DottedEdgesComputer.java129
-rw-r--r--platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/visible/FilterGraphWithHiddenNodes.java21
-rw-r--r--platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogFilterer.java22
-rw-r--r--platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java67
-rw-r--r--platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogFilterCollectionImpl.java9
-rw-r--r--platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogHashFilterImpl.java36
-rw-r--r--platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogSettingsImpl.java5
-rw-r--r--platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogClassicFilterUi.java41
-rw-r--r--platform/xdebugger-api/src/com/intellij/xdebugger/XDebugSession.java18
-rw-r--r--platform/xdebugger-api/src/com/intellij/xdebugger/frame/XNearestSourcePosition.java22
-rw-r--r--platform/xdebugger-api/src/com/intellij/xdebugger/frame/XReferrersProvider.java23
-rw-r--r--platform/xdebugger-api/src/com/intellij/xdebugger/frame/XValue.java5
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java47
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerSmartStepIntoHandler.java2
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java3
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointManager.java2
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointActionsPanel.java7
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java11
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/CodeFragmentInputComponent.java1
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/EvaluationInputComponent.java2
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/ExpressionInputComponent.java1
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java187
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java40
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java43
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java4
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesViewBase.java95
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/GeneralConfigurableUi.form14
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/GeneralConfigurableUi.java6
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerGeneralSettings.java9
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerCopyPastePreprocessor.java47
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java1
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerEditorBase.java17
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerExpressionComboBox.java26
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerMultilineEditor.java2
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/ShowReferringObjectsAction.java51
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XAddToWatchesAction.java11
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XStackFrameNode.java37
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java8
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java66
-rw-r--r--plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ShowByteCodeAction.java2
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml12
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties11
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/TypeMayBeWeakenedInspection.java58
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EqualsWithItselfInspection.java78
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/StaticInheritanceFix.java11
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/JUnit3MethodNamingConventionInspectionBase.java102
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/JUnit3StyleTestMethodInJUnit4ClassInspection.java56
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/JUnit4MethodNamingConventionInspectionBase.java102
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/TestMethodIsPublicVoidNoArgInspection.java29
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/InstanceMethodNamingConventionInspectionBase.java39
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/NativeMethodNamingConventionInspectionBase.java2
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/StaticMethodNamingConventionInspectionBase.java15
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/PointlessArithmeticExpressionInspection.java18
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ImportUtils.java5
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/InheritanceUtil.java6
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/SideEffectChecker.java9
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/TestUtils.java35
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessarilyQualifiedInnerClassAccessInspection.java33
-rw-r--r--plugins/InspectionGadgets/src/com/siyeh/ig/junit/JUnit3MethodNamingConventionInspection.java30
-rw-r--r--plugins/InspectionGadgets/src/com/siyeh/ig/junit/JUnit4AnnotatedMethodInJUnit3TestCaseInspection.java31
-rw-r--r--plugins/InspectionGadgets/src/com/siyeh/ig/junit/JUnit4MethodNamingConventionInspection.java30
-rw-r--r--plugins/InspectionGadgets/src/inspectionDescriptions/EqualsWithItself.html10
-rw-r--r--plugins/InspectionGadgets/src/inspectionDescriptions/InstanceMethodNamingConvention.html2
-rw-r--r--plugins/InspectionGadgets/src/inspectionDescriptions/JUnit3MethodNamingConvention.html13
-rw-r--r--plugins/InspectionGadgets/src/inspectionDescriptions/JUnit4MethodNamingConvention.html13
-rw-r--r--plugins/InspectionGadgets/src/inspectionDescriptions/NativeMethodNamingConvention.html6
-rw-r--r--plugins/InspectionGadgets/src/inspectionDescriptions/StaticMethodNamingConvention.html2
-rw-r--r--plugins/InspectionGadgets/src/inspectionDescriptions/TestMethodIsPublicVoidNoArg.html4
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igfixes/abstraction/type_may_be_weakened/LocalClass.after.java11
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igfixes/abstraction/type_may_be_weakened/LocalClass.java11
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/weaken_type/TypeMayBeWeakened.java13
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/equals_with_itself/EqualsWithItself.java23
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igtest/junit/TestCaseWithNoTestMethodsInspection.java15
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igtest/junit/junit3_method_naming_convention/JUnit3MethodNamingConvention.java10
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igtest/junit/junit3_style_test_method_in_junit4_class/BeforeAnnotationUsed.java9
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igtest/junit/junit3_style_test_method_in_junit4_class/JUnit3StyleTestMethodInJUnit4Class.java10
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igtest/junit/junit4_method_naming_convention/JUnit4MethodNamingConvention.java16
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igtest/junit/test_case_with_no_test_methods/TestCaseWithNoTestMethods.java19
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igtest/junit/test_method_is_public_void_no_arg/JUnit3TestMethodIsPublicVoidNoArg.java16
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igtest/junit/test_method_is_public_void_no_arg/JUnit4TestMethodIsPublicVoidNoArg.java24
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igtest/migration/if_switch/IfCanBeSwitch.java29
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igtest/migration/if_switch/expected.xml44
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igtest/naming/native_method_naming_convention/NativeMethodNamingConvention.java2
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igtest/numeric/pointless_arithmetic_expression/PointlessArithmeticExpression.java51
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igtest/numeric/pointless_arithmetic_expression/expected.xml129
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/LightInspectionTestCase.java9
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/EqualsWithItselfInspectionTest.java (renamed from platform/platform-impl/src/com/intellij/ide/actionMacro/EditMacrosDialog.java)29
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/abstraction/TypeMayBeWeakenedFixTest.java5
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/junit/JUnit3MethodNamingConventionInspectionTest.java45
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/junit/JUnit3StyleTestMethodInJUnit4ClassInspectionTest.java57
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/junit/JUnit4MethodNamingConventionInspectionTest.java48
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/junit/TestCaseWithNoTestMethodsInspectionTest.java45
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/junit/TestMethodIsPublicVoidNoArgInspectionTest.java46
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/migration/IfCanBeSwitchInspectionTest.java25
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/naming/InstanceMethodNamingConventionInspectionTest.java8
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/naming/OverloadedVarargsMethodInspectionTest.java (renamed from plugins/InspectionGadgets/testsrc/com/siyeh/ig/naming/com/siyeh/ig/naming/OverloadedVarargsMethodInspectionTest.java)2
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/naming/StaticMethodNamingConventionInspectionTest.java8
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/numeric/PointlessArithmeticExpressionInspectionTest.java17
-rw-r--r--plugins/ShortcutPromoter/src/com/intellij/promoter/ShortcutPromoterManager.java7
-rw-r--r--plugins/ant/src/com/intellij/lang/ant/config/execution/AntRunner.java6
-rw-r--r--plugins/ant/src/com/intellij/lang/ant/config/impl/AntToolWindowFactory.java3
-rw-r--r--plugins/copyright/src/META-INF/plugin.xml2
-rw-r--r--plugins/copyright/src/com/maddyhome/idea/copyright/ui/CopyrightProfilesPanel.java45
-rw-r--r--plugins/cvs/javacvs-src/org/netbeans/lib/cvsclient/ConnectionStreams.java19
-rw-r--r--plugins/devkit/resources/META-INF/plugin.xml1
-rw-r--r--plugins/devkit/src/actions/NewActionDialog.java3
-rw-r--r--plugins/devkit/src/dom/generator/DomGenPanel.java4
-rw-r--r--plugins/devkit/src/inspections/DevKitImplementedAtRuntimeCondition.java32
-rw-r--r--plugins/devkit/src/inspections/DevKitImplicitUsageProvider.java2
-rw-r--r--plugins/devkit/src/run/PluginRunConfiguration.java6
-rw-r--r--plugins/devkit/testData/inspections/implicitUsage/ImplementedAtRuntimeDomElementImpl.java1
-rw-r--r--plugins/devkit/testData/inspections/implicitUsage/ImplementedAtRuntimeJamElementImpl.java1
-rw-r--r--plugins/devkit/testSources/inspections/DevKitImplicitUsageProviderTest.java24
-rw-r--r--plugins/eclipse/testData/iml/allProps/expected/expected.iml4
-rw-r--r--plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseImlTest.java19
-rw-r--r--plugins/git4idea/src/git4idea/GitTaskHandler.java5
-rw-r--r--plugins/git4idea/src/git4idea/commands/GitSSHGUIHandler.java39
-rw-r--r--plugins/git4idea/src/git4idea/log/GitBekParentFixer.java6
-rw-r--r--plugins/git4idea/src/git4idea/log/GitLogProvider.java2
-rw-r--r--plugins/git4idea/src/git4idea/push/GitPusher.java20
-rw-r--r--plugins/git4idea/test-stepdefs/git4idea/GitCherryPickStepdefs.java4
-rw-r--r--plugins/git4idea/test-stepdefs/git4idea/GitCucumberWorld.java2
-rw-r--r--plugins/git4idea/tests/git4idea/repo/GitRepositoryReaderTest.java2
-rw-r--r--plugins/git4idea/tests/git4idea/test/GitPlatformTest.java15
-rw-r--r--plugins/git4idea/tests/git4idea/test/MockVcsHelper.java (renamed from platform/dvcs-impl/testFramework/com/intellij/dvcs/test/MockVcsHelper.java)5
-rw-r--r--plugins/git4idea/tests/git4idea/test/MockVirtualFile.java (renamed from platform/dvcs-impl/testFramework/com/intellij/dvcs/test/MockVirtualFile.java)31
-rw-r--r--plugins/git4idea/tests/git4idea/validators/GitRefNameValidatorTest.java130
-rw-r--r--plugins/github/test/org/jetbrains/plugins/github/test/GithubTest.java3
-rw-r--r--plugins/gradle/jps-plugin/gradle-jps-plugin.iml2
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java65
-rw-r--r--plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/findUsages/AnnotatedMembersSearcher.java108
-rw-r--r--plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/members/GrMethodBaseImpl.java2
-rw-r--r--plugins/groovy/rt/src/org/jetbrains/groovy/compiler/rt/GroovycRunner.java3
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/GroovyCreateClassDialog.java2
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GrHighlightHandlerFactory.java14
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/parameterToEntry/ConvertParameterToMapEntryIntention.java31
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyNameSuggestionUtil.java2
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureUtil.java3
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrIntroduceConstantDialog.java2
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrIntroduceConstantProcessor.java4
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/runner/DefaultGroovyScriptRunner.java2
-rw-r--r--plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTestCase.java3
-rw-r--r--plugins/groovy/test/org/jetbrains/plugins/groovy/lang/actions/generate/GroovyGenerateMembersTest.groovy4
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgChangeProvider.java1
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/push/HgOutgoingCommitsProvider.java12
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushSupport.java34
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPusher.java28
-rw-r--r--plugins/hg4idea/testSrc/org/zmlx/hg4idea/push/HgPushParseTest.java75
-rw-r--r--plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/GenerateGetterSetterTest.java2
-rw-r--r--plugins/javaFX/src/org/jetbrains/plugins/javaFX/codeInsight/JavaFxGetterSetterPrototypeProvider.java7
-rw-r--r--plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxControllerFieldSearcher.java66
-rw-r--r--plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/model/MavenConstants.java4
-rw-r--r--plugins/properties/properties-psi-api/resources/messages/PropertiesBundle.properties3
-rw-r--r--plugins/properties/properties-psi-api/src/com/intellij/lang/properties/PropertiesUtil.java75
-rw-r--r--plugins/properties/properties-psi-api/src/com/intellij/lang/properties/ResourceBundle.java20
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/BundleNameEvaluator.java2
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/CustomResourceBundle.java109
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/CustomResourceBundleState.java93
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/PropertiesImplUtil.java30
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/ResourceBundleImpl.java20
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/ResourceBundleManager.java256
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/ResourceBundleManagerState.java72
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundlePropertyStructureViewElement.java11
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertiesFileImpl.java3
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/xml/XmlPropertiesFileImpl.java4
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/properties/PropertiesCoreEnvironment.java2
-rw-r--r--plugins/properties/src/META-INF/plugin.xml7
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/PropertiesFilesManager.java9
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/ResourceBundleReference.java4
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/customizeActions/CombinePropertiesFilesAction.java155
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/customizeActions/DissociateResourceBundleAction.java80
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleAsVirtualFile.java32
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditor.java4
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditorProvider.java2
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleStructureViewComponent.java2
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleUtil.java2
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/projectView/CustomResourceBundlePropertiesFileNode.java56
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleGrouper.java5
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleNode.java2
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/refactoring/rename/RenamePropertyProcessor.java2
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleRenamer.java9
-rw-r--r--plugins/properties/testSrc/com/intellij/lang/properties/CustomResourceBundleTest.java139
-rw-r--r--plugins/properties/testSrc/com/intellij/lang/properties/PropertiesUtilTest.java17
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java4
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java55
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/WorkingCopy.java10
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/api/BaseSvnClient.java50
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/api/ClientFactory.java38
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdClientFactory.java9
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdVersionClient.java11
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnClient.java2
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitClientFactory.java3
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitVersionClient.java3
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/api/VersionClient.java4
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/auth/AbstractAuthenticator.java14
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/auth/AuthenticationService.java (renamed from plugins/svn4idea/src/org/jetbrains/idea/svn/auth/IdeaSvnkitBasedAuthenticationCallback.java)51
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/auth/CredentialsAuthenticator.java14
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/auth/SSLServerCertificateAuthenticator.java10
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/auth/SvnAuthenticationNotifier.java26
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/BranchesLoader.java39
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/browse/SvnKitBrowseClient.java12
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/AuthCallbackCase.java7
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/AuthenticationCallback.java107
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/BaseCommandRuntimeModule.java5
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CertificateCallbackCase.java7
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandParametersResolutionModule.java2
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandRuntime.java29
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CredentialsCallback.java9
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/PassphraseCallback.java9
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/ProxyCallback.java9
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/ProxyModule.java8
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnBindException.java28
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnExecutableChecker.java3
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/TerminalSshModule.java2
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/TwoWaySslCallback.java5
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UsernamePasswordCallback.java14
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/update/CmdUpdateClient.java11
-rw-r--r--plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnCachingRepositoryPoolTest.java10
-rw-r--r--plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnCommandLineStabilityTest.java32
-rw-r--r--plugins/tasks/tasks-api/src/com/intellij/tasks/impl/BaseRepositoryImpl.java5
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskDialog.java5
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/impl/httpclient/NewBaseRepositoryImpl.java2
-rw-r--r--plugins/tasks/tasks-tests/test/com/intellij/tasks/vcs/TaskVcsTest.java3
-rw-r--r--plugins/terminal/resources/META-INF/terminal.xml2
-rw-r--r--plugins/testng/src/META-INF/plugin.xml3
-rw-r--r--plugins/testng/src/com/theoryinpractice/testng/TestNGReferenceContributor.java2
-rw-r--r--plugins/testng/src/com/theoryinpractice/testng/configuration/SearchingForTestsTask.java26
-rw-r--r--plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGRunnableState.java15
-rw-r--r--plugins/testng/src/com/theoryinpractice/testng/inspection/DependsOnMethodInspection.java46
-rw-r--r--plugins/testng/src/com/theoryinpractice/testng/inspection/TestNGMethodNamingConventionInspection.java105
-rw-r--r--plugins/testng/src/com/theoryinpractice/testng/model/TestNGRemoteListener.java4
-rw-r--r--plugins/testng/src/com/theoryinpractice/testng/ui/ResultTreeRenderer.java14
-rw-r--r--plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java7
-rw-r--r--plugins/testng/src/com/theoryinpractice/testng/ui/TestNGTestTreeView.java2
-rw-r--r--plugins/testng/src/com/theoryinpractice/testng/ui/actions/RerunFailedTestsAction.java22
-rw-r--r--plugins/testng/src/com/theoryinpractice/testng/util/TestNGUtil.java43
-rw-r--r--plugins/testng/src/inspectionDescriptions/TestNGMethodNamingConvention.html13
-rw-r--r--plugins/testng/testData/inspection/dependsOn/Dependencies.java8
-rw-r--r--plugins/ui-designer-core/src/com/intellij/designer/propertyTable/actions/ShowJavadoc.java2
-rw-r--r--plugins/ui-designer/src/com/intellij/uiDesigner/actions/AbstractCreateFormAction.java3
-rw-r--r--plugins/ui-designer/src/com/intellij/uiDesigner/actions/GenerateMainAction.java5
-rw-r--r--plugins/ui-designer/src/com/intellij/uiDesigner/binding/BoundIconRenderer.java4
-rw-r--r--plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormClassAnnotator.java4
-rw-r--r--plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormClassIndex.java8
-rw-r--r--plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormReferenceProvider.java4
-rw-r--r--plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormReferencesSearcher.java192
-rw-r--r--plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormRelatedFilesProvider.java4
-rw-r--r--plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormsRenamer.java4
-rw-r--r--plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormsRenamerFactory.java4
-rw-r--r--plugins/ui-designer/src/com/intellij/uiDesigner/binding/ResourceBundleFileReference.java4
-rw-r--r--plugins/ui-designer/src/com/intellij/uiDesigner/binding/ResourceBundleKeyReference.java4
-rw-r--r--plugins/ui-designer/src/com/intellij/uiDesigner/palette/ComponentItemDialog.java4
-rw-r--r--plugins/ui-designer/src/com/intellij/uiDesigner/projectView/Form.java4
-rw-r--r--plugins/ui-designer/src/com/intellij/uiDesigner/propertyInspector/properties/BindingProperty.java2
-rw-r--r--plugins/ui-designer/src/com/intellij/uiDesigner/propertyInspector/properties/IdentifierValidator.java3
-rw-r--r--plugins/ui-designer/src/com/intellij/uiDesigner/wizard/BeanStep.java2
-rw-r--r--plugins/ui-designer/src/com/intellij/uiDesigner/wizard/BindToNewBeanStep.java2
-rw-r--r--plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/XsltDebuggerRunner.java22
-rw-r--r--plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltExecutionStack.java3
-rw-r--r--python/build/pycharm_community_build.gant2
-rw-r--r--python/edu/build/desktop.ini6
-rw-r--r--python/edu/build/idea.nsi83
-rw-r--r--python/edu/build/paths.nsi2
-rw-r--r--python/edu/build/plugin-list.txt3
-rw-r--r--python/edu/build/pycharm_edu_build.gant19
-rw-r--r--python/edu/build/python.txt2
-rw-r--r--python/edu/build/resources/logo.bmpbin0 -> 154544 bytes
-rw-r--r--python/edu/build/resources/logo.pngbin46439 -> 0 bytes
-rw-r--r--python/edu/build/upload_pythonInfo.xml32
-rw-r--r--python/edu/course-creator/course-creator.iml16
-rw-r--r--python/edu/course-creator/resources/META-INF/plugin.xml60
-rw-r--r--python/edu/course-creator/resources/fileTemplates/internal/task.html.ft4
-rw-r--r--python/edu/course-creator/resources/fileTemplates/internal/task.py.ft1
-rw-r--r--python/edu/course-creator/resources/fileTemplates/internal/test_helper.py.ft127
-rw-r--r--python/edu/course-creator/resources/fileTemplates/internal/tests.py.ft17
-rw-r--r--python/edu/course-creator/resources/icons/gutter.pngbin0 -> 500 bytes
-rw-r--r--python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCEditorFactoryListener.java80
-rw-r--r--python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCProjectComponent.java58
-rw-r--r--python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCProjectGenerator.java101
-rw-r--r--python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCProjectService.java138
-rw-r--r--python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/StudyDocumentListener.java71
-rw-r--r--python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/AddTaskWindow.java105
-rw-r--r--python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CreateCourseArchive.java198
-rw-r--r--python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CreateLesson.java89
-rw-r--r--python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CreateTask.java122
-rw-r--r--python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CreateTaskFile.java110
-rw-r--r--python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/DeleteTaskWindow.java62
-rw-r--r--python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/ShowTaskWindowText.java44
-rw-r--r--python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/Course.java55
-rw-r--r--python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/Lesson.java45
-rw-r--r--python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/Task.java41
-rw-r--r--python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/TaskFile.java111
-rw-r--r--python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/TaskWindow.java133
-rw-r--r--python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/highlighting/CCTaskLineMarkerProvider.java75
-rw-r--r--python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/highlighting/TaskTextGutter.java60
-rw-r--r--python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/projectView/CCDirectoryNode.java63
-rw-r--r--python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/projectView/CCTreeStructureProvider.java55
-rw-r--r--python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CCNewProjectPanel.form77
-rw-r--r--python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CCNewProjectPanel.java59
-rw-r--r--python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateCourseArchiveDialog.java40
-rw-r--r--python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateCourseArchivePanel.form79
-rw-r--r--python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateCourseArchivePanel.java65
-rw-r--r--python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateTaskWindowDialog.java153
-rw-r--r--python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateTaskWindowPanel.form102
-rw-r--r--python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateTaskWindowPanel.java96
-rw-r--r--python/edu/learn-python/gen/icons/StudyIcons.java20
-rw-r--r--python/edu/learn-python/learn-python.iml1
-rw-r--r--python/edu/learn-python/resources/META-INF/plugin.xml10
-rw-r--r--python/edu/learn-python/resources/courses/introduction_course.zipbin93360 -> 93557 bytes
-rw-r--r--python/edu/learn-python/resources/icons/com/jetbrains/python/edu/EducationalProjectType.pngbin0 -> 1340 bytes
-rw-r--r--python/edu/learn-python/resources/icons/com/jetbrains/python/edu/EducationalProjectType_dark.pngbin0 -> 1338 bytes
-rw-r--r--python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Lesson.pngbin0 -> 285 bytes
-rw-r--r--python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Lesson@2x.pngbin0 -> 751 bytes
-rw-r--r--python/edu/learn-python/resources/icons/com/jetbrains/python/edu/LessonComp@2x.pngbin0 -> 1193 bytes
-rw-r--r--python/edu/learn-python/resources/icons/com/jetbrains/python/edu/LessonCompl.pngbin0 -> 483 bytes
-rw-r--r--python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Playground.pngbin0 -> 265 bytes
-rw-r--r--python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Playground@2x.pngbin0 -> 455 bytes
-rw-r--r--python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Run.pngbin1260 -> 0 bytes
-rw-r--r--python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Task.pngbin0 -> 160 bytes
-rw-r--r--python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Task@2x.pngbin0 -> 269 bytes
-rw-r--r--python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Task@2x_dark.pngbin0 -> 385 bytes
-rw-r--r--python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskCompl.pngbin0 -> 369 bytes
-rw-r--r--python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskCompl@2x.pngbin0 -> 822 bytes
-rw-r--r--python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskCompl@2x_dark.pngbin0 -> 965 bytes
-rw-r--r--python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskCompl_dark.pngbin0 -> 481 bytes
-rw-r--r--python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskProbl.pngbin0 -> 336 bytes
-rw-r--r--python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskProbl@2x.pngbin0 -> 738 bytes
-rw-r--r--python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskProbl@2x_dark.pngbin0 -> 899 bytes
-rw-r--r--python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskProbl_dark.pngbin0 -> 449 bytes
-rw-r--r--python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Task_dark.pngbin0 -> 241 bytes
-rw-r--r--python/edu/learn-python/resources/icons/com/jetbrains/python/edu/add.pngbin213 -> 0 bytes
-rw-r--r--python/edu/learn-python/resources/icons/com/jetbrains/python/edu/checked.pngbin606 -> 0 bytes
-rw-r--r--python/edu/learn-python/resources/icons/com/jetbrains/python/edu/failed.pngbin549 -> 0 bytes
-rw-r--r--python/edu/learn-python/resources/icons/com/jetbrains/python/edu/icon.jpgbin4389 -> 0 bytes
-rw-r--r--python/edu/learn-python/resources/icons/com/jetbrains/python/edu/next.pngbin1345 -> 0 bytes
-rw-r--r--python/edu/learn-python/resources/icons/com/jetbrains/python/edu/playground.pngbin855 -> 0 bytes
-rw-r--r--python/edu/learn-python/resources/icons/com/jetbrains/python/edu/prev.pngbin1354 -> 437 bytes
-rw-r--r--python/edu/learn-python/resources/icons/com/jetbrains/python/edu/refresh.pngbin657 -> 0 bytes
-rw-r--r--python/edu/learn-python/resources/icons/com/jetbrains/python/edu/refresh24.pngbin1569 -> 0 bytes
-rw-r--r--python/edu/learn-python/resources/icons/com/jetbrains/python/edu/resolve.pngbin342 -> 393 bytes
-rw-r--r--python/edu/learn-python/resources/icons/com/jetbrains/python/edu/resolve_dark.pngbin449 -> 576 bytes
-rw-r--r--python/edu/learn-python/resources/icons/com/jetbrains/python/edu/unchecked.pngbin604 -> 0 bytes
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/StudyDirectoryProjectGenerator.java4
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/StudyDocumentListener.java3
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/StudyInstructionPainter.java5
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/StudyState.java52
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/StudyTaskManager.java24
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/StudyTestRunner.java76
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/StudyUtils.java44
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyCheckAction.java378
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyEditInputAction.java4
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNewProject.java34
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNextStudyTaskAction.java5
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNextWindowAction.java4
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyPreviousStudyTaskAction.java5
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyRefreshTaskFileAction.java (renamed from python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyRefreshTaskAction.java)15
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyShowHintAction.java103
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyTaskNavigationAction.java49
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/course/TaskFile.java48
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/course/TaskWindow.java67
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/editor/StudyEditor.java96
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/highlighting/StudyVisitorFilter.java18
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/projectView/StudyDirectoryNode.java11
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyNewProjectPanel.form10
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyNewProjectPanel.java7
-rw-r--r--python/edu/main_pycharm_edu.iml1
-rw-r--r--python/edu/resources/idea/PyCharmEduApplicationInfo.xml2
-rw-r--r--python/edu/src/META-INF/PyCharmEduPlugin.xml10
-rw-r--r--python/edu/src/com/intellij/openapi/application/PyCharmEduConfigImportSettings.java12
-rw-r--r--python/edu/src/com/jetbrains/python/edu/PyCharmEduInitialConfigurator.java45
-rw-r--r--python/edu/src/com/jetbrains/python/edu/PyExecuteFileLineMarkerProvider.java91
-rw-r--r--python/edu/src/com/jetbrains/python/edu/PyRunCurrentFileAction.java56
-rw-r--r--python/helpers/pycharm/_bdd_utils.py14
-rw-r--r--python/helpers/pycharm/behave_runner.py2
-rw-r--r--python/helpers/pycharm/lettuce_runner.py1
-rw-r--r--python/helpers/pydev/README.md7
-rw-r--r--python/helpers/pydev/__init__.py0
-rw-r--r--python/helpers/pydev/_pydev_BaseHTTPServer.py604
-rw-r--r--python/helpers/pydev/_pydev_Queue.py244
-rw-r--r--python/helpers/pydev/_pydev_SimpleXMLRPCServer.py610
-rw-r--r--python/helpers/pydev/_pydev_SocketServer.py715
-rw-r--r--python/helpers/pydev/_pydev_imps/_pydev_Queue.py3
-rw-r--r--python/helpers/pydev/_pydev_imps/_pydev_inspect.py8
-rw-r--r--python/helpers/pydev/_pydev_imps/_pydev_select.py10
-rw-r--r--python/helpers/pydev/_pydev_imps/_pydev_socket.py10
-rw-r--r--python/helpers/pydev/_pydev_imps/_pydev_thread.py8
-rw-r--r--python/helpers/pydev/_pydev_imps/_pydev_time.py8
-rw-r--r--python/helpers/pydev/_pydev_inspect.py788
-rw-r--r--python/helpers/pydev/_pydev_jy_imports_tipper.py3
-rw-r--r--python/helpers/pydev/_pydev_select.py1
-rw-r--r--python/helpers/pydev/_pydev_socket.py1
-rw-r--r--python/helpers/pydev/_pydev_threading.py986
-rw-r--r--python/helpers/pydev/_pydev_time.py1
-rw-r--r--python/helpers/pydev/_pydev_xmlrpclib.py1493
-rw-r--r--python/helpers/pydev/django_debug.py1
-rw-r--r--python/helpers/pydev/fix_getpass.py19
-rw-r--r--python/helpers/pydev/merge_pydev_pycharm.txt22
-rw-r--r--python/helpers/pydev/pycompletionserver.py39
-rw-r--r--python/helpers/pydev/pydev_console_utils.py6
-rw-r--r--python/helpers/pydev/pydev_imports.py4
-rw-r--r--python/helpers/pydev/pydev_ipython/inputhookglut.py1
-rw-r--r--python/helpers/pydev/pydev_ipython/inputhookpyglet.py1
-rw-r--r--python/helpers/pydev/pydev_ipython/inputhookqt4.py6
-rw-r--r--python/helpers/pydev/pydev_ipython_console.py4
-rw-r--r--python/helpers/pydev/pydev_ipython_console_011.py46
-rw-r--r--python/helpers/pydev/pydev_localhost.py2
-rw-r--r--python/helpers/pydev/pydev_monkey.py44
-rw-r--r--python/helpers/pydev/pydev_monkey_qt.py89
-rw-r--r--python/helpers/pydev/pydev_run_in_console.py83
-rw-r--r--python/helpers/pydev/pydev_runfiles_parallel.py9
-rw-r--r--python/helpers/pydev/pydev_runfiles_pytest2.py6
-rw-r--r--python/helpers/pydev/pydev_runfiles_xml_rpc.py1
-rw-r--r--python/helpers/pydev/pydevconsole.py22
-rw-r--r--python/helpers/pydev/pydevd.py240
-rw-r--r--python/helpers/pydev/pydevd_additional_thread_info.py7
-rw-r--r--python/helpers/pydev/pydevd_breakpoints.py5
-rw-r--r--python/helpers/pydev/pydevd_comm.py83
-rw-r--r--python/helpers/pydev/pydevd_constants.py9
-rw-r--r--python/helpers/pydev/pydevd_custom_frames.py3
-rw-r--r--python/helpers/pydev/pydevd_file_utils.py4
-rw-r--r--python/helpers/pydev/pydevd_frame.py6
-rw-r--r--python/helpers/pydev/pydevd_frame_utils.py21
-rw-r--r--python/helpers/pydev/pydevd_resolver.py49
-rw-r--r--python/helpers/pydev/pydevd_signature.py9
-rw-r--r--python/helpers/pydev/pydevd_tracing.py7
-rw-r--r--python/helpers/pydev/pydevd_vars.py11
-rw-r--r--python/helpers/pydev/requirements.txt4
-rw-r--r--python/helpers/pydev/runfiles.py7
-rw-r--r--python/helpers/pydev/tests/test_check_pydevconsole.py (renamed from python/helpers/pydev/tests/check_pydevconsole.py)67
-rw-r--r--python/helpers/pydev/tests/test_get_referrers.py14
-rw-r--r--python/helpers/pydev/tests/test_jyserver.py8
-rw-r--r--python/helpers/pydev/tests/test_jysimpleTipper.py43
-rw-r--r--python/helpers/pydev/tests/test_pydev_ipython_010.py80
-rw-r--r--python/helpers/pydev/tests/test_pydev_ipython_011.py217
-rw-r--r--python/helpers/pydev/tests/test_pydevconsole.py283
-rw-r--r--python/helpers/pydev/tests/test_pyserver.py22
-rw-r--r--python/helpers/pydev/tests/test_simpleTipper.py38
-rw-r--r--python/helpers/pydev/tests_mainloop/gui-glut.py80
-rw-r--r--python/helpers/pydev/tests_mainloop/gui-gtk.py49
-rw-r--r--python/helpers/pydev/tests_mainloop/gui-gtk3.py45
-rw-r--r--python/helpers/pydev/tests_mainloop/gui-pyglet.py35
-rw-r--r--python/helpers/pydev/tests_mainloop/gui-qt.py45
-rw-r--r--python/helpers/pydev/tests_mainloop/gui-tk.py44
-rw-r--r--python/helpers/pydev/tests_mainloop/gui-wx.py174
-rw-r--r--python/helpers/pydev/tests_python/_debugger_case18.py4
-rw-r--r--python/helpers/pydev/tests_python/_debugger_case19.py2
-rw-r--r--python/helpers/pydev/tests_python/_debugger_case7.py2
-rw-r--r--python/helpers/pydev/tests_python/_debugger_case89.py12
-rw-r--r--python/helpers/pydev/tests_python/_debugger_case_qthread1.py25
-rw-r--r--python/helpers/pydev/tests_python/_debugger_case_qthread2.py32
-rw-r--r--python/helpers/pydev/tests_python/_debugger_case_qthread3.py29
-rw-r--r--python/helpers/pydev/tests_python/test_additional_thread_info.py26
-rw-r--r--python/helpers/pydev/tests_python/test_debugger.py510
-rw-r--r--python/helpers/pydev/tests_python/test_pydev_monkey.py21
-rw-r--r--python/helpers/pydev/tests_python/test_save_locals.py6
-rw-r--r--python/helpers/pydev/tests_runfiles/samples/__init__.py0
-rw-r--r--python/helpers/pydev/tests_runfiles/samples/nested_dir/.cvsignore2
-rw-r--r--python/helpers/pydev/tests_runfiles/samples/nested_dir/nested2/.cvsignore2
-rw-r--r--python/helpers/pydev/tests_runfiles/samples/nested_dir/nested3/.cvsignore2
-rw-r--r--python/helpers/pydev/tests_runfiles/samples/not_in_default_pythonpath.txt1
-rw-r--r--python/helpers/pydev/tests_runfiles/test_runfiles.py65
-rw-r--r--python/helpers/pydev/third_party/__init__.py1
-rw-r--r--python/helpers/pydev/third_party/pep8/autopep8.py3687
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/.gitignore1
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/Grammar.txt158
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/PatternGrammar.txt28
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/__init__.py1
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/__main__.py4
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/btm_matcher.py168
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/btm_utils.py283
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixer_base.py189
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixer_util.py432
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/__init__.py1
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_apply.py59
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_basestring.py14
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_buffer.py22
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_callable.py37
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_dict.py107
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_except.py93
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_exec.py40
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_execfile.py52
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_exitfunc.py72
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_filter.py76
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_funcattrs.py21
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_future.py22
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_getcwdu.py19
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_has_key.py110
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_idioms.py152
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_import.py99
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_imports.py145
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_imports2.py16
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_input.py26
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_intern.py46
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_isinstance.py52
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_itertools.py43
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_itertools_imports.py57
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_long.py19
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_map.py91
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_metaclass.py228
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_methodattrs.py24
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_ne.py23
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_next.py103
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_nonzero.py21
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_numliterals.py28
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_operator.py96
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_paren.py44
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_print.py87
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_raise.py90
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_raw_input.py17
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_reduce.py35
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_renames.py70
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_repr.py23
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_set_literal.py53
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_standarderror.py18
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_sys_exc.py30
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_throw.py56
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_tuple_params.py175
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_types.py62
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_unicode.py42
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_urllib.py197
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_ws_comma.py39
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_xrange.py73
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_xreadlines.py25
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_zip.py35
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/main.py269
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/patcomp.py205
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/__init__.py4
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/conv.py257
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/driver.py157
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/grammar.py184
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/literals.py60
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/parse.py201
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/pgen.py386
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/token.py82
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/tokenize.py499
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pygram.py40
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pytree.py887
-rw-r--r--python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/refactor.py747
-rw-r--r--python/helpers/pydev/third_party/pep8/pep8.py1959
-rw-r--r--python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/__init__.py518
-rw-r--r--python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/_ctypes.dllbin0 -> 287417 bytes
-rw-r--r--python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/_endian.py58
-rw-r--r--python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/ctypes-README.txt134
-rw-r--r--python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/macholib/.cvsignore1
-rw-r--r--python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/macholib/__init__.py9
-rw-r--r--python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/macholib/dyld.py167
-rw-r--r--python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/macholib/dylib.py63
-rw-r--r--python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/macholib/framework.py65
-rw-r--r--python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/util.py124
-rw-r--r--python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/wintypes.py98
-rw-r--r--python/helpers/pydev/third_party/wrapped_for_pydev/not_in_default_pythonpath.txt1
-rw-r--r--python/helpers/rest_formatter.py48
-rw-r--r--python/ide/src/com/jetbrains/python/PyIdeCommonOptionsForm.java2
-rw-r--r--python/ide/src/com/jetbrains/python/configuration/PyContentEntriesModuleConfigurable.java353
-rw-r--r--python/ide/src/com/jetbrains/python/configuration/PythonPathEditor.java2
-rw-r--r--python/ide/src/com/jetbrains/python/configuration/PythonSdkDetailsDialog.java2
-rw-r--r--python/ide/src/com/jetbrains/python/newProject/actions/AbstractProjectSettingsStep.java32
-rw-r--r--python/ide/src/com/jetbrains/python/newProject/actions/GenerateProjectCallback.java159
-rw-r--r--python/ide/src/com/jetbrains/python/newProject/actions/PluginSpecificProjectsStep.java4
-rw-r--r--python/ide/src/com/jetbrains/python/newProject/actions/ProjectSpecificAction.java12
-rw-r--r--python/ide/src/com/jetbrains/python/newProject/actions/ProjectSpecificSettingsStep.java4
-rw-r--r--python/ide/src/com/jetbrains/python/newProject/actions/PyCharmNewProjectStep.java140
-rw-r--r--python/openapi/src/com/jetbrains/python/run/PythonRunConfigurationParams.java3
-rw-r--r--python/pluginSrc/com/jetbrains/python/module/PythonModuleConfigurationEditorProvider.java11
-rw-r--r--python/psi-api/src/com/jetbrains/python/psi/PyAnnotation.java6
-rw-r--r--python/psi-api/src/com/jetbrains/python/psi/PyTargetExpression.java2
-rw-r--r--python/pydevSrc/com/jetbrains/python/debugger/IPyDebugProcess.java2
-rw-r--r--python/pydevSrc/com/jetbrains/python/debugger/pydev/AbstractCommand.java6
-rw-r--r--python/pydevSrc/com/jetbrains/python/debugger/pydev/AbstractThreadCommand.java4
-rw-r--r--python/pydevSrc/com/jetbrains/python/debugger/pydev/RemoteDebugger.java19
-rw-r--r--python/rest/gen/com/jetbrains/rest/lexer/_RestFlexLexer.java8
-rw-r--r--python/rest/src/com/jetbrains/rest/lexer/rest.flex2
-rw-r--r--python/rest/src/com/jetbrains/rest/parsing/RestParser.java9
-rw-r--r--python/src/META-INF/pycharm-core.xml3
-rw-r--r--python/src/META-INF/python-core.xml3
-rw-r--r--python/src/com/jetbrains/python/codeInsight/PyTypingTypeProvider.java375
-rw-r--r--python/src/com/jetbrains/python/codeInsight/highlighting/PyHighlightExitPointsHandlerFactory.java24
-rw-r--r--python/src/com/jetbrains/python/codeInsight/intentions/ImportToImportFromIntention.java122
-rw-r--r--python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java1
-rw-r--r--python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java8
-rw-r--r--python/src/com/jetbrains/python/console/PyConsoleOptions.java1
-rw-r--r--python/src/com/jetbrains/python/console/PyDebugConsoleBuilder.java2
-rw-r--r--python/src/com/jetbrains/python/console/PydevConsoleRunner.java45
-rw-r--r--python/src/com/jetbrains/python/debugger/PyDebugProcess.java22
-rw-r--r--python/src/com/jetbrains/python/debugger/PyExecutionStack.java2
-rw-r--r--python/src/com/jetbrains/python/documentation/PythonDocumentationProvider.java18
-rw-r--r--python/src/com/jetbrains/python/documentation/doctest/PyDocstringVisitorFilter.java2
-rw-r--r--python/src/com/jetbrains/python/formatter/PythonFormattingModelBuilder.java4
-rw-r--r--python/src/com/jetbrains/python/inspections/PyCompatibilityInspection.java4
-rw-r--r--python/src/com/jetbrains/python/inspections/PyStatementEffectInspection.java3
-rw-r--r--python/src/com/jetbrains/python/inspections/quickfix/PyDefaultArgumentQuickFix.java39
-rw-r--r--python/src/com/jetbrains/python/inspections/quickfix/StatementEffectFunctionCallQuickFix.java96
-rw-r--r--python/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesInspection.java3
-rw-r--r--python/src/com/jetbrains/python/module/PyContentEntriesEditor.java367
-rw-r--r--python/src/com/jetbrains/python/psi/impl/PyAnnotationImpl.java31
-rw-r--r--python/src/com/jetbrains/python/psi/impl/PyClassImpl.java28
-rw-r--r--python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java29
-rw-r--r--python/src/com/jetbrains/python/psi/impl/PyNamedParameterImpl.java10
-rw-r--r--python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java7
-rw-r--r--python/src/com/jetbrains/python/psi/resolve/PyResolveUtil.java8
-rw-r--r--python/src/com/jetbrains/python/psi/resolve/QualifiedNameFinder.java34
-rw-r--r--python/src/com/jetbrains/python/psi/stubs/PyClassNameIndex.java2
-rw-r--r--python/src/com/jetbrains/python/psi/types/PyFunctionType.java10
-rw-r--r--python/src/com/jetbrains/python/psi/types/PyTypeChecker.java90
-rw-r--r--python/src/com/jetbrains/python/refactoring/PyReplaceExpressionUtil.java13
-rw-r--r--python/src/com/jetbrains/python/refactoring/inline/PyInlineLocalHandler.java61
-rw-r--r--python/src/com/jetbrains/python/refactoring/surround/surrounders/statements/PyWithIfElseSurrounder.java1
-rw-r--r--python/src/com/jetbrains/python/refactoring/surround/surrounders/statements/PyWithIfSurrounder.java9
-rw-r--r--python/src/com/jetbrains/python/refactoring/surround/surrounders/statements/PyWithTryExceptSurrounder.java2
-rw-r--r--python/src/com/jetbrains/python/refactoring/surround/surrounders/statements/PyWithTryFinallySurrounder.java1
-rw-r--r--python/src/com/jetbrains/python/refactoring/surround/surrounders/statements/PyWithWhileSurrounder.java1
-rw-r--r--python/src/com/jetbrains/python/run/AbstractPythonRunConfiguration.java3
-rw-r--r--python/src/com/jetbrains/python/run/PythonCommandLineState.java6
-rw-r--r--python/src/com/jetbrains/python/run/PythonRunConfiguration.java13
-rw-r--r--python/src/com/jetbrains/python/run/PythonRunConfigurationForm.form13
-rw-r--r--python/src/com/jetbrains/python/run/PythonRunConfigurationForm.java12
-rw-r--r--python/src/com/jetbrains/python/run/PythonScriptCommandLineState.java118
-rw-r--r--python/src/com/jetbrains/python/sdk/PySdkListCellRenderer.java3
-rw-r--r--python/src/com/jetbrains/python/sdk/flavors/WinPythonSdkFlavor.java31
-rw-r--r--python/src/com/jetbrains/python/validation/CompatibilityVisitor.java2
-rw-r--r--python/testData/dotNet/whole_namespace.py2
-rw-r--r--python/testData/formatter/reformatOfSingleElementPossible.py2
-rw-r--r--python/testData/formatter/reformatOfSingleElementPossible_after.py2
-rw-r--r--python/testData/highlighting/unsupportedFeaturesInPython3.py2
-rw-r--r--python/testData/inspections/DefaultArgumentEmptyList.py1
-rw-r--r--python/testData/inspections/DefaultArgumentEmptyList_after.py3
-rw-r--r--python/testData/inspections/DefaultArgument_after.py3
-rw-r--r--python/testData/inspections/ReplacePrintComment.py1
-rw-r--r--python/testData/inspections/ReplacePrintComment_after.py1
-rw-r--r--python/testData/inspections/ReplacePrintEnd.py1
-rw-r--r--python/testData/inspections/ReplacePrintEnd_after.py1
-rw-r--r--python/testData/intentions/afterDocStubKeywordOnly.py2
-rw-r--r--python/testData/intentions/afterImportToImportFrom.py9
-rw-r--r--python/testData/intentions/beforeDocStubKeywordOnly.py2
-rw-r--r--python/testData/intentions/beforeImportToImportFrom.py9
-rw-r--r--python/testData/refactoring/inlinelocal/py5832.after.py2
-rw-r--r--python/testData/refactoring/inlinelocal/referenceInParenthesis.after.py3
-rw-r--r--python/testData/refactoring/inlinelocal/referenceInParenthesis.before.py5
-rw-r--r--python/testData/refactoring/inlinelocal/resultExceedsRightMargin.after.py3
-rw-r--r--python/testData/refactoring/inlinelocal/resultExceedsRightMargin.before.py3
-rw-r--r--python/testData/typing/typing.py582
-rw-r--r--python/testSrc/com/jetbrains/python/PyFillParagraphTest.java4
-rw-r--r--python/testSrc/com/jetbrains/python/PyFormatterTest.java32
-rw-r--r--python/testSrc/com/jetbrains/python/PyQuickFixTest.java22
-rw-r--r--python/testSrc/com/jetbrains/python/PyTypeTest.java31
-rw-r--r--python/testSrc/com/jetbrains/python/PyTypingTest.java267
-rw-r--r--python/testSrc/com/jetbrains/python/PyWrapTest.java16
-rw-r--r--python/testSrc/com/jetbrains/python/fixtures/PyTestCase.java1
-rw-r--r--python/testSrc/com/jetbrains/python/intentions/PyIntentionTest.java5
-rw-r--r--python/testSrc/com/jetbrains/python/refactoring/PyInlineLocalTest.java17
-rw-r--r--resources-en/src/messages/DebuggerBundle.properties2
-rw-r--r--resources-en/src/postfixTemplates/AssertStatementPostfixTemplate/description.html4
-rw-r--r--resources-en/src/postfixTemplates/CastExpressionPostfixTemplate/description.html2
-rw-r--r--resources-en/src/postfixTemplates/ElseStatementPostfixTemplate/description.html2
-rw-r--r--resources-en/src/postfixTemplates/ForAscendingPostfixTemplate/description.html2
-rw-r--r--resources-en/src/postfixTemplates/ForDescendingPostfixTemplate/description.html2
-rw-r--r--resources-en/src/postfixTemplates/ForeachPostfixTemplate/description.html2
-rw-r--r--resources-en/src/postfixTemplates/FormatPostfixTemplate/description.html2
-rw-r--r--resources-en/src/postfixTemplates/IfStatementPostfixTemplate/description.html2
-rw-r--r--resources-en/src/postfixTemplates/InstanceofExpressionPostfixTemplate/description.html2
-rw-r--r--resources-en/src/postfixTemplates/IntroduceFieldPostfixTemplate/description.html2
-rw-r--r--resources-en/src/postfixTemplates/IntroduceVariablePostfixTemplate/description.html2
-rw-r--r--resources-en/src/postfixTemplates/IsNullCheckPostfixTemplate/description.html2
-rw-r--r--resources-en/src/postfixTemplates/NotExpressionPostfixTemplate/description.html2
-rw-r--r--resources-en/src/postfixTemplates/NotNullCheckPostfixTemplate/description.html2
-rw-r--r--resources-en/src/postfixTemplates/ParenthesizedExpressionPostfixTemplate/description.html2
-rw-r--r--resources-en/src/postfixTemplates/ReturnStatementPostfixTemplate/description.html2
-rw-r--r--resources-en/src/postfixTemplates/SoutPostfixTemplate/description.html2
-rw-r--r--resources-en/src/postfixTemplates/SwitchStatementPostfixTemplate/description.html2
-rw-r--r--resources-en/src/postfixTemplates/SynchronizedStatementPostfixTemplate/description.html2
-rw-r--r--resources-en/src/postfixTemplates/ThrowExceptionPostfixTemplate/description.html2
-rw-r--r--resources-en/src/postfixTemplates/TryStatementPostfixTemplate/description.html2
-rw-r--r--resources-en/src/postfixTemplates/TryWithResourcesPostfixTemplate/description.html2
-rw-r--r--resources-en/src/postfixTemplates/WhileStatementPostfixTemplate/description.html2
-rw-r--r--resources/src/META-INF/IdeaPlugin.xml8
-rw-r--r--resources/src/idea/JavaActions.xml3
-rw-r--r--resources/src/idea/RichPlatformActions.xml15
-rw-r--r--resources/src/idea/RichPlatformPlugin.xml7
-rw-r--r--spellchecker/src/com/intellij/spellchecker/jetbrains.dic3
-rw-r--r--spellchecker/src/com/intellij/spellchecker/tokenizer/SpellcheckingStrategy.java3
-rw-r--r--tools/launcher-generator/.idea/codeStyleSettings.xml200
-rw-r--r--tools/launcher-generator/.idea/copyright/profiles_settings.xml4
-rw-r--r--tools/launcher-generator/.idea/libraries/guava.xml2
-rw-r--r--xml/dom-impl/src/com/intellij/util/xml/highlighting/DomElementAnnotationsManagerImpl.java2
-rw-r--r--xml/dom-tests/tests/com/intellij/util/xml/DomFileDescriptionTest.java55
-rw-r--r--xml/dom-tests/tests/com/intellij/util/xml/DomHighlightingLiteTest.java29
-rw-r--r--xml/dom-tests/tests/com/intellij/util/xml/MockDomElement.java20
-rw-r--r--xml/dom-tests/tests/com/intellij/util/xml/MockDomFileElement.java29
-rw-r--r--xml/dom-tests/tests/com/intellij/util/xml/MockGenericAttributeValue.java16
-rw-r--r--xml/dom-tests/tests/com/intellij/util/xml/ProxyTest.java2
-rw-r--r--xml/dom-tests/tests/com/intellij/util/xml/impl/IncrementalUpdateEventsTest.java29
-rw-r--r--xml/impl/src/com/intellij/codeInsight/editorActions/HtmlCopyPastePreProcessor.java106
-rw-r--r--xml/impl/src/com/intellij/codeInsight/template/emmet/generators/XmlZenCodingGenerator.java21
-rw-r--r--xml/impl/src/com/intellij/ide/browsers/BrowserLauncherImpl.java11
-rw-r--r--xml/impl/src/com/intellij/ide/browsers/BrowserStarter.java6
-rw-r--r--xml/impl/src/com/intellij/ide/browsers/JavaScriptDebuggerStarter.java15
-rw-r--r--xml/impl/src/com/intellij/ide/browsers/OpenUrlHyperlinkInfo.java8
-rw-r--r--xml/impl/src/com/intellij/ide/browsers/StartBrowserPanel.java2
-rw-r--r--xml/impl/src/com/intellij/lang/xml/XmlEnclosingTagUnwrapper.java29
-rw-r--r--xml/impl/src/com/intellij/xml/util/documentation/html5.html2334
-rw-r--r--xml/impl/src/com/intellij/xml/util/documentation/html5TagTableGen.rb2
-rw-r--r--xml/relaxng/test/org/intellij/plugins/relaxNG/HighlightingTestBase.java2
-rw-r--r--xml/xml-psi-impl/src/com/intellij/psi/xml/XmlElementType.java2
-rw-r--r--xml/xml-psi-impl/src/com/intellij/xml/util/documentation/html5table.xml149
1529 files changed, 50505 insertions, 20897 deletions
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index 3407e7c49c03..7885bf8ff8af 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -27,6 +27,7 @@
</annotationProcessing>
<bytecodeTargetLevel target="1.6">
<module name="annotations" target="1.5" />
+ <module name="gradle-jps-plugin" target="1.5" />
<module name="groovy-rt-constants" target="1.5" />
<module name="groovy_rt" target="1.5" />
<module name="intellilang-jps-plugin" target="1.6" />
diff --git a/.idea/libraries/Netty.xml b/.idea/libraries/Netty.xml
index 723ad4eef42d..1c2042bff2df 100644
--- a/.idea/libraries/Netty.xml
+++ b/.idea/libraries/Netty.xml
@@ -1,11 +1,11 @@
<component name="libraryTable">
<library name="Netty">
<CLASSES>
- <root url="jar://$PROJECT_DIR$/lib/netty-all-4.1.0.Beta1.jar!/" />
+ <root url="jar://$PROJECT_DIR$/lib/netty-all-4.1.0.Beta3.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
- <root url="jar://$PROJECT_DIR$/lib/src/netty-all-4.1.0.Beta1-sources.jar!/" />
+ <root url="jar://$PROJECT_DIR$/lib/src/netty-all-4.1.0.Beta3-sources.jar!/" />
</SOURCES>
</library>
</component> \ No newline at end of file
diff --git a/bin/win/runnerw.exe b/bin/win/runnerw.exe
index 29c5d336d08c..47ae098d81f6 100644
--- a/bin/win/runnerw.exe
+++ b/bin/win/runnerw.exe
Binary files differ
diff --git a/build/conf/classVersions.txt b/build/conf/classVersions.txt
index dd39ad0006d3..7835116e0be0 100644
--- a/build/conf/classVersions.txt
+++ b/build/conf/classVersions.txt
@@ -36,4 +36,6 @@
1.5 => plugins/Groovy/lib/groovy_rt.jar
1.5 => lib/annotations.jar
+1.5 => plugins/gradle/lib/gradle-jps-plugin.jar
+
1.3 => plugins/junit/lib/junit-rt.jar \ No newline at end of file
diff --git a/build/scripts/libLicenses.gant b/build/scripts/libLicenses.gant
index 872cc5f6e9fe..5319444eaae6 100644
--- a/build/scripts/libLicenses.gant
+++ b/build/scripts/libLicenses.gant
@@ -252,7 +252,7 @@ libraryLicense(name: "XML-RPC", libraryName: "XmlRPC", version: "2.0", license:
libraryLicense(name: "XStream", version: "1.4.3", license: "BSD", url: "http://xstream.codehaus.org/", licenseUrl: "http://xstream.codehaus.org/license.html")
libraryLicense(name: "YourKit Java Profiler", libraryName: "yjp-controller-api-redist.jar", version: "8.0.x", license: "link (commercial license)", url: "http://yourkit.com/", licenseUrl: "http://www.yourkit.com/purchase/license.html")
libraryLicense(name: "protobuf", version: "2.5.0", license: "New BSD", url: "http://code.google.com/p/protobuf/", licenseUrl: "http://code.google.com/p/protobuf/source/browse/trunk/COPYING.txt?r=367")
-libraryLicense(name: "Netty", libraryName: "Netty", version: "4.1.0.Beta1", license: "Apache 2.0", url: "http://netty.io", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0")
+libraryLicense(name: "Netty", libraryName: "Netty", version: "4.1.0.Beta3", license: "Apache 2.0", url: "http://netty.io", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0")
libraryLicense(name: "Kryo", libraryName: "Kryo", version: "2.22", license: "New BSD License", url: "https://github.com/EsotericSoftware/kryo", licenseUrl: "https://github.com/EsotericSoftware/kryo/blob/master/license.txt")
libraryLicense(name: "Snappy-Java", libraryName: "Snappy-Java", version: "0.3", license: "Apache 2.0", url: "https://github.com/dain/snappy", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0")
libraryLicense(name: "Cucumber-Java", libraryName: "cucumber-java", version: "1.0.14", license: "MIT License", url: "https://github.com/cucumber/cucumber-jvm/", licenseUrl: "http://www.opensource.org/licenses/mit-license.html")
diff --git a/community-main.iml b/community-main.iml
index 124943e8a84a..9aad39f5611f 100644
--- a/community-main.iml
+++ b/community-main.iml
@@ -109,6 +109,7 @@
<orderEntry type="module" module-name="structuralsearch-java" />
<orderEntry type="module" module-name="structuralsearch-tests" scope="TEST" />
<orderEntry type="module" module-name="structuralsearch-groovy" />
+ <orderEntry type="module" module-name="typeMigration" />
</component>
</module>
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileContextImpl.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileContextImpl.java
index c9e9ce31020a..f57753ef7afc 100644
--- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileContextImpl.java
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileContextImpl.java
@@ -55,7 +55,7 @@ import java.util.*;
public class CompileContextImpl extends UserDataHolderBase implements CompileContextEx {
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.CompileContextImpl");
private final Project myProject;
- private final CompilerTask myTask;
+ private final CompilerTask myBuildSession;
private final Map<CompilerMessageCategory, Collection<CompilerMessage>> myMessages = new EnumMap<CompilerMessageCategory, Collection<CompilerMessage>>(CompilerMessageCategory.class);
private final boolean myShouldUpdateProblemsView;
private CompileScope myCompileScope;
@@ -77,7 +77,7 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon
CompileScope compileScope,
boolean isMake, boolean isRebuild) {
myProject = project;
- myTask = compilerSession;
+ myBuildSession = compilerSession;
myCompileScope = compileScope;
myMake = isMake;
myIsRebuild = isRebuild;
@@ -99,6 +99,10 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon
myShouldUpdateProblemsView = workspaceConfig.MAKE_PROJECT_ON_SAVE;
}
+ public CompilerTask getBuildSession() {
+ return myBuildSession;
+ }
+
public boolean shouldUpdateProblemsView() {
return myShouldUpdateProblemsView;
}
@@ -154,7 +158,7 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon
myMessages.put(msg.getCategory(), messages);
}
if (messages.add(msg)) {
- myTask.addMessage(msg);
+ myBuildSession.addMessage(msg);
}
if (myShouldUpdateProblemsView && msg.getCategory() == CompilerMessageCategory.ERROR) {
ProblemsView.SERVICE.getInstance(myProject).addMessage(msg, mySessionId);
@@ -200,7 +204,7 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon
}
public ProgressIndicator getProgressIndicator() {
- return myTask.getIndicator();
+ return myBuildSession.getIndicator();
}
public Module getModuleByFile(VirtualFile file) {
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java
index 406d16574955..c40edf0f595c 100644
--- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java
@@ -28,8 +28,9 @@ import com.intellij.compiler.ModuleCompilerUtil;
import com.intellij.compiler.ProblemsView;
import com.intellij.compiler.progress.CompilerTask;
import com.intellij.compiler.server.BuildManager;
-import com.intellij.compiler.server.CustomBuilderMessageHandler;
import com.intellij.compiler.server.DefaultMessageHandler;
+import com.intellij.notification.Notification;
+import com.intellij.notification.NotificationListener;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.compiler.*;
import com.intellij.openapi.compiler.ex.CompilerPathsEx;
@@ -54,10 +55,7 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFileManager;
-import com.intellij.openapi.wm.StatusBar;
-import com.intellij.openapi.wm.ToolWindowId;
-import com.intellij.openapi.wm.ToolWindowManager;
-import com.intellij.openapi.wm.WindowManager;
+import com.intellij.openapi.wm.*;
import com.intellij.packaging.artifacts.Artifact;
import com.intellij.packaging.impl.compiler.ArtifactCompilerUtil;
import com.intellij.packaging.impl.compiler.ArtifactsCompiler;
@@ -69,6 +67,7 @@ import com.intellij.util.ThrowableRunnable;
import com.intellij.util.containers.HashMap;
import com.intellij.util.containers.MultiMap;
import com.intellij.util.messages.MessageBus;
+import com.intellij.util.text.DateFormatUtil;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -80,7 +79,9 @@ import org.jetbrains.jps.api.RequestFuture;
import org.jetbrains.jps.model.java.JavaSourceRootType;
import javax.swing.*;
+import javax.swing.event.HyperlinkEvent;
import java.io.File;
+import java.lang.ref.WeakReference;
import java.util.*;
import java.util.concurrent.TimeUnit;
@@ -340,13 +341,6 @@ public class CompileDriver {
}
compileContext.putUserDataIfAbsent(COMPILE_SERVER_BUILD_STATUS, status);
break;
- case CUSTOM_BUILDER_MESSAGE:
- if (event.hasCustomBuilderMessage()) {
- CmdlineRemoteProto.Message.BuilderMessage.BuildEvent.CustomBuilderMessage message = event.getCustomBuilderMessage();
- messageBus.syncPublisher(CustomBuilderMessageHandler.TOPIC).messageReceived(message.getBuilderId(), message.getMessageType(),
- message.getMessageText());
- }
- break;
}
}
});
@@ -510,9 +504,24 @@ public class CompileDriver {
if (duration > ONE_MINUTE_MS && CompilerWorkspaceConfiguration.getInstance(myProject).DISPLAY_NOTIFICATION_POPUP) {
ToolWindowManager.getInstance(myProject).notifyByBalloon(ToolWindowId.MESSAGES_WINDOW, messageType, statusMessage);
}
- CompilerManager.NOTIFICATION_GROUP.createNotification(statusMessage, messageType).notify(myProject);
+
+ final String wrappedMessage = _status != ExitStatus.UP_TO_DATE? "<a href='#'>" + statusMessage + "</a>" : statusMessage;
+ final Notification notification = CompilerManager.NOTIFICATION_GROUP.createNotification(
+ "", wrappedMessage,
+ messageType.toNotificationType(),
+ new MessagesActivationListener(compileContext)
+ );
+ compileContext.getBuildSession().registerCloseAction(new Runnable() {
+ @Override
+ public void run() {
+ notification.expire();
+ }
+ });
+ notification.notify(myProject);
+
if (_status != ExitStatus.UP_TO_DATE && compileContext.getMessageCount(null) > 0) {
- compileContext.addMessage(CompilerMessageCategory.INFORMATION, statusMessage, null, -1, -1);
+ final String msg = DateFormatUtil.formatDateTime(new Date()) + " - " + statusMessage;
+ compileContext.addMessage(CompilerMessageCategory.INFORMATION, msg, null, -1, -1);
}
}
}
@@ -793,4 +802,28 @@ public class CompileDriver {
private void showConfigurationDialog(String moduleNameToSelect, String tabNameToSelect) {
ProjectSettingsService.getInstance(myProject).showModuleConfigurationDialog(moduleNameToSelect, tabNameToSelect);
}
+
+ private static class MessagesActivationListener extends NotificationListener.Adapter {
+ private final WeakReference<Project> myProjectRef;
+ private final Object myContentId;
+
+ public MessagesActivationListener(CompileContextImpl compileContext) {
+ myProjectRef = new WeakReference<Project>(compileContext.getProject());
+ myContentId = compileContext.getBuildSession().getContentId();
+ }
+
+ @Override
+ protected void hyperlinkActivated(@NotNull Notification notification, @NotNull HyperlinkEvent e) {
+ final Project project = myProjectRef.get();
+ if (project != null && !project.isDisposed() && CompilerTask.showCompilerContent(project, myContentId)) {
+ final ToolWindow tw = ToolWindowManager.getInstance(project).getToolWindow(ToolWindowId.MESSAGES_WINDOW);
+ if (tw != null) {
+ tw.activate(null, false);
+ }
+ }
+ else {
+ notification.expire();
+ }
+ }
+ }
}
diff --git a/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java b/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java
index f568f2d06364..2f9f023bc52a 100644
--- a/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java
+++ b/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java
@@ -22,12 +22,11 @@
package com.intellij.compiler.progress;
import com.intellij.compiler.CompilerManagerImpl;
-import com.intellij.compiler.CompilerMessageImpl;
import com.intellij.compiler.impl.CompilerErrorTreeView;
import com.intellij.ide.errorTreeView.NewErrorTreeViewPanel;
import com.intellij.ide.errorTreeView.impl.ErrorTreeViewConfiguration;
import com.intellij.ide.impl.ProjectUtil;
-import com.intellij.openapi.application.Application;
+import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.compiler.*;
@@ -42,6 +41,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.project.ProjectManagerListener;
import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
@@ -120,6 +120,26 @@ public class CompilerTask extends Task.Backgroundable {
mySessionId = sessionId;
}
+ @NotNull
+ public Object getContentId() {
+ return myContentId;
+ }
+
+ public void registerCloseAction(final Runnable onClose) {
+ synchronized (myMessageViewLock) {
+ if (myErrorTreeView != null) {
+ Disposer.register(myErrorTreeView, new Disposable() {
+ @Override
+ public void dispose() {
+ onClose.run();
+ }
+ });
+ return;
+ }
+ }
+ onClose.run();
+ }
+
@Override
public String getProcessId() {
return "compilation";
@@ -221,13 +241,15 @@ public class CompilerTask extends Task.Backgroundable {
private void addIndicatorDelegate() {
ProgressIndicator indicator = myIndicator;
- if (!(indicator instanceof ProgressIndicatorEx)) return;
+ if (!(indicator instanceof ProgressIndicatorEx)) {
+ return;
+ }
((ProgressIndicatorEx)indicator).addStateDelegate(new ProgressIndicatorBase() {
@Override
public void cancel() {
super.cancel();
- closeUI();
+ selectFirstMessage();
stopAppIconProgress();
}
@@ -235,11 +257,26 @@ public class CompilerTask extends Task.Backgroundable {
public void stop() {
super.stop();
if (!isCanceled()) {
- closeUI();
+ selectFirstMessage();
}
stopAppIconProgress();
}
+ private void selectFirstMessage() {
+ if (!isHeadlessMode()) {
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ synchronized (myMessageViewLock) {
+ if (myErrorTreeView != null) {
+ myErrorTreeView.selectFirstMessage();
+ }
+ }
+ }
+ });
+ }
+ }
+
private void stopAppIconProgress() {
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
@@ -249,7 +286,8 @@ public class CompilerTask extends Task.Backgroundable {
if (myErrorCount > 0) {
appIcon.setErrorBadge(myProject, String.valueOf(myErrorCount));
appIcon.requestAttention(myProject, true);
- } else if (!myCompilationStartedAutomatically) {
+ }
+ else if (!myCompilationStartedAutomatically) {
appIcon.setOkBadge(myProject, true);
appIcon.requestAttention(myProject, false);
}
@@ -450,18 +488,22 @@ public class CompilerTask extends Task.Backgroundable {
public void showCompilerContent() {
synchronized (myMessageViewLock) {
if (myErrorTreeView != null) {
- final MessageView messageView = MessageView.SERVICE.getInstance(myProject);
- Content[] contents = messageView.getContentManager().getContents();
- for (Content content : contents) {
- if (CONTENT_ID_KEY.get(content) == myContentId) {
- messageView.getContentManager().setSelectedContent(content);
- return;
- }
- }
+ showCompilerContent(myProject, myContentId);
}
}
}
+ public static boolean showCompilerContent(final Project project, final Object contentId) {
+ final MessageView messageView = MessageView.SERVICE.getInstance(project);
+ for (Content content : messageView.getContentManager().getContents()) {
+ if (CONTENT_ID_KEY.get(content) == contentId) {
+ messageView.getContentManager().setSelectedContent(content);
+ return true;
+ }
+ }
+ return false;
+ }
+
private void removeAllContents(Project project, Content notRemove) {
if (project.isDisposed()) {
return;
@@ -488,7 +530,7 @@ public class CompilerTask extends Task.Backgroundable {
private void activateMessageView() {
synchronized (myMessageViewLock) {
- if (myErrorTreeView != null) {
+ if (myErrorTreeView != null && myProject != null) {
final ToolWindow tw = ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.MESSAGES_WINDOW);
if (tw != null) {
tw.activate(null, false);
@@ -497,34 +539,6 @@ public class CompilerTask extends Task.Backgroundable {
}
}
- private void closeUI() {
- if (isHeadlessMode()) {
- return;
- }
- Window window = getWindow();
- ModalityState modalityState = window != null ? ModalityState.stateForComponent(window) : ModalityState.NON_MODAL;
- final Application application = ApplicationManager.getApplication();
- application.invokeLater(new Runnable() {
- @Override
- public void run() {
- synchronized (myMessageViewLock) {
- if (myErrorTreeView != null) {
- final boolean shouldRetainView = myErrorCount > 0 || myWarningCount > 0 && !myErrorTreeView.isHideWarnings();
- if (shouldRetainView) {
- addMessage(new CompilerMessageImpl(myProject, CompilerMessageCategory.STATISTICS, CompilerBundle.message("statistics.error.count", myErrorCount)));
- addMessage(new CompilerMessageImpl(myProject, CompilerMessageCategory.STATISTICS, CompilerBundle.message("statistics.warnings.count", myWarningCount)));
- //activateMessageView();
- myErrorTreeView.selectFirstMessage();
- }
- else {
- removeAllContents(myProject, null);
- }
- }
- }
- }
- }, modalityState);
- }
-
public Window getWindow(){
return null;
}
@@ -607,7 +621,7 @@ public class CompilerTask extends Task.Backgroundable {
if (event.getContent() == myContent) {
synchronized (myMessageViewLock) {
if (myErrorTreeView != null) {
- myErrorTreeView.dispose();
+ Disposer.dispose(myErrorTreeView);
myErrorTreeView = null;
if (myIndicator.isRunning()) {
cancel();
diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java
index c40135db7c5f..669cf92d37da 100644
--- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java
+++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java
@@ -34,7 +34,9 @@ import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.compiler.CompilationStatusListener;
import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.CompilerTopics;
import com.intellij.openapi.components.ApplicationComponent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.EditorFactory;
@@ -64,16 +66,14 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.CharsetToolkit;
+import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
import com.intellij.openapi.vfs.newvfs.impl.FileNameCache;
import com.intellij.openapi.wm.IdeFrame;
-import com.intellij.util.Alarm;
-import com.intellij.util.Function;
-import com.intellij.util.PathUtil;
-import com.intellij.util.SmartList;
+import com.intellij.util.*;
import com.intellij.util.concurrency.Semaphore;
import com.intellij.util.concurrency.SequentialTaskExecutor;
import com.intellij.util.containers.IntArrayList;
@@ -1117,6 +1117,44 @@ public class BuildManager implements ApplicationComponent{
scheduleAutoMake();
}
});
+ conn.subscribe(CompilerTopics.COMPILATION_STATUS, new CompilationStatusListener() {
+ private final Set<String> myRootsToRefresh = new THashSet<String>(FileUtil.PATH_HASHING_STRATEGY);
+ @Override
+ public void compilationFinished(boolean aborted, int errors, int warnings, CompileContext compileContext) {
+ final String[] roots;
+ synchronized (myRootsToRefresh) {
+ roots = ArrayUtil.toStringArray(myRootsToRefresh);
+ myRootsToRefresh.clear();
+ }
+ ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
+ @Override
+ public void run() {
+ if (project.isDisposed()) {
+ return;
+ }
+ final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
+ final LocalFileSystem lfs = LocalFileSystem.getInstance();
+ final Set<VirtualFile> filesToRefresh = new HashSet<VirtualFile>();
+ for (String root : roots) {
+ final VirtualFile rootFile = lfs.refreshAndFindFileByPath(root);
+ if (rootFile != null && fileIndex.isInSourceContent(rootFile)) {
+ filesToRefresh.add(rootFile);
+ }
+ }
+ if (!filesToRefresh.isEmpty()) {
+ lfs.refreshFiles(filesToRefresh, true, true, null);
+ }
+ }
+ });
+ }
+
+ @Override
+ public void fileGenerated(String outputRoot, String relativePath) {
+ synchronized (myRootsToRefresh) {
+ myRootsToRefresh.add(outputRoot);
+ }
+ }
+ });
final String projectPath = getProjectPath(project);
Disposer.register(project, new Disposable() {
@Override
diff --git a/java/compiler/impl/src/com/intellij/compiler/server/DefaultMessageHandler.java b/java/compiler/impl/src/com/intellij/compiler/server/DefaultMessageHandler.java
index 6a8c9740df80..bfde64d4396e 100644
--- a/java/compiler/impl/src/com/intellij/compiler/server/DefaultMessageHandler.java
+++ b/java/compiler/impl/src/com/intellij/compiler/server/DefaultMessageHandler.java
@@ -20,6 +20,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.util.ProgressIndicatorBase;
import com.intellij.openapi.progress.util.ProgressIndicatorUtils;
import com.intellij.openapi.progress.util.ReadTask;
import com.intellij.openapi.project.DumbService;
@@ -40,7 +41,6 @@ import org.jetbrains.jps.api.CmdlineRemoteProto;
import org.jetbrains.org.objectweb.asm.Opcodes;
import java.util.*;
-import java.util.concurrent.atomic.AtomicBoolean;
/**
* @author Eugene Zhuravlev
@@ -66,19 +66,23 @@ public abstract class DefaultMessageHandler implements BuilderMessageHandler {
//noinspection EnumSwitchStatementWhichMissesCases
switch (msg.getType()) {
case BUILD_EVENT:
- handleBuildEvent(sessionId, msg.getBuildEvent());
+ final CmdlineRemoteProto.Message.BuilderMessage.BuildEvent event = msg.getBuildEvent();
+ if (event.getEventType() == CmdlineRemoteProto.Message.BuilderMessage.BuildEvent.Type.CUSTOM_BUILDER_MESSAGE && event.hasCustomBuilderMessage()) {
+ final CmdlineRemoteProto.Message.BuilderMessage.BuildEvent.CustomBuilderMessage message = event.getCustomBuilderMessage();
+ if (!myProject.isDisposed()) {
+ myProject.getMessageBus().syncPublisher(CustomBuilderMessageHandler.TOPIC).messageReceived(
+ message.getBuilderId(), message.getMessageType(), message.getMessageText()
+ );
+ }
+ }
+ handleBuildEvent(sessionId, event);
break;
case COMPILE_MESSAGE:
handleCompileMessage(sessionId, msg.getCompileMessage());
break;
case CONSTANT_SEARCH_TASK:
final CmdlineRemoteProto.Message.BuilderMessage.ConstantSearchTask task = msg.getConstantSearchTask();
- myTaskExecutor.submit(new Runnable() {
- @Override
- public void run() {
- handleConstantSearchTask(channel, sessionId, task);
- }
- });
+ handleConstantSearchTask(channel, sessionId, task);
break;
}
}
@@ -88,30 +92,29 @@ public abstract class DefaultMessageHandler implements BuilderMessageHandler {
protected abstract void handleBuildEvent(UUID sessionId, CmdlineRemoteProto.Message.BuilderMessage.BuildEvent event);
private void handleConstantSearchTask(final Channel channel, final UUID sessionId, final CmdlineRemoteProto.Message.BuilderMessage.ConstantSearchTask task) {
- while (true) {
- final AtomicBoolean canceled = new AtomicBoolean(false);
- DumbService.getInstance(myProject).waitForSmartMode();
- ProgressIndicatorUtils.runWithWriteActionPriority(new ReadTask() {
- @Override
- public void computeInReadAction(@NotNull ProgressIndicator indicator) {
- if (DumbService.isDumb(myProject)) {
- canceled.set(true);
- return;
- }
-
- doHandleConstantSearchTask(channel, sessionId, task);
+ ProgressIndicatorUtils.scheduleWithWriteActionPriority(new ProgressIndicatorBase(), myTaskExecutor, new ReadTask() {
+ @Override
+ public void computeInReadAction(@NotNull ProgressIndicator indicator) {
+ if (DumbService.isDumb(myProject)) {
+ onCanceled(indicator);
}
-
- @Override
- public void onCanceled(@NotNull ProgressIndicator indicator) {
- canceled.set(true);
+ else {
+ doHandleConstantSearchTask(channel, sessionId, task);
}
- });
- if (!canceled.get()) {
- break;
}
- }
+
+ @Override
+ public void onCanceled(@NotNull ProgressIndicator indicator) {
+ DumbService.getInstance(myProject).runWhenSmart(new Runnable() {
+ @Override
+ public void run() {
+ handleConstantSearchTask(channel, sessionId, task);
+ }
+ });
+ }
+ });
}
+
private void doHandleConstantSearchTask(Channel channel, UUID sessionId, CmdlineRemoteProto.Message.BuilderMessage.ConstantSearchTask task) {
final String ownerClassName = task.getOwnerClassName();
final String fieldName = task.getFieldName();
diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/AdjustArrayRangeAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/AdjustArrayRangeAction.java
index 3a821fb10c0f..ce375815bb77 100644
--- a/java/debugger/impl/src/com/intellij/debugger/actions/AdjustArrayRangeAction.java
+++ b/java/debugger/impl/src/com/intellij/debugger/actions/AdjustArrayRangeAction.java
@@ -23,12 +23,10 @@ import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl;
import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl;
import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl;
import com.intellij.debugger.ui.tree.render.*;
-import com.intellij.ide.actions.ShowSettingsUtilImpl;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.options.Configurable;
-import com.intellij.openapi.options.ex.SingleConfigurableEditor;
+import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.DialogWrapper;
import org.jetbrains.annotations.Nullable;
public class AdjustArrayRangeAction extends DebuggerAction {
@@ -67,30 +65,25 @@ public class AdjustArrayRangeAction extends DebuggerAction {
title = title + " " + label.substring(index);
}
final ArrayRenderer clonedRenderer = renderer.clone();
- final NamedArrayConfigurable configurable = new NamedArrayConfigurable(title, clonedRenderer);
- SingleConfigurableEditor editor = new SingleConfigurableEditor(project, configurable,
- ShowSettingsUtilImpl.createDimensionKey(configurable), false);
- editor.show();
-
- if(editor.getExitCode() == DialogWrapper.OK_EXIT_CODE) {
+ if (ShowSettingsUtil.getInstance().editConfigurable(project, new NamedArrayConfigurable(title, clonedRenderer))) {
debugProcess.getManagerThread().schedule(new SuspendContextCommandImpl(debuggerContext.getSuspendContext()) {
- @Override
- public void contextAction() throws Exception {
- final ValueDescriptorImpl nodeDescriptor = (ValueDescriptorImpl)selectedNode.getDescriptor();
- final Renderer lastRenderer = nodeDescriptor.getLastRenderer();
- if (lastRenderer instanceof ArrayRenderer) {
- selectedNode.setRenderer(clonedRenderer);
- }
- else if (lastRenderer instanceof CompoundNodeRenderer) {
- final CompoundNodeRenderer compoundRenderer = (CompoundNodeRenderer)lastRenderer;
- final ChildrenRenderer childrenRenderer = compoundRenderer.getChildrenRenderer();
- if (childrenRenderer instanceof ExpressionChildrenRenderer) {
- ExpressionChildrenRenderer.setPreferableChildrenRenderer(nodeDescriptor, clonedRenderer);
- selectedNode.calcRepresentation();
- }
+ @Override
+ public void contextAction() throws Exception {
+ final ValueDescriptorImpl nodeDescriptor = (ValueDescriptorImpl)selectedNode.getDescriptor();
+ final Renderer lastRenderer = nodeDescriptor.getLastRenderer();
+ if (lastRenderer instanceof ArrayRenderer) {
+ selectedNode.setRenderer(clonedRenderer);
+ }
+ else if (lastRenderer instanceof CompoundNodeRenderer) {
+ final CompoundNodeRenderer compoundRenderer = (CompoundNodeRenderer)lastRenderer;
+ final ChildrenRenderer childrenRenderer = compoundRenderer.getChildrenRenderer();
+ if (childrenRenderer instanceof ExpressionChildrenRenderer) {
+ ExpressionChildrenRenderer.setPreferableChildrenRenderer(nodeDescriptor, clonedRenderer);
+ selectedNode.calcRepresentation();
}
}
- });
+ }
+ });
}
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/CustomizeThreadsViewAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/CustomizeThreadsViewAction.java
index 64705a373a21..7cef867334df 100644
--- a/java/debugger/impl/src/com/intellij/debugger/actions/CustomizeThreadsViewAction.java
+++ b/java/debugger/impl/src/com/intellij/debugger/actions/CustomizeThreadsViewAction.java
@@ -19,23 +19,15 @@ import com.intellij.debugger.settings.ThreadsViewConfigurable;
import com.intellij.debugger.settings.ThreadsViewSettings;
import com.intellij.idea.ActionsBundle;
import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.actionSystem.CommonDataKeys;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
-import com.intellij.openapi.options.ex.SingleConfigurableEditor;
-import com.intellij.openapi.project.Project;
+import com.intellij.openapi.options.ShowSettingsUtil;
-/**
- * User: lex
- * Date: Sep 26, 2003
- * Time: 4:40:12 PM
- */
public class CustomizeThreadsViewAction extends DebuggerAction {
+ @Override
public void actionPerformed(AnActionEvent e) {
- Project project = CommonDataKeys.PROJECT.getData(e.getDataContext());
- final SingleConfigurableEditor editor = new SingleConfigurableEditor(project, new ThreadsViewConfigurable(ThreadsViewSettings.getInstance()));
- editor.show();
+ ShowSettingsUtil.getInstance().editConfigurable(e.getProject(), new ThreadsViewConfigurable(ThreadsViewSettings.getInstance()));
}
+ @Override
public void update(AnActionEvent e) {
e.getPresentation().setVisible(true);
e.getPresentation().setText(ActionsBundle.actionText(DebuggerActions.CUSTOMIZE_THREADS_VIEW));
diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/JavaReferringObjectsValue.java b/java/debugger/impl/src/com/intellij/debugger/actions/JavaReferringObjectsValue.java
new file mode 100644
index 000000000000..815ddd231f14
--- /dev/null
+++ b/java/debugger/impl/src/com/intellij/debugger/actions/JavaReferringObjectsValue.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.actions;
+
+import com.intellij.debugger.DebuggerContext;
+import com.intellij.debugger.engine.JavaValue;
+import com.intellij.debugger.engine.evaluation.EvaluateException;
+import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
+import com.intellij.debugger.engine.events.SuspendContextCommandImpl;
+import com.intellij.debugger.ui.impl.watch.FieldDescriptorImpl;
+import com.intellij.debugger.ui.impl.watch.NodeManagerImpl;
+import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl;
+import com.intellij.psi.PsiExpression;
+import com.intellij.xdebugger.frame.*;
+import com.intellij.xdebugger.frame.presentation.XValuePresentation;
+import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodePresentationConfigurator;
+import com.sun.jdi.Field;
+import com.sun.jdi.ObjectReference;
+import com.sun.jdi.Value;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.util.List;
+
+public class JavaReferringObjectsValue extends JavaValue {
+ private static final long MAX_REFERRING = 100;
+ private final boolean myIsField;
+
+ private JavaReferringObjectsValue(@Nullable JavaValue parent,
+ @NotNull ValueDescriptorImpl valueDescriptor,
+ @NotNull EvaluationContextImpl evaluationContext,
+ NodeManagerImpl nodeManager,
+ boolean isField) {
+ super(parent, valueDescriptor, evaluationContext, nodeManager, false);
+ myIsField = isField;
+ }
+
+ public JavaReferringObjectsValue(@NotNull JavaValue javaValue, boolean isField) {
+ super(null, javaValue.getDescriptor(), javaValue.getEvaluationContext(), null, false);
+ myIsField = isField;
+ }
+
+ @Override
+ public boolean canNavigateToSource() {
+ return true;
+ }
+
+ @Override
+ public void computeChildren(@NotNull final XCompositeNode node) {
+ getEvaluationContext().getDebugProcess().getManagerThread().schedule(
+ new SuspendContextCommandImpl(getEvaluationContext().getSuspendContext()) {
+ @Override
+ public Priority getPriority() {
+ return Priority.NORMAL;
+ }
+
+ @Override
+ public void contextAction() throws Exception {
+ final XValueChildrenList children = new XValueChildrenList();
+
+ Value value = getDescriptor().getValue();
+ List<ObjectReference> references = ((ObjectReference)value).referringObjects(MAX_REFERRING);
+ int i = 1;
+ for (final ObjectReference reference : references) {
+ // try to find field name
+ Field field = findField(reference, value);
+ if (field != null) {
+ ValueDescriptorImpl descriptor = new FieldDescriptorImpl(getProject(), reference, field) {
+ @Override
+ public Value calcValue(EvaluationContextImpl evaluationContext) throws EvaluateException {
+ return reference;
+ }
+ };
+ children.add(new JavaReferringObjectsValue(null, descriptor, getEvaluationContext(), null, true));
+ i++;
+ }
+ else {
+ ValueDescriptorImpl descriptor = new ValueDescriptorImpl(getProject(), reference) {
+ @Override
+ public Value calcValue(EvaluationContextImpl evaluationContext) throws EvaluateException {
+ return reference;
+ }
+
+ @Override
+ public String getName() {
+ return "Ref";
+ }
+
+ @Override
+ public String calcValueName() {
+ return "Ref";
+ }
+
+ @Override
+ public PsiExpression getDescriptorEvaluation(DebuggerContext context) throws EvaluateException {
+ return null;
+ }
+ };
+ children.add("Referrer " + i++, new JavaReferringObjectsValue(null, descriptor, getEvaluationContext(), null, false));
+ }
+ }
+
+ node.addChildren(children, true);
+ }
+ }
+ );
+ }
+
+ @Override
+ public void computePresentation(@NotNull final XValueNode node, @NotNull final XValuePlace place) {
+ if (!myIsField) {
+ super.computePresentation(node, place);
+ }
+ else {
+ super.computePresentation(new XValueNodePresentationConfigurator.ConfigurableXValueNodeImpl() {
+ @Override
+ public void applyPresentation(@Nullable Icon icon, @NotNull final XValuePresentation valuePresenter, boolean hasChildren) {
+ node.setPresentation(icon, new XValuePresentation() {
+ @NotNull
+ @Override
+ public String getSeparator() {
+ return " in ";
+ }
+
+ @Nullable
+ @Override
+ public String getType() {
+ return valuePresenter.getType();
+ }
+
+ @Override
+ public void renderValue(@NotNull XValueTextRenderer renderer) {
+ valuePresenter.renderValue(renderer);
+ }
+ }, hasChildren);
+ }
+
+ @Override
+ public void setFullValueEvaluator(@NotNull XFullValueEvaluator fullValueEvaluator) {
+ }
+
+ @Override
+ public boolean isObsolete() {
+ return false;
+ }
+ }, place);
+ }
+ }
+
+ private static Field findField(ObjectReference reference, Value value) {
+ for (Field field : reference.referenceType().allFields()) {
+ if (reference.getValue(field) == value) {
+ return field;
+ }
+ }
+ return null;
+ }
+}
diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ShowReferringObjectsAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/ShowReferringObjectsAction.java
deleted file mode 100644
index 68275af275c4..000000000000
--- a/java/debugger/impl/src/com/intellij/debugger/actions/ShowReferringObjectsAction.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright 2000-2014 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.debugger.actions;
-
-import com.intellij.debugger.DebuggerContext;
-import com.intellij.debugger.engine.JavaValue;
-import com.intellij.debugger.engine.evaluation.EvaluateException;
-import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
-import com.intellij.debugger.engine.events.SuspendContextCommandImpl;
-import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl;
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.psi.PsiExpression;
-import com.intellij.xdebugger.frame.*;
-import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
-import com.intellij.xdebugger.impl.ui.tree.XInspectDialog;
-import com.intellij.xdebugger.impl.ui.tree.actions.XDebuggerTreeActionBase;
-import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
-import com.sun.jdi.ObjectReference;
-import com.sun.jdi.Value;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.List;
-
-/**
- * @author egor
- */
-public class ShowReferringObjectsAction extends XDebuggerTreeActionBase {
- private static final long MAX_REFERRING = 100;
-
- @Override
- public void update(AnActionEvent e) {
- super.update(e);
- }
-
- @Override
- protected void perform(XValueNodeImpl node, @NotNull String nodeName, AnActionEvent e) {
- XValue container = node.getValueContainer();
- JavaValue javaValue = null;
- if (container instanceof ReferringObjectsValue) {
- javaValue = ((ReferringObjectsValue)container).myJavaValue;
- }
- else if (container instanceof JavaValue) {
- javaValue = ((JavaValue)container);
- }
- if (javaValue != null) {
- XDebuggerTree tree = XDebuggerTree.getTree(e.getDataContext());
- XInspectDialog dialog = new XInspectDialog(tree.getProject(),
- tree.getEditorsProvider(),
- tree.getSourcePosition(),
- nodeName,
- new ReferringObjectsValue(javaValue),
- tree.getValueMarkers());
- dialog.setTitle("Referring objects for " + nodeName);
- dialog.show();
- }
- }
-
- private static class ReferringObjectsValue extends XValue {
- private final JavaValue myJavaValue;
-
- public ReferringObjectsValue(JavaValue javaValue) {
- myJavaValue = javaValue;
- }
-
- @Override
- public void computePresentation(@NotNull XValueNode node, @NotNull XValuePlace place) {
- myJavaValue.computePresentation(node, place);
- }
-
- @Override
- public void computeChildren(@NotNull final XCompositeNode node) {
- myJavaValue.getEvaluationContext().getDebugProcess().getManagerThread().schedule(
- new SuspendContextCommandImpl(myJavaValue.getEvaluationContext().getSuspendContext()) {
- @Override
- public Priority getPriority() {
- return Priority.NORMAL;
- }
-
- @Override
- public void contextAction() throws Exception {
- final XValueChildrenList children = new XValueChildrenList();
-
- Value value = myJavaValue.getDescriptor().getValue();
- List<ObjectReference> references = ((ObjectReference)value).referringObjects(MAX_REFERRING);
- int i = 1;
- for (final ObjectReference reference : references) {
- ValueDescriptorImpl descriptor = new ValueDescriptorImpl(myJavaValue.getProject(), reference) {
- @Override
- public Value calcValue(EvaluationContextImpl evaluationContext) throws EvaluateException {
- return reference;
- }
-
- @Override
- public String getName() {
- return "Ref";
- }
-
- @Override
- public String calcValueName() {
- return "Ref";
- }
-
- @Override
- public PsiExpression getDescriptorEvaluation(DebuggerContext context) throws EvaluateException {
- return null;
- }
- };
- JavaValue jValue = JavaValue.create(descriptor, myJavaValue.getEvaluationContext(), null);
- children.add("Referrer " + i++ ,new ReferringObjectsValue(jValue));
- }
-
- node.addChildren(children, true);
- }
- }
- );
- }
- }
-}
diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ToggleMethodBreakpointAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/ToggleMethodBreakpointAction.java
index 097039b0f9f4..b239fee363fc 100644
--- a/java/debugger/impl/src/com/intellij/debugger/actions/ToggleMethodBreakpointAction.java
+++ b/java/debugger/impl/src/com/intellij/debugger/actions/ToggleMethodBreakpointAction.java
@@ -38,6 +38,7 @@ import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiMethod;
+import com.intellij.util.DocumentUtil;
import com.intellij.util.text.CharArrayUtil;
import org.jetbrains.annotations.Nullable;
@@ -66,7 +67,7 @@ public class ToggleMethodBreakpointAction extends AnAction {
}
final BreakpointManager manager = debugManager.getBreakpointManager();
final PlaceInDocument place = getPlace(e);
- if(place != null) {
+ if(place != null && DocumentUtil.isValidOffset(place.getOffset(), place.getDocument())) {
Breakpoint breakpoint = manager.findBreakpoint(place.getDocument(), place.getOffset(), MethodBreakpoint.CATEGORY);
if(breakpoint == null) {
final int methodLine = place.getDocument().getLineNumber(place.getOffset());
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebuggerEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebuggerEvaluator.java
index e37576bae8f4..f2178c1d4fb5 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebuggerEvaluator.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebuggerEvaluator.java
@@ -15,6 +15,7 @@
*/
package com.intellij.debugger.engine;
+import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
import com.intellij.debugger.engine.evaluation.TextWithImportsImpl;
import com.intellij.debugger.engine.events.DebuggerContextCommandImpl;
@@ -73,9 +74,16 @@ public class JavaDebuggerEvaluator extends XDebuggerEvaluator {
callback.errorOccurred("Context is not available");
return;
}
+ descriptor.setContext(evalContext);
+ @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
+ EvaluateException exception = descriptor.getEvaluateException();
+ if (exception != null) {
+ callback.errorOccurred(exception.getMessage());
+ return;
+ }
JavaDebugProcess process = myDebugProcess.getXdebugProcess();
if (process != null) {
- callback.evaluated(JavaValue.create(descriptor, evalContext, process.getNodeManager()));
+ callback.evaluated(JavaValue.create(null, descriptor, evalContext, process.getNodeManager(), true));
}
}
});
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java
index f2cb40008ad5..1bd95096055f 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java
@@ -17,7 +17,6 @@ package com.intellij.debugger.engine;
import com.intellij.debugger.DebuggerBundle;
import com.intellij.debugger.engine.evaluation.EvaluateException;
-import com.intellij.debugger.engine.events.DebuggerCommandImpl;
import com.intellij.debugger.engine.events.DebuggerContextCommandImpl;
import com.intellij.debugger.engine.events.SuspendContextCommandImpl;
import com.intellij.debugger.impl.DebuggerUtilsEx;
@@ -46,7 +45,7 @@ public class JavaExecutionStack extends XExecutionStack {
private final DebugProcessImpl myDebugProcess;
private final NodeManagerImpl myNodeManager;
private volatile JavaStackFrame myTopFrame;
- private boolean myTopFrameReady = false;
+ private volatile boolean myTopFrameReady = false;
private final MethodsTracker myTracker = new MethodsTracker();
public JavaExecutionStack(@NotNull ThreadReferenceProxyImpl threadProxy, @NotNull DebugProcessImpl debugProcess, boolean current) {
@@ -99,25 +98,7 @@ public class JavaExecutionStack extends XExecutionStack {
@Nullable
@Override
public JavaStackFrame getTopFrame() {
- if (!myTopFrameReady) {
- //TODO: remove sync calculation
- if (DebuggerManagerThreadImpl.isManagerThread()) {
- myTopFrame = calcTopFrame();
- }
- else {
- myDebugProcess.getManagerThread().invokeAndWait(new DebuggerCommandImpl() {
- @Override
- public Priority getPriority() {
- return Priority.HIGH;
- }
-
- @Override
- protected void action() throws Exception {
- myTopFrame = calcTopFrame();
- }
- });
- }
- }
+ assert myTopFrameReady : "Top frame must be already calculated here";
return myTopFrame;
}
@@ -183,8 +164,20 @@ public class JavaExecutionStack extends XExecutionStack {
@Override
public void contextAction() throws Exception {
if (myStackFramesIterator.hasNext()) {
- JavaStackFrame frame = new JavaStackFrame(myStackFramesIterator.next(), myDebugProcess, myTracker, myNodeManager);
- if (DebuggerSettings.getInstance().SHOW_LIBRARY_STACKFRAMES || (!frame.getDescriptor().isSynthetic() && !frame.getDescriptor().isInLibraryContent())) {
+ JavaStackFrame frame;
+ boolean first = myAdded == 0;
+ if (first && myTopFrameReady) {
+ frame = myTopFrame;
+ myStackFramesIterator.next();
+ }
+ else {
+ frame = new JavaStackFrame(myStackFramesIterator.next(), myDebugProcess, myTracker, myNodeManager);
+ if (first && !myTopFrameReady) {
+ myTopFrame = frame;
+ myTopFrameReady = true;
+ }
+ }
+ if (first || DebuggerSettings.getInstance().SHOW_LIBRARY_STACKFRAMES || (!frame.getDescriptor().isSynthetic() && !frame.getDescriptor().isInLibraryContent())) {
if (++myAdded > mySkip) {
myContainer.addStackFrames(Arrays.asList(frame), false);
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java
index 3f649e2b1dab..e7db635abe13 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java
@@ -370,7 +370,7 @@ public class JavaStackFrame extends XStackFrame {
ArgumentValueDescriptorImpl descriptor = myNodeManager.getArgumentValueDescriptor(null, index, value, name);
// setContext is required to calculate correct name
descriptor.setContext(evaluationContext);
- return JavaValue.create(descriptor, evaluationContext, myNodeManager);
+ return JavaValue.create(null, descriptor, evaluationContext, myNodeManager, true);
}
protected void superBuildVariables(final EvaluationContextImpl evaluationContext, XValueChildrenList children) throws EvaluateException {
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java
index 9cfb2bfde84e..7b0ffffe98d5 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java
@@ -17,6 +17,7 @@ package com.intellij.debugger.engine;
import com.intellij.debugger.DebuggerInvocationUtil;
import com.intellij.debugger.SourcePosition;
+import com.intellij.debugger.actions.JavaReferringObjectsValue;
import com.intellij.debugger.actions.JumpToObjectAction;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
@@ -66,27 +67,34 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV
private final ValueDescriptorImpl myValueDescriptor;
private final EvaluationContextImpl myEvaluationContext;
private final NodeManagerImpl myNodeManager;
+ private final boolean myContextSet;
- private JavaValue(JavaValue parent,
+ protected JavaValue(JavaValue parent,
@NotNull ValueDescriptorImpl valueDescriptor,
@NotNull EvaluationContextImpl evaluationContext,
- NodeManagerImpl nodeManager) {
+ NodeManagerImpl nodeManager,
+ boolean contextSet) {
super(valueDescriptor.getName());
myParent = parent;
myValueDescriptor = valueDescriptor;
myEvaluationContext = evaluationContext;
myNodeManager = nodeManager;
+ myContextSet = contextSet;
}
- private static JavaValue create(JavaValue parent, @NotNull ValueDescriptorImpl valueDescriptor, EvaluationContextImpl evaluationContext, NodeManagerImpl nodeManager, boolean init) {
+ static JavaValue create(JavaValue parent,
+ @NotNull ValueDescriptorImpl valueDescriptor,
+ EvaluationContextImpl evaluationContext,
+ NodeManagerImpl nodeManager,
+ boolean contextSet) {
DebuggerManagerThreadImpl.assertIsManagerThread();
- return new JavaValue(parent, valueDescriptor, evaluationContext, nodeManager);
+ return new JavaValue(parent, valueDescriptor, evaluationContext, nodeManager, contextSet);
}
- public static JavaValue create(@NotNull ValueDescriptorImpl valueDescriptor,
+ static JavaValue create(@NotNull ValueDescriptorImpl valueDescriptor,
EvaluationContextImpl evaluationContext,
NodeManagerImpl nodeManager) {
- return create(null, valueDescriptor, evaluationContext, nodeManager, true);
+ return create(null, valueDescriptor, evaluationContext, nodeManager, false);
}
public JavaValue getParent() {
@@ -113,7 +121,9 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV
@Override
public void threadAction() {
- myValueDescriptor.setContext(myEvaluationContext);
+ if (!myContextSet) {
+ myValueDescriptor.setContext(myEvaluationContext);
+ }
myValueDescriptor.updateRepresentation(myEvaluationContext, new DescriptorLabelListener() {
@Override
public void labelChanged() {
@@ -123,12 +133,12 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV
String type = strings[0];
XValuePresentation presentation;
if (myValueDescriptor.isString()) {
- presentation = new TypedStringValuePresentation(StringUtil.unquoteString(value), type);
+ presentation = new TypedStringValuePresentation(value, type);
}
else {
EvaluateException exception = myValueDescriptor.getEvaluateException();
if (myValueDescriptor.getLastRenderer() instanceof ToStringRenderer && exception == null) {
- presentation = new XRegularValuePresentation(StringUtil.wrapWithDoubleQuote(value), type);
+ presentation = new XRegularValuePresentation(StringUtil.wrapWithDoubleQuote(value.substring(0,Math.min(value.length(), XValueNode.MAX_VALUE_LENGTH))), type);
}
else {
presentation = new JavaValuePresentation(value, type, exception != null ? exception.getMessage() : null);
@@ -339,15 +349,16 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public void run() {
+ final boolean nearest = navigatable instanceof XNearestSourcePosition;
if (myValueDescriptor instanceof FieldDescriptorImpl) {
- SourcePosition position = ((FieldDescriptorImpl)myValueDescriptor).getSourcePosition(getProject(), getDebuggerContext());
+ SourcePosition position = ((FieldDescriptorImpl)myValueDescriptor).getSourcePosition(getProject(), getDebuggerContext(), nearest);
if (position != null) {
navigatable.setSourcePosition(DebuggerUtilsEx.toXSourcePosition(position));
}
}
if (myValueDescriptor instanceof LocalVariableDescriptorImpl) {
SourcePosition position =
- ((LocalVariableDescriptorImpl)myValueDescriptor).getSourcePosition(getProject(), getDebuggerContext());
+ ((LocalVariableDescriptorImpl)myValueDescriptor).getSourcePosition(getProject(), getDebuggerContext(), nearest);
if (position != null) {
navigatable.setSourcePosition(DebuggerUtilsEx.toXSourcePosition(position));
}
@@ -442,4 +453,14 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV
public String getValueText() {
return myValueDescriptor.getValueText();
}
+ @Nullable
+ @Override
+ public XReferrersProvider getReferrersProvider() {
+ return new XReferrersProvider() {
+ @Override
+ public XValue getReferringObjectsValue() {
+ return new JavaReferringObjectsValue(JavaValue.this, false);
+ }
+ };
+ }
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java
index 45af0e10ac72..83ad91b4e27d 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java
@@ -40,6 +40,7 @@ import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiTypesUtil;
+import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.IncorrectOperationException;
import com.sun.jdi.Value;
@@ -1036,7 +1037,8 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
final PsiType castType = expression.getCastType().getType();
final PsiType operandType = operandExpr.getType();
- if (castType != null && operandType != null && !TypeConversionUtil.areTypesConvertible(operandType, castType)) {
+ // if operand type can not be resolved in current context - leave it for runtime checks
+ if (castType != null && operandType != null && !TypeConversionUtil.areTypesConvertible(operandType, castType) && PsiUtil.resolveClassInType(operandType) != null) {
throw new EvaluateRuntimeException(
new EvaluateException(JavaErrorMessages.message("inconvertible.type.cast", JavaHighlightUtil.formatType(operandType), JavaHighlightUtil
.formatType(castType)))
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/MethodEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/MethodEvaluator.java
index 2569559d2d11..6ba88653749b 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/MethodEvaluator.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/MethodEvaluator.java
@@ -21,21 +21,19 @@
package com.intellij.debugger.engine.evaluation.expression;
import com.intellij.debugger.DebuggerBundle;
+import com.intellij.debugger.engine.DebugProcess;
import com.intellij.debugger.engine.DebugProcessImpl;
import com.intellij.debugger.engine.DebuggerUtils;
import com.intellij.debugger.engine.JVMName;
-import com.intellij.debugger.engine.evaluation.EvaluateException;
-import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil;
-import com.intellij.debugger.engine.evaluation.EvaluateRuntimeException;
-import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
+import com.intellij.debugger.engine.evaluation.*;
import com.intellij.debugger.impl.DebuggerUtilsEx;
+import com.intellij.debugger.jdi.VirtualMachineProxyImpl;
import com.intellij.openapi.diagnostic.Logger;
-import com.sun.jdi.ClassType;
-import com.sun.jdi.Method;
-import com.sun.jdi.ObjectReference;
-import com.sun.jdi.ReferenceType;
+import com.intellij.rt.debugger.DefaultMethodInvoker;
+import com.sun.jdi.*;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
public class MethodEvaluator implements Evaluator {
@@ -149,7 +147,13 @@ public class MethodEvaluator implements Evaluator {
if (requiresSuperObject) {
return debugProcess.invokeInstanceMethod(context, objRef, jdiMethod, args, ObjectReference.INVOKE_NONVIRTUAL);
}
- return debugProcess.invokeMethod(context, objRef, jdiMethod, args);
+ // fix for default methods in interfaces, see IDEA-124066
+ if (Boolean.valueOf(System.getProperty("debugger.invoke.default")) && jdiMethod.declaringType() instanceof InterfaceType) {
+ return invokeDefaultMethod(debugProcess, context, objRef, myMethodName);
+ }
+ else {
+ return debugProcess.invokeMethod(context, objRef, jdiMethod, args);
+ }
}
catch (Exception e) {
if (LOG.isDebugEnabled()) {
@@ -158,4 +162,22 @@ public class MethodEvaluator implements Evaluator {
throw EvaluateExceptionUtil.createEvaluateException(e);
}
}
+
+ // only methods without arguments for now
+ private static Value invokeDefaultMethod(DebugProcess debugProcess, EvaluationContext evaluationContext,
+ Value obj, String name)
+ throws EvaluateException, ClassNotLoadedException, InvalidTypeException {
+ ClassType invokerClass = (ClassType)debugProcess.findClass(
+ evaluationContext, DefaultMethodInvoker.class.getName(),
+ evaluationContext.getClassLoader());
+
+ if (invokerClass != null) {
+ List<Method> methods = invokerClass.methodsByName("invoke");
+ if (!methods.isEmpty()) {
+ return debugProcess.invokeMethod(evaluationContext, invokerClass, methods.get(0),
+ Arrays.asList(obj, ((VirtualMachineProxyImpl)debugProcess.getVirtualMachineProxy()).mirrorOf(name)));
+ }
+ }
+ return null;
+ }
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerContextUtil.java b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerContextUtil.java
index e75abd2f1e52..8408364f7e73 100644
--- a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerContextUtil.java
+++ b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerContextUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,13 +15,27 @@
*/
package com.intellij.debugger.impl;
+import com.intellij.codeInsight.daemon.impl.IdentifierHighlighterPass;
+import com.intellij.debugger.SourcePosition;
import com.intellij.debugger.engine.SuspendContextImpl;
import com.intellij.debugger.engine.SuspendManagerUtil;
import com.intellij.debugger.jdi.StackFrameProxyImpl;
import com.intellij.debugger.ui.impl.watch.ThreadDescriptorImpl;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.util.Couple;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.util.PsiUtilBase;
+import com.intellij.xdebugger.XDebugSession;
+import com.intellij.xdebugger.XSourcePosition;
import org.jetbrains.annotations.NotNull;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
public class DebuggerContextUtil {
public static void setStackFrame(DebuggerStateManager manager, final StackFrameProxyImpl stackFrame) {
ApplicationManager.getApplication().assertIsDispatchThread();
@@ -53,4 +67,43 @@ public class DebuggerContextUtil {
public static DebuggerContextImpl createDebuggerContext(@NotNull DebuggerSession session, SuspendContextImpl suspendContext){
return DebuggerContextImpl.createDebuggerContext(session, suspendContext, suspendContext != null ? suspendContext.getThread() : null, null);
}
+
+ public static SourcePosition findNearest(@NotNull DebuggerContextImpl context, @NotNull PsiElement psi, @NotNull PsiFile file) {
+ final DebuggerSession session = context.getDebuggerSession();
+ if (session != null) {
+ try {
+ final XDebugSession debugSession = session.getXDebugSession();
+ if (debugSession != null) {
+ final XSourcePosition position = debugSession.getCurrentPosition();
+ final Editor editor = PsiUtilBase.findEditor(psi);
+ if (editor != null && position != null && file.getVirtualFile().equals(position.getFile())) {
+ final Couple<Collection<TextRange>> usages = IdentifierHighlighterPass.getHighlightUsages(psi, file);
+ final List<TextRange> ranges = new ArrayList<TextRange>();
+ ranges.addAll(usages.first);
+ ranges.addAll(usages.second);
+ final int breakPointLine = position.getLine();
+ int bestLine = -1;
+ boolean hasSameLine = false;
+ for (TextRange range : ranges) {
+ final int line = editor.offsetToLogicalPosition(range.getStartOffset()).line;
+ if (line > bestLine && line < breakPointLine) {
+ bestLine = line;
+ } else if (line == breakPointLine) {
+ hasSameLine = true;
+ }
+ }
+ if (bestLine > 0) {
+ if (hasSameLine && breakPointLine - bestLine > 4) {
+ return SourcePosition.createFromLine(file, breakPointLine);
+ }
+ return SourcePosition.createFromLine(file, bestLine);
+ }
+ }
+ }
+ }
+ catch (Exception ignore) {
+ }
+ }
+ return SourcePosition.createFromOffset(file, psi.getTextOffset());
+ }
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/HotSwapProgressImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/HotSwapProgressImpl.java
index b2b0091fc949..601ec7957849 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/HotSwapProgressImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/HotSwapProgressImpl.java
@@ -38,7 +38,7 @@ import java.util.Collections;
import java.util.List;
public class HotSwapProgressImpl extends HotSwapProgress{
- static final NotificationGroup NOTIFICATION_GROUP = NotificationGroup.toolWindowGroup("HotSwap", ToolWindowId.DEBUG, true);
+ static final NotificationGroup NOTIFICATION_GROUP = NotificationGroup.toolWindowGroup("HotSwap", ToolWindowId.DEBUG);
TIntObjectHashMap<List<String>> myMessages = new TIntObjectHashMap<List<String>>();
private final ProgressWindow myProgressWindow;
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java b/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java
index 20d95f8fff3d..ec2288fa7a57 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java
@@ -165,7 +165,7 @@ public class JavaDebuggerSupport extends DebuggerSupport {
@NotNull
@Override
public DebuggerActionHandler getAddToWatchesActionHandler() {
- return myAddToWatchedActionHandler;
+ return DISABLED;
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluator.java
new file mode 100644
index 000000000000..042216c40f05
--- /dev/null
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluator.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.ui.impl.watch;
+
+import com.intellij.debugger.engine.DebugProcess;
+import com.intellij.debugger.engine.evaluation.EvaluateException;
+import com.intellij.debugger.engine.evaluation.EvaluationContext;
+import com.intellij.debugger.engine.evaluation.TextWithImports;
+import com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator;
+import com.intellij.debugger.engine.evaluation.expression.Modifier;
+import com.intellij.debugger.jdi.VirtualMachineProxyImpl;
+import com.sun.jdi.*;
+
+import javax.tools.*;
+import java.io.ByteArrayOutputStream;
+import java.net.URI;
+import java.util.*;
+
+/**
+* @author egor
+*/
+class CompilingEvaluator implements ExpressionEvaluator {
+ private final TextWithImports myText;
+
+ public CompilingEvaluator(TextWithImports text) {
+ myText = text;
+ }
+
+ @Override
+ public Value getValue() {
+ return null;
+ }
+
+ @Override
+ public Modifier getModifier() {
+ return null;
+ }
+
+ @Override
+ public Value evaluate(EvaluationContext context) throws EvaluateException {
+ try {
+ DebugProcess process = context.getDebugProcess();
+ ThreadReference threadReference = context.getSuspendContext().getThread().getThreadReference();
+
+ ClassLoaderReference classLoader = getClassLoader(context);
+
+ Collection<OutputFileObject> classes = compile();
+
+ ClassType mainClass = defineClasses(classes, context, process, threadReference, classLoader);
+
+ Method foo = mainClass.methodsByName(GEN_METHOD_NAME).get(0);
+ return mainClass.invokeMethod(threadReference, foo, Collections.<Value>emptyList() ,ClassType.INVOKE_SINGLE_THREADED);
+ }
+ catch (Exception e) {
+ throw new EvaluateException(e.getMessage());
+ }
+ }
+
+ private static ClassLoaderReference getClassLoader(EvaluationContext context)
+ throws EvaluateException, InvocationException, InvalidTypeException, ClassNotLoadedException, IncompatibleThreadStateException {
+ // TODO: cache
+ DebugProcess process = context.getDebugProcess();
+ ClassType loaderClass = (ClassType)process.findClass(context, "java.net.URLClassLoader", context.getClassLoader());
+ Method ctorMethod = loaderClass.concreteMethodByName("<init>", "([Ljava/net/URL;)V");
+ ThreadReference threadReference = context.getSuspendContext().getThread().getThreadReference();
+ return (ClassLoaderReference)loaderClass.newInstance(threadReference, ctorMethod,
+ Arrays.asList(createURLArray(context)), ClassType.INVOKE_SINGLE_THREADED);
+ }
+
+ private static ClassType defineClasses(Collection<OutputFileObject> classes,
+ EvaluationContext context,
+ DebugProcess process,
+ ThreadReference threadReference,
+ ClassLoaderReference classLoader)
+ throws EvaluateException, InvalidTypeException, ClassNotLoadedException, IncompatibleThreadStateException, InvocationException {
+
+ VirtualMachineProxyImpl proxy = (VirtualMachineProxyImpl)process.getVirtualMachineProxy();
+ for (OutputFileObject cls : classes) {
+ Method defineMethod = ((ClassType)classLoader.referenceType()).concreteMethodByName("defineClass", "(Ljava/lang/String;[BII)Ljava/lang/Class;");
+ byte[] bytes = cls.toByteArray();
+ ArrayList<Value> args = new ArrayList<Value>();
+ args.add(proxy.mirrorOf(cls.myOrigName));
+ args.add(mirrorOf(bytes, context, process));
+ args.add(proxy.mirrorOf(0));
+ args.add(proxy.mirrorOf(bytes.length));
+ classLoader.invokeMethod(threadReference, defineMethod, args, ClassType.INVOKE_SINGLE_THREADED);
+ }
+ return (ClassType)process.findClass(context, GEN_CLASS_FULL_NAME, classLoader);
+ }
+
+ private static ArrayReference mirrorOf(byte[] bytes, EvaluationContext context, DebugProcess process)
+ throws EvaluateException, InvalidTypeException, ClassNotLoadedException {
+ ArrayType arrayClass = (ArrayType)process.findClass(context, "byte[]", context.getClassLoader());
+ ArrayReference reference = process.newInstance(arrayClass, bytes.length);
+ reference.disableCollection();
+ for (int i = 0; i < bytes.length; i++) {
+ reference.setValue(i, ((VirtualMachineProxyImpl)process.getVirtualMachineProxy()).mirrorOf(bytes[i]));
+ }
+ return reference;
+ }
+
+ private static final String GEN_CLASS_NAME = "Evaluator";
+ private static final String GEN_CLASS_PACKAGE = "dummy";
+ private static final String GEN_CLASS_FULL_NAME = GEN_CLASS_PACKAGE + '.' + GEN_CLASS_NAME;
+ private static final String GEN_METHOD_NAME = "eval";
+
+ private static String createClassCode(TextWithImports body) {
+ StringBuilder text = new StringBuilder();
+ text.append("package " + GEN_CLASS_PACKAGE + ";");
+ String imports = body.getImports();
+ if (!imports.isEmpty()) {
+ for (String s : imports.split(",")) {
+ text.append("import " + s + ";");
+ }
+ }
+ String bodyText = body.getText();
+ if (!bodyText.endsWith(";")) {
+ bodyText += ';';
+ }
+ text.append("public class " + GEN_CLASS_NAME + " { public static Object " + GEN_METHOD_NAME + "() throws Exception {" + bodyText + "}}");
+ return text.toString();
+ }
+
+ private static ArrayReference createURLArray(EvaluationContext context)
+ throws EvaluateException, InvocationException, InvalidTypeException, ClassNotLoadedException, IncompatibleThreadStateException {
+ DebugProcess process = context.getDebugProcess();
+ ArrayType arrayType = (ArrayType)process.findClass(context, "java.net.URL[]", context.getClassLoader());
+ ArrayReference arrayRef = arrayType.newInstance(1);
+ ClassType classType = (ClassType)process.findClass(context, "java.net.URL", context.getClassLoader());
+ VirtualMachineProxyImpl proxy = (VirtualMachineProxyImpl)process.getVirtualMachineProxy();
+ ThreadReference threadReference = context.getSuspendContext().getThread().getThreadReference();
+ ObjectReference reference = classType.newInstance(threadReference, classType.concreteMethodByName("<init>", "(Ljava/lang/String;)V"),
+ Arrays.asList(proxy.mirrorOf("file:a")), ClassType.INVOKE_SINGLE_THREADED);
+ arrayRef.setValues(Arrays.asList(reference));
+ return arrayRef;
+ }
+
+ ///////////////// Compiler stuff
+
+ private Collection<OutputFileObject> compile() throws EvaluateException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ MemoryFileManager manager = new MemoryFileManager(compiler);
+ DiagnosticCollector<JavaFileObject> diagnostic = new DiagnosticCollector<JavaFileObject>();
+ if (!compiler.getTask(null, manager, diagnostic, null, null, Arrays
+ .asList(new SourceFileObject(GEN_CLASS_NAME, JavaFileObject.Kind.SOURCE, createClassCode(myText)))).call()) {
+ // TODO: show only errors
+ throw new EvaluateException(diagnostic.getDiagnostics().get(0).getMessage(Locale.getDefault()));
+ }
+ return manager.classes;
+ }
+
+ private static URI getUri(String name, JavaFileObject.Kind kind) {
+ return URI.create("memo:///" + name.replace('.', '/') + kind.extension);
+ }
+
+ private static class SourceFileObject extends SimpleJavaFileObject {
+ private final String myContent;
+
+ SourceFileObject(String name, Kind kind, String content) {
+ super(getUri(name, kind), kind);
+ myContent = content;
+ }
+
+ @Override
+ public CharSequence getCharContent(boolean ignore) {
+ return myContent;
+ }
+ }
+
+ private static class OutputFileObject extends SimpleJavaFileObject {
+ private final ByteArrayOutputStream myStream = new ByteArrayOutputStream();
+ private final String myOrigName;
+
+ OutputFileObject(String name, Kind kind) {
+ super(getUri(name, kind), kind);
+ myOrigName = name;
+ }
+
+ byte[] toByteArray() {
+ return myStream.toByteArray();
+ }
+
+ @Override
+ public ByteArrayOutputStream openOutputStream() {
+ return myStream;
+ }
+ }
+
+ private static class MemoryFileManager extends ForwardingJavaFileManager {
+ private final Collection<OutputFileObject> classes = new ArrayList<OutputFileObject>();
+
+ MemoryFileManager(JavaCompiler compiler) {
+ super(compiler.getStandardFileManager(null, null, null));
+ }
+
+ @Override
+ public OutputFileObject getJavaFileForOutput(Location location, String name, JavaFileObject.Kind kind, FileObject source) {
+ OutputFileObject mc = new OutputFileObject(name, kind);
+ classes.add(mc);
+ return mc;
+ }
+ }
+
+}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/EvaluationDescriptor.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/EvaluationDescriptor.java
index e09c17c979e5..1f880513cacd 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/EvaluationDescriptor.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/EvaluationDescriptor.java
@@ -28,6 +28,7 @@ import com.intellij.debugger.impl.DebuggerUtilsEx;
import com.intellij.debugger.impl.PositionUtil;
import com.intellij.debugger.jdi.StackFrameProxyImpl;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.psi.PsiCodeFragment;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiExpression;
@@ -80,14 +81,20 @@ public abstract class EvaluationDescriptor extends ValueDescriptorImpl{
try {
final EvaluationContextImpl thisEvaluationContext = getEvaluationContext(evaluationContext);
- final ExpressionEvaluator evaluator = DebuggerInvocationUtil.commitAndRunReadAction(myProject, new EvaluatingComputable<ExpressionEvaluator>() {
- public ExpressionEvaluator compute() throws EvaluateException {
- final PsiElement psiContext = PositionUtil.getContextElement(evaluationContext);
- return getEffectiveCodeFragmentFactory(psiContext).getEvaluatorBuilder().build(getEvaluationCode(thisEvaluationContext),
- ContextUtil.getSourcePosition(thisEvaluationContext));
- }
- });
-
+ final ExpressionEvaluator evaluator;
+ if (Registry.is("debugger.compiling.evaluator")) {
+ evaluator = new CompilingEvaluator(getEvaluationText());
+ }
+ else {
+ evaluator = DebuggerInvocationUtil.commitAndRunReadAction(myProject, new EvaluatingComputable<ExpressionEvaluator>() {
+ public ExpressionEvaluator compute() throws EvaluateException {
+ final PsiElement psiContext = PositionUtil.getContextElement(evaluationContext);
+ return getEffectiveCodeFragmentFactory(psiContext).getEvaluatorBuilder().build(getEvaluationCode(thisEvaluationContext),
+ ContextUtil
+ .getSourcePosition(thisEvaluationContext));
+ }
+ });
+ }
if (!thisEvaluationContext.getDebugProcess().isAttached()) {
throw EvaluateExceptionUtil.PROCESS_EXITED;
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/FieldDescriptorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/FieldDescriptorImpl.java
index 6a7a57ba7670..c36630e3a973 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/FieldDescriptorImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/FieldDescriptorImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@ import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
import com.intellij.debugger.impl.DebuggerContextImpl;
+import com.intellij.debugger.impl.DebuggerContextUtil;
import com.intellij.debugger.impl.DebuggerSession;
import com.intellij.debugger.impl.PositionUtil;
import com.intellij.debugger.settings.NodeRendererSettings;
@@ -73,6 +74,12 @@ public class FieldDescriptorImpl extends ValueDescriptorImpl implements FieldDes
@SuppressWarnings({"HardCodedStringLiteral"})
@Nullable
public SourcePosition getSourcePosition(final Project project, final DebuggerContextImpl context) {
+ return getSourcePosition(project, context, false);
+ }
+
+ @SuppressWarnings({"HardCodedStringLiteral"})
+ @Nullable
+ public SourcePosition getSourcePosition(final Project project, final DebuggerContextImpl context, boolean nearest) {
if (context.getFrameProxy() == null) {
return null;
}
@@ -95,6 +102,9 @@ public class FieldDescriptorImpl extends ValueDescriptorImpl implements FieldDes
if (psiVariable == null) {
return null;
}
+ if (nearest) {
+ return DebuggerContextUtil.findNearest(context, psiVariable, aClass.getContainingFile());
+ }
return SourcePosition.createFromOffset(psiVariable.getContainingFile(), psiVariable.getTextOffset());
}
else {
@@ -125,6 +135,9 @@ public class FieldDescriptorImpl extends ValueDescriptorImpl implements FieldDes
aClass = (PsiClass) aClass.getNavigationElement();
for (PsiField field : aClass.getFields()) {
if (fieldName.equals(field.getName())) {
+ if (nearest) {
+ return DebuggerContextUtil.findNearest(context, field, aClass.getContainingFile());
+ }
return SourcePosition.createFromOffset(field.getContainingFile(), field.getTextOffset());
}
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/LocalVariableDescriptorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/LocalVariableDescriptorImpl.java
index d2109c54f1c4..f936d79a6725 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/LocalVariableDescriptorImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/LocalVariableDescriptorImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@ import com.intellij.debugger.engine.DebuggerUtils;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
import com.intellij.debugger.impl.DebuggerContextImpl;
+import com.intellij.debugger.impl.DebuggerContextUtil;
import com.intellij.debugger.impl.PositionUtil;
import com.intellij.debugger.jdi.LocalVariableProxyImpl;
import com.intellij.debugger.jdi.StackFrameProxyImpl;
@@ -61,6 +62,11 @@ public class LocalVariableDescriptorImpl extends ValueDescriptorImpl implements
@Nullable
public SourcePosition getSourcePosition(final Project project, final DebuggerContextImpl context) {
+ return getSourcePosition(project, context, false);
+ }
+
+ @Nullable
+ public SourcePosition getSourcePosition(final Project project, final DebuggerContextImpl context, boolean nearest) {
StackFrameProxyImpl frame = context.getFrameProxy();
if (frame == null) return null;
@@ -77,7 +83,9 @@ public class LocalVariableDescriptorImpl extends ValueDescriptorImpl implements
PsiFile containingFile = psiVariable.getContainingFile();
if(containingFile == null) return null;
-
+ if (nearest) {
+ return DebuggerContextUtil.findNearest(context, psiVariable, containingFile);
+ }
return SourcePosition.createFromOffset(containingFile, psiVariable.getTextOffset());
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java
index f4da39f318a7..680d2ab424c3 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java
@@ -203,6 +203,7 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements
}
catch (EvaluateException e) {
myValueException = e;
+ setFailed(e);
myValue = getTargetExceptionWithStackTraceFilled(evaluationContext, e);
myIsExpandable = false;
}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/SourcePosition.java b/java/debugger/openapi/src/com/intellij/debugger/SourcePosition.java
index 9028b1489970..45f50d34b922 100644
--- a/java/debugger/openapi/src/com/intellij/debugger/SourcePosition.java
+++ b/java/debugger/openapi/src/com/intellij/debugger/SourcePosition.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -128,7 +128,12 @@ public abstract class SourcePosition implements Navigatable{
return true;
}
final PsiElement psiElement = myPsiElement;
- return psiElement != null && !psiElement.isValid();
+ return psiElement != null && !ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
+ @Override
+ public Boolean compute() {
+ return psiElement.isValid();
+ }
+ });
}
@Override
@@ -194,7 +199,7 @@ public abstract class SourcePosition implements Navigatable{
@Nullable
protected PsiElement calcPsiElement() {
- PsiFile psiFile = getFile();
+ final PsiFile psiFile = getFile();
int lineNumber = getLine();
if(lineNumber < 0) {
return psiFile;
@@ -207,47 +212,52 @@ public abstract class SourcePosition implements Navigatable{
if (lineNumber >= document.getLineCount()) {
return psiFile;
}
- int startOffset = document.getLineStartOffset(lineNumber);
+ final int startOffset = document.getLineStartOffset(lineNumber);
if(startOffset == -1) {
return null;
}
- PsiElement rootElement = psiFile;
-
- List<PsiFile> allFiles = psiFile.getViewProvider().getAllFiles();
- if (allFiles.size() > 1) { // jsp & gsp
- PsiClassOwner owner = ContainerUtil.findInstance(allFiles, PsiClassOwner.class);
- if (owner != null) {
- PsiClass[] classes = owner.getClasses();
- if (classes.length == 1 && classes[0] instanceof SyntheticElement) {
- rootElement = classes[0];
+ return ApplicationManager.getApplication().runReadAction(new Computable<PsiElement>() {
+ @Override
+ public PsiElement compute() {
+ PsiElement rootElement = psiFile;
+
+ List<PsiFile> allFiles = psiFile.getViewProvider().getAllFiles();
+ if (allFiles.size() > 1) { // jsp & gsp
+ PsiClassOwner owner = ContainerUtil.findInstance(allFiles, PsiClassOwner.class);
+ if (owner != null) {
+ PsiClass[] classes = owner.getClasses();
+ if (classes.length == 1 && classes[0] instanceof SyntheticElement) {
+ rootElement = classes[0];
+ }
+ }
}
- }
- }
- PsiElement element;
- while(true) {
- final CharSequence charsSequence = document.getCharsSequence();
- for (; startOffset < charsSequence.length(); startOffset++) {
- char c = charsSequence.charAt(startOffset);
- if (c != ' ' && c != '\t') {
- break;
+ PsiElement element;
+ int offset = startOffset;
+ while (true) {
+ final CharSequence charsSequence = document.getCharsSequence();
+ for (; offset < charsSequence.length(); offset++) {
+ char c = charsSequence.charAt(offset);
+ if (c != ' ' && c != '\t') {
+ break;
+ }
+ }
+ element = rootElement.findElementAt(offset);
+
+ if (element instanceof PsiComment) {
+ offset = element.getTextRange().getEndOffset() + 1;
+ }
+ else {
+ break;
+ }
}
+ if (element != null && element.getParent() instanceof PsiForStatement) {
+ return ((PsiForStatement)element.getParent()).getInitialization();
+ }
+ return element;
}
- element = rootElement.findElementAt(startOffset);
-
- if(element instanceof PsiComment) {
- startOffset = element.getTextRange().getEndOffset() + 1;
- }
- else{
- break;
- }
- }
-
- if (element != null && element.getParent() instanceof PsiForStatement) {
- return ((PsiForStatement)element.getParent()).getInitialization();
- }
- return element;
+ });
}
}
diff --git a/java/execution/impl/src/com/intellij/execution/impl/DefaultJavaProgramRunner.java b/java/execution/impl/src/com/intellij/execution/impl/DefaultJavaProgramRunner.java
index 27280b193c2c..626a47509144 100644
--- a/java/execution/impl/src/com/intellij/execution/impl/DefaultJavaProgramRunner.java
+++ b/java/execution/impl/src/com/intellij/execution/impl/DefaultJavaProgramRunner.java
@@ -69,10 +69,7 @@ public class DefaultJavaProgramRunner extends JavaPatchableProgramRunner {
}
@Override
- protected RunContentDescriptor doExecute(@NotNull final Project project,
- @NotNull final RunProfileState state,
- final RunContentDescriptor contentToReuse,
- @NotNull final ExecutionEnvironment env) throws ExecutionException {
+ protected RunContentDescriptor doExecute(@NotNull final RunProfileState state, @NotNull final ExecutionEnvironment env) throws ExecutionException {
FileDocumentManager.getInstance().saveAllDocuments();
ExecutionResult executionResult;
@@ -100,11 +97,11 @@ public class DefaultJavaProgramRunner extends JavaPatchableProgramRunner {
onProcessStarted(env.getRunnerSettings(), executionResult);
final RunContentBuilder contentBuilder = new RunContentBuilder(executionResult, env);
- Disposer.register(project, contentBuilder);
+ Disposer.register(env.getProject(), contentBuilder);
if (shouldAddDefaultActions) {
addDefaultActions(contentBuilder);
}
- return contentBuilder.showRunContent(contentToReuse);
+ return contentBuilder.showRunContent(env.getContentToReuse());
}
@Deprecated
diff --git a/java/execution/openapi/src/com/intellij/execution/configurations/JavaParameters.java b/java/execution/openapi/src/com/intellij/execution/configurations/JavaParameters.java
index daf045c2638f..bf89d82ea5c1 100644
--- a/java/execution/openapi/src/com/intellij/execution/configurations/JavaParameters.java
+++ b/java/execution/openapi/src/com/intellij/execution/configurations/JavaParameters.java
@@ -18,6 +18,7 @@ package com.intellij.execution.configurations;
import com.intellij.execution.CantRunException;
import com.intellij.execution.ExecutionBundle;
import com.intellij.openapi.actionSystem.DataKey;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
@@ -25,6 +26,7 @@ import com.intellij.openapi.roots.*;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.encoding.EncodingProjectManager;
import com.intellij.util.NotNullFunction;
+import com.intellij.util.PathsList;
import org.intellij.lang.annotations.MagicConstant;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -32,6 +34,8 @@ import org.jetbrains.annotations.Nullable;
import java.nio.charset.Charset;
public class JavaParameters extends SimpleJavaParameters {
+ private static final Logger LOG = Logger.getInstance(JavaParameters.class);
+ private static final String JAVA_LIBRARY_PATH_PROPERTY = "java.library.path";
public static final DataKey<JavaParameters> JAVA_PARAMETERS = DataKey.create("javaParameters");
public String getJdkPath() throws CantRunException {
@@ -70,6 +74,21 @@ public class JavaParameters extends SimpleJavaParameters {
setDefaultCharset(module.getProject());
configureEnumerator(OrderEnumerator.orderEntries(module).runtimeOnly().recursively(), classPathType, jdk).collectPaths(getClassPath());
+ configureJavaLibraryPath(OrderEnumerator.orderEntries(module).recursively());
+ }
+
+ private void configureJavaLibraryPath(OrderEnumerator enumerator) {
+ PathsList pathsList = new PathsList();
+ enumerator.runtimeOnly().withoutSdk().roots(NativeLibraryOrderRootType.getInstance()).collectPaths(pathsList);
+ if (!pathsList.getPathList().isEmpty()) {
+ ParametersList vmParameters = getVMParametersList();
+ if (vmParameters.hasProperty(JAVA_LIBRARY_PATH_PROPERTY)) {
+ LOG.info(JAVA_LIBRARY_PATH_PROPERTY + " property is already specified, native library paths from dependencies (" + pathsList.getPathsString() + ") won't be added");
+ }
+ else {
+ vmParameters.addProperty(JAVA_LIBRARY_PATH_PROPERTY, pathsList.getPathsString());
+ }
+ }
}
@Nullable
@@ -123,6 +142,7 @@ public class JavaParameters extends SimpleJavaParameters {
}
setDefaultCharset(project);
configureEnumerator(OrderEnumerator.orderEntries(project).runtimeOnly(), classPathType, jdk).collectPaths(getClassPath());
+ configureJavaLibraryPath(OrderEnumerator.orderEntries(project));
}
private static OrderRootsEnumerator configureEnumerator(OrderEnumerator enumerator, @MagicConstant(valuesFromClass = JavaParameters.class) int classPathType, Sdk jdk) {
diff --git a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryOptionsPanel.java b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryOptionsPanel.java
index d44864e1485c..3bb96adb1141 100644
--- a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryOptionsPanel.java
+++ b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryOptionsPanel.java
@@ -246,7 +246,7 @@ public class LibraryOptionsPanel implements Disposable {
onVersionChanged(getPresentableVersion());
}
});
- myExistingLibraryComboBox.setRenderer(new ColoredListCellRenderer() {
+ myExistingLibraryComboBox.setRenderer(new ColoredListCellRenderer(myExistingLibraryComboBox) {
@Override
protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) {
if (value == null) {
diff --git a/java/idea-ui/src/com/intellij/ide/actions/ImportModuleAction.java b/java/idea-ui/src/com/intellij/ide/actions/ImportModuleAction.java
index 2faa20bc412d..3d497b829d50 100644
--- a/java/idea-ui/src/com/intellij/ide/actions/ImportModuleAction.java
+++ b/java/idea-ui/src/com/intellij/ide/actions/ImportModuleAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@ import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
+import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.fileChooser.FileChooserDialog;
import com.intellij.openapi.fileChooser.FileChooserFactory;
import com.intellij.openapi.module.Module;
@@ -39,7 +40,6 @@ import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import javax.swing.*;
import java.awt.*;
import java.util.Arrays;
import java.util.Collections;
@@ -94,14 +94,7 @@ public class ImportModuleAction extends AnAction {
@Nullable
public static AddModuleWizard selectFileAndCreateWizard(final Project project, Component dialogParent) {
- FileChooserDescriptor descriptor = new FileChooserDescriptor(true, true, true, true, false, false) {
- FileChooserDescriptor myDelegate = new OpenProjectFileChooserDescriptor(true);
- @Override
- public Icon getIcon(VirtualFile file) {
- Icon icon = myDelegate.getIcon(file);
- return icon == null ? super.getIcon(file) : icon;
- }
- };
+ FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleLocalFileDescriptor();
descriptor.setHideIgnored(false);
descriptor.setTitle("Select File or Directory to Import");
ProjectImportProvider[] providers = ProjectImportProvider.PROJECT_IMPORT_PROVIDER.getExtensions();
diff --git a/java/idea-ui/src/com/intellij/ide/actions/OpenProjectAction.java b/java/idea-ui/src/com/intellij/ide/actions/OpenProjectAction.java
deleted file mode 100644
index 8cbb5543db6b..000000000000
--- a/java/idea-ui/src/com/intellij/ide/actions/OpenProjectAction.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright 2000-2013 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.ide.actions;
-
-import com.intellij.ide.IdeBundle;
-import com.intellij.ide.highlighter.ProjectFileType;
-import com.intellij.ide.impl.ProjectUtil;
-import com.intellij.openapi.actionSystem.ActionPlaces;
-import com.intellij.openapi.actionSystem.AnAction;
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.actionSystem.CommonDataKeys;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
-import com.intellij.openapi.extensions.Extensions;
-import com.intellij.openapi.fileChooser.FileChooser;
-import com.intellij.openapi.fileChooser.FileChooserDescriptor;
-import com.intellij.openapi.fileChooser.PathChooserDialog;
-import com.intellij.openapi.project.DumbAware;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.SystemInfo;
-import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.openapi.vfs.VfsUtil;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.projectImport.ProjectOpenProcessor;
-import com.intellij.projectImport.ProjectOpenProcessorBase;
-import com.intellij.util.Consumer;
-
-import java.util.Collections;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Set;
-
-public class OpenProjectAction extends AnAction implements DumbAware {
- public void actionPerformed(AnActionEvent e) {
- final FileChooserDescriptor descriptor = new OpenProjectFileChooserDescriptor(true);
- descriptor.setTitle(IdeBundle.message("title.open.project"));
- final Set<String> extensions = new LinkedHashSet<String>();
- extensions.add(ProjectFileType.DOT_DEFAULT_EXTENSION);
- final ProjectOpenProcessor[] openProcessors = Extensions.getExtensions(ProjectOpenProcessor.EXTENSION_POINT_NAME);
- for (ProjectOpenProcessor openProcessor : openProcessors) {
- if (!(openProcessor instanceof ProjectOpenProcessorBase)) continue;
- final String[] supportedExtensions = ((ProjectOpenProcessorBase)openProcessor).getSupportedExtensions();
- if (supportedExtensions != null) {
- Collections.addAll(extensions, supportedExtensions);
- }
- }
- descriptor.setDescription(IdeBundle.message("filter.project.files", StringUtil.join(extensions, ", ")));
-
- VirtualFile userHomeDir = null;
- if (SystemInfo.isUnix) {
- userHomeDir = VfsUtil.getUserHomeDir();
- }
-
- descriptor.putUserData(PathChooserDialog.PREFER_LAST_OVER_EXPLICIT, Boolean.TRUE);
-
- final Project project = CommonDataKeys.PROJECT.getData(e.getDataContext());
- FileChooser.chooseFiles(descriptor, project, userHomeDir, new Consumer<List<VirtualFile>>() {
- @Override
- public void consume(final List<VirtualFile> files) {
- if (files.size() == 1) {
- ProjectUtil.openOrImport(files.get(0).getPath(), project, false);
- }
- }
- });
- }
-
- @Override
- public void update(AnActionEvent e) {
- super.update(e);
- e.getPresentation().setEnabledAndVisible(ActionPlaces.WELCOME_SCREEN.equals(e.getPlace()));
- }
-} \ No newline at end of file
diff --git a/java/idea-ui/src/com/intellij/ide/actions/ShowStructureSettingsAction.java b/java/idea-ui/src/com/intellij/ide/actions/ShowStructureSettingsAction.java
index ded07d482ed3..b43698ece136 100644
--- a/java/idea-ui/src/com/intellij/ide/actions/ShowStructureSettingsAction.java
+++ b/java/idea-ui/src/com/intellij/ide/actions/ShowStructureSettingsAction.java
@@ -37,6 +37,7 @@ import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
public class ShowStructureSettingsAction extends AnAction implements DumbAware {
+ @Override
public void actionPerformed(AnActionEvent e) {
Project project = CommonDataKeys.PROJECT.getData(e.getDataContext());
if (project == null) {
@@ -56,12 +57,13 @@ public class ShowStructureSettingsAction extends AnAction implements DumbAware {
protected JComponent createSouthPanel() {
JComponent panel = super.createSouthPanel();
assert panel != null;
- CustomLineBorder line = new CustomLineBorder(new JBColor(Gray._153, Gray._80), 1, 0, 0, 0);
+ CustomLineBorder line = new CustomLineBorder(new JBColor(Gray._153.withAlpha(128), Gray._100.withAlpha(128)), 1, 0, 0, 0);
panel.setBorder(new CompoundBorder(line, new EmptyBorder(10, 5, 5, 5)));
return panel;
}
}.show();
- } else {
+ }
+ else {
ShowSettingsUtil
.getInstance().editConfigurable(project, OptionsEditorDialog.DIMENSION_KEY, ProjectStructureConfigurable.getInstance(project));
}
diff --git a/java/idea-ui/src/com/intellij/ide/actions/TemplateProjectStructureAction.java b/java/idea-ui/src/com/intellij/ide/actions/TemplateProjectStructureAction.java
index 0255cb005ee7..093552e12be0 100644
--- a/java/idea-ui/src/com/intellij/ide/actions/TemplateProjectStructureAction.java
+++ b/java/idea-ui/src/com/intellij/ide/actions/TemplateProjectStructureAction.java
@@ -25,6 +25,7 @@ import com.intellij.openapi.project.ex.ProjectManagerEx;
import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable;
public class TemplateProjectStructureAction extends AnAction implements DumbAware {
+ @Override
public void actionPerformed(final AnActionEvent e) {
Project defaultProject = ProjectManagerEx.getInstanceEx().getDefaultProject();
ShowSettingsUtil.getInstance().editConfigurable(defaultProject, OptionsEditorDialog.DIMENSION_KEY, ProjectStructureConfigurable.getInstance(defaultProject));
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/DefaultLibraryRootsComponentDescriptor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/DefaultLibraryRootsComponentDescriptor.java
index 34bd02b84950..eb87df2a47e7 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/DefaultLibraryRootsComponentDescriptor.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/DefaultLibraryRootsComponentDescriptor.java
@@ -16,6 +16,7 @@
package com.intellij.openapi.roots.ui.configuration.libraryEditor;
import com.intellij.codeInsight.ExternalAnnotationsManager;
+import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.progress.ProgressIndicator;
@@ -23,22 +24,22 @@ import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.projectRoots.ui.Util;
import com.intellij.openapi.roots.AnnotationOrderRootType;
import com.intellij.openapi.roots.JavadocOrderRootType;
+import com.intellij.openapi.roots.NativeLibraryOrderRootType;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.libraries.ui.*;
import com.intellij.openapi.roots.ui.OrderRootTypeUIFactory;
import com.intellij.openapi.roots.ui.configuration.PathUIUtils;
+import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileVisitor;
import com.intellij.util.IconUtil;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
+import java.util.*;
/**
* @author nik
@@ -63,7 +64,15 @@ public class DefaultLibraryRootsComponentDescriptor extends LibraryRootsComponen
PathUIUtils.JAVA_SOURCE_ROOT_DETECTOR,
new FileTypeBasedRootFilter(OrderRootType.SOURCES, true, StdFileTypes.JAVA, "source archive directory"),
new JavadocRootDetector(),
- new AnnotationsRootFilter());
+ new AnnotationsRootFilter(), new NativeLibraryRootFilter());
+ }
+
+ @NotNull
+ @Override
+ public FileChooserDescriptor createAttachFilesChooserDescriptor(@Nullable String libraryName) {
+ FileChooserDescriptor descriptor = super.createAttachFilesChooserDescriptor(libraryName);
+ descriptor.setDescription(ProjectBundle.message("library.java.attach.files.description"));
+ return descriptor;
}
public static OrderRootTypePresentation getDefaultPresentation(OrderRootType type) {
@@ -110,6 +119,27 @@ public class DefaultLibraryRootsComponentDescriptor extends LibraryRootsComponen
}
}
+ private static class NativeLibraryRootFilter extends RootFilter {
+ private static final Set<String> NATIVE_LIBRARY_EXTENSIONS = ContainerUtil.newTroveSet(FileUtil.PATH_HASHING_STRATEGY, "dll", "so", "dylib");
+
+ private NativeLibraryRootFilter() {
+ super(NativeLibraryOrderRootType.getInstance(), false, "external annotations");
+ }
+
+ @Override
+ public boolean isAccepted(@NotNull VirtualFile rootCandidate, @NotNull ProgressIndicator progressIndicator) {
+ if (rootCandidate.isDirectory()) {
+ for (VirtualFile file : rootCandidate.getChildren()) {
+ String extension = file.getExtension();
+ if (extension != null && NATIVE_LIBRARY_EXTENSIONS.contains(extension)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ }
+
private static class AttachUrlJavadocDescriptor extends AttachRootButtonDescriptor {
private AttachUrlJavadocDescriptor() {
super(JavadocOrderRootType.getInstance(), IconUtil.getAddLinkIcon(), ProjectBundle.message("module.libraries.javadoc.url.button"));
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/NativeLibraryOrderRootTypeUIFactory.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/NativeLibraryOrderRootTypeUIFactory.java
new file mode 100644
index 000000000000..85ddcc42405c
--- /dev/null
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/NativeLibraryOrderRootTypeUIFactory.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * User: anna
+ * Date: 26-Dec-2007
+ */
+package com.intellij.openapi.roots.ui.configuration.libraryEditor;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.project.ProjectBundle;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.projectRoots.ui.SdkPathEditor;
+import com.intellij.openapi.roots.ui.OrderRootTypeUIFactory;
+
+import javax.swing.*;
+
+public class NativeLibraryOrderRootTypeUIFactory implements OrderRootTypeUIFactory {
+ @Override
+ public Icon getIcon() {
+ return AllIcons.Nodes.NativeLibrariesFolder;
+ }
+
+ @Override
+ public String getNodeText() {
+ return ProjectBundle.message("project.roots.native.library.node.text");
+ }
+
+ @Override
+ public SdkPathEditor createPathEditor(Sdk sdk) {
+ return null;
+ }
+}
diff --git a/java/java-analysis-impl/src/com/intellij/analysis/JavaAnalysisScope.java b/java/java-analysis-impl/src/com/intellij/analysis/JavaAnalysisScope.java
index c69b3739f00b..681d0e4ca51a 100644
--- a/java/java-analysis-impl/src/com/intellij/analysis/JavaAnalysisScope.java
+++ b/java/java-analysis-impl/src/com/intellij/analysis/JavaAnalysisScope.java
@@ -85,14 +85,16 @@ public class JavaAnalysisScope extends AnalysisScope {
}
-
+ @NotNull
@Override
public String getShortenName() {
- if (myType == PACKAGE)
- return AnalysisScopeBundle.message("scope.package", ((PsiPackage)myElement).getQualifiedName());
+ if (myType == PACKAGE) {
+ return AnalysisScopeBundle.message("scope.package", ((PsiPackage)myElement).getQualifiedName());
+ }
return super.getShortenName();
}
+ @NotNull
@Override
public String getDisplayName() {
if (myType == PACKAGE) {
@@ -125,7 +127,8 @@ public class JavaAnalysisScope extends AnalysisScope {
for (PsiDirectory dir : dirs) {
accept(dir, visitor, needReadAction);
}
- } else {
+ }
+ else {
super.accept(visitor, needReadAction);
}
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/JavaHighlightInfoTypes.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/JavaHighlightInfoTypes.java
index 6e69b5a157a9..2558ccf43feb 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/JavaHighlightInfoTypes.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/JavaHighlightInfoTypes.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,7 +25,7 @@ import com.intellij.openapi.editor.colors.CodeInsightColors;
* @author anna
* Date: 01-Feb-2008
*/
-public interface JavaHighlightInfoTypes extends HighlightInfoType {
+public interface JavaHighlightInfoTypes {
HighlightInfoType UNUSED_IMPORT = new HighlightInfoType.HighlightInfoTypeSeverityByKey(
HighlightDisplayKey.findOrRegister(UnusedImportLocalInspection.SHORT_NAME, UnusedImportLocalInspection.DISPLAY_NAME), CodeInsightColors.NOT_USED_ELEMENT_ATTRIBUTES);
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Analysis.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Analysis.java
index 47ef448c7484..01993d5e9dd0 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Analysis.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Analysis.java
@@ -15,7 +15,10 @@
*/
package com.intellij.codeInspection.bytecodeAnalysis;
-import gnu.trove.TIntObjectHashMap;
+import com.intellij.codeInspection.bytecodeAnalysis.asm.ControlFlowGraph;
+import com.intellij.codeInspection.bytecodeAnalysis.asm.DFSTree;
+import com.intellij.codeInspection.bytecodeAnalysis.asm.RichControlFlow;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.org.objectweb.asm.Opcodes;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.tree.MethodNode;
@@ -71,6 +74,12 @@ class AbstractValues {
}
}
+ static final BasicValue CLASS_VALUE = new NotNullValue(Type.getObjectType("java/lang/Class"));
+ static final BasicValue METHOD_VALUE = new NotNullValue(Type.getObjectType("java/lang/invoke/MethodType"));
+ static final BasicValue STRING_VALUE = new NotNullValue(Type.getObjectType("java/lang/String"));
+ static final BasicValue METHOD_HANDLE_VALUE = new NotNullValue(Type.getObjectType("java/lang/invoke/MethodHandle"));
+
+
static boolean isInstance(Conf curr, Conf prev) {
if (curr.insnIndex != prev.insnIndex) {
return false;
@@ -187,50 +196,30 @@ final class State {
}
}
-interface PendingAction<Res> {}
-class ProceedState<Res> implements PendingAction<Res> {
- final State state;
-
- ProceedState(State state) {
- this.state = state;
- }
-}
-class MakeResult<Res> implements PendingAction<Res> {
- final State state;
- final Res subResult;
- final int[] indices;
-
- MakeResult(State state, Res subResult, int[] indices) {
- this.state = state;
- this.subResult = subResult;
- this.indices = indices;
- }
-}
-
abstract class Analysis<Res> {
+
public static final int STEPS_LIMIT = 30000;
public static final int EQUATION_SIZE_LIMIT = 30;
+
+ protected static final ThreadLocal<State[]> ourPendingStates = new ThreadLocal<State[]>() {
+ @Override
+ protected State[] initialValue() {
+ return new State[STEPS_LIMIT];
+ }
+ };
+
final RichControlFlow richControlFlow;
final Direction direction;
final ControlFlowGraph controlFlow;
final MethodNode methodNode;
final Method method;
final DFSTree dfsTree;
- final Res myIdentity;
- final Deque<PendingAction<Res>> pending = new LinkedList<PendingAction<Res>>();
- final TIntObjectHashMap<List<State>> computed = new TIntObjectHashMap<List<State>>();
- final TIntObjectHashMap<Res> results = new TIntObjectHashMap<Res>();
+ final protected List<State>[] computed;
final Key aKey;
Res earlyResult = null;
- abstract Res identity();
- abstract Res combineResults(Res delta, List<Res> subResults) throws AnalyzerException;
- abstract boolean isEarlyResult(Res res);
- abstract Equation<Key, Value> mkEquation(Res result);
- abstract void processState(State state) throws AnalyzerException;
-
protected Analysis(RichControlFlow richControlFlow, Direction direction, boolean stable) {
this.richControlFlow = richControlFlow;
this.direction = direction;
@@ -239,7 +228,7 @@ abstract class Analysis<Res> {
method = new Method(controlFlow.className, methodNode.name, methodNode.desc);
dfsTree = richControlFlow.dfsTree;
aKey = new Key(method, direction, stable);
- myIdentity = identity();
+ computed = (List<State>[]) new List[controlFlow.transitions.length];
}
final State createStartState() {
@@ -269,87 +258,8 @@ abstract class Analysis<Res> {
return true;
}
- final Equation<Key, Value> analyze() throws AnalyzerException {
- pending.push(new ProceedState<Res>(createStartState()));
- int steps = 0;
- while (!pending.isEmpty() && earlyResult == null) {
- steps ++;
- if (steps >= STEPS_LIMIT) {
- throw new AnalyzerException(null, "limit is reached, steps: " + steps + " in method " + method);
- }
- PendingAction<Res> action = pending.pop();
- if (action instanceof MakeResult) {
- MakeResult<Res> makeResult = (MakeResult<Res>) action;
- ArrayList<Res> subResults = new ArrayList<Res>();
- for (int index : makeResult.indices) {
- subResults.add(results.get(index));
- }
- Res result = combineResults(makeResult.subResult, subResults);
- if (isEarlyResult(result)) {
- earlyResult = result;
- } else {
- State state = makeResult.state;
- int insnIndex = state.conf.insnIndex;
- results.put(state.index, result);
- List<State> thisComputed = computed.get(insnIndex);
- if (thisComputed == null) {
- thisComputed = new ArrayList<State>();
- computed.put(insnIndex, thisComputed);
- }
- thisComputed.add(state);
- }
- }
- else if (action instanceof ProceedState) {
- ProceedState<Res> proceedState = (ProceedState<Res>) action;
- State state = proceedState.state;
- int insnIndex = state.conf.insnIndex;
- Conf conf = state.conf;
- List<Conf> history = state.history;
-
- boolean fold = false;
- if (dfsTree.loopEnters.contains(insnIndex)) {
- for (Conf prev : history) {
- if (AbstractValues.isInstance(conf, prev)) {
- fold = true;
- }
- }
- }
- if (fold) {
- results.put(state.index, myIdentity);
- List<State> thisComputed = computed.get(insnIndex);
- if (thisComputed == null) {
- thisComputed = new ArrayList<State>();
- computed.put(insnIndex, thisComputed);
- }
- thisComputed.add(state);
- }
- else {
- State baseState = null;
- List<State> thisComputed = computed.get(insnIndex);
- if (thisComputed != null) {
- for (State prevState : thisComputed) {
- if (stateEquiv(state, prevState)) {
- baseState = prevState;
- break;
- }
- }
- }
- if (baseState != null) {
- results.put(state.index, results.get(baseState.index));
- } else {
- // the main call
- processState(state);
- }
-
- }
- }
- }
- if (earlyResult != null) {
- return mkEquation(earlyResult);
- } else {
- return mkEquation(results.get(0));
- }
- }
+ @NotNull
+ protected abstract Equation<Key, Value> analyze() throws AnalyzerException;
final Frame<BasicValue> createStartFrame() {
Frame<BasicValue> frame = new Frame<BasicValue>(methodNode.maxLocals, methodNode.maxStack);
@@ -396,4 +306,13 @@ abstract class Analysis<Res> {
result.add(x);
return result;
}
+
+ protected void addComputed(int i, State s) {
+ List<State> states = computed[i];
+ if (states == null) {
+ states = new ArrayList<State>();
+ computed[i] = states;
+ }
+ states.add(s);
+ }
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisConverter.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisConverter.java
index 0239a661c4ee..84a5851e847d 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisConverter.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisConverter.java
@@ -15,271 +15,208 @@
*/
package com.intellij.codeInspection.bytecodeAnalysis;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.components.ApplicationComponent;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.TypeConversionUtil;
-import gnu.trove.TLongArrayList;
-import gnu.trove.TLongHashSet;
-import gnu.trove.TLongObjectHashMap;
-import gnu.trove.TLongObjectIterator;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.org.objectweb.asm.Type;
+import org.jetbrains.annotations.Nullable;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.*;
import static com.intellij.codeInspection.bytecodeAnalysis.ProjectBytecodeAnalysis.LOG;
/**
* @author lambdamix
*/
-public abstract class BytecodeAnalysisConverter implements ApplicationComponent {
+public class BytecodeAnalysisConverter {
- public static final int SHIFT = 4096;
+ // how many bytes are taken from class fqn digest
+ public static final int CLASS_HASH_SIZE = 10;
+ // how many bytes are taken from signature digest
+ public static final int SIGNATURE_HASH_SIZE = 4;
+ public static final int HASH_SIZE = CLASS_HASH_SIZE + SIGNATURE_HASH_SIZE;
- public static BytecodeAnalysisConverter getInstance() {
- return ApplicationManager.getApplication().getComponent(BytecodeAnalysisConverter.class);
+ public static MessageDigest getMessageDigest() throws NoSuchAlgorithmException {
+ return MessageDigest.getInstance("MD5");
}
+ /**
+ * Converts an equation over asm keys into equation over small hash keys.
+ */
@NotNull
- @Override
- public String getComponentName() {
- return "BytecodeAnalysisConverter";
- }
-
- public abstract int getVersion();
-
- protected abstract int enumerateString(@NotNull String s) throws IOException;
-
- protected abstract int enumerateCompoundKey(@NotNull int[] key) throws IOException;
-
- IdEquation convert(Equation<Key, Value> equation) throws IOException {
+ static DirectionResultPair convert(@NotNull Equation<Key, Value> equation, @NotNull MessageDigest md) {
ProgressManager.checkCanceled();
Result<Key, Value> rhs = equation.rhs;
- IdResult result;
+ HResult result;
if (rhs instanceof Final) {
- result = new IdFinal(((Final<Key, Value>)rhs).value);
+ result = new HFinal(((Final<Key, Value>)rhs).value);
} else {
Pending<Key, Value> pending = (Pending<Key, Value>)rhs;
Set<Product<Key, Value>> sumOrigin = pending.sum;
- IntIdComponent[] components = new IntIdComponent[sumOrigin.size()];
+ HComponent[] components = new HComponent[sumOrigin.size()];
int componentI = 0;
for (Product<Key, Value> prod : sumOrigin) {
- long[] intProd = new long[prod.ids.size()];
+ HKey[] intProd = new HKey[prod.ids.size()];
int idI = 0;
for (Key id : prod.ids) {
- long rawId = mkAsmKey(id);
- if (rawId <= 0) {
- LOG.error("raw key should be positive. rawId = " + rawId);
- }
- intProd[idI] = id.stable ? rawId : -rawId;
+ intProd[idI] = asmKey(id, md);
idI++;
}
- IntIdComponent intIdComponent = new IntIdComponent(prod.value, intProd);
+ HComponent intIdComponent = new HComponent(prod.value, intProd);
components[componentI] = intIdComponent;
componentI++;
}
- result = new IdPending(components);
+ result = new HPending(components);
}
-
- long rawKey = mkAsmKey(equation.id);
- if (rawKey <= 0) {
- LOG.error("raw key should be positive. rawKey = " + rawKey);
- }
-
- long key = equation.id.stable ? rawKey : -rawKey;
- return new IdEquation(key, result);
+ return new DirectionResultPair(mkDirectionKey(equation.id.direction), result);
}
- public long mkAsmKey(@NotNull Key key) throws IOException {
- long baseKey = mkAsmSignatureKey(key.method);
- long directionKey = mkDirectionKey(key.direction);
- return baseKey * SHIFT + directionKey;
+ /**
+ * Converts an asm method key to a small hash key (HKey)
+ */
+ @NotNull
+ public static HKey asmKey(@NotNull Key key, @NotNull MessageDigest md) {
+ byte[] classDigest = md.digest(key.method.internalClassName.getBytes());
+ md.update(key.method.methodName.getBytes());
+ md.update(key.method.methodDesc.getBytes());
+ byte[] sigDigest = md.digest();
+ byte[] digest = new byte[HASH_SIZE];
+ System.arraycopy(classDigest, 0, digest, 0, CLASS_HASH_SIZE);
+ System.arraycopy(sigDigest, 0, digest, CLASS_HASH_SIZE, SIGNATURE_HASH_SIZE);
+ return new HKey(digest, mkDirectionKey(key.direction), key.stable);
}
- private static int mkDirectionKey(Direction dir) throws IOException {
- if (dir instanceof Out) {
- return 0;
- } else if (dir instanceof In) {
- In in = (In)dir;
- return 8 * in.paramId() + 1;
- } else {
- InOut inOut = (InOut)dir;
- return 8 * inOut.paramId() + 2 + inOut.valueId();
+ /**
+ * Converts a Psi method to a small hash key (HKey).
+ * Returns null if conversion is impossible (something is not resolvable).
+ */
+ @Nullable
+ public static HKey psiKey(@NotNull PsiMethod psiMethod, @NotNull Direction direction, @NotNull MessageDigest md) {
+ final PsiClass psiClass = PsiTreeUtil.getParentOfType(psiMethod, PsiClass.class, false);
+ if (psiClass == null) {
+ return null;
}
- }
-
- @NotNull
- private static Direction extractDirection(int directionKey) {
- if (directionKey == 0) {
- return new Out();
+ byte[] classDigest = psiClassDigest(psiClass, md);
+ if (classDigest == null) {
+ return null;
}
- else {
- int paramId = directionKey / 8;
- int subDirection = directionKey % 8;
- if (subDirection == 1) {
- return new In(paramId);
- }
- else {
- return new InOut(paramId, Value.values()[subDirection - 2]);
- }
+ byte[] sigDigest = methodDigest(psiMethod, md);
+ if (sigDigest == null) {
+ return null;
}
+ byte[] digest = new byte[HASH_SIZE];
+ System.arraycopy(classDigest, 0, digest, 0, CLASS_HASH_SIZE);
+ System.arraycopy(sigDigest, 0, digest, CLASS_HASH_SIZE, SIGNATURE_HASH_SIZE);
+ return new HKey(digest, mkDirectionKey(direction), true);
}
- // class + short signature
- private int mkAsmSignatureKey(@NotNull Method method) throws IOException {
- int[] sigKey = new int[2];
- sigKey[0] = mkAsmTypeKey(Type.getObjectType(method.internalClassName));
- sigKey[1] = mkAsmShortSignatureKey(method);
- return enumerateCompoundKey(sigKey);
- }
-
- private int mkAsmShortSignatureKey(@NotNull Method method) throws IOException {
- Type[] argTypes = Type.getArgumentTypes(method.methodDesc);
- int arity = argTypes.length;
- int[] sigKey = new int[2 + arity];
- sigKey[0] = mkAsmTypeKey(Type.getReturnType(method.methodDesc));
- sigKey[1] = enumerateString(method.methodName);
- for (int i = 0; i < argTypes.length; i++) {
- sigKey[2 + i] = mkAsmTypeKey(argTypes[i]);
+ @Nullable
+ private static byte[] psiClassDigest(@NotNull PsiClass psiClass, @NotNull MessageDigest md) {
+ String descriptor = descriptor(psiClass, 0, false);
+ if (descriptor == null) {
+ return null;
}
- return enumerateCompoundKey(sigKey);
+ return md.digest(descriptor.getBytes());
}
- private int mkAsmTypeKey(Type type) throws IOException {
- String className = type.getClassName();
- int dotIndex = className.lastIndexOf('.');
- String packageName;
- String simpleName;
- if (dotIndex > 0) {
- packageName = className.substring(0, dotIndex);
- simpleName = className.substring(dotIndex + 1);
- } else {
- packageName = "";
- simpleName = className;
+ @Nullable
+ private static byte[] methodDigest(@NotNull PsiMethod psiMethod, @NotNull MessageDigest md) {
+ String descriptor = descriptor(psiMethod);
+ if (descriptor == null) {
+ return null;
}
- int[] classKey = new int[]{enumerateString(packageName), enumerateString(simpleName)};
- return enumerateCompoundKey(classKey);
+ return md.digest(descriptor.getBytes());
}
- public long mkPsiKey(@NotNull PsiMethod psiMethod, Direction direction) throws IOException {
- final PsiClass psiClass = PsiTreeUtil.getParentOfType(psiMethod, PsiClass.class, false);
- if (psiClass == null) {
- LOG.debug("PsiClass was null for " + psiMethod.getName());
- return -1;
- }
- long sigKey = mkPsiSignatureKey(psiMethod);
- if (sigKey == -1) {
- return -1;
- }
- long directionKey = mkDirectionKey(direction);
- return sigKey * SHIFT + directionKey;
- }
-
- private int mkPsiSignatureKey(@NotNull PsiMethod psiMethod) throws IOException {
+ @Nullable
+ private static String descriptor(@NotNull PsiMethod psiMethod) {
+ StringBuilder sb = new StringBuilder();
final PsiClass psiClass = PsiTreeUtil.getParentOfType(psiMethod, PsiClass.class, false);
if (psiClass == null) {
- LOG.debug("PsiClass was null for " + psiMethod.getName());
- return -1;
+ return null;
}
PsiClass outerClass = psiClass.getContainingClass();
boolean isInnerClassConstructor = psiMethod.isConstructor() && (outerClass != null) && !psiClass.hasModifierProperty(PsiModifier.STATIC);
PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
PsiType returnType = psiMethod.getReturnType();
- final int shift = isInnerClassConstructor ? 1 : 0;
- final int arity = parameters.length + shift;
- int[] shortSigKey = new int[2 + arity];
- if (returnType == null) {
- shortSigKey[0] = mkPsiTypeKey(PsiType.VOID);
- shortSigKey[1] = enumerateString("<init>");
- } else {
- shortSigKey[0] = mkPsiTypeKey(returnType);
- shortSigKey[1] = enumerateString(psiMethod.getName());
- }
+ sb.append(returnType == null ? "<init>" : psiMethod.getName());
+ sb.append('(');
+
+ String desc;
+
if (isInnerClassConstructor) {
- shortSigKey[2] = mkPsiClassKey(outerClass, 0);
- }
- for (int i = 0; i < parameters.length; i++) {
- PsiParameter parameter = parameters[i];
- shortSigKey[2 + i + shift] = mkPsiTypeKey(parameter.getType());
- }
- for (int aShortSigKey : shortSigKey) {
- if (aShortSigKey == -1) {
- return -1;
+ desc = descriptor(outerClass, 0, true);
+ if (desc == null) {
+ return null;
}
+ sb.append(desc);
}
-
- int[] sigKey = new int[2];
- int classKey = mkPsiClassKey(psiClass, 0);
- if (classKey == -1) {
- return -1;
+ for (PsiParameter parameter : parameters) {
+ desc = descriptor(parameter.getType());
+ if (desc == null) {
+ return null;
+ }
+ sb.append(desc);
}
- sigKey[0] = classKey;
- sigKey[1] = enumerateCompoundKey(shortSigKey);
-
- return enumerateCompoundKey(sigKey);
- }
-
- public TLongArrayList mkInOutKeys(@NotNull PsiMethod psiMethod, long primaryKey) throws IOException {
- PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
- TLongArrayList keys = new TLongArrayList(parameters.length * 2 + 1);
- for (int i = 0; i < parameters.length; i++) {
- PsiParameter parameter = parameters[i];
- PsiType parameterType = parameter.getType();
- if (parameterType instanceof PsiPrimitiveType) {
- if (PsiType.BOOLEAN.equals(parameterType)) {
- keys.add(primaryKey + mkDirectionKey(new InOut(i, Value.False)));
- keys.add(primaryKey + mkDirectionKey(new InOut(i, Value.True)));
- }
+ sb.append(')');
+ if (returnType == null) {
+ sb.append('V');
+ } else {
+ desc = descriptor(returnType);
+ if (desc == null) {
+ return null;
} else {
- keys.add(primaryKey + mkDirectionKey(new InOut(i, Value.NotNull)));
- keys.add(primaryKey + mkDirectionKey(new InOut(i, Value.Null)));
+ sb.append(desc);
}
}
- return keys;
+ return sb.toString();
}
-
- private int mkPsiClassKey(PsiClass psiClass, int dimensions) throws IOException {
+ @Nullable
+ private static String descriptor(@NotNull PsiClass psiClass, int dimensions, boolean full) {
PsiFile containingFile = psiClass.getContainingFile();
if (!(containingFile instanceof PsiClassOwner)) {
LOG.debug("containingFile was not resolved for " + psiClass.getQualifiedName());
- return -1;
+ return null;
}
PsiClassOwner psiFile = (PsiClassOwner)containingFile;
String packageName = psiFile.getPackageName();
String qname = psiClass.getQualifiedName();
if (qname == null) {
- return -1;
+ return null;
}
- String className = qname;
+ String className;
if (packageName.length() > 0) {
className = qname.substring(packageName.length() + 1).replace('.', '$');
- }
- int[] classKey = new int[2];
- classKey[0] = enumerateString(packageName);
- if (dimensions == 0) {
- classKey[1] = enumerateString(className);
} else {
- StringBuilder sb = new StringBuilder(className);
- for (int j = 0; j < dimensions; j++) {
- sb.append("[]");
- }
- classKey[1] = enumerateString(sb.toString());
+ className = qname.replace('.', '$');
+ }
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < dimensions; i++) {
+ sb.append('[');
+ }
+ if (full) {
+ sb.append('L');
}
- return enumerateCompoundKey(classKey);
+ if (packageName.length() > 0) {
+ sb.append(packageName.replace('.', '/'));
+ sb.append('/');
+ }
+ sb.append(className);
+ if (full) {
+ sb.append(';');
+ }
+ return sb.toString();
}
- private int mkPsiTypeKey(PsiType psiType) throws IOException {
+ @Nullable
+ private static String descriptor(@NotNull PsiType psiType) {
int dimensions = 0;
psiType = TypeConversionUtil.erasure(psiType);
if (psiType instanceof PsiArrayType) {
@@ -289,56 +226,130 @@ public abstract class BytecodeAnalysisConverter implements ApplicationComponent
}
if (psiType instanceof PsiClassType) {
- // no resolve() -> no package/class split
PsiClass psiClass = ((PsiClassType)psiType).resolve();
if (psiClass != null) {
- return mkPsiClassKey(psiClass, dimensions);
+ return descriptor(psiClass, dimensions, true);
}
else {
LOG.debug("resolve was null for " + ((PsiClassType)psiType).getClassName());
- return -1;
+ return null;
}
}
else if (psiType instanceof PsiPrimitiveType) {
- String packageName = "";
- String className = psiType.getPresentableText();
- int[] classKey = new int[2];
- classKey[0] = enumerateString(packageName);
- if (dimensions == 0) {
- classKey[1] = enumerateString(className);
- } else {
- StringBuilder sb = new StringBuilder(className);
- for (int j = 0; j < dimensions; j++) {
- sb.append("[]");
- }
- classKey[1] = enumerateString(sb.toString());
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < dimensions; i++) {
+ sb.append('[');
+ }
+ if (PsiType.VOID.equals(psiType)) {
+ sb.append('V');
+ }
+ else if (PsiType.BOOLEAN.equals(psiType)) {
+ sb.append('Z');
+ }
+ else if (PsiType.CHAR.equals(psiType)) {
+ sb.append('C');
+ }
+ else if (PsiType.BYTE.equals(psiType)) {
+ sb.append('B');
+ }
+ else if (PsiType.SHORT.equals(psiType)) {
+ sb.append('S');
+ }
+ else if (PsiType.INT.equals(psiType)) {
+ sb.append('I');
}
- return enumerateCompoundKey(classKey);
+ else if (PsiType.FLOAT.equals(psiType)) {
+ sb.append('F');
+ }
+ else if (PsiType.LONG.equals(psiType)) {
+ sb.append('J');
+ }
+ else if (PsiType.DOUBLE.equals(psiType)) {
+ sb.append('D');
+ }
+ return sb.toString();
}
- return -1;
+ return null;
}
- public void addMethodAnnotations(TLongObjectHashMap<Value> internalIdSolutions, Annotations annotations, long methodKey, int arity) {
+ private static int mkDirectionKey(Direction dir) {
+ if (dir instanceof Out) {
+ return 0;
+ } else if (dir instanceof In) {
+ In in = (In)dir;
+ // nullity mask is 0/1
+ return 8 * in.paramId() + 1 + in.nullityMask;
+ } else {
+ InOut inOut = (InOut)dir;
+ return 8 * inOut.paramId() + 3 + inOut.valueId();
+ }
+ }
- List<String> clauses = new ArrayList<String>();
- TLongObjectIterator<Value> solutionsIterator = internalIdSolutions.iterator();
+ @NotNull
+ private static Direction extractDirection(int directionKey) {
+ if (directionKey == 0) {
+ return new Out();
+ }
+ else {
+ int paramId = directionKey / 8;
+ int subDirection = directionKey % 8;
+ if (subDirection <= 2) {
+ return new In(paramId, subDirection - 1);
+ }
+ else {
+ return new InOut(paramId, Value.values()[subDirection - 3]);
+ }
+ }
+ }
+
+ /**
+ * Given a PSI method and its primary HKey enumerate all contract keys for it.
+ */
+ @NotNull
+ public static ArrayList<HKey> mkInOutKeys(@NotNull PsiMethod psiMethod, @NotNull HKey primaryKey) {
+ PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
+ ArrayList<HKey> keys = new ArrayList<HKey>(parameters.length * 2 + 1);
+ for (int i = 0; i < parameters.length; i++) {
+ PsiParameter parameter = parameters[i];
+ PsiType parameterType = parameter.getType();
+ if (parameterType instanceof PsiPrimitiveType) {
+ if (PsiType.BOOLEAN.equals(parameterType)) {
+ keys.add(primaryKey.updateDirection(mkDirectionKey(new InOut(i, Value.False))));
+ keys.add(primaryKey.updateDirection(mkDirectionKey(new InOut(i, Value.True))));
+ }
+ } else {
+ keys.add(primaryKey.updateDirection(mkDirectionKey(new InOut(i, Value.NotNull))));
+ keys.add(primaryKey.updateDirection(mkDirectionKey(new InOut(i, Value.Null))));
+ }
+ }
+ return keys;
+ }
- TLongHashSet notNulls = annotations.notNulls;
- TLongObjectHashMap<String> contracts = annotations.contracts;
- for (int i = internalIdSolutions.size(); i-- > 0;) {
- solutionsIterator.advance();
- long key = Math.abs(solutionsIterator.key());
- Value value = solutionsIterator.value();
+ /**
+ * Given `solution` of all dependencies of a method with the `methodKey`, converts this solution into annotations.
+ *
+ * @param solution solution of equations
+ * @param methodAnnotations annotations to which corresponding solutions should be added
+ * @param methodKey a primary key of a method being analyzed
+ * @param arity arity of this method (hint for constructing @Contract annotations)
+ */
+ public static void addMethodAnnotations(@NotNull HashMap<HKey, Value> solution, @NotNull MethodAnnotations methodAnnotations, @NotNull HKey methodKey, int arity) {
+ List<String> clauses = new ArrayList<String>();
+ HashSet<HKey> notNulls = methodAnnotations.notNulls;
+ HashMap<HKey, String> contracts = methodAnnotations.contracts;
+ for (Map.Entry<HKey, Value> entry : solution.entrySet()) {
+ HKey key = entry.getKey().mkStable();
+ Value value = entry.getValue();
if (value == Value.Top || value == Value.Bot) {
continue;
}
- Direction direction = extractDirection((int)(key % SHIFT));
- if (value == Value.NotNull && direction instanceof Out && key == methodKey) {
+ Direction direction = extractDirection(key.dirKey);
+ if (value == Value.NotNull && direction instanceof Out && methodKey.equals(key)) {
notNulls.add(key);
}
else if (direction instanceof InOut) {
- long baseKey = key - (key % SHIFT);
- if (baseKey == methodKey) {
+ HKey baseKey = key.mkBase();
+ if (methodKey.equals(baseKey)) {
clauses.add(contractElement(arity, (InOut)direction, value));
}
}
@@ -353,24 +364,7 @@ public abstract class BytecodeAnalysisConverter implements ApplicationComponent
}
}
- public void addParameterAnnotations(TLongObjectHashMap<Value> internalIdSolutions, Annotations annotations) {
- TLongObjectIterator<Value> solutionsIterator = internalIdSolutions.iterator();
- TLongHashSet notNulls = annotations.notNulls;
- for (int i = internalIdSolutions.size(); i-- > 0;) {
- solutionsIterator.advance();
- long key = Math.abs(solutionsIterator.key());
- Value value = solutionsIterator.value();
- if (value == Value.Top || value == Value.Bot) {
- continue;
- }
- Direction direction = extractDirection((int)(key % SHIFT));
- if (value == Value.NotNull && (direction instanceof In || direction instanceof Out)) {
- notNulls.add(key);
- }
- }
- }
-
- static String contractValueString(Value v) {
+ private static String contractValueString(@NotNull Value v) {
switch (v) {
case False: return "false";
case True: return "true";
@@ -380,7 +374,7 @@ public abstract class BytecodeAnalysisConverter implements ApplicationComponent
}
}
- static String contractElement(int arity, InOut inOut, Value value) {
+ private static String contractElement(int arity, InOut inOut, Value value) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < arity; i++) {
Value currentValue = Value.Top;
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisConverterImpl.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisConverterImpl.java
deleted file mode 100644
index 067cc743679e..000000000000
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisConverterImpl.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright 2000-2014 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.codeInspection.bytecodeAnalysis;
-
-import com.intellij.ide.util.PropertiesComponent;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.application.PathManager;
-import com.intellij.openapi.util.ThrowableComputable;
-import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.util.io.*;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.io.*;
-import java.io.DataOutputStream;
-import java.util.Arrays;
-
-import static com.intellij.codeInspection.bytecodeAnalysis.ProjectBytecodeAnalysis.LOG;
-
-/**
- * @author lambdamix
- */
-public class BytecodeAnalysisConverterImpl extends BytecodeAnalysisConverter {
- private static final int LOGIC_VERSION = 1;
- private static final String ENUMERATORS_VERSION_KEY = "BytecodeAnalysisConverter.Enumerators";
-
- private File myVersionFile;
- private PersistentStringEnumerator myNamesEnumerator;
- private PersistentEnumeratorDelegate<int[]> myCompoundKeyEnumerator;
- private int version;
-
- @Override
- public void initComponent() {
-
- // suffix as an indicator of version
- final File keysDir = new File(PathManager.getIndexRoot(), "bytecodekeys");
- final File namesFile = new File(keysDir, "names" + LOGIC_VERSION);
- final File compoundKeysFile = new File(keysDir, "compound" + LOGIC_VERSION);
- myVersionFile = new File(keysDir, "version" + LOGIC_VERSION);
-
- version = PropertiesComponent.getInstance().getOrInitInt(ENUMERATORS_VERSION_KEY, 0);
- if (ApplicationManager.getApplication().isUnitTestMode()) {
- version = _readVersion();
- }
-
- if (!namesFile.exists() || !compoundKeysFile.exists() || !myVersionFile.exists()) {
- LOG.info("No enumerators detected, re-initialization of enumerators.");
- IOUtil.deleteAllFilesStartingWith(keysDir);
- version++;
- }
-
- try {
- IOUtil.openCleanOrResetBroken(new ThrowableComputable<Void, IOException>() {
- @Override
- public Void compute() throws IOException {
- myNamesEnumerator = new PersistentStringEnumerator(namesFile, true);
- myCompoundKeyEnumerator = new IntArrayPersistentEnumerator(compoundKeysFile, new IntArrayKeyDescriptor());
- return null;
- }
- }, new Runnable() {
- @Override
- public void run() {
- LOG.info("Error during initialization of enumerators in bytecode analysis. Re-initializing.");
- IOUtil.deleteAllFilesStartingWith(keysDir);
- version++;
- }
- });
- }
- catch (IOException e) {
- LOG.error("Re-initialization of enumerators in bytecode analysis failed.", e);
- }
- PropertiesComponent.getInstance().setValue(ENUMERATORS_VERSION_KEY, String.valueOf(version));
- _saveVersion();
- }
-
- @Override
- public void disposeComponent() {
- try {
- myNamesEnumerator.close();
- myCompoundKeyEnumerator.close();
- }
- catch (IOException e) {
- LOG.debug(e);
- }
- }
-
- public int _readVersion() {
- try {
- final DataInputStream is = new DataInputStream(new FileInputStream(myVersionFile));
- try {
- return is.readInt();
- }
- finally {
- is.close();
- }
- }
- catch (FileNotFoundException ignored) {
- }
- catch (IOException ignored) {
- }
- return 0;
- }
-
- private void _saveVersion() {
- try {
- FileUtil.createIfDoesntExist(myVersionFile);
- final DataOutputStream os = new DataOutputStream(new FileOutputStream(myVersionFile));
- try {
- os.writeInt(version);
- }
- finally {
- os.close();
- }
- }
- catch (IOException ignored) {
- }
- }
-
- public int getVersion() {
- return version;
- }
-
- @Override
- protected int enumerateString(@NotNull String s) throws IOException {
- return myNamesEnumerator.enumerate(s);
- }
-
- @Override
- protected int enumerateCompoundKey(@NotNull int[] key) throws IOException {
- return myCompoundKeyEnumerator.enumerate(key);
- }
-
- private static class IntArrayKeyDescriptor implements KeyDescriptor<int[]>, DifferentSerializableBytesImplyNonEqualityPolicy {
-
- @Override
- public void save(@NotNull DataOutput out, int[] value) throws IOException {
- DataInputOutputUtil.writeINT(out, value.length);
- for (int i : value) {
- DataInputOutputUtil.writeINT(out, i);
- }
- }
-
- @Override
- public int[] read(@NotNull DataInput in) throws IOException {
- int[] value = new int[DataInputOutputUtil.readINT(in)];
- for (int i = 0; i < value.length; i++) {
- value[i] = DataInputOutputUtil.readINT(in);
- }
- return value;
- }
-
- @Override
- public int getHashCode(int[] value) {
- return Arrays.hashCode(value);
- }
-
- @Override
- public boolean isEqual(int[] val1, int[] val2) {
- return Arrays.equals(val1, val2);
- }
- }
-
- private static class IntArrayPersistentEnumerator extends PersistentEnumeratorDelegate<int[]> {
- private final CachingEnumerator<int[]> myCache;
-
- public IntArrayPersistentEnumerator(File compoundKeysFile, IntArrayKeyDescriptor descriptor) throws IOException {
- super(compoundKeysFile, descriptor, 1024 * 4);
- myCache = new CachingEnumerator<int[]>(new DataEnumerator<int[]>() {
- @Override
- public int enumerate(@Nullable int[] value) throws IOException {
- return IntArrayPersistentEnumerator.super.enumerate(value);
- }
-
- @Nullable
- @Override
- public int[] valueOf(int idx) throws IOException {
- return IntArrayPersistentEnumerator.super.valueOf(idx);
- }
- }, descriptor);
- }
-
- @Override
- public int enumerate(@Nullable int[] value) throws IOException {
- return myCache.enumerate(value);
- }
-
- @Nullable
- @Override
- public int[] valueOf(int idx) throws IOException {
- return myCache.valueOf(idx);
- }
- }
-}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisIndex.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisIndex.java
index 297b2b694c62..a7070b882431 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisIndex.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisIndex.java
@@ -16,8 +16,6 @@
package com.intellij.codeInspection.bytecodeAnalysis;
import com.intellij.ide.highlighter.JavaClassFileType;
-import com.intellij.openapi.application.Application;
-import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.SystemProperties;
import com.intellij.util.indexing.*;
@@ -30,46 +28,42 @@ import org.jetbrains.annotations.NotNull;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
/**
* @author lambdamix
*/
-public class BytecodeAnalysisIndex extends FileBasedIndexExtension<Long, IdEquation> {
- public static final ID<Long, IdEquation> NAME = ID.create("bytecodeAnalysis");
- private final EquationExternalizer myExternalizer = new EquationExternalizer();
- private static final DataIndexer<Long, IdEquation, FileContent> INDEXER =
- new ClassDataIndexer(BytecodeAnalysisConverter.getInstance());
- private static final SmartLongKeyDescriptor KEY_DESCRIPTOR = new SmartLongKeyDescriptor();
-
- private static final int ourInternalVersion = 3;
- private static boolean ourEnabled = SystemProperties.getBooleanProperty("idea.enable.bytecode.contract.inference", isEnabledByDefault());
-
- private static boolean isEnabledByDefault() {
- Application application = ApplicationManager.getApplication();
- return application.isInternal() || application.isUnitTestMode();
- }
+public class BytecodeAnalysisIndex extends FileBasedIndexExtension<Bytes, HEquations> {
+ public static final ID<Bytes, HEquations> NAME = ID.create("bytecodeAnalysis");
+ private final HEquationsExternalizer myExternalizer = new HEquationsExternalizer();
+ private static final ClassDataIndexer INDEXER = new ClassDataIndexer();
+ private static final HKeyDescriptor KEY_DESCRIPTOR = new HKeyDescriptor();
+
+ private static final int ourInternalVersion = 1;
+ private static boolean ourEnabled = SystemProperties.getBooleanProperty("idea.enable.bytecode.contract.inference", true);
@NotNull
@Override
- public ID<Long, IdEquation> getName() {
+ public ID<Bytes, HEquations> getName() {
return NAME;
}
@NotNull
@Override
- public DataIndexer<Long, IdEquation, FileContent> getIndexer() {
+ public DataIndexer<Bytes, HEquations, FileContent> getIndexer() {
return INDEXER;
}
@NotNull
@Override
- public KeyDescriptor<Long> getKeyDescriptor() {
+ public KeyDescriptor<Bytes> getKeyDescriptor() {
return KEY_DESCRIPTOR;
}
@NotNull
@Override
- public DataExternalizer<IdEquation> getValueExternalizer() {
+ public DataExternalizer<HEquations> getValueExternalizer() {
return myExternalizer;
}
@@ -91,111 +85,103 @@ public class BytecodeAnalysisIndex extends FileBasedIndexExtension<Long, IdEquat
@Override
public int getVersion() {
- return ourInternalVersion + BytecodeAnalysisConverter.getInstance().getVersion() + (ourEnabled ? 0xFF : 0);
+ return ourInternalVersion + (ourEnabled ? 0xFF : 0);
}
- public static class EquationExternalizer implements DataExternalizer<IdEquation>, DifferentSerializableBytesImplyNonEqualityPolicy {
+ private static class HKeyDescriptor implements KeyDescriptor<Bytes>, DifferentSerializableBytesImplyNonEqualityPolicy {
+
@Override
- public void save(@NotNull DataOutput out, IdEquation equation) throws IOException {
- long id = equation.id;
- int sign = id > 0 ? 1 : -1;
- id = Math.abs(id);
- int primaryId = (int)(id / BytecodeAnalysisConverter.SHIFT);
- int secondaryId = (int)(id % BytecodeAnalysisConverter.SHIFT);
- out.writeInt(sign * primaryId);
- DataInputOutputUtil.writeINT(out, secondaryId);
- IdResult rhs = equation.rhs;
- if (rhs instanceof IdFinal) {
- IdFinal finalResult = (IdFinal)rhs;
- out.writeBoolean(true); // final flag
- DataInputOutputUtil.writeINT(out, finalResult.value.ordinal());
- } else {
- IdPending pendResult = (IdPending)rhs;
- out.writeBoolean(false); // pending flag
- DataInputOutputUtil.writeINT(out, pendResult.delta.length);
-
- for (IntIdComponent component : pendResult.delta) {
- DataInputOutputUtil.writeINT(out, component.value.ordinal());
- long[] ids = component.ids;
- DataInputOutputUtil.writeINT(out, ids.length);
- for (long id1 : ids) {
- sign = id1 > 0 ? 1 : -1;
- id = Math.abs(id1);
- primaryId = (int)(id / BytecodeAnalysisConverter.SHIFT);
- secondaryId = (int)(id % BytecodeAnalysisConverter.SHIFT);
- out.writeInt(sign * primaryId);
- DataInputOutputUtil.writeINT(out, secondaryId);
- }
- }
- }
+ public void save(@NotNull DataOutput out, Bytes value) throws IOException {
+ out.write(value.bytes);
}
@Override
- public IdEquation read(@NotNull DataInput in) throws IOException {
- long primaryId = in.readInt();
- int sign = primaryId > 0 ? 1 : -1;
- primaryId = Math.abs(primaryId);
- int secondaryId = DataInputOutputUtil.readINT(in);
- long equationId = sign * (primaryId * BytecodeAnalysisConverter.SHIFT + secondaryId);
- boolean isFinal = in.readBoolean(); // flag
- if (isFinal) {
- int ordinal = DataInputOutputUtil.readINT(in);
- Value value = Value.values()[ordinal];
- return new IdEquation(equationId, new IdFinal(value));
- } else {
-
- int sumLength = DataInputOutputUtil.readINT(in);
- IntIdComponent[] components = new IntIdComponent[sumLength];
-
- for (int i = 0; i < sumLength; i++) {
- int ordinal = DataInputOutputUtil.readINT(in);
- Value value = Value.values()[ordinal];
- int componentSize = DataInputOutputUtil.readINT(in);
- long[] ids = new long[componentSize];
- for (int j = 0; j < componentSize; j++) {
- primaryId = in.readInt();
- sign = primaryId > 0 ? 1 : -1;
- primaryId = Math.abs(primaryId);
- secondaryId = DataInputOutputUtil.readINT(in);
- long id = sign * (primaryId * BytecodeAnalysisConverter.SHIFT + secondaryId);
- ids[j] = id;
- }
- components[i] = new IntIdComponent(value, ids);
- }
- return new IdEquation(equationId, new IdPending(components));
+ public Bytes read(@NotNull DataInput in) throws IOException {
+ byte[] bytes = new byte[BytecodeAnalysisConverter.HASH_SIZE];
+ for (int i = 0; i < bytes.length; i++) {
+ bytes[i] = in.readByte();
}
+ return new Bytes(bytes);
}
- }
- private static class SmartLongKeyDescriptor implements KeyDescriptor<Long>, DifferentSerializableBytesImplyNonEqualityPolicy {
@Override
- public void save(@NotNull DataOutput out, Long value) throws IOException {
- long id = value.longValue();
- int sign = id > 0 ? 1 : -1;
- id = Math.abs(id);
- int primaryId = (int)(id / BytecodeAnalysisConverter.SHIFT);
- int secondaryId = (int)(id % BytecodeAnalysisConverter.SHIFT);
- out.writeInt(primaryId * sign);
- DataInputOutputUtil.writeINT(out, secondaryId);
+ public int getHashCode(Bytes value) {
+ return Arrays.hashCode(value.bytes);
}
@Override
- public Long read(@NotNull DataInput in) throws IOException {
- long primaryId = in.readInt();
- int sign = primaryId > 0 ? 1 : -1;
- primaryId = Math.abs(primaryId);
- int secondaryId = DataInputOutputUtil.readINT(in);
- return sign * (primaryId * BytecodeAnalysisConverter.SHIFT + secondaryId);
+ public boolean isEqual(Bytes val1, Bytes val2) {
+ return Arrays.equals(val1.bytes, val2.bytes);
}
+ }
+ public static class HEquationsExternalizer implements DataExternalizer<HEquations>, DifferentSerializableBytesImplyNonEqualityPolicy {
@Override
- public int getHashCode(Long value) {
- return value.hashCode();
+ public void save(@NotNull DataOutput out, HEquations eqs) throws IOException {
+ out.writeBoolean(eqs.stable);
+ DataInputOutputUtil.writeINT(out, eqs.results.size());
+ for (DirectionResultPair pair : eqs.results) {
+ DataInputOutputUtil.writeINT(out, pair.directionKey);
+ HResult rhs = pair.hResult;
+ if (rhs instanceof HFinal) {
+ HFinal finalResult = (HFinal)rhs;
+ out.writeBoolean(true); // final flag
+ DataInputOutputUtil.writeINT(out, finalResult.value.ordinal());
+ }
+ else {
+ HPending pendResult = (HPending)rhs;
+ out.writeBoolean(false); // pending flag
+ DataInputOutputUtil.writeINT(out, pendResult.delta.length);
+
+ for (HComponent component : pendResult.delta) {
+ DataInputOutputUtil.writeINT(out, component.value.ordinal());
+ HKey[] ids = component.ids;
+ DataInputOutputUtil.writeINT(out, ids.length);
+ for (HKey hKey : ids) {
+ out.write(hKey.key);
+ DataInputOutputUtil.writeINT(out, hKey.dirKey);
+ out.writeBoolean(hKey.stable);
+ }
+ }
+ }
+ }
}
@Override
- public boolean isEqual(Long val1, Long val2) {
- return val1.longValue() == val2.longValue();
+ public HEquations read(@NotNull DataInput in) throws IOException {
+ boolean stable = in.readBoolean();
+ int size = DataInputOutputUtil.readINT(in);
+ ArrayList<DirectionResultPair> results = new ArrayList<DirectionResultPair>(size);
+ for (int k = 0; k < size; k++) {
+ int directionKey = DataInputOutputUtil.readINT(in);
+ boolean isFinal = in.readBoolean(); // flag
+ if (isFinal) {
+ int ordinal = DataInputOutputUtil.readINT(in);
+ Value value = Value.values()[ordinal];
+ results.add(new DirectionResultPair(directionKey, new HFinal(value)));
+ }
+ else {
+ int sumLength = DataInputOutputUtil.readINT(in);
+ HComponent[] components = new HComponent[sumLength];
+
+ for (int i = 0; i < sumLength; i++) {
+ int ordinal = DataInputOutputUtil.readINT(in);
+ Value value = Value.values()[ordinal];
+ int componentSize = DataInputOutputUtil.readINT(in);
+ HKey[] ids = new HKey[componentSize];
+ for (int j = 0; j < componentSize; j++) {
+ byte[] bytes = new byte[BytecodeAnalysisConverter.HASH_SIZE];
+ for (int bi = 0; bi < bytes.length; bi++) {
+ bytes[bi] = in.readByte();
+ }
+ ids[j] = new HKey(bytes, DataInputOutputUtil.readINT(in), in.readBoolean());
+ }
+ components[i] = new HComponent(value, ids);
+ }
+ results.add(new DirectionResultPair(directionKey, new HPending(components)));
+ }
+ }
+ return new HEquations(results, stable);
}
}
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/ClassDataIndexer.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/ClassDataIndexer.java
index 9e656b98a7fb..316307896467 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/ClassDataIndexer.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/ClassDataIndexer.java
@@ -15,17 +15,20 @@
*/
package com.intellij.codeInspection.bytecodeAnalysis;
+import com.intellij.codeInspection.bytecodeAnalysis.asm.*;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.util.NotNullLazyValue;
+import com.intellij.openapi.util.NullableLazyValue;
+import com.intellij.openapi.util.Pair;
import com.intellij.util.indexing.DataIndexer;
import com.intellij.util.indexing.FileContent;
-import gnu.trove.TIntHashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.org.objectweb.asm.*;
import org.jetbrains.org.objectweb.asm.tree.MethodNode;
import org.jetbrains.org.objectweb.asm.tree.analysis.AnalyzerException;
+import java.security.MessageDigest;
import java.util.*;
import static com.intellij.codeInspection.bytecodeAnalysis.ProjectBytecodeAnalysis.LOG;
@@ -33,29 +36,32 @@ import static com.intellij.codeInspection.bytecodeAnalysis.ProjectBytecodeAnalys
/**
* @author lambdamix
*/
-public class ClassDataIndexer implements DataIndexer<Long, IdEquation, FileContent> {
- final BytecodeAnalysisConverter myConverter;
+public class ClassDataIndexer implements DataIndexer<Bytes, HEquations, FileContent> {
- public ClassDataIndexer(BytecodeAnalysisConverter converter) {
- myConverter = converter;
- }
+ private static final int STABLE_FLAGS = Opcodes.ACC_FINAL | Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC;
+ public static final Final<Key, Value> FINAL_TOP = new Final<Key, Value>(Value.Top);
+ public static final Final<Key, Value> FINAL_BOT = new Final<Key, Value>(Value.Bot);
+ public static final Final<Key, Value> FINAL_NOT_NULL = new Final<Key, Value>(Value.NotNull);
+ public static final Final<Key, Value> FINAL_NULL = new Final<Key, Value>(Value.Null);
+ private static final List<Equation<Key, Value>> EMPTY_EQUATIONS = Collections.EMPTY_LIST;
@NotNull
@Override
- public Map<Long, IdEquation> map(@NotNull FileContent inputData) {
- HashMap<Long, IdEquation> map = new HashMap<Long, IdEquation>();
+ public Map<Bytes, HEquations> map(@NotNull FileContent inputData) {
+ HashMap<Bytes, HEquations> map = new HashMap<Bytes, HEquations>();
try {
- ClassEquations rawEquations = processClass(new ClassReader(inputData.getContent()));
- List<Equation<Key, Value>> rawParameterEquations = rawEquations.parameterEquations;
- List<Equation<Key, Value>> rawContractEquations = rawEquations.contractEquations;
+ MessageDigest md = BytecodeAnalysisConverter.getMessageDigest();
+ Map<Key, List<Equation<Key, Value>>> rawEquations = processClass(new ClassReader(inputData.getContent()), inputData.getFile().getPresentableUrl());
+ for (Map.Entry<Key, List<Equation<Key, Value>>> entry: rawEquations.entrySet()) {
+ Key primaryKey = entry.getKey();
+ Key serKey = new Key(primaryKey.method, primaryKey.direction, true);
- for (Equation<Key, Value> rawParameterEquation: rawParameterEquations) {
- IdEquation equation = myConverter.convert(rawParameterEquation);
- map.put(equation.id, equation);
- }
- for (Equation<Key, Value> rawContractEquation: rawContractEquations) {
- IdEquation equation = myConverter.convert(rawContractEquation);
- map.put(equation.id, equation);
+ List<Equation<Key, Value>> equations = entry.getValue();
+ List<DirectionResultPair> result = new ArrayList<DirectionResultPair>(equations.size());
+ for (Equation<Key, Value> equation : equations) {
+ result.add(BytecodeAnalysisConverter.convert(equation, md));
+ }
+ map.put(new Bytes(BytecodeAnalysisConverter.asmKey(serKey, md).key), new HEquations(result, primaryKey.stable));
}
}
catch (ProcessCanceledException e) {
@@ -66,28 +72,21 @@ public class ClassDataIndexer implements DataIndexer<Long, IdEquation, FileConte
// so here we suppose that exception is due to incorrect bytecode
LOG.debug("Unexpected Error during indexing of bytecode", e);
}
+ //return map;
return map;
}
- private static class ClassEquations {
- final List<Equation<Key, Value>> parameterEquations;
- final List<Equation<Key, Value>> contractEquations;
-
- private ClassEquations(List<Equation<Key, Value>> parameterEquations, List<Equation<Key, Value>> contractEquations) {
- this.parameterEquations = parameterEquations;
- this.contractEquations = contractEquations;
- }
- }
+ public static Map<Key, List<Equation<Key, Value>>> processClass(final ClassReader classReader, final String presentableUrl) {
- public static ClassEquations processClass(final ClassReader classReader) {
- final List<Equation<Key, Value>> parameterEquations = new ArrayList<Equation<Key, Value>>();
- final List<Equation<Key, Value>> contractEquations = new ArrayList<Equation<Key, Value>>();
+ final Map<Key, List<Equation<Key, Value>>> equations = new HashMap<Key, List<Equation<Key, Value>>>();
classReader.accept(new ClassVisitor(Opcodes.ASM5) {
+ private String className;
private boolean stableClass;
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
+ className = name;
stableClass = (access & Opcodes.ACC_FINAL) != 0;
super.visit(version, access, name, signature, superName, interfaces);
}
@@ -96,164 +95,286 @@ public class ClassDataIndexer implements DataIndexer<Long, IdEquation, FileConte
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
final MethodNode node = new MethodNode(Opcodes.ASM5, access, name, desc, signature, exceptions);
return new MethodVisitor(Opcodes.ASM5, node) {
+ private boolean jsr;
+
+ @Override
+ public void visitJumpInsn(int opcode, Label label) {
+ if (opcode == Opcodes.JSR) {
+ jsr = true;
+ }
+ super.visitJumpInsn(opcode, label);
+ }
+
@Override
public void visitEnd() {
super.visitEnd();
- processMethod(classReader.getClassName(), node, stableClass);
+ Pair<Key, List<Equation<Key, Value>>> methodEquations = processMethod(node, jsr);
+ equations.put(methodEquations.first, methodEquations.second);
}
};
}
- void processMethod(final String className, final MethodNode methodNode, boolean stableClass) {
+ private Pair<Key, List<Equation<Key, Value>>> processMethod(final MethodNode methodNode, boolean jsr) {
ProgressManager.checkCanceled();
- Type[] argumentTypes = Type.getArgumentTypes(methodNode.desc);
- Type resultType = Type.getReturnType(methodNode.desc);
- int resultSort = resultType.getSort();
- boolean isReferenceResult = resultSort == Type.OBJECT || resultSort == Type.ARRAY;
- boolean isBooleanResult = Type.BOOLEAN_TYPE == resultType;
- boolean isInterestingResult = isReferenceResult || isBooleanResult;
+ final Type[] argumentTypes = Type.getArgumentTypes(methodNode.desc);
+ final Type resultType = Type.getReturnType(methodNode.desc);
+ final boolean isReferenceResult = ASMUtils.isReferenceType(resultType);
+ final boolean isBooleanResult = ASMUtils.isBooleanType(resultType);
+ final boolean isInterestingResult = isReferenceResult || isBooleanResult;
+ final Method method = new Method(className, methodNode.name, methodNode.desc);
+ final boolean stable = stableClass || (methodNode.access & STABLE_FLAGS) != 0 || "<init>".equals(methodNode.name);
+
+ Key primaryKey = new Key(method, new Out(), stable);
if (argumentTypes.length == 0 && !isInterestingResult) {
- return;
+ return Pair.create(primaryKey, EMPTY_EQUATIONS);
}
- Method method = new Method(className, methodNode.name, methodNode.desc);
- int access = methodNode.access;
- boolean stable =
- stableClass ||
- (access & Opcodes.ACC_FINAL) != 0 ||
- (access & Opcodes.ACC_PRIVATE) != 0 ||
- (access & Opcodes.ACC_STATIC) != 0 ||
- "<init>".equals(methodNode.name);
try {
- boolean added = false;
- ControlFlowGraph graph = cfg.buildControlFlowGraph(className, methodNode);
-
- boolean maybeLeakingParameter = false;
- for (Type argType : argumentTypes) {
- int argSort = argType.getSort();
- if (argSort == Type.OBJECT || argSort == Type.ARRAY || (isInterestingResult && Type.BOOLEAN_TYPE.equals(argType))) {
- maybeLeakingParameter = true;
- break;
+ final ControlFlowGraph graph = ControlFlowGraph.build(className, methodNode, jsr);
+ if (graph.transitions.length > 0) {
+ final DFSTree dfs = DFSTree.build(graph.transitions, graph.edgeCount);
+ boolean branching = !dfs.back.isEmpty();
+ if (!branching) {
+ for (int[] transition : graph.transitions) {
+ if (transition != null && transition.length > 1) {
+ branching = true;
+ break;
+ }
+ }
+ }
+
+ if (branching) {
+ RichControlFlow richControlFlow = new RichControlFlow(graph, dfs);
+ if (richControlFlow.reducible()) {
+ return Pair.create(primaryKey,
+ processBranchingMethod(method, methodNode, richControlFlow, argumentTypes, isReferenceResult, isInterestingResult, stable, jsr));
+ }
+ LOG.debug(method + ": CFG is not reducible");
+ }
+ // simple
+ else {
+ return Pair.create(primaryKey,
+ processNonBranchingMethod(method, argumentTypes, graph, isReferenceResult, isBooleanResult, stable));
}
}
+ return Pair.create(primaryKey, topEquations(method, argumentTypes, isReferenceResult, isInterestingResult, stable));
+ }
+ catch (ProcessCanceledException e) {
+ throw e;
+ }
+ catch (Throwable e) {
+ // incorrect bytecode may result in Runtime exceptions during analysis
+ // so here we suppose that exception is due to incorrect bytecode
+ LOG.debug("Unexpected Error during processing of " + method + " in " + presentableUrl, e);
+ return Pair.create(primaryKey, topEquations(method, argumentTypes, isReferenceResult, isInterestingResult, stable));
+ }
+ }
- if (graph.transitions.length > 0) {
- DFSTree dfs = cfg.buildDFSTree(graph.transitions);
- boolean reducible = dfs.back.isEmpty() || cfg.reducible(graph, dfs);
- if (reducible) {
- NotNullLazyValue<TIntHashSet> resultOrigins = new NotNullLazyValue<TIntHashSet>() {
- @NotNull
- @Override
- protected TIntHashSet compute() {
- try {
- return cfg.resultOrigins(className, methodNode);
- }
- catch (AnalyzerException e) {
- throw new RuntimeException(e);
- }
- }
- };
- boolean[] leakingParameters = maybeLeakingParameter ? cfg.leakingParameters(className, methodNode) : null;
- boolean shouldComputeResult = isReferenceResult;
-
- if (!shouldComputeResult && isInterestingResult && maybeLeakingParameter) {
- loop: for (int i = 0; i < argumentTypes.length; i++) {
- Type argType = argumentTypes[i];
- int argSort = argType.getSort();
- boolean isReferenceArg = argSort == Type.OBJECT || argSort == Type.ARRAY;
- boolean isBooleanArg = Type.BOOLEAN_TYPE.equals(argType);
- if ((isReferenceArg || isBooleanArg) && !leakingParameters[i]) {
- shouldComputeResult = true;
- break loop;
- }
- }
+ private List<Equation<Key, Value>> processBranchingMethod(final Method method,
+ final MethodNode methodNode,
+ final RichControlFlow richControlFlow,
+ Type[] argumentTypes,
+ boolean isReferenceResult,
+ boolean isInterestingResult,
+ final boolean stable,
+ boolean jsr) throws AnalyzerException {
+
+ List<Equation<Key, Value>> result = new ArrayList<Equation<Key, Value>>(argumentTypes.length * 4 + 1);
+ boolean maybeLeakingParameter = isInterestingResult;
+ for (Type argType : argumentTypes) {
+ if (ASMUtils.isReferenceType(argType) || (isReferenceResult && ASMUtils.isBooleanType(argType))) {
+ maybeLeakingParameter = true;
+ break;
+ }
+ }
+
+ final LeakingParameters leakingParametersAndFrames =
+ maybeLeakingParameter ? leakingParametersAndFrames(method, methodNode, argumentTypes, jsr) : null;
+ boolean[] leakingParameters =
+ leakingParametersAndFrames != null ? leakingParametersAndFrames.parameters : null;
+ boolean[] leakingNullableParameters =
+ leakingParametersAndFrames != null ? leakingParametersAndFrames.nullableParameters : null;
+
+ final NullableLazyValue<boolean[]> origins = new NullableLazyValue<boolean[]>() {
+ @Override
+ protected boolean[] compute() {
+ try {
+ return OriginsAnalysis.resultOrigins(leakingParametersAndFrames.frames, methodNode.instructions, richControlFlow.controlFlow);
+ }
+ catch (AnalyzerException e) {
+ LOG.debug("when processing " + method + " in " + presentableUrl, e);
+ return null;
+ }
+ }
+ };
+
+ NotNullLazyValue<Equation<Key, Value>> outEquation = new NotNullLazyValue<Equation<Key, Value>>() {
+ @NotNull
+ @Override
+ protected Equation<Key, Value> compute() {
+ if (origins.getValue() != null) {
+ try {
+ return new InOutAnalysis(richControlFlow, new Out(), origins.getValue(), stable).analyze();
+ }
+ catch (AnalyzerException ignored) {
}
+ }
+ return new Equation<Key, Value>(new Key(method, new Out(), stable), FINAL_TOP);
+ }
+ };
- Equation<Key, Value> resultEquation =
- shouldComputeResult ? new InOutAnalysis(new RichControlFlow(graph, dfs), new Out(), resultOrigins.getValue(), stable).analyze() : null;
-
- for (int i = 0; i < argumentTypes.length; i++) {
- Type argType = argumentTypes[i];
- int argSort = argType.getSort();
- boolean isReferenceArg = argSort == Type.OBJECT || argSort == Type.ARRAY;
- boolean isBooleanArg = Type.BOOLEAN_TYPE.equals(argType);
- if (isReferenceArg) {
- if (leakingParameters[i]) {
- parameterEquations.add(new NonNullInAnalysis(new RichControlFlow(graph, dfs), new In(i), stable).analyze());
- } else {
- parameterEquations.add(new Equation<Key, Value>(new Key(method, new In(i), stable), new Final<Key, Value>(Value.Top)));
- }
- }
- if (isReferenceArg && isInterestingResult) {
- if (leakingParameters[i]) {
- contractEquations.add(new InOutAnalysis(new RichControlFlow(graph, dfs), new InOut(i, Value.Null), resultOrigins.getValue(), stable).analyze());
- contractEquations.add(new InOutAnalysis(new RichControlFlow(graph, dfs), new InOut(i, Value.NotNull), resultOrigins.getValue(), stable).analyze());
- } else {
- contractEquations.add(new Equation<Key, Value>(new Key(method, new InOut(i, Value.Null), stable), resultEquation.rhs));
- contractEquations.add(new Equation<Key, Value>(new Key(method, new InOut(i, Value.NotNull), stable), resultEquation.rhs));
- }
+ if (isReferenceResult) {
+ result.add(outEquation.getValue());
+ }
+
+ for (int i = 0; i < argumentTypes.length; i++) {
+ boolean isReferenceArg = ASMUtils.isReferenceType(argumentTypes[i]);
+ boolean notNullParam = false;
+
+ if (isReferenceArg) {
+ boolean possibleNPE = false;
+ if (leakingParameters[i]) {
+ NonNullInAnalysis notNullInAnalysis = new NonNullInAnalysis(richControlFlow, new In(i, In.NOT_NULL), stable);
+ Equation<Key, Value> notNullParamEquation = notNullInAnalysis.analyze();
+ possibleNPE = notNullInAnalysis.possibleNPE;
+ notNullParam = notNullParamEquation.rhs.equals(FINAL_NOT_NULL);
+ result.add(notNullParamEquation);
+ }
+ else {
+ // parameter is not leaking, so it is definitely NOT @NotNull
+ result.add(new Equation<Key, Value>(new Key(method, new In(i, In.NOT_NULL), stable), FINAL_TOP));
+ }
+ if (leakingNullableParameters[i]) {
+ if (notNullParam || possibleNPE) {
+ result.add(new Equation<Key, Value>(new Key(method, new In(i, In.NULLABLE), stable), FINAL_TOP));
+ }
+ else {
+ result.add(new NullableInAnalysis(richControlFlow, new In(i, In.NULLABLE), stable).analyze());
+ }
+ }
+ else {
+ result.add(new Equation<Key, Value>(new Key(method, new In(i, In.NULLABLE), stable), FINAL_NULL));
+ }
+ }
+ if (isReferenceArg && isInterestingResult) {
+ if (leakingParameters[i]) {
+ if (origins.getValue() != null) {
+ // result origins analysis was ok
+ if (!notNullParam) {
+ // may be null on some branch, running "null->..." analysis
+ result.add(new InOutAnalysis(richControlFlow, new InOut(i, Value.Null), origins.getValue(), stable).analyze());
}
- if (isBooleanArg && isInterestingResult) {
- if (leakingParameters[i]) {
- contractEquations.add(new InOutAnalysis(new RichControlFlow(graph, dfs), new InOut(i, Value.False), resultOrigins.getValue(), stable).analyze());
- contractEquations.add(new InOutAnalysis(new RichControlFlow(graph, dfs), new InOut(i, Value.True), resultOrigins.getValue(), stable).analyze());
- } else {
- contractEquations.add(new Equation<Key, Value>(new Key(method, new InOut(i, Value.False), stable), resultEquation.rhs));
- contractEquations.add(new Equation<Key, Value>(new Key(method, new InOut(i, Value.True), stable), resultEquation.rhs));
- }
+ else {
+ // @NotNull, so "null->fail"
+ result.add(new Equation<Key, Value>(new Key(method, new InOut(i, Value.Null), stable), FINAL_BOT));
}
+ result.add(new InOutAnalysis(richControlFlow, new InOut(i, Value.NotNull), origins.getValue(), stable).analyze());
}
- if (isReferenceResult) {
- if (resultEquation != null) {
- contractEquations.add(resultEquation);
- } else {
- contractEquations.add(new InOutAnalysis(new RichControlFlow(graph, dfs), new Out(), resultOrigins.getValue(), stable).analyze());
- }
+ else {
+ // result origins analysis failed, approximating to Top
+ result.add(new Equation<Key, Value>(new Key(method, new InOut(i, Value.Null), stable), FINAL_TOP));
+ result.add(new Equation<Key, Value>(new Key(method, new InOut(i, Value.NotNull), stable), FINAL_TOP));
}
- added = true;
}
else {
- LOG.debug("CFG for " + method + " is not reducible");
+ // parameter is not leaking, so a contract is the same as for the whole method
+ result.add(new Equation<Key, Value>(new Key(method, new InOut(i, Value.Null), stable), outEquation.getValue().rhs));
+ result.add(new Equation<Key, Value>(new Key(method, new InOut(i, Value.NotNull), stable), outEquation.getValue().rhs));
}
}
-
- if (!added) {
- method = new Method(className, methodNode.name, methodNode.desc);
- for (int i = 0; i < argumentTypes.length; i++) {
- Type argType = argumentTypes[i];
- int argSort = argType.getSort();
- boolean isReferenceArg = argSort == Type.OBJECT || argSort == Type.ARRAY;
- boolean isBooleanArg = Type.BOOLEAN_TYPE.equals(argType);
-
- if (isReferenceArg) {
- parameterEquations.add(new Equation<Key, Value>(new Key(method, new In(i), stable), new Final<Key, Value>(Value.Top)));
- }
- if (isReferenceArg && isInterestingResult) {
- contractEquations.add(new Equation<Key, Value>(new Key(method, new InOut(i, Value.Null), stable), new Final<Key, Value>(Value.Top)));
- contractEquations.add(new Equation<Key, Value>(new Key(method, new InOut(i, Value.NotNull), stable), new Final<Key, Value>(Value.Top)));
+ if (ASMUtils.isBooleanType(argumentTypes[i]) && isInterestingResult) {
+ if (leakingParameters[i]) {
+ if (origins.getValue() != null) {
+ // result origins analysis was ok
+ result.add(new InOutAnalysis(richControlFlow, new InOut(i, Value.False), origins.getValue(), stable).analyze());
+ result.add(new InOutAnalysis(richControlFlow, new InOut(i, Value.True), origins.getValue(), stable).analyze());
}
- if (isBooleanArg && isInterestingResult) {
- contractEquations.add(new Equation<Key, Value>(new Key(method, new InOut(i, Value.False), stable), new Final<Key, Value>(Value.Top)));
- contractEquations.add(new Equation<Key, Value>(new Key(method, new InOut(i, Value.True), stable), new Final<Key, Value>(Value.Top)));
+ else {
+ // result origins analysis failed, approximating to Top
+ result.add(new Equation<Key, Value>(new Key(method, new InOut(i, Value.False), stable), FINAL_TOP));
+ result.add(new Equation<Key, Value>(new Key(method, new InOut(i, Value.True), stable), FINAL_TOP));
}
}
- if (isReferenceResult) {
- contractEquations.add(new Equation<Key, Value>(new Key(method, new Out(), stable), new Final<Key, Value>(Value.Top)));
+ else {
+ // parameter is not leaking, so a contract is the same as for the whole method
+ result.add(new Equation<Key, Value>(new Key(method, new InOut(i, Value.False), stable), outEquation.getValue().rhs));
+ result.add(new Equation<Key, Value>(new Key(method, new InOut(i, Value.True), stable), outEquation.getValue().rhs));
}
}
}
- catch (ProcessCanceledException e) {
- throw e;
+ return result;
+ }
+
+ private List<Equation<Key, Value>> processNonBranchingMethod(Method method,
+ Type[] argumentTypes,
+ ControlFlowGraph graph,
+ boolean isReferenceResult,
+ boolean isBooleanResult,
+ boolean stable) throws AnalyzerException {
+ List<Equation<Key, Value>> result = new ArrayList<Equation<Key, Value>>(argumentTypes.length * 4 + 1);
+ CombinedSingleAnalysis analyzer = new CombinedSingleAnalysis(method, graph);
+ analyzer.analyze();
+ if (isReferenceResult) {
+ result.add(analyzer.outContractEquation(stable));
}
- catch (Throwable e) {
- // incorrect bytecode may result in Runtime exceptions during analysis
- // so here we suppose that exception is due to incorrect bytecode
- LOG.debug("Unexpected Error during processing of " + method, e);
+ for (int i = 0; i < argumentTypes.length; i++) {
+ Type argType = argumentTypes[i];
+ boolean isRefArg = ASMUtils.isReferenceType(argType);
+ if (isRefArg) {
+ result.add(analyzer.notNullParamEquation(i, stable));
+ result.add(analyzer.nullableParamEquation(i, stable));
+ }
+ if (isRefArg && (isReferenceResult || isBooleanResult)) {
+ result.add(analyzer.contractEquation(i, Value.Null, stable));
+ result.add(analyzer.contractEquation(i, Value.NotNull, stable));
+ }
+ if (ASMUtils.isBooleanType(argType) && (isReferenceResult || isBooleanResult)) {
+ result.add(analyzer.contractEquation(i, Value.True, stable));
+ result.add(analyzer.contractEquation(i, Value.False, stable));
+ }
}
+ return result;
+ }
+
+ private List<Equation<Key, Value>> topEquations(Method method,
+ Type[] argumentTypes,
+ boolean isReferenceResult,
+ boolean isInterestingResult,
+ boolean stable) {
+ List<Equation<Key, Value>> result = new ArrayList<Equation<Key, Value>>(argumentTypes.length * 3 + 1);
+ if (isReferenceResult) {
+ result.add(new Equation<Key, Value>(new Key(method, new Out(), stable), FINAL_TOP));
+ }
+ for (int i = 0; i < argumentTypes.length; i++) {
+ Type argType = argumentTypes[i];
+ boolean isReferenceArg = ASMUtils.isReferenceType(argType);
+ boolean isBooleanArg = ASMUtils.isBooleanType(argType);
+
+ if (isReferenceArg) {
+ result.add(new Equation<Key, Value>(new Key(method, new In(i, In.NOT_NULL), stable), FINAL_TOP));
+ result.add(new Equation<Key, Value>(new Key(method, new In(i, In.NULLABLE), stable), FINAL_TOP));
+ }
+ if (isReferenceArg && isInterestingResult) {
+ result.add(new Equation<Key, Value>(new Key(method, new InOut(i, Value.Null), stable), FINAL_TOP));
+ result.add(new Equation<Key, Value>(new Key(method, new InOut(i, Value.NotNull), stable), FINAL_TOP));
+ }
+ if (isBooleanArg && isInterestingResult) {
+ result.add(new Equation<Key, Value>(new Key(method, new InOut(i, Value.False), stable), FINAL_TOP));
+ result.add(new Equation<Key, Value>(new Key(method, new InOut(i, Value.True), stable), FINAL_TOP));
+ }
+ }
+ return result;
+ }
+
+ private LeakingParameters leakingParametersAndFrames(Method method, MethodNode methodNode, Type[] argumentTypes, boolean jsr)
+ throws AnalyzerException {
+ return argumentTypes.length < 32 ?
+ LeakingParameters.buildFast(method.internalClassName, methodNode, jsr) :
+ LeakingParameters.build(method.internalClassName, methodNode, jsr);
}
}, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
- return new ClassEquations(parameterEquations, contractEquations);
+ return equations;
}
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Combined.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Combined.java
new file mode 100644
index 000000000000..645c00260af1
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Combined.java
@@ -0,0 +1,465 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection.bytecodeAnalysis;
+
+import com.intellij.codeInspection.bytecodeAnalysis.asm.ASMUtils;
+import com.intellij.codeInspection.bytecodeAnalysis.asm.ControlFlowGraph;
+import com.intellij.util.SingletonSet;
+import com.intellij.util.containers.HashSet;
+import org.jetbrains.org.objectweb.asm.Handle;
+import org.jetbrains.org.objectweb.asm.Opcodes;
+import org.jetbrains.org.objectweb.asm.Type;
+import org.jetbrains.org.objectweb.asm.tree.*;
+import org.jetbrains.org.objectweb.asm.tree.analysis.AnalyzerException;
+import org.jetbrains.org.objectweb.asm.tree.analysis.BasicInterpreter;
+import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue;
+import org.jetbrains.org.objectweb.asm.tree.analysis.Frame;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import static com.intellij.codeInspection.bytecodeAnalysis.AbstractValues.*;
+import static org.jetbrains.org.objectweb.asm.Opcodes.*;
+
+final class ParamKey {
+ final Method method;
+ final int i;
+ final boolean stable;
+
+
+ ParamKey(Method method, int i, boolean stable) {
+ this.method = method;
+ this.i = i;
+ this.stable = stable;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ ParamKey paramKey = (ParamKey)o;
+
+ if (i != paramKey.i) return false;
+ if (stable != paramKey.stable) return false;
+ if (!method.equals(paramKey.method)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = method.hashCode();
+ result = 31 * result + i;
+ result = 31 * result + (stable ? 1 : 0);
+ return result;
+ }
+}
+
+final class CombinedCall extends BasicValue {
+ final Method method;
+ final boolean stableCall;
+ final List<? extends BasicValue> args;
+
+ CombinedCall(Type tp, Method method, boolean stableCall, List<? extends BasicValue> args) {
+ super(tp);
+ this.method = method;
+ this.stableCall = stableCall;
+ this.args = args;
+ }
+}
+
+final class NParamValue extends BasicValue {
+ final int n;
+ public NParamValue(Type type, int n) {
+ super(type);
+ this.n = n;
+ }
+}
+
+final class CombinedSingleAnalysis {
+ private final ControlFlowGraph controlFlow;
+ private final Method method;
+ private final CombinedInterpreter interpreter;
+ private BasicValue returnValue;
+ private boolean exception;
+ private final MethodNode methodNode;
+
+ CombinedSingleAnalysis(Method method, ControlFlowGraph controlFlow) {
+ this.method = method;
+ this.controlFlow = controlFlow;
+ methodNode = controlFlow.methodNode;
+ interpreter = new CombinedInterpreter(Type.getArgumentTypes(methodNode.desc).length);
+ }
+
+ final void analyze() throws AnalyzerException {
+ Frame<BasicValue> frame = createStartFrame();
+ int insnIndex = 0;
+
+ while (true) {
+ AbstractInsnNode insnNode = methodNode.instructions.get(insnIndex);
+ switch (insnNode.getType()) {
+ case AbstractInsnNode.LABEL:
+ case AbstractInsnNode.LINE:
+ case AbstractInsnNode.FRAME:
+ insnIndex = controlFlow.transitions[insnIndex][0];
+ break;
+ default:
+ switch (insnNode.getOpcode()) {
+ case ATHROW:
+ exception = true;
+ return;
+ case ARETURN:
+ case IRETURN:
+ case LRETURN:
+ case FRETURN:
+ case DRETURN:
+ returnValue = frame.pop();
+ return;
+ case RETURN:
+ // nothing to return
+ return;
+ default:
+ frame.execute(insnNode, interpreter);
+ insnIndex = controlFlow.transitions[insnIndex][0];
+ }
+ }
+ }
+ }
+
+ final Equation<Key, Value> notNullParamEquation(int i, boolean stable) {
+ final Key key = new Key(method, new In(i, In.NOT_NULL), stable);
+ final Result<Key, Value> result;
+ if (interpreter.dereferenced[i]) {
+ result = new Final<Key, Value>(Value.NotNull);
+ }
+ else {
+ Set<ParamKey> calls = interpreter.callDerefs[i];
+ if (calls == null || calls.isEmpty()) {
+ result = new Final<Key, Value>(Value.Top);
+ }
+ else {
+ Set<Key> keys = new HashSet<Key>();
+ for (ParamKey pk: calls) {
+ keys.add(new Key(pk.method, new In(pk.i, In.NOT_NULL), pk.stable));
+ }
+ result = new Pending<Key, Value>(new SingletonSet<Product<Key, Value>>(new Product<Key, Value>(Value.Top, keys)));
+ }
+ }
+ return new Equation<Key, Value>(key, result);
+ }
+
+ final Equation<Key, Value> nullableParamEquation(int i, boolean stable) {
+ final Key key = new Key(method, new In(i, In.NULLABLE), stable);
+ final Result<Key, Value> result;
+ if (interpreter.dereferenced[i] || interpreter.notNullable[i] || returnValue instanceof NParamValue && ((NParamValue)returnValue).n == i) {
+ result = new Final<Key, Value>(Value.Top);
+ }
+ else {
+ Set<ParamKey> calls = interpreter.callDerefs[i];
+ if (calls == null || calls.isEmpty()) {
+ result = new Final<Key, Value>(Value.Null);
+ }
+ else {
+ Set<Product<Key, Value>> sum = new HashSet<Product<Key, Value>>();
+ for (ParamKey pk: calls) {
+ sum.add(new Product<Key, Value>(Value.Top, Collections.singleton(new Key(pk.method, new In(pk.i, In.NULLABLE), pk.stable))));
+ }
+ result = new Pending<Key, Value>(sum);
+ }
+ }
+ return new Equation<Key, Value>(key, result);
+ }
+
+ final Equation<Key, Value> contractEquation(int i, Value inValue, boolean stable) {
+ final Key key = new Key(method, new InOut(i, inValue), stable);
+ final Result<Key, Value> result;
+ if (exception || (inValue == Value.Null && interpreter.dereferenced[i])) {
+ result = new Final<Key, Value>(Value.Bot);
+ }
+ else if (FalseValue == returnValue) {
+ result = new Final<Key, Value>(Value.False);
+ }
+ else if (TrueValue == returnValue) {
+ result = new Final<Key, Value>(Value.True);
+ }
+ else if (NullValue == returnValue) {
+ result = new Final<Key, Value>(Value.Null);
+ }
+ else if (returnValue instanceof NotNullValue) {
+ result = new Final<Key, Value>(Value.NotNull);
+ }
+ else if (returnValue instanceof NParamValue && ((NParamValue)returnValue).n == i) {
+ result = new Final<Key, Value>(inValue);
+ }
+ else if (returnValue instanceof CombinedCall) {
+ CombinedCall call = (CombinedCall)returnValue;
+ HashSet<Key> keys = new HashSet<Key>();
+ for (int argI = 0; argI < call.args.size(); argI++) {
+ BasicValue arg = call.args.get(argI);
+ if (arg instanceof NParamValue) {
+ NParamValue npv = (NParamValue)arg;
+ if (npv.n == i) {
+ keys.add(new Key(call.method, new InOut(argI, inValue), call.stableCall));
+ }
+ }
+ }
+ if (ASMUtils.isReferenceType(call.getType())) {
+ keys.add(new Key(call.method, new Out(), call.stableCall));
+ }
+ if (keys.isEmpty()) {
+ result = new Final<Key, Value>(Value.Top);
+ } else {
+ result = new Pending<Key, Value>(new SingletonSet<Product<Key, Value>>(new Product<Key, Value>(Value.Top, keys)));
+ }
+ }
+ else {
+ result = new Final<Key, Value>(Value.Top);
+ }
+ return new Equation<Key, Value>(key, result);
+ }
+
+ final Equation<Key, Value> outContractEquation(boolean stable) {
+ final Key key = new Key(method, new Out(), stable);
+ final Result<Key, Value> result;
+ if (exception) {
+ result = new Final<Key, Value>(Value.Bot);
+ }
+ else if (FalseValue == returnValue) {
+ result = new Final<Key, Value>(Value.False);
+ }
+ else if (TrueValue == returnValue) {
+ result = new Final<Key, Value>(Value.True);
+ }
+ else if (NullValue == returnValue) {
+ result = new Final<Key, Value>(Value.Null);
+ }
+ else if (returnValue instanceof NotNullValue) {
+ result = new Final<Key, Value>(Value.NotNull);
+ }
+ else if (returnValue instanceof CombinedCall) {
+ CombinedCall call = (CombinedCall)returnValue;
+ Key callKey = new Key(call.method, new Out(), call.stableCall);
+ Set<Key> keys = new SingletonSet<Key>(callKey);
+ result = new Pending<Key, Value>(new SingletonSet<Product<Key, Value>>(new Product<Key, Value>(Value.Top, keys)));
+ }
+ else {
+ result = new Final<Key, Value>(Value.Top);
+ }
+ return new Equation<Key, Value>(key, result);
+ }
+
+ final Frame<BasicValue> createStartFrame() {
+ Frame<BasicValue> frame = new Frame<BasicValue>(methodNode.maxLocals, methodNode.maxStack);
+ Type returnType = Type.getReturnType(methodNode.desc);
+ BasicValue returnValue = Type.VOID_TYPE.equals(returnType) ? null : new BasicValue(returnType);
+ frame.setReturn(returnValue);
+
+ Type[] args = Type.getArgumentTypes(methodNode.desc);
+ int local = 0;
+ if ((methodNode.access & Opcodes.ACC_STATIC) == 0) {
+ frame.setLocal(local++, new AbstractValues.NotNullValue(Type.getObjectType(controlFlow.className)));
+ }
+ for (int i = 0; i < args.length; i++) {
+ BasicValue value = new NParamValue(args[i], i);
+ frame.setLocal(local++, value);
+ if (args[i].getSize() == 2) {
+ frame.setLocal(local++, BasicValue.UNINITIALIZED_VALUE);
+ }
+ }
+ while (local < methodNode.maxLocals) {
+ frame.setLocal(local++, BasicValue.UNINITIALIZED_VALUE);
+ }
+ return frame;
+ }
+}
+
+final class CombinedInterpreter extends BasicInterpreter {
+ final boolean[] dereferenced;
+ final boolean[] notNullable;
+ final Set<ParamKey>[] callDerefs;
+
+ CombinedInterpreter(int arity) {
+ dereferenced = new boolean[arity];
+ notNullable = new boolean[arity];
+ callDerefs = new Set[arity];
+ }
+
+ @Override
+ public BasicValue newOperation(AbstractInsnNode insn) throws AnalyzerException {
+ switch (insn.getOpcode()) {
+ case ICONST_0:
+ return FalseValue;
+ case ICONST_1:
+ return TrueValue;
+ case ACONST_NULL:
+ return NullValue;
+ case LDC:
+ Object cst = ((LdcInsnNode)insn).cst;
+ if (cst instanceof Type) {
+ Type type = (Type)cst;
+ if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
+ return CLASS_VALUE;
+ }
+ if (type.getSort() == Type.METHOD) {
+ return METHOD_VALUE;
+ }
+ }
+ else if (cst instanceof String) {
+ return STRING_VALUE;
+ }
+ else if (cst instanceof Handle) {
+ return METHOD_HANDLE_VALUE;
+ }
+ break;
+ case NEW:
+ return new NotNullValue(Type.getObjectType(((TypeInsnNode)insn).desc));
+ default:
+ }
+ return super.newOperation(insn);
+ }
+
+ @Override
+ public BasicValue unaryOperation(AbstractInsnNode insn, BasicValue value) throws AnalyzerException {
+ switch (insn.getOpcode()) {
+ case GETFIELD:
+ case ARRAYLENGTH:
+ case MONITORENTER:
+ if (value instanceof NParamValue) {
+ dereferenced[((NParamValue)value).n] = true;
+ }
+ return super.unaryOperation(insn, value);
+ case CHECKCAST:
+ if (value instanceof NParamValue) {
+ return new NParamValue(Type.getObjectType(((TypeInsnNode)insn).desc), ((NParamValue)value).n);
+ }
+ break;
+ case NEWARRAY:
+ case ANEWARRAY:
+ return new NotNullValue(super.unaryOperation(insn, value).getType());
+ default:
+ }
+ return super.unaryOperation(insn, value);
+ }
+
+ @Override
+ public BasicValue binaryOperation(AbstractInsnNode insn, BasicValue value1, BasicValue value2) throws AnalyzerException {
+ switch (insn.getOpcode()) {
+ case IALOAD:
+ case LALOAD:
+ case FALOAD:
+ case DALOAD:
+ case AALOAD:
+ case BALOAD:
+ case CALOAD:
+ case SALOAD:
+ if (value1 instanceof NParamValue) {
+ dereferenced[((NParamValue)value1).n] = true;
+ }
+ break;
+ case PUTFIELD:
+ if (value1 instanceof NParamValue) {
+ dereferenced[((NParamValue)value1).n] = true;
+ }
+ if (value2 instanceof NParamValue) {
+ notNullable[((NParamValue)value2).n] = true;
+ }
+ break;
+ default:
+ }
+ return super.binaryOperation(insn, value1, value2);
+ }
+
+ @Override
+ public BasicValue ternaryOperation(AbstractInsnNode insn, BasicValue value1, BasicValue value2, BasicValue value3)
+ throws AnalyzerException {
+ switch (insn.getOpcode()) {
+ case IASTORE:
+ case LASTORE:
+ case FASTORE:
+ case DASTORE:
+ case BASTORE:
+ case CASTORE:
+ case SASTORE:
+ if (value1 instanceof NParamValue) {
+ dereferenced[((NParamValue)value1).n] = true;
+ }
+ break;
+ case AASTORE:
+ if (value1 instanceof NParamValue) {
+ dereferenced[((NParamValue)value1).n] = true;
+ }
+ if (value3 instanceof NParamValue) {
+ notNullable[((NParamValue)value3).n] = true;
+ }
+ break;
+ default:
+ }
+ return super.ternaryOperation(insn, value1, value2, value3);
+ }
+
+ @Override
+ public BasicValue naryOperation(AbstractInsnNode insn, List<? extends BasicValue> values) throws AnalyzerException {
+ int opCode = insn.getOpcode();
+ int shift = opCode == INVOKESTATIC ? 0 : 1;
+
+ switch (opCode) {
+ case INVOKESPECIAL:
+ case INVOKEINTERFACE:
+ case INVOKEVIRTUAL:
+ if (values.get(0) instanceof NParamValue) {
+ dereferenced[((NParamValue)values.get(0)).n] = true;
+ }
+ }
+
+ switch (opCode) {
+ case INVOKESTATIC:
+ case INVOKESPECIAL:
+ case INVOKEVIRTUAL:
+ case INVOKEINTERFACE:
+ boolean stable = opCode == INVOKESTATIC || opCode == INVOKESPECIAL;
+ MethodInsnNode mNode = (MethodInsnNode)insn;
+ Method method = new Method(mNode.owner, mNode.name, mNode.desc);
+ Type retType = Type.getReturnType(mNode.desc);
+
+ for (int i = shift; i < values.size(); i++) {
+ if (values.get(i) instanceof NParamValue) {
+ int n = ((NParamValue)values.get(i)).n;
+ if (opCode == INVOKEINTERFACE) {
+ notNullable[n] = true;
+ }
+ else {
+ Set<ParamKey> npKeys = callDerefs[n];
+ if (npKeys == null) {
+ npKeys = new HashSet<ParamKey>();
+ callDerefs[n] = npKeys;
+ }
+ npKeys.add(new ParamKey(method, i - shift, stable));
+ }
+ }
+ }
+ if (shift == 1) {
+ values.remove(0);
+ }
+ return new CombinedCall(retType, method, stable, values);
+ case MULTIANEWARRAY:
+ return new NotNullValue(super.naryOperation(insn, values).getType());
+ default:
+ }
+ return super.naryOperation(insn, values);
+ }
+}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Contracts.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Contracts.java
index 7b6c52e75a63..c382148abb05 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Contracts.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Contracts.java
@@ -15,7 +15,10 @@
*/
package com.intellij.codeInspection.bytecodeAnalysis;
-import gnu.trove.TIntHashSet;
+import com.intellij.codeInspection.bytecodeAnalysis.asm.ASMUtils;
+import com.intellij.codeInspection.bytecodeAnalysis.asm.ControlFlowGraph.Edge;
+import com.intellij.codeInspection.bytecodeAnalysis.asm.RichControlFlow;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.org.objectweb.asm.Handle;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.tree.*;
@@ -24,75 +27,104 @@ import org.jetbrains.org.objectweb.asm.tree.analysis.BasicInterpreter;
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue;
import org.jetbrains.org.objectweb.asm.tree.analysis.Frame;
-import java.util.*;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
import static com.intellij.codeInspection.bytecodeAnalysis.AbstractValues.*;
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
class InOutAnalysis extends Analysis<Result<Key, Value>> {
- final ResultUtil<Key, Value> resultUtil =
+ static final ResultUtil<Key, Value> resultUtil =
new ResultUtil<Key, Value>(new ELattice<Value>(Value.Bot, Value.Top));
+ final private State[] pending = ourPendingStates.get();
private final InOutInterpreter interpreter;
private final Value inValue;
+ private final int generalizeShift;
+ private Result<Key, Value> internalResult;
+ private int id = 0;
+ private int pendingTop = 0;
- protected InOutAnalysis(RichControlFlow richControlFlow, Direction direction, TIntHashSet resultOrigins, boolean stable) {
+ protected InOutAnalysis(RichControlFlow richControlFlow, Direction direction, boolean[] resultOrigins, boolean stable) {
super(richControlFlow, direction, stable);
interpreter = new InOutInterpreter(direction, richControlFlow.controlFlow.methodNode.instructions, resultOrigins);
inValue = direction instanceof InOut ? ((InOut)direction).inValue : null;
+ generalizeShift = (methodNode.access & ACC_STATIC) == 0 ? 1 : 0;
+ internalResult = new Final<Key, Value>(Value.Bot);
}
- @Override
- Result<Key, Value> identity() {
- return new Final<Key, Value>(Value.Bot);
+ @NotNull
+ Equation<Key, Value> mkEquation(Result<Key, Value> res) {
+ return new Equation<Key, Value>(aKey, res);
}
- @Override
- Result<Key, Value> combineResults(Result<Key, Value> delta, List<Result<Key, Value>> subResults) throws AnalyzerException {
- Result<Key, Value> result = null;
- for (Result<Key, Value> subResult : subResults) {
- if (result == null) {
- result = subResult;
- } else {
- result = resultUtil.join(result, subResult);
+ @NotNull
+ protected Equation<Key, Value> analyze() throws AnalyzerException {
+ pendingPush(createStartState());
+ int steps = 0;
+ while (pendingTop > 0 && earlyResult == null) {
+ steps ++;
+ if (steps >= STEPS_LIMIT) {
+ throw new AnalyzerException(null, "limit is reached, steps: " + steps + " in method " + method);
+ }
+ State state = pending[--pendingTop];
+ int insnIndex = state.conf.insnIndex;
+ Conf conf = state.conf;
+ List<Conf> history = state.history;
+
+ boolean fold = false;
+ if (dfsTree.loopEnters[insnIndex]) {
+ for (Conf prev : history) {
+ if (AbstractValues.isInstance(conf, prev)) {
+ fold = true;
+ break;
+ }
+ }
+ }
+ if (fold) {
+ addComputed(insnIndex, state);
+ }
+ else {
+ State baseState = null;
+ List<State> thisComputed = computed[insnIndex];
+ if (thisComputed != null) {
+ for (State prevState : thisComputed) {
+ if (stateEquiv(state, prevState)) {
+ baseState = prevState;
+ break;
+ }
+ }
+ }
+ if (baseState == null) {
+ processState(state);
+ }
}
}
- return result;
- }
-
- @Override
- boolean isEarlyResult(Result<Key, Value> res) {
- if (res instanceof Final) {
- return ((Final<?, Value>)res).value == Value.Top;
+ if (earlyResult != null) {
+ return mkEquation(earlyResult);
+ } else {
+ return mkEquation(internalResult);
}
- return false;
- }
-
- @Override
- Equation<Key, Value> mkEquation(Result<Key, Value> res) {
- return new Equation<Key, Value>(aKey, res);
}
- private int id = 0;
-
- @Override
void processState(State state) throws AnalyzerException {
- int stateIndex = state.index;
Conf preConf = state.conf;
int insnIndex = preConf.insnIndex;
- boolean loopEnter = dfsTree.loopEnters.contains(insnIndex);
+ boolean loopEnter = dfsTree.loopEnters[insnIndex];
Conf conf = loopEnter ? generalize(preConf) : preConf;
List<Conf> history = state.history;
boolean taken = state.taken;
Frame<BasicValue> frame = conf.frame;
AbstractInsnNode insnNode = methodNode.instructions.get(insnIndex);
- List<Conf> nextHistory = dfsTree.loopEnters.contains(insnIndex) ? append(history, conf) : history;
+ List<Conf> nextHistory = loopEnter ? append(history, conf) : history;
Frame<BasicValue> nextFrame = execute(frame, insnNode);
+ addComputed(insnIndex, state);
+
if (interpreter.deReferenced) {
- results.put(stateIndex, new Final<Key, Value>(Value.Bot));
- computed.put(insnIndex, append(computed.get(insnIndex), state));
return;
}
@@ -105,38 +137,36 @@ class InOutAnalysis extends Analysis<Result<Key, Value>> {
case DRETURN:
case RETURN:
BasicValue stackTop = popValue(frame);
+ Result<Key, Value> subResult;
if (FalseValue == stackTop) {
- results.put(stateIndex, new Final<Key, Value>(Value.False));
- computed.put(insnIndex, append(computed.get(insnIndex), state));
+ subResult = new Final<Key, Value>(Value.False);
}
else if (TrueValue == stackTop) {
- results.put(stateIndex, new Final<Key, Value>(Value.True));
- computed.put(insnIndex, append(computed.get(insnIndex), state));
+ subResult = new Final<Key, Value>(Value.True);
}
else if (NullValue == stackTop) {
- results.put(stateIndex, new Final<Key, Value>(Value.Null));
- computed.put(insnIndex, append(computed.get(insnIndex), state));
+ subResult = new Final<Key, Value>(Value.Null);
}
else if (stackTop instanceof NotNullValue) {
- results.put(stateIndex, new Final<Key, Value>(Value.NotNull));
- computed.put(insnIndex, append(computed.get(insnIndex), state));
+ subResult = new Final<Key, Value>(Value.NotNull);
}
else if (stackTop instanceof ParamValue) {
- results.put(stateIndex, new Final<Key, Value>(inValue));
- computed.put(insnIndex, append(computed.get(insnIndex), state));
+ subResult = new Final<Key, Value>(inValue);
}
else if (stackTop instanceof CallResultValue) {
Set<Key> keys = ((CallResultValue) stackTop).inters;
- results.put(stateIndex, new Pending<Key, Value>(Collections.singleton(new Product<Key, Value>(Value.Top, keys))));
- computed.put(insnIndex, append(computed.get(insnIndex), state));
+ subResult = new Pending<Key, Value>(Collections.singleton(new Product<Key, Value>(Value.Top, keys)));
}
else {
earlyResult = new Final<Key, Value>(Value.Top);
+ return;
+ }
+ internalResult = resultUtil.join(internalResult, subResult);
+ if (internalResult instanceof Final && ((Final<?, Value>)internalResult).value == Value.Top) {
+ earlyResult = internalResult;
}
return;
case ATHROW:
- results.put(stateIndex, new Final<Key, Value>(Value.Bot));
- computed.put(insnIndex, append(computed.get(insnIndex), state));
return;
default:
}
@@ -144,72 +174,62 @@ class InOutAnalysis extends Analysis<Result<Key, Value>> {
if (opcode == IFNONNULL && popValue(frame) instanceof ParamValue) {
int nextInsnIndex = inValue == Value.Null ? insnIndex + 1 : methodNode.instructions.indexOf(((JumpInsnNode)insnNode).label);
State nextState = new State(++id, new Conf(nextInsnIndex, nextFrame), nextHistory, true, false);
- pending.push(new MakeResult<Result<Key, Value>>(state, myIdentity, new int[]{nextState.index}));
- pending.push(new ProceedState<Result<Key, Value>>(nextState));
+ pendingPush(nextState);
return;
}
if (opcode == IFNULL && popValue(frame) instanceof ParamValue) {
int nextInsnIndex = inValue == Value.NotNull ? insnIndex + 1 : methodNode.instructions.indexOf(((JumpInsnNode)insnNode).label);
State nextState = new State(++id, new Conf(nextInsnIndex, nextFrame), nextHistory, true, false);
- pending.push(new MakeResult<Result<Key, Value>>(state, myIdentity, new int[]{nextState.index}));
- pending.push(new ProceedState<Result<Key, Value>>(nextState));
+ pendingPush(nextState);
return;
}
if (opcode == IFEQ && popValue(frame) == InstanceOfCheckValue && inValue == Value.Null) {
int nextInsnIndex = methodNode.instructions.indexOf(((JumpInsnNode)insnNode).label);
State nextState = new State(++id, new Conf(nextInsnIndex, nextFrame), nextHistory, true, false);
- pending.push(new MakeResult<Result<Key, Value>>(state, myIdentity, new int[]{nextState.index}));
- pending.push(new ProceedState<Result<Key, Value>>(nextState));
+ pendingPush(nextState);
return;
}
if (opcode == IFNE && popValue(frame) == InstanceOfCheckValue && inValue == Value.Null) {
int nextInsnIndex = insnIndex + 1;
State nextState = new State(++id, new Conf(nextInsnIndex, nextFrame), nextHistory, true, false);
- pending.push(new MakeResult<Result<Key, Value>>(state, myIdentity, new int[]{nextState.index}));
- pending.push(new ProceedState<Result<Key, Value>>(nextState));
+ pendingPush(nextState);
return;
}
if (opcode == IFEQ && popValue(frame) instanceof ParamValue) {
int nextInsnIndex = inValue == Value.True ? insnIndex + 1 : methodNode.instructions.indexOf(((JumpInsnNode)insnNode).label);
State nextState = new State(++id, new Conf(nextInsnIndex, nextFrame), nextHistory, true, false);
- pending.push(new MakeResult<Result<Key, Value>>(state, myIdentity, new int[]{nextState.index}));
- pending.push(new ProceedState<Result<Key, Value>>(nextState));
+ pendingPush(nextState);
return;
}
if (opcode == IFNE && popValue(frame) instanceof ParamValue) {
int nextInsnIndex = inValue == Value.False ? insnIndex + 1 : methodNode.instructions.indexOf(((JumpInsnNode)insnNode).label);
State nextState = new State(++id, new Conf(nextInsnIndex, nextFrame), nextHistory, true, false);
- pending.push(new MakeResult<Result<Key, Value>>(state, myIdentity, new int[]{nextState.index}));
- pending.push(new ProceedState<Result<Key, Value>>(nextState));
+ pendingPush(nextState);
return;
}
// general case
- int[] nextInsnIndices = controlFlow.transitions[insnIndex];
- List<State> nextStates = new ArrayList<State>(nextInsnIndices.length);
- int[] subIndices = new int[nextInsnIndices.length];
-
- for (int i = 0; i < nextInsnIndices.length; i++) {
- int nextInsnIndex = nextInsnIndices[i];
+ for (int nextInsnIndex : controlFlow.transitions[insnIndex]) {
Frame<BasicValue> nextFrame1 = nextFrame;
- if (controlFlow.errorTransitions.contains(new Edge(insnIndex, nextInsnIndex))) {
+ if (controlFlow.errors[nextInsnIndex] && controlFlow.errorTransitions.contains(new Edge(insnIndex, nextInsnIndex))) {
nextFrame1 = new Frame<BasicValue>(frame);
nextFrame1.clearStack();
- nextFrame1.push(new BasicValue(Type.getType("java/lang/Throwable")));
+ nextFrame1.push(ASMUtils.THROWABLE_VALUE);
}
- nextStates.add(new State(++id, new Conf(nextInsnIndex, nextFrame1), nextHistory, taken, false));
- subIndices[i] = id;
+ pendingPush(new State(++id, new Conf(nextInsnIndex, nextFrame1), nextHistory, taken, false));
}
+ }
- pending.push(new MakeResult<Result<Key, Value>>(state, myIdentity, subIndices));
- for (State nextState : nextStates) {
- pending.push(new ProceedState<Result<Key, Value>>(nextState));
+ private void pendingPush(State st) throws AnalyzerException {
+ if (pendingTop >= STEPS_LIMIT) {
+ throw new AnalyzerException(null, "limit is reached in method " + method);
}
+ pending[pendingTop++] = st;
}
private Frame<BasicValue> execute(Frame<BasicValue> frame, AbstractInsnNode insnNode) throws AnalyzerException {
@@ -226,9 +246,9 @@ class InOutAnalysis extends Analysis<Result<Key, Value>> {
}
}
- private static Conf generalize(Conf conf) {
+ private Conf generalize(Conf conf) {
Frame<BasicValue> frame = new Frame<BasicValue>(conf.frame);
- for (int i = 0; i < frame.getLocals(); i++) {
+ for (int i = generalizeShift; i < frame.getLocals(); i++) {
BasicValue value = frame.getLocal(i);
Class<?> valueClass = value.getClass();
if (valueClass != BasicValue.class && valueClass != ParamValue.class) {
@@ -258,12 +278,12 @@ class InOutAnalysis extends Analysis<Result<Key, Value>> {
class InOutInterpreter extends BasicInterpreter {
final Direction direction;
final InsnList insns;
- final TIntHashSet resultOrigins;
+ final boolean[] resultOrigins;
final boolean nullAnalysis;
boolean deReferenced = false;
- InOutInterpreter(Direction direction, InsnList insns, TIntHashSet resultOrigins) {
+ InOutInterpreter(Direction direction, InsnList insns, boolean[] resultOrigins) {
this.direction = direction;
this.insns = insns;
this.resultOrigins = resultOrigins;
@@ -272,7 +292,7 @@ class InOutInterpreter extends BasicInterpreter {
@Override
public BasicValue newOperation(AbstractInsnNode insn) throws AnalyzerException {
- boolean propagate = resultOrigins.contains(insns.indexOf(insn));
+ boolean propagate = resultOrigins[insns.indexOf(insn)];
if (propagate) {
switch (insn.getOpcode()) {
case ICONST_0:
@@ -286,17 +306,17 @@ class InOutInterpreter extends BasicInterpreter {
if (cst instanceof Type) {
Type type = (Type)cst;
if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
- return new NotNullValue(Type.getObjectType("java/lang/Class"));
+ return CLASS_VALUE;
}
if (type.getSort() == Type.METHOD) {
- return new NotNullValue(Type.getObjectType("java/lang/invoke/MethodType"));
+ return METHOD_VALUE;
}
}
else if (cst instanceof String) {
- return new NotNullValue(Type.getObjectType("java/lang/String"));
+ return STRING_VALUE;
}
else if (cst instanceof Handle) {
- return new NotNullValue(Type.getObjectType("java/lang/invoke/MethodHandle"));
+ return METHOD_HANDLE_VALUE;
}
break;
case NEW:
@@ -309,7 +329,7 @@ class InOutInterpreter extends BasicInterpreter {
@Override
public BasicValue unaryOperation(AbstractInsnNode insn, BasicValue value) throws AnalyzerException {
- boolean propagate = resultOrigins.contains(insns.indexOf(insn));
+ boolean propagate = resultOrigins[insns.indexOf(insn)];
switch (insn.getOpcode()) {
case GETFIELD:
case ARRAYLENGTH:
@@ -381,7 +401,7 @@ class InOutInterpreter extends BasicInterpreter {
@Override
public BasicValue naryOperation(AbstractInsnNode insn, List<? extends BasicValue> values) throws AnalyzerException {
- boolean propagate = resultOrigins.contains(insns.indexOf(insn));
+ boolean propagate = resultOrigins[insns.indexOf(insn)];
int opCode = insn.getOpcode();
int shift = opCode == INVOKESTATIC ? 0 : 1;
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/ControlFlow.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/ControlFlow.java
deleted file mode 100644
index 910d75b9a57f..000000000000
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/ControlFlow.java
+++ /dev/null
@@ -1,1030 +0,0 @@
-/*
- * Copyright 2000-2014 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.codeInspection.bytecodeAnalysis;
-
-import gnu.trove.TIntArrayList;
-import gnu.trove.TIntHashSet;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.org.objectweb.asm.Opcodes;
-import org.jetbrains.org.objectweb.asm.Type;
-import org.jetbrains.org.objectweb.asm.tree.*;
-import org.jetbrains.org.objectweb.asm.tree.analysis.*;
-import org.jetbrains.org.objectweb.asm.tree.analysis.Value;
-
-import java.util.*;
-
-import static org.jetbrains.org.objectweb.asm.Opcodes.*;
-
-final class cfg {
- static ControlFlowGraph buildControlFlowGraph(String className, MethodNode methodNode) throws AnalyzerException {
- return new ControlFlowBuilder(className, methodNode).buildCFG();
- }
-
- static TIntHashSet resultOrigins(String className, MethodNode methodNode) throws AnalyzerException {
- Frame<SourceValue>[] frames = new Analyzer<SourceValue>(MININAL_ORIGIN_INTERPRETER).analyze(className, methodNode);
- InsnList insns = methodNode.instructions;
- TIntHashSet result = new TIntHashSet();
- for (int i = 0; i < frames.length; i++) {
- AbstractInsnNode insnNode = insns.get(i);
- Frame<SourceValue> frame = frames[i];
- if (frame != null) {
- switch (insnNode.getOpcode()) {
- case ARETURN:
- case IRETURN:
- case LRETURN:
- case FRETURN:
- case DRETURN:
- for (AbstractInsnNode sourceInsn : frame.pop().insns) {
- result.add(insns.indexOf(sourceInsn));
- }
- break;
-
- default:
- break;
- }
- }
- }
- return result;
- }
-
- static boolean[] leakingParameters(String className, MethodNode methodNode) throws AnalyzerException {
- Frame<ParamsValue>[] frames = new Analyzer<ParamsValue>(new ParametersUsage(methodNode)).analyze(className, methodNode);
- InsnList insns = methodNode.instructions;
- LeakingParametersCollector collector = new LeakingParametersCollector(methodNode);
- for (int i = 0; i < frames.length; i++) {
- AbstractInsnNode insnNode = insns.get(i);
- Frame<ParamsValue> frame = frames[i];
- if (frame != null) {
- switch (insnNode.getType()) {
- case AbstractInsnNode.LABEL:
- case AbstractInsnNode.LINE:
- case AbstractInsnNode.FRAME:
- break;
- default:
- frame.execute(insnNode, collector);
- }
- }
- }
- return collector.leaking;
- }
-
- static final Interpreter<SourceValue> MININAL_ORIGIN_INTERPRETER = new SourceInterpreter() {
- final SourceValue[] sourceVals = {new SourceValue(1), new SourceValue(2)};
-
- @Override
- public SourceValue newOperation(AbstractInsnNode insn) {
- SourceValue result = super.newOperation(insn);
- switch (insn.getOpcode()) {
- case ICONST_0:
- case ICONST_1:
- case ACONST_NULL:
- case LDC:
- case NEW:
- return result;
- default:
- return sourceVals[result.getSize() - 1];
- }
- }
-
- @Override
- public SourceValue unaryOperation(AbstractInsnNode insn, SourceValue value) {
- SourceValue result = super.unaryOperation(insn, value);
- switch (insn.getOpcode()) {
- case CHECKCAST:
- case NEWARRAY:
- case ANEWARRAY:
- return result;
- default:
- return sourceVals[result.getSize() - 1];
- }
- }
-
- @Override
- public SourceValue binaryOperation(AbstractInsnNode insn, SourceValue value1, SourceValue value2) {
- switch (insn.getOpcode()) {
- case LALOAD:
- case DALOAD:
- case LADD:
- case DADD:
- case LSUB:
- case DSUB:
- case LMUL:
- case DMUL:
- case LDIV:
- case DDIV:
- case LREM:
- case LSHL:
- case LSHR:
- case LUSHR:
- case LAND:
- case LOR:
- case LXOR:
- return sourceVals[1];
- default:
- return sourceVals[0];
- }
- }
-
- @Override
- public SourceValue ternaryOperation(AbstractInsnNode insn, SourceValue value1, SourceValue value2, SourceValue value3) {
- return sourceVals[0];
- }
-
- @Override
- public SourceValue copyOperation(AbstractInsnNode insn, SourceValue value) {
- return value;
- }
-
- };
-
- private interface Action {}
- private static class MarkScanned implements Action {
- final int node;
- private MarkScanned(int node) {
- this.node = node;
- }
- }
- private static class ExamineEdge implements Action {
- final int from;
- final int to;
-
- private ExamineEdge(int from, int to) {
- this.from = from;
- this.to = to;
- }
- }
-
- // Graphs: Theory and Algorithms. by K. Thulasiraman , M. N. S. Swamy (1992)
- // 11.7.2 DFS of a directed graph
- static DFSTree buildDFSTree(int[][] transitions) {
- Set<Edge> tree = new HashSet<Edge>();
- Set<Edge> forward = new HashSet<Edge>();
- Set<Edge> back = new HashSet<Edge>();
- Set<Edge> cross = new HashSet<Edge>();
-
- boolean[] marked = new boolean[transitions.length];
- boolean[] scanned = new boolean[transitions.length];
- int[] preOrder = new int[transitions.length];
- int[] postOrder = new int[transitions.length];
-
- int entered = 0;
- int completed = 0;
-
- Deque<Action> stack = new LinkedList<Action>();
- Set<Integer> loopEnters = new HashSet<Integer>();
-
- // enter 0
- entered ++;
- preOrder[0] = entered;
- marked[0] = true;
- stack.push(new MarkScanned(0));
- for (int to : transitions[0]) {
- stack.push(new ExamineEdge(0, to));
- }
-
- while (!stack.isEmpty()) {
- Action action = stack.pop();
- if (action instanceof MarkScanned) {
- MarkScanned markScannedAction = (MarkScanned) action;
- completed ++;
- postOrder[markScannedAction.node] = completed;
- scanned[markScannedAction.node] = true;
- }
- else {
- ExamineEdge examineEdgeAction = (ExamineEdge) action;
- int from = examineEdgeAction.from;
- int to = examineEdgeAction.to;
- if (!marked[to]) {
- tree.add(new Edge(from, to));
- // enter to
- entered ++;
- preOrder[to] = entered;
- marked[to] = true;
- stack.push(new MarkScanned(to));
- for (int to1 : transitions[to]) {
- stack.push(new ExamineEdge(to, to1));
- }
- }
- else if (preOrder[to] > preOrder[from]) {
- forward.add(new Edge(from, to));
- }
- else if (preOrder[to] < preOrder[from] && !scanned[to]) {
- back.add(new Edge(from, to));
- loopEnters.add(to);
- } else {
- cross.add(new Edge(from, to));
- }
- }
- }
-
- return new DFSTree(preOrder, postOrder, tree, forward, back, cross, loopEnters);
- }
-
- // Tarjan. Testing flow graph reducibility.
- // Journal of Computer and System Sciences 9.3 (1974): 355-365.
- static boolean reducible(ControlFlowGraph cfg, DFSTree dfs) {
- int size = cfg.transitions.length;
- HashSet<Integer>[] cycles = new HashSet[size];
- HashSet<Integer>[] nonCycles = new HashSet[size];
- int[] collapsedTo = new int[size];
- for (int i = 0; i < size; i++) {
- cycles[i] = new HashSet<Integer>();
- nonCycles[i] = new HashSet<Integer>();
- collapsedTo[i] = i;
- }
-
- for (Edge edge : dfs.back) {
- cycles[edge.to].add(edge.from);
- }
- for (Edge edge : dfs.tree) {
- nonCycles[edge.to].add(edge.from);
- }
- for (Edge edge : dfs.forward) {
- nonCycles[edge.to].add(edge.from);
- }
- for (Edge edge : dfs.cross) {
- nonCycles[edge.to].add(edge.from);
- }
-
- for (int w = size - 1; w >= 0 ; w--) {
- HashSet<Integer> p = new HashSet<Integer>(cycles[w]);
- Queue<Integer> queue = new LinkedList<Integer>(cycles[w]);
-
- while (!queue.isEmpty()) {
- int x = queue.remove();
- for (int y : nonCycles[x]) {
- int y1 = collapsedTo[y];
- if (!dfs.isDescendant(y1, w)) {
- return false;
- }
- if (y1 != w && p.add(y1)) {
- queue.add(y1);
- }
- }
- }
-
- for (int x : p) {
- collapsedTo[x] = w;
- }
- }
-
- return true;
- }
-
-}
-
-final class Edge {
- final int from, to;
-
- Edge(int from, int to) {
- this.from = from;
- this.to = to;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (!(o instanceof Edge)) {
- return false;
- }
- Edge edge = (Edge) o;
- return from == edge.from && to == edge.to;
- }
-
- @Override
- public int hashCode() {
- return 31 * from + to;
- }
-
- @Override
- public String toString() {
- return "(" + from + "," + to + ")";
- }
-}
-
-final class ControlFlowGraph {
- final String className;
- final MethodNode methodNode;
- final int[][] transitions;
- final Set<Edge> errorTransitions;
-
- ControlFlowGraph(String className, MethodNode methodNode, int[][] transitions, Set<Edge> errorTransitions) {
- this.className = className;
- this.methodNode = methodNode;
- this.transitions = transitions;
- this.errorTransitions = errorTransitions;
- }
-
- @Override
- public String toString() {
- return "CFG(" +
- Arrays.toString(transitions) + "," +
- errorTransitions +
- ')';
- }
-}
-
-final class RichControlFlow {
- final ControlFlowGraph controlFlow;
- final DFSTree dfsTree;
-
- RichControlFlow(ControlFlowGraph controlFlow, DFSTree dfsTree) {
- this.controlFlow = controlFlow;
- this.dfsTree = dfsTree;
- }
-}
-
-final class ControlFlowBuilder extends CfgAnalyzer {
- final String className;
- final MethodNode methodNode;
- final TIntArrayList[] transitions;
- final Set<Edge> errorTransitions;
-
- ControlFlowBuilder(String className, MethodNode methodNode) {
- this.className = className;
- this.methodNode = methodNode;
- transitions = new TIntArrayList[methodNode.instructions.size()];
- for (int i = 0; i < transitions.length; i++) {
- transitions[i] = new TIntArrayList();
- }
- errorTransitions = new HashSet<Edge>();
- }
-
- final ControlFlowGraph buildCFG() throws AnalyzerException {
- if ((methodNode.access & (ACC_ABSTRACT | ACC_NATIVE)) == 0) {
- analyze(methodNode);
- }
- int[][] resultTransitions = new int[transitions.length][];
- for (int i = 0; i < resultTransitions.length; i++) {
- resultTransitions[i] = transitions[i].toNativeArray();
- }
- return new ControlFlowGraph(className, methodNode, resultTransitions, errorTransitions);
- }
-
- @Override
- protected final void newControlFlowEdge(int insn, int successor) {
- if (!transitions[insn].contains(successor)) {
- transitions[insn].add(successor);
- }
- }
-
- @Override
- protected final boolean newControlFlowExceptionEdge(int insn, int successor) {
- if (!transitions[insn].contains(successor)) {
- transitions[insn].add(successor);
- errorTransitions.add(new Edge(insn, successor));
- }
- return true;
- }
-}
-
-final class DFSTree {
- final int[] preOrder, postOrder;
- final Set<Edge> tree, forward, back, cross;
- final Set<Integer> loopEnters;
-
- DFSTree(int[] preOrder,
- int[] postOrder,
- Set<Edge> tree,
- Set<Edge> forward,
- Set<Edge> back,
- Set<Edge> cross,
- Set<Integer> loopEnters) {
- this.preOrder = preOrder;
- this.postOrder = postOrder;
- this.tree = tree;
- this.forward = forward;
- this.back = back;
- this.cross = cross;
- this.loopEnters = loopEnters;
- }
-
- final boolean isDescendant(int child, int parent) {
- return preOrder[parent] <= preOrder[child] && postOrder[child] <= postOrder[parent];
- }
-}
-
-final class ParamsValue implements Value {
- @NotNull final boolean[] params;
- final int size;
-
- ParamsValue(@NotNull boolean[] params, int size) {
- this.params = params;
- this.size = size;
- }
-
- @Override
- public int getSize() {
- return size;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null) return false;
- ParamsValue that = (ParamsValue)o;
- return (this.size == that.size && Arrays.equals(this.params, that.params));
- }
-
- @Override
- public int hashCode() {
- return 31 * Arrays.hashCode(params) + size;
- }
-}
-
-class ParametersUsage extends Interpreter<ParamsValue> {
- final ParamsValue val1;
- final ParamsValue val2;
- int called = -1;
- final int rangeStart;
- final int rangeEnd;
- final int arity;
- final int shift;
-
- ParametersUsage(MethodNode methodNode) {
- super(ASM5);
- arity = Type.getArgumentTypes(methodNode.desc).length;
- boolean[] emptyParams = new boolean[arity];
- val1 = new ParamsValue(emptyParams, 1);
- val2 = new ParamsValue(emptyParams, 2);
-
- shift = (methodNode.access & ACC_STATIC) == 0 ? 2 : 1;
- rangeStart = shift;
- rangeEnd = arity + shift;
- }
-
- @Override
- public ParamsValue newValue(Type type) {
- if (type == null) return val1;
- called++;
- if (type == Type.VOID_TYPE) return null;
- if (called < rangeEnd && rangeStart <= called) {
- boolean[] params = new boolean[arity];
- params[called - shift] = true;
- return type.getSize() == 1 ? new ParamsValue(params, 1) : new ParamsValue(params, 2);
- }
- else {
- return type.getSize() == 1 ? val1 : val2;
- }
- }
-
- @Override
- public ParamsValue newOperation(final AbstractInsnNode insn) {
- int size;
- switch (insn.getOpcode()) {
- case LCONST_0:
- case LCONST_1:
- case DCONST_0:
- case DCONST_1:
- size = 2;
- break;
- case LDC:
- Object cst = ((LdcInsnNode) insn).cst;
- size = cst instanceof Long || cst instanceof Double ? 2 : 1;
- break;
- case GETSTATIC:
- size = Type.getType(((FieldInsnNode) insn).desc).getSize();
- break;
- default:
- size = 1;
- }
- return size == 1 ? val1 : val2;
- }
-
- @Override
- public ParamsValue copyOperation(AbstractInsnNode insn, ParamsValue value) {
- return value;
- }
-
- @Override
- public ParamsValue unaryOperation(AbstractInsnNode insn, ParamsValue value) {
- int size;
- switch (insn.getOpcode()) {
- case CHECKCAST:
- return new ParamsValue(value.params, Type.getObjectType(((TypeInsnNode)insn).desc).getSize());
- case LNEG:
- case DNEG:
- case I2L:
- case I2D:
- case L2D:
- case F2L:
- case F2D:
- case D2L:
- size = 2;
- break;
- case GETFIELD:
- size = Type.getType(((FieldInsnNode) insn).desc).getSize();
- break;
- default:
- size = 1;
- }
- return size == 1 ? val1 : val2;
- }
-
- @Override
- public ParamsValue binaryOperation(AbstractInsnNode insn, ParamsValue value1, ParamsValue value2) {
- int size;
- switch (insn.getOpcode()) {
- case LALOAD:
- case DALOAD:
- case LADD:
- case DADD:
- case LSUB:
- case DSUB:
- case LMUL:
- case DMUL:
- case LDIV:
- case DDIV:
- case LREM:
- case DREM:
- case LSHL:
- case LSHR:
- case LUSHR:
- case LAND:
- case LOR:
- case LXOR:
- size = 2;
- break;
- default:
- size = 1;
- }
- return size == 1 ? val1 : val2;
- }
-
- @Override
- public ParamsValue ternaryOperation(AbstractInsnNode insn, ParamsValue value1, ParamsValue value2, ParamsValue value3) {
- return val1;
- }
-
- @Override
- public ParamsValue naryOperation(AbstractInsnNode insn, List<? extends ParamsValue> values) {
- int size;
- int opcode = insn.getOpcode();
- if (opcode == MULTIANEWARRAY) {
- size = 1;
- } else {
- String desc = (opcode == INVOKEDYNAMIC) ? ((InvokeDynamicInsnNode) insn).desc : ((MethodInsnNode) insn).desc;
- size = Type.getReturnType(desc).getSize();
- }
- return size == 1 ? val1 : val2;
- }
-
- @Override
- public void returnOperation(AbstractInsnNode insn, ParamsValue value, ParamsValue expected) {}
-
- @Override
- public ParamsValue merge(ParamsValue v1, ParamsValue v2) {
- if (v1.equals(v2)) return v1;
- boolean[] params = new boolean[arity];
- boolean[] params1 = v1.params;
- boolean[] params2 = v2.params;
- for (int i = 0; i < arity; i++) {
- params[i] = params1[i] || params2[i];
- }
- return new ParamsValue(params, Math.min(v1.size, v2.size));
- }
-}
-
-class LeakingParametersCollector extends ParametersUsage {
- final boolean[] leaking;
- LeakingParametersCollector(MethodNode methodNode) {
- super(methodNode);
- leaking = new boolean[arity];
- }
-
- @Override
- public ParamsValue unaryOperation(AbstractInsnNode insn, ParamsValue value) {
- switch (insn.getOpcode()) {
- case GETFIELD:
- case ARRAYLENGTH:
- case MONITORENTER:
- case INSTANCEOF:
- case IRETURN:
- case ARETURN:
- case IFNONNULL:
- case IFNULL:
- case IFEQ:
- case IFNE:
- boolean[] params = value.params;
- for (int i = 0; i < arity; i++) {
- leaking[i] |= params[i];
- }
- break;
- default:
- }
- return super.unaryOperation(insn, value);
- }
-
- @Override
- public ParamsValue binaryOperation(AbstractInsnNode insn, ParamsValue value1, ParamsValue value2) {
- switch (insn.getOpcode()) {
- case IALOAD:
- case LALOAD:
- case FALOAD:
- case DALOAD:
- case AALOAD:
- case BALOAD:
- case CALOAD:
- case SALOAD:
- case PUTFIELD:
- boolean[] params = value1.params;
- for (int i = 0; i < arity; i++) {
- leaking[i] |= params[i];
- }
- break;
- default:
- }
- return super.binaryOperation(insn, value1, value2);
- }
-
- @Override
- public ParamsValue ternaryOperation(AbstractInsnNode insn, ParamsValue value1, ParamsValue value2, ParamsValue value3) {
- switch (insn.getOpcode()) {
- case IASTORE:
- case LASTORE:
- case FASTORE:
- case DASTORE:
- case AASTORE:
- case BASTORE:
- case CASTORE:
- case SASTORE:
- boolean[] params = value1.params;
- for (int i = 0; i < arity; i++) {
- leaking[i] |= params[i];
- }
- break;
- default:
- }
- return super.ternaryOperation(insn, value1, value2, value3);
- }
-
- @Override
- public ParamsValue naryOperation(AbstractInsnNode insn, List<? extends ParamsValue> values) {
- switch (insn.getOpcode()) {
- case INVOKESTATIC:
- case INVOKESPECIAL:
- case INVOKEVIRTUAL:
- case INVOKEINTERFACE:
- for (ParamsValue value : values) {
- boolean[] params = value.params;
- for (int i = 0; i < arity; i++) {
- leaking[i] |= params[i];
- }
- }
- break;
- default:
- }
- return super.naryOperation(insn, values);
- }
-}
-
-/**
- * Specialized lite version of {@link org.jetbrains.org.objectweb.asm.tree.analysis.Analyzer}.
- * Calculation of fix-point of frames is removed, since frames are not needed to build control flow graph.
- * So, the main point here is handling of subroutines (jsr) and try-catch-finally blocks.
- */
-class CfgAnalyzer implements Opcodes {
- static class Subroutine {
-
- LabelNode start;
-
- boolean[] access;
-
- List<JumpInsnNode> callers;
-
- private Subroutine() {
- }
-
- Subroutine(final LabelNode start, final int maxLocals,
- final JumpInsnNode caller) {
- this.start = start;
- this.access = new boolean[maxLocals];
- this.callers = new ArrayList<JumpInsnNode>();
- callers.add(caller);
- }
-
- public Subroutine copy() {
- Subroutine result = new Subroutine();
- result.start = start;
- result.access = new boolean[access.length];
- System.arraycopy(access, 0, result.access, 0, access.length);
- result.callers = new ArrayList<JumpInsnNode>(callers);
- return result;
- }
-
- public boolean merge(final Subroutine subroutine) throws AnalyzerException {
- boolean changes = false;
- for (int i = 0; i < access.length; ++i) {
- if (subroutine.access[i] && !access[i]) {
- access[i] = true;
- changes = true;
- }
- }
- if (subroutine.start == start) {
- for (int i = 0; i < subroutine.callers.size(); ++i) {
- JumpInsnNode caller = subroutine.callers.get(i);
- if (!callers.contains(caller)) {
- callers.add(caller);
- changes = true;
- }
- }
- }
- return changes;
- }
- }
- private int n;
- private InsnList insns;
- private List<TryCatchBlockNode>[] handlers;
- private Subroutine[] subroutines;
- private boolean[] wasQueued;
- private boolean[] queued;
- private int[] queue;
- private int top;
-
- public void analyze(final MethodNode m) throws AnalyzerException {
- n = m.instructions.size();
- insns = m.instructions;
- handlers = (List<TryCatchBlockNode>[]) new List<?>[n];
- subroutines = new Subroutine[n];
- queued = new boolean[n];
- wasQueued = new boolean[n];
- queue = new int[n];
- top = 0;
-
- // computes exception handlers for each instruction
- for (int i = 0; i < m.tryCatchBlocks.size(); ++i) {
- TryCatchBlockNode tcb = m.tryCatchBlocks.get(i);
- int begin = insns.indexOf(tcb.start);
- int end = insns.indexOf(tcb.end);
- for (int j = begin; j < end; ++j) {
- List<TryCatchBlockNode> insnHandlers = handlers[j];
- if (insnHandlers == null) {
- insnHandlers = new ArrayList<TryCatchBlockNode>();
- handlers[j] = insnHandlers;
- }
- insnHandlers.add(tcb);
- }
- }
-
- // computes the subroutine for each instruction:
- Subroutine main = new Subroutine(null, m.maxLocals, null);
- List<AbstractInsnNode> subroutineCalls = new ArrayList<AbstractInsnNode>();
- Map<LabelNode, Subroutine> subroutineHeads = new HashMap<LabelNode, Subroutine>();
-
- findSubroutine(0, main, subroutineCalls);
- while (!subroutineCalls.isEmpty()) {
- JumpInsnNode jsr = (JumpInsnNode) subroutineCalls.remove(0);
- Subroutine sub = subroutineHeads.get(jsr.label);
- if (sub == null) {
- sub = new Subroutine(jsr.label, m.maxLocals, jsr);
- subroutineHeads.put(jsr.label, sub);
- findSubroutine(insns.indexOf(jsr.label), sub, subroutineCalls);
- } else {
- sub.callers.add(jsr);
- }
- }
- for (int i = 0; i < n; ++i) {
- if (subroutines[i] != null && subroutines[i].start == null) {
- subroutines[i] = null;
- }
- }
-
- merge(0, null);
- // control flow analysis
- while (top > 0) {
- int insn = queue[--top];
- Subroutine subroutine = subroutines[insn];
- queued[insn] = false;
-
- AbstractInsnNode insnNode = null;
- try {
- insnNode = m.instructions.get(insn);
- int insnOpcode = insnNode.getOpcode();
- int insnType = insnNode.getType();
-
- if (insnType == AbstractInsnNode.LABEL || insnType == AbstractInsnNode.LINE || insnType == AbstractInsnNode.FRAME) {
- merge(insn + 1, subroutine);
- newControlFlowEdge(insn, insn + 1);
- } else {
- subroutine = subroutine == null ? null : subroutine.copy();
-
- if (insnNode instanceof JumpInsnNode) {
- JumpInsnNode j = (JumpInsnNode) insnNode;
- if (insnOpcode != GOTO && insnOpcode != JSR) {
- merge(insn + 1, subroutine);
- newControlFlowEdge(insn, insn + 1);
- }
- int jump = insns.indexOf(j.label);
- if (insnOpcode == JSR) {
- merge(jump, new Subroutine(j.label, m.maxLocals, j));
- } else {
- merge(jump, subroutine);
- }
- newControlFlowEdge(insn, jump);
- } else if (insnNode instanceof LookupSwitchInsnNode) {
- LookupSwitchInsnNode lsi = (LookupSwitchInsnNode) insnNode;
- int jump = insns.indexOf(lsi.dflt);
- merge(jump, subroutine);
- newControlFlowEdge(insn, jump);
- for (int j = 0; j < lsi.labels.size(); ++j) {
- LabelNode label = lsi.labels.get(j);
- jump = insns.indexOf(label);
- merge(jump, subroutine);
- newControlFlowEdge(insn, jump);
- }
- } else if (insnNode instanceof TableSwitchInsnNode) {
- TableSwitchInsnNode tsi = (TableSwitchInsnNode) insnNode;
- int jump = insns.indexOf(tsi.dflt);
- merge(jump, subroutine);
- newControlFlowEdge(insn, jump);
- for (int j = 0; j < tsi.labels.size(); ++j) {
- LabelNode label = tsi.labels.get(j);
- jump = insns.indexOf(label);
- merge(jump, subroutine);
- newControlFlowEdge(insn, jump);
- }
- } else if (insnOpcode == RET) {
- if (subroutine == null) {
- throw new AnalyzerException(insnNode, "RET instruction outside of a sub routine");
- }
- for (int i = 0; i < subroutine.callers.size(); ++i) {
- JumpInsnNode caller = subroutine.callers.get(i);
- int call = insns.indexOf(caller);
- if (wasQueued[call]) {
- merge(call + 1, subroutines[call], subroutine.access);
- newControlFlowEdge(insn, call + 1);
- }
- }
- } else if (insnOpcode != ATHROW && (insnOpcode < IRETURN || insnOpcode > RETURN)) {
- if (subroutine != null) {
- if (insnNode instanceof VarInsnNode) {
- int var = ((VarInsnNode) insnNode).var;
- subroutine.access[var] = true;
- if (insnOpcode == LLOAD || insnOpcode == DLOAD
- || insnOpcode == LSTORE
- || insnOpcode == DSTORE) {
- subroutine.access[var + 1] = true;
- }
- } else if (insnNode instanceof IincInsnNode) {
- int var = ((IincInsnNode) insnNode).var;
- subroutine.access[var] = true;
- }
- }
- merge(insn + 1, subroutine);
- newControlFlowEdge(insn, insn + 1);
- }
- }
-
- List<TryCatchBlockNode> insnHandlers = handlers[insn];
- if (insnHandlers != null) {
- for (TryCatchBlockNode tcb : insnHandlers) {
- newControlFlowExceptionEdge(insn, tcb);
- merge(insns.indexOf(tcb.handler), subroutine);
- }
- }
- } catch (AnalyzerException e) {
- throw new AnalyzerException(e.node, "Error at instruction "
- + insn + ": " + e.getMessage(), e);
- } catch (Exception e) {
- throw new AnalyzerException(insnNode, "Error at instruction "
- + insn + ": " + e.getMessage(), e);
- }
- }
- }
-
- private void findSubroutine(int insn, final Subroutine sub,
- final List<AbstractInsnNode> calls) throws AnalyzerException {
- while (true) {
- if (insn < 0 || insn >= n) {
- throw new AnalyzerException(null, "Execution can fall off end of the code");
- }
- if (subroutines[insn] != null) {
- return;
- }
- subroutines[insn] = sub.copy();
- AbstractInsnNode node = insns.get(insn);
-
- // calls findSubroutine recursively on normal successors
- if (node instanceof JumpInsnNode) {
- if (node.getOpcode() == JSR) {
- // do not follow a JSR, it leads to another subroutine!
- calls.add(node);
- } else {
- JumpInsnNode jnode = (JumpInsnNode) node;
- findSubroutine(insns.indexOf(jnode.label), sub, calls);
- }
- } else if (node instanceof TableSwitchInsnNode) {
- TableSwitchInsnNode tsnode = (TableSwitchInsnNode) node;
- findSubroutine(insns.indexOf(tsnode.dflt), sub, calls);
- for (int i = tsnode.labels.size() - 1; i >= 0; --i) {
- LabelNode l = tsnode.labels.get(i);
- findSubroutine(insns.indexOf(l), sub, calls);
- }
- } else if (node instanceof LookupSwitchInsnNode) {
- LookupSwitchInsnNode lsnode = (LookupSwitchInsnNode) node;
- findSubroutine(insns.indexOf(lsnode.dflt), sub, calls);
- for (int i = lsnode.labels.size() - 1; i >= 0; --i) {
- LabelNode l = lsnode.labels.get(i);
- findSubroutine(insns.indexOf(l), sub, calls);
- }
- }
-
- // calls findSubroutine recursively on exception handler successors
- List<TryCatchBlockNode> insnHandlers = handlers[insn];
- if (insnHandlers != null) {
- for (int i = 0; i < insnHandlers.size(); ++i) {
- TryCatchBlockNode tcb = insnHandlers.get(i);
- findSubroutine(insns.indexOf(tcb.handler), sub, calls);
- }
- }
-
- // if insn does not falls through to the next instruction, return.
- switch (node.getOpcode()) {
- case GOTO:
- case RET:
- case TABLESWITCH:
- case LOOKUPSWITCH:
- case IRETURN:
- case LRETURN:
- case FRETURN:
- case DRETURN:
- case ARETURN:
- case RETURN:
- case ATHROW:
- return;
- }
- insn++;
- }
- }
-
- protected void newControlFlowEdge(final int insn, final int successor) {}
-
- protected boolean newControlFlowExceptionEdge(final int insn,
- final int successor) {
- return true;
- }
-
- protected boolean newControlFlowExceptionEdge(final int insn,
- final TryCatchBlockNode tcb) {
- return newControlFlowExceptionEdge(insn, insns.indexOf(tcb.handler));
- }
-
- // -------------------------------------------------------------------------
-
- private void merge(final int insn, final Subroutine subroutine) throws AnalyzerException {
- Subroutine oldSubroutine = subroutines[insn];
- boolean changes = false;
-
- if (!wasQueued[insn]) {
- wasQueued[insn] = true;
- changes = true;
- }
-
- if (oldSubroutine == null) {
- if (subroutine != null) {
- subroutines[insn] = subroutine.copy();
- changes = true;
- }
- } else {
- if (subroutine != null) {
- changes |= oldSubroutine.merge(subroutine);
- }
- }
- if (changes && !queued[insn]) {
- queued[insn] = true;
- queue[top++] = insn;
- }
- }
-
- private void merge(final int insn, final Subroutine subroutineBeforeJSR, final boolean[] access) throws AnalyzerException {
- Subroutine oldSubroutine = subroutines[insn];
- boolean changes = false;
-
- if (!wasQueued[insn]) {
- wasQueued[insn] = true;
- changes = true;
- }
-
- if (oldSubroutine != null && subroutineBeforeJSR != null) {
- changes |= oldSubroutine.merge(subroutineBeforeJSR);
- }
- if (changes && !queued[insn]) {
- queued[insn] = true;
- queue[top++] = insn;
- }
- }
-}
-
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Data.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Data.java
index 132c5643b2d6..55a842af684c 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Data.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Data.java
@@ -52,20 +52,17 @@ enum Value {
Bot, NotNull, Null, True, False, Top
}
-interface Direction {
- static final int OUT_DIRECTION = 0;
- static final int IN_DIRECTION = 1;
- static final int INOUT_DIRECTION = 2;
- int directionId();
- int paramId();
- int valueId();
-}
+interface Direction {}
final class In implements Direction {
+ static final int NOT_NULL = 0;
+ static final int NULLABLE = 1;
final int paramIndex;
+ final int nullityMask;
- In(int paramIndex) {
+ In(int paramIndex, int nullityMask) {
this.paramIndex = paramIndex;
+ this.nullityMask = nullityMask;
}
@Override
@@ -79,28 +76,19 @@ final class In implements Direction {
if (o == null || getClass() != o.getClass()) return false;
In in = (In) o;
if (paramIndex != in.paramIndex) return false;
+ if (nullityMask != in.nullityMask) return false;
return true;
}
@Override
public int hashCode() {
- return paramIndex;
+ return 31*paramIndex + nullityMask;
}
- @Override
- public int directionId() {
- return IN_DIRECTION;
- }
-
- @Override
public int paramId() {
return paramIndex;
}
- @Override
- public int valueId() {
- return 0;
- }
}
final class InOut implements Direction {
@@ -137,17 +125,10 @@ final class InOut implements Direction {
return "InOut " + paramIndex + " " + inValue.toString();
}
- @Override
- public int directionId() {
- return INOUT_DIRECTION;
- }
-
- @Override
public int paramId() {
return paramIndex;
}
- @Override
public int valueId() {
return inValue.ordinal();
}
@@ -168,21 +149,6 @@ final class Out implements Direction {
public boolean equals(Object obj) {
return obj instanceof Out;
}
-
- @Override
- public int directionId() {
- return OUT_DIRECTION;
- }
-
- @Override
- public int paramId() {
- return 0;
- }
-
- @Override
- public int valueId() {
- return 0;
- }
}
final class Key {
@@ -219,8 +185,6 @@ final class Key {
@Override
public String toString() {
- return "" + method + ' ' + direction + ' ' + stable;
+ return method + " " + direction + " " + stable;
}
}
-
-
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/HData.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/HData.java
new file mode 100644
index 000000000000..7c938347ccb9
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/HData.java
@@ -0,0 +1,311 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection.bytecodeAnalysis;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Small size key, constructed by hashing method signature.
+ * @see com.intellij.codeInspection.bytecodeAnalysis.BytecodeAnalysisConverter for details of construction.
+ */
+final class HKey {
+ @NotNull
+ final byte[] key;
+ final int dirKey;
+ final boolean stable;
+
+ HKey(@NotNull byte[] key, int dirKey, boolean stable) {
+ this.key = key;
+ this.dirKey = dirKey;
+ this.stable = stable;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ HKey hKey = (HKey)o;
+ if (dirKey != hKey.dirKey) return false;
+ if (stable != hKey.stable) return false;
+ if (!Arrays.equals(key, hKey.key)) return false;
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = Arrays.hashCode(key);
+ result = 31 * result + dirKey;
+ result = 31 * result + (stable ? 1 : 0);
+ return result;
+ }
+
+ HKey negate() {
+ return new HKey(key, dirKey, !stable);
+ }
+
+ HKey mkStable() {
+ return stable ? this : new HKey(key, dirKey, true);
+ }
+
+ HKey mkUnstable() {
+ return stable ? new HKey(key, dirKey, false) : this;
+ }
+
+ public HKey mkBase() {
+ return dirKey == 0 ? this : new HKey(key, 0, stable);
+ }
+
+ HKey updateDirection(int newDirKey) {
+ return new HKey(key, newDirKey, stable);
+ }
+}
+
+final class HComponent {
+ @NotNull Value value;
+ @NotNull final HKey[] ids;
+
+ HComponent(@NotNull Value value, @NotNull HKey[] ids) {
+ this.value = value;
+ this.ids = ids;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ HComponent that = (HComponent)o;
+
+ if (!Arrays.equals(ids, that.ids)) return false;
+ if (value != that.value) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = value.hashCode();
+ result = 31 * result + Arrays.hashCode(ids);
+ return result;
+ }
+
+ public boolean remove(@NotNull HKey id) {
+ return HUtils.remove(ids, id);
+ }
+
+ public boolean isEmpty() {
+ return HUtils.isEmpty(ids);
+ }
+
+ @NotNull
+ public HComponent copy() {
+ return new HComponent(value, ids.clone());
+ }
+}
+
+class HUtils {
+
+ static boolean isEmpty(HKey[] ids) {
+ for (HKey id : ids) {
+ if (id != null) return false;
+ }
+ return true;
+ }
+
+ static boolean remove(HKey[] ids, @NotNull HKey id) {
+ boolean removed = false;
+ for (int i = 0; i < ids.length; i++) {
+ if (id.equals(ids[i])) {
+ ids[i] = null;
+ removed = true;
+ }
+ }
+ return removed;
+ }
+}
+
+final class HEquation {
+ @NotNull final HKey key;
+ @NotNull final HResult result;
+
+ HEquation(@NotNull HKey key, @NotNull HResult result) {
+ this.key = key;
+ this.result = result;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ HEquation hEquation = (HEquation)o;
+ if (!key.equals(hEquation.key)) return false;
+ if (!result.equals(hEquation.result)) return false;
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result1 = key.hashCode();
+ result1 = 31 * result1 + result.hashCode();
+ return result1;
+ }
+}
+class Bytes {
+ @NotNull
+ final byte[] bytes;
+ Bytes(@NotNull byte[] bytes) {
+ this.bytes = bytes;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Bytes bytes1 = (Bytes)o;
+
+ if (!Arrays.equals(bytes, bytes1.bytes)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return Arrays.hashCode(bytes);
+ }
+}
+
+class HEquations {
+ @NotNull final List<DirectionResultPair> results;
+ final boolean stable;
+
+ HEquations(@NotNull List<DirectionResultPair> results, boolean stable) {
+ this.results = results;
+ this.stable = stable;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ HEquations that = (HEquations)o;
+
+ if (stable != that.stable) return false;
+ if (!results.equals(that.results)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = results.hashCode();
+ result = 31 * result + (stable ? 1 : 0);
+ return result;
+ }
+}
+
+class DirectionResultPair {
+ final int directionKey;
+ @NotNull
+ final HResult hResult;
+
+ DirectionResultPair(int directionKey, @NotNull HResult hResult) {
+ this.directionKey = directionKey;
+ this.hResult = hResult;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ DirectionResultPair that = (DirectionResultPair)o;
+
+ if (directionKey != that.directionKey) return false;
+ if (!hResult.equals(that.hResult)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = directionKey;
+ result = 31 * result + hResult.hashCode();
+ return result;
+ }
+}
+
+interface HResult {}
+final class HFinal implements HResult {
+ @NotNull final Value value;
+
+ HFinal(@NotNull Value value) {
+ this.value = value;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ HFinal hFinal = (HFinal)o;
+
+ if (value != hFinal.value) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return value.ordinal();
+ }
+}
+
+final class HPending implements HResult {
+ @NotNull final HComponent[] delta;
+
+ HPending(@NotNull HComponent[] delta) {
+ this.delta = delta;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ HPending hPending = (HPending)o;
+ if (!Arrays.equals(delta, hPending.delta)) return false;
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return Arrays.hashCode(delta);
+ }
+
+ @NotNull
+ HPending copy() {
+ HComponent[] delta1 = new HComponent[delta.length];
+ for (int i = 0; i < delta.length; i++) {
+ delta1[i] = delta[i].copy();
+
+ }
+ return new HPending(delta1);
+ }
+} \ No newline at end of file
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Parameters.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Parameters.java
index 625eb8eed977..a7c25782d48b 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Parameters.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Parameters.java
@@ -15,6 +15,10 @@
*/
package com.intellij.codeInspection.bytecodeAnalysis;
+import com.intellij.codeInspection.bytecodeAnalysis.asm.ASMUtils;
+import com.intellij.codeInspection.bytecodeAnalysis.asm.ControlFlowGraph.Edge;
+import com.intellij.codeInspection.bytecodeAnalysis.asm.RichControlFlow;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode;
import org.jetbrains.org.objectweb.asm.tree.JumpInsnNode;
@@ -25,7 +29,9 @@ import org.jetbrains.org.objectweb.asm.tree.analysis.BasicInterpreter;
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue;
import org.jetbrains.org.objectweb.asm.tree.analysis.Frame;
-import java.util.*;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
import static com.intellij.codeInspection.bytecodeAnalysis.AbstractValues.InstanceOfCheckValue;
import static com.intellij.codeInspection.bytecodeAnalysis.AbstractValues.ParamValue;
@@ -101,6 +107,18 @@ abstract class PResults {
}
}
+ static PResult combineNullable(PResult r1, PResult r2) throws AnalyzerException {
+ if (Identity == r1) return r2;
+ if (Identity == r2) return r1;
+ if (Return == r1) return r2;
+ if (Return == r2) return r1;
+ if (NPE == r1) return NPE;
+ if (NPE == r2) return NPE;
+ ConditionalNPE cnpe1 = (ConditionalNPE) r1;
+ ConditionalNPE cnpe2 = (ConditionalNPE) r2;
+ return new ConditionalNPE(join(cnpe1.sop, cnpe2.sop));
+ }
+
static PResult join(PResult r1, PResult r2) throws AnalyzerException {
if (Identity == r1) return r2;
if (Identity == r2) return r1;
@@ -127,34 +145,62 @@ abstract class PResults {
}
+interface PendingAction {}
+class ProceedState implements PendingAction {
+ final State state;
+
+ ProceedState(State state) {
+ this.state = state;
+ }
+}
+class MakeResult implements PendingAction {
+ final State state;
+ final PResult subResult;
+ final int[] indices;
+
+ MakeResult(State state, PResult subResult, int[] indices) {
+ this.state = state;
+ this.subResult = subResult;
+ this.indices = indices;
+ }
+}
+
class NonNullInAnalysis extends Analysis<PResult> {
+ private static final ThreadLocal<PendingAction[]> ourPending = new ThreadLocal<PendingAction[]>() {
+ @Override
+ protected PendingAction[] initialValue() {
+ return new PendingAction[Analysis.STEPS_LIMIT];
+ }
+ };
+ private static final ThreadLocal<PResult[]> ourResults = new ThreadLocal<PResult[]>() {
+ @Override
+ protected PResult[] initialValue() {
+ return new PResult[Analysis.STEPS_LIMIT];
+ }
+ };
+
+ final private PendingAction[] pending = ourPending.get();
- private final NonNullInInterpreter interpreter = new NonNullInInterpreter();
+ private final NotNullInterpreter interpreter = new NotNullInterpreter();
+ private PResult[] results;
+
+ // Flag saying that at some branch NPE was found. Used later as an evidence that this param is *NOT* @Nullable (optimization).
+ boolean possibleNPE;
protected NonNullInAnalysis(RichControlFlow richControlFlow, Direction direction, boolean stable) {
super(richControlFlow, direction, stable);
+ results = ourResults.get();
}
- @Override
- PResult identity() {
- return Identity;
- }
-
- @Override
- PResult combineResults(PResult delta, List<PResult> subResults) throws AnalyzerException {
- PResult subResult = Identity;
- for (PResult sr : subResults) {
- subResult = join(subResult, sr);
+ PResult combineResults(PResult delta, int[] subResults) throws AnalyzerException {
+ PResult result = Identity;
+ for (int subResult : subResults) {
+ result = join(result, results[subResult]);
}
- return meet(delta, subResult);
+ return meet(delta, result);
}
- @Override
- boolean isEarlyResult(PResult result) {
- return false;
- }
-
- @Override
+ @NotNull
Equation<Key, Value> mkEquation(PResult result) {
if (Identity == result || Return == result) {
return new Equation<Key, Value>(aKey, new Final<Key, Value>(Value.Top));
@@ -176,8 +222,73 @@ class NonNullInAnalysis extends Analysis<PResult> {
private Frame<BasicValue> nextFrame = null;
private PResult subResult = null;
- @Override
- void processState(State state) throws AnalyzerException {
+ @NotNull
+ protected Equation<Key, Value> analyze() throws AnalyzerException {
+ pendingPush(new ProceedState(createStartState()));
+ int steps = 0;
+ while (pendingTop > 0 && earlyResult == null) {
+ steps ++;
+ if (steps >= STEPS_LIMIT) {
+ throw new AnalyzerException(null, "limit is reached, steps: " + steps + " in method " + method);
+ }
+ PendingAction action = pending[--pendingTop];
+ if (action instanceof MakeResult) {
+ MakeResult makeResult = (MakeResult) action;
+ PResult result = combineResults(makeResult.subResult, makeResult.indices);
+ State state = makeResult.state;
+ int insnIndex = state.conf.insnIndex;
+ results[state.index] = result;
+ addComputed(insnIndex, state);
+ }
+ else if (action instanceof ProceedState) {
+ ProceedState proceedState = (ProceedState) action;
+ State state = proceedState.state;
+ int insnIndex = state.conf.insnIndex;
+ Conf conf = state.conf;
+ List<Conf> history = state.history;
+
+ boolean fold = false;
+ if (dfsTree.loopEnters[insnIndex]) {
+ for (Conf prev : history) {
+ if (AbstractValues.isInstance(conf, prev)) {
+ fold = true;
+ break;
+ }
+ }
+ }
+ if (fold) {
+ results[state.index] = Identity;
+ addComputed(insnIndex, state);
+ }
+ else {
+ State baseState = null;
+ List<State> thisComputed = computed[insnIndex];
+ if (thisComputed != null) {
+ for (State prevState : thisComputed) {
+ if (stateEquiv(state, prevState)) {
+ baseState = prevState;
+ break;
+ }
+ }
+ }
+ if (baseState != null) {
+ results[state.index] = results[baseState.index];
+ } else {
+ // the main call
+ processState(state);
+ }
+
+ }
+ }
+ }
+ if (earlyResult != null) {
+ return mkEquation(earlyResult);
+ } else {
+ return mkEquation(results[0]);
+ }
+ }
+
+ private void processState(State state) throws AnalyzerException {
int stateIndex = state.index;
Conf conf = state.conf;
int insnIndex = conf.insnIndex;
@@ -185,15 +296,16 @@ class NonNullInAnalysis extends Analysis<PResult> {
boolean taken = state.taken;
Frame<BasicValue> frame = conf.frame;
AbstractInsnNode insnNode = methodNode.instructions.get(insnIndex);
- List<Conf> nextHistory = dfsTree.loopEnters.contains(insnIndex) ? append(history, conf) : history;
+ List<Conf> nextHistory = dfsTree.loopEnters[insnIndex] ? append(history, conf) : history;
boolean hasCompanions = state.hasCompanions;
execute(frame, insnNode);
boolean notEmptySubResult = subResult != Identity;
if (subResult == NPE) {
- results.put(stateIndex, NPE);
- computed.put(insnIndex, append(computed.get(insnIndex), state));
+ results[stateIndex] = NPE;
+ possibleNPE = true;
+ addComputed(insnIndex, state);
return;
}
@@ -208,8 +320,8 @@ class NonNullInAnalysis extends Analysis<PResult> {
if (!hasCompanions) {
earlyResult = Return;
} else {
- results.put(stateIndex, Return);
- computed.put(insnIndex, append(computed.get(insnIndex), state));
+ results[stateIndex] = Return;
+ addComputed(insnIndex, state);
}
return;
default:
@@ -217,70 +329,265 @@ class NonNullInAnalysis extends Analysis<PResult> {
if (opcode == ATHROW) {
if (taken) {
- results.put(stateIndex, NPE);
+ results[stateIndex] = NPE;
+ possibleNPE = true;
} else {
- results.put(stateIndex, Identity);
+ results[stateIndex] = Identity;
}
- computed.put(insnIndex, append(computed.get(insnIndex), state));
+ addComputed(insnIndex, state);
return;
}
if (opcode == IFNONNULL && popValue(frame) instanceof ParamValue) {
int nextInsnIndex = insnIndex + 1;
State nextState = new State(++id, new Conf(nextInsnIndex, nextFrame), nextHistory, true, hasCompanions || notEmptySubResult);
- pending.push(new MakeResult<PResult>(state, subResult, new int[]{nextState.index}));
- pending.push(new ProceedState<PResult>(nextState));
+ pendingPush(new MakeResult(state, subResult, new int[]{nextState.index}));
+ pendingPush(new ProceedState(nextState));
return;
}
if (opcode == IFNULL && popValue(frame) instanceof ParamValue) {
int nextInsnIndex = methodNode.instructions.indexOf(((JumpInsnNode)insnNode).label);
State nextState = new State(++id, new Conf(nextInsnIndex, nextFrame), nextHistory, true, hasCompanions || notEmptySubResult);
- pending.push(new MakeResult<PResult>(state, subResult, new int[]{nextState.index}));
- pending.push(new ProceedState<PResult>(nextState));
+ pendingPush(new MakeResult(state, subResult, new int[]{nextState.index}));
+ pendingPush(new ProceedState(nextState));
return;
}
if (opcode == IFEQ && popValue(frame) == InstanceOfCheckValue) {
int nextInsnIndex = methodNode.instructions.indexOf(((JumpInsnNode)insnNode).label);
State nextState = new State(++id, new Conf(nextInsnIndex, nextFrame), nextHistory, true, hasCompanions || notEmptySubResult);
- pending.push(new MakeResult<PResult>(state, subResult, new int[]{nextState.index}));
- pending.push(new ProceedState<PResult>(nextState));
+ pendingPush(new MakeResult(state, subResult, new int[]{nextState.index}));
+ pendingPush(new ProceedState(nextState));
return;
}
if (opcode == IFNE && popValue(frame) == InstanceOfCheckValue) {
int nextInsnIndex = insnIndex + 1;
State nextState = new State(++id, new Conf(nextInsnIndex, nextFrame), nextHistory, true, hasCompanions || notEmptySubResult);
- pending.push(new MakeResult<PResult>(state, subResult, new int[]{nextState.index}));
- pending.push(new ProceedState<PResult>(nextState));
+ pendingPush(new MakeResult(state, subResult, new int[]{nextState.index}));
+ pendingPush(new ProceedState(nextState));
return;
}
// general case
int[] nextInsnIndices = controlFlow.transitions[insnIndex];
- List<State> nextStates = new ArrayList<State>(nextInsnIndices.length);
int[] subIndices = new int[nextInsnIndices.length];
-
+ for (int i = 0; i < nextInsnIndices.length; i++) {
+ subIndices[i] = ++id;
+ }
+ pendingPush(new MakeResult(state, subResult, subIndices));
for (int i = 0; i < nextInsnIndices.length; i++) {
int nextInsnIndex = nextInsnIndices[i];
Frame<BasicValue> nextFrame1 = nextFrame;
- if (controlFlow.errorTransitions.contains(new Edge(insnIndex, nextInsnIndex))) {
+ if (controlFlow.errors[nextInsnIndex] && controlFlow.errorTransitions.contains(new Edge(insnIndex, nextInsnIndex))) {
nextFrame1 = new Frame<BasicValue>(frame);
nextFrame1.clearStack();
- nextFrame1.push(new BasicValue(Type.getType("java/lang/Throwable")));
+ nextFrame1.push(ASMUtils.THROWABLE_VALUE);
+ }
+ pendingPush(new ProceedState(new State(subIndices[i], new Conf(nextInsnIndex, nextFrame1), nextHistory, taken, hasCompanions || notEmptySubResult)));
+ }
+
+ }
+
+ private int pendingTop = 0;
+
+ private void pendingPush(PendingAction action) throws AnalyzerException {
+ if (pendingTop >= STEPS_LIMIT) {
+ throw new AnalyzerException(null, "limit is reached in method " + method);
+ }
+ pending[pendingTop++] = action;
+ }
+
+ private void execute(Frame<BasicValue> frame, AbstractInsnNode insnNode) throws AnalyzerException {
+ switch (insnNode.getType()) {
+ case AbstractInsnNode.LABEL:
+ case AbstractInsnNode.LINE:
+ case AbstractInsnNode.FRAME:
+ nextFrame = frame;
+ subResult = Identity;
+ break;
+ default:
+ nextFrame = new Frame<BasicValue>(frame);
+ interpreter.reset();
+ nextFrame.execute(insnNode, interpreter);
+ subResult = interpreter.getSubResult();
+ }
+ }
+}
+
+class NullableInAnalysis extends Analysis<PResult> {
+ final private State[] pending = ourPendingStates.get();
+
+ private final NullableInterpreter interpreter = new NullableInterpreter();
+
+ protected NullableInAnalysis(RichControlFlow richControlFlow, Direction direction, boolean stable) {
+ super(richControlFlow, direction, stable);
+ }
+
+ @NotNull
+ Equation<Key, Value> mkEquation(PResult result) {
+ if (NPE == result) {
+ return new Equation<Key, Value>(aKey, new Final<Key, Value>(Value.Top));
+ }
+ if (Identity == result || Return == result) {
+ return new Equation<Key, Value>(aKey, new Final<Key, Value>(Value.Null));
+ }
+ else {
+ ConditionalNPE condNpe = (ConditionalNPE) result;
+ Set<Product<Key, Value>> components = new HashSet<Product<Key, Value>>();
+ for (Set<Key> prod : condNpe.sop) {
+ components.add(new Product<Key, Value>(Value.Top, prod));
+ }
+ return new Equation<Key, Value>(aKey, new Pending<Key, Value>(components));
+ }
+ }
+
+ private int id = 0;
+ private Frame<BasicValue> nextFrame = null;
+ private PResult myResult = Identity;
+ private PResult subResult = Identity;
+ private boolean top = false;
+
+ @NotNull
+ protected Equation<Key, Value> analyze() throws AnalyzerException {
+ pendingPush(createStartState());
+ int steps = 0;
+ while (pendingTop > 0 && earlyResult == null) {
+ steps ++;
+ if (steps >= STEPS_LIMIT) {
+ throw new AnalyzerException(null, "limit is reached, steps: " + steps + " in method " + method);
+ }
+ State state = pending[--pendingTop];
+ int insnIndex = state.conf.insnIndex;
+ Conf conf = state.conf;
+ List<Conf> history = state.history;
+
+ boolean fold = false;
+ if (dfsTree.loopEnters[insnIndex]) {
+ for (Conf prev : history) {
+ if (AbstractValues.isInstance(conf, prev)) {
+ fold = true;
+ break;
+ }
+ }
+ }
+ if (fold) {
+ addComputed(insnIndex, state);
+ }
+ else {
+ State baseState = null;
+ List<State> thisComputed = computed[insnIndex];
+ if (thisComputed != null) {
+ for (State prevState : thisComputed) {
+ if (stateEquiv(state, prevState)) {
+ baseState = prevState;
+ break;
+ }
+ }
+ }
+ if (baseState == null) {
+ processState(state);
+ }
}
- nextStates.add(new State(++id, new Conf(nextInsnIndex, nextFrame1), nextHistory, taken, hasCompanions || notEmptySubResult));
- subIndices[i] = (id);
+ }
+ if (earlyResult != null) {
+ return mkEquation(earlyResult);
+ } else {
+ return mkEquation(myResult);
+ }
+ }
+
+ private void processState(State state) throws AnalyzerException {
+ Conf conf = state.conf;
+ int insnIndex = conf.insnIndex;
+ List<Conf> history = state.history;
+ boolean taken = state.taken;
+ Frame<BasicValue> frame = conf.frame;
+ AbstractInsnNode insnNode = methodNode.instructions.get(insnIndex);
+ List<Conf> nextHistory = dfsTree.loopEnters[insnIndex] ? append(history, conf) : history;
+
+ addComputed(insnIndex, state);
+ execute(frame, insnNode);
+
+ if (subResult == NPE || top) {
+ earlyResult = NPE;
+ return;
+ }
+
+ if (subResult instanceof ConditionalNPE) {
+ myResult = combineNullable(myResult, subResult);
+ }
+
+ int opcode = insnNode.getOpcode();
+ switch (opcode) {
+ case ARETURN:
+ if (popValue(frame) instanceof ParamValue) {
+ earlyResult = NPE;
+ }
+ return;
+ case IRETURN:
+ case LRETURN:
+ case FRETURN:
+ case DRETURN:
+ case RETURN:
+ return;
+ default:
+ }
+
+ if (opcode == ATHROW) {
+ if (taken) {
+ earlyResult = NPE;
+ }
+ return;
+ }
+
+ if (opcode == IFNONNULL && popValue(frame) instanceof ParamValue) {
+ int nextInsnIndex = insnIndex + 1;
+ pendingPush(new State(++id, new Conf(nextInsnIndex, nextFrame), nextHistory, true, false));
+ return;
+ }
+
+ if (opcode == IFNULL && popValue(frame) instanceof ParamValue) {
+ int nextInsnIndex = methodNode.instructions.indexOf(((JumpInsnNode)insnNode).label);
+ pendingPush(new State(++id, new Conf(nextInsnIndex, nextFrame), nextHistory, true, false));
+ return;
+ }
+
+ if (opcode == IFEQ && popValue(frame) == InstanceOfCheckValue) {
+ int nextInsnIndex = methodNode.instructions.indexOf(((JumpInsnNode)insnNode).label);
+ pendingPush(new State(++id, new Conf(nextInsnIndex, nextFrame), nextHistory, true, false));
+ return;
}
- pending.push(new MakeResult<PResult>(state, subResult, subIndices));
- for (State nextState : nextStates) {
- pending.push(new ProceedState<PResult>(nextState));
+ if (opcode == IFNE && popValue(frame) == InstanceOfCheckValue) {
+ int nextInsnIndex = insnIndex + 1;
+ pendingPush(new State(++id, new Conf(nextInsnIndex, nextFrame), nextHistory, true, false));
+ return;
+ }
+
+ // general case
+ for (int nextInsnIndex : controlFlow.transitions[insnIndex]) {
+ Frame<BasicValue> nextFrame1 = nextFrame;
+ if (controlFlow.errors[nextInsnIndex] && controlFlow.errorTransitions.contains(new Edge(insnIndex, nextInsnIndex))) {
+ nextFrame1 = new Frame<BasicValue>(frame);
+ nextFrame1.clearStack();
+ nextFrame1.push(ASMUtils.THROWABLE_VALUE);
+ }
+ pendingPush(new State(++id, new Conf(nextInsnIndex, nextFrame1), nextHistory, taken, false));
}
}
+ private int pendingTop = 0;
+
+ private void pendingPush(State state) throws AnalyzerException {
+ if (pendingTop >= STEPS_LIMIT) {
+ throw new AnalyzerException(null, "limit is reached in method " + method);
+ }
+ pending[pendingTop++] = state;
+ }
+
private void execute(Frame<BasicValue> frame, AbstractInsnNode insnNode) throws AnalyzerException {
switch (insnNode.getType()) {
case AbstractInsnNode.LABEL:
@@ -288,23 +595,37 @@ class NonNullInAnalysis extends Analysis<PResult> {
case AbstractInsnNode.FRAME:
nextFrame = frame;
subResult = Identity;
+ top = false;
break;
default:
nextFrame = new Frame<BasicValue>(frame);
interpreter.reset();
nextFrame.execute(insnNode, interpreter);
subResult = interpreter.getSubResult();
+ top = interpreter.top;
}
}
}
-class NonNullInInterpreter extends BasicInterpreter {
+abstract class NullityInterpreter extends BasicInterpreter {
+ boolean top = false;
+ final boolean nullableAnalysis;
+ final int nullityMask;
private PResult subResult = Identity;
+
+ NullityInterpreter(boolean nullableAnalysis, int nullityMask) {
+ this.nullableAnalysis = nullableAnalysis;
+ this.nullityMask = nullityMask;
+ }
+
+ abstract PResult combine(PResult res1, PResult res2) throws AnalyzerException;
+
public PResult getSubResult() {
return subResult;
}
void reset() {
subResult = Identity;
+ top = false;
}
@Override
@@ -344,10 +665,17 @@ class NonNullInInterpreter extends BasicInterpreter {
case BALOAD:
case CALOAD:
case SALOAD:
+ if (value1 instanceof ParamValue) {
+ subResult = NPE;
+ }
+ break;
case PUTFIELD:
if (value1 instanceof ParamValue) {
subResult = NPE;
}
+ if (nullableAnalysis && value2 instanceof ParamValue) {
+ subResult = NPE;
+ }
break;
default:
}
@@ -361,13 +689,21 @@ class NonNullInInterpreter extends BasicInterpreter {
case LASTORE:
case FASTORE:
case DASTORE:
- case AASTORE:
case BASTORE:
case CASTORE:
case SASTORE:
if (value1 instanceof ParamValue) {
subResult = NPE;
}
+ break;
+ case AASTORE:
+ if (value1 instanceof ParamValue) {
+ subResult = NPE;
+ }
+ if (nullableAnalysis && value3 instanceof ParamValue) {
+ subResult = NPE;
+ }
+ break;
default:
}
return super.ternaryOperation(insn, value1, value2, value3);
@@ -382,20 +718,54 @@ class NonNullInInterpreter extends BasicInterpreter {
subResult = NPE;
}
switch (opcode) {
+ case INVOKEINTERFACE:
+ if (nullableAnalysis) {
+ for (int i = shift; i < values.size(); i++) {
+ if (values.get(i) instanceof ParamValue) {
+ top = true;
+ return super.naryOperation(insn, values);
+ }
+ }
+ }
+ break;
case INVOKESTATIC:
case INVOKESPECIAL:
case INVOKEVIRTUAL:
- case INVOKEINTERFACE:
boolean stable = opcode == INVOKESTATIC || opcode == INVOKESPECIAL;
MethodInsnNode methodNode = (MethodInsnNode) insn;
+ Method method = new Method(methodNode.owner, methodNode.name, methodNode.desc);
for (int i = shift; i < values.size(); i++) {
if (values.get(i) instanceof ParamValue) {
- Method method = new Method(methodNode.owner, methodNode.name, methodNode.desc);
- subResult = meet(subResult, new ConditionalNPE(new Key(method, new In(i - shift), stable)));
+ subResult = combine(subResult, new ConditionalNPE(new Key(method, new In(i - shift, nullityMask), stable)));
}
}
+ break;
default:
}
return super.naryOperation(insn, values);
}
}
+
+class NotNullInterpreter extends NullityInterpreter {
+
+ NotNullInterpreter() {
+ super(false, In.NOT_NULL);
+ }
+
+ @Override
+ PResult combine(PResult res1, PResult res2) throws AnalyzerException {
+ return meet(res1, res2);
+ }
+}
+
+class NullableInterpreter extends NullityInterpreter {
+
+ NullableInterpreter() {
+ super(true, In.NULLABLE);
+ }
+
+ @Override
+ PResult combine(PResult res1, PResult res2) throws AnalyzerException {
+ return join(res1, res2);
+ }
+}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/ProjectBytecodeAnalysis.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/ProjectBytecodeAnalysis.java
index 23d9d5a9e1c5..aa44951961ad 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/ProjectBytecodeAnalysis.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/ProjectBytecodeAnalysis.java
@@ -30,16 +30,14 @@ import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.PsiFormatUtil;
import com.intellij.util.IncorrectOperationException;
-import com.intellij.util.containers.LongStack;
+import com.intellij.util.containers.Stack;
import com.intellij.util.indexing.FileBasedIndex;
-import gnu.trove.TLongArrayList;
-import gnu.trove.TLongHashSet;
-import gnu.trove.TLongObjectHashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.io.IOException;
-import java.util.List;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.*;
/**
* @author lambdamix
@@ -63,7 +61,7 @@ public class ProjectBytecodeAnalysis {
if (!(listOwner instanceof PsiCompiledElement)) {
return null;
}
- if (annotationFQN.equals(AnnotationUtil.NOT_NULL) || annotationFQN.equals(ControlFlowAnalyzer.ORG_JETBRAINS_ANNOTATIONS_CONTRACT)) {
+ if (annotationFQN.equals(AnnotationUtil.NOT_NULL) || annotationFQN.equals(AnnotationUtil.NULLABLE) || annotationFQN.equals(ControlFlowAnalyzer.ORG_JETBRAINS_ANNOTATIONS_CONTRACT)) {
PsiAnnotation[] annotations = findInferredAnnotations(listOwner);
for (PsiAnnotation annotation : annotations) {
if (annotationFQN.equals(annotation.getQualifiedName())) {
@@ -94,37 +92,45 @@ public class ProjectBytecodeAnalysis {
@NotNull
private PsiAnnotation[] collectInferredAnnotations(PsiModifierListOwner listOwner) {
try {
- long ownerKey = getKey(listOwner);
- if (ownerKey == -1) {
+ MessageDigest md = BytecodeAnalysisConverter.getMessageDigest();
+ HKey primaryKey = getKey(listOwner, md);
+ if (primaryKey == null) {
return PsiAnnotation.EMPTY_ARRAY;
}
- TLongArrayList allKeys = contractKeys(listOwner, ownerKey);
- Annotations annotations = loadAnnotations(listOwner, ownerKey, allKeys);
- boolean notNull = annotations.notNulls.contains(ownerKey);
- String contractValue = annotations.contracts.get(ownerKey);
-
- if (notNull && contractValue != null) {
- return new PsiAnnotation[]{
- getNotNullAnnotation(),
- createAnnotationFromText("@" + ControlFlowAnalyzer.ORG_JETBRAINS_ANNOTATIONS_CONTRACT + "(" + contractValue + ")")
- };
- }
- else if (notNull) {
- return new PsiAnnotation[]{
- getNotNullAnnotation()
- };
- }
- else if (contractValue != null) {
- return new PsiAnnotation[]{
- createAnnotationFromText("@" + ControlFlowAnalyzer.ORG_JETBRAINS_ANNOTATIONS_CONTRACT + "(" + contractValue + ")")
- };
- }
- else {
- return PsiAnnotation.EMPTY_ARRAY;
+ if (listOwner instanceof PsiMethod) {
+ ArrayList<HKey> allKeys = contractKeys((PsiMethod)listOwner, primaryKey);
+ MethodAnnotations methodAnnotations = loadMethodAnnotations((PsiMethod)listOwner, primaryKey, allKeys);
+ boolean notNull = methodAnnotations.notNulls.contains(primaryKey);
+ String contractValue = methodAnnotations.contracts.get(primaryKey);
+ if (notNull && contractValue != null) {
+ return new PsiAnnotation[]{
+ getNotNullAnnotation(),
+ createAnnotationFromText("@" + ControlFlowAnalyzer.ORG_JETBRAINS_ANNOTATIONS_CONTRACT + "(" + contractValue + ")")
+ };
+ }
+ else if (notNull) {
+ return new PsiAnnotation[]{
+ getNotNullAnnotation()
+ };
+ }
+ else if (contractValue != null) {
+ return new PsiAnnotation[]{
+ createAnnotationFromText("@" + ControlFlowAnalyzer.ORG_JETBRAINS_ANNOTATIONS_CONTRACT + "(" + contractValue + ")")
+ };
+ }
+ } else if (listOwner instanceof PsiParameter) {
+ ParameterAnnotations parameterAnnotations = loadParameterAnnotations(primaryKey);
+ if (parameterAnnotations.notNull) {
+ return new PsiAnnotation[]{
+ getNotNullAnnotation()
+ };
+ }
+ else if (parameterAnnotations.nullable) {
+ return new PsiAnnotation[]{
+ getNullableAnnotation()
+ };
+ }
}
- }
- catch (IOException e) {
- LOG.debug(e);
return PsiAnnotation.EMPTY_ARRAY;
}
catch (EquationsLimitException e) {
@@ -132,6 +138,10 @@ public class ProjectBytecodeAnalysis {
LOG.info("Too many equations for " + externalName);
return PsiAnnotation.EMPTY_ARRAY;
}
+ catch (NoSuchAlgorithmException e) {
+ LOG.error(e);
+ return PsiAnnotation.EMPTY_ARRAY;
+ }
}
private PsiAnnotation getNotNullAnnotation() {
@@ -144,14 +154,25 @@ public class ProjectBytecodeAnalysis {
});
}
+ private PsiAnnotation getNullableAnnotation() {
+ return CachedValuesManager.getManager(myProject).getCachedValue(myProject, new CachedValueProvider<PsiAnnotation>() {
+ @Nullable
+ @Override
+ public Result<PsiAnnotation> compute() {
+ return Result.create(createAnnotationFromText("@" + AnnotationUtil.NULLABLE), ModificationTracker.NEVER_CHANGED);
+ }
+ });
+ }
+
public PsiAnnotation createContractAnnotation(String contractValue) {
return createAnnotationFromText("@org.jetbrains.annotations.Contract(" + contractValue + ")");
}
- public static long getKey(@NotNull PsiModifierListOwner owner) throws IOException {
+ @Nullable
+ public static HKey getKey(@NotNull PsiModifierListOwner owner, MessageDigest md) {
LOG.assertTrue(owner instanceof PsiCompiledElement, owner);
if (owner instanceof PsiMethod) {
- return BytecodeAnalysisConverter.getInstance().mkPsiKey((PsiMethod)owner, new Out());
+ return BytecodeAnalysisConverter.psiKey((PsiMethod)owner, new Out(), md);
}
if (owner instanceof PsiParameter) {
PsiElement parent = owner.getParent();
@@ -159,80 +180,93 @@ public class ProjectBytecodeAnalysis {
PsiElement gParent = parent.getParent();
if (gParent instanceof PsiMethod) {
final int index = ((PsiParameterList)parent).getParameterIndex((PsiParameter)owner);
- return BytecodeAnalysisConverter.getInstance().mkPsiKey((PsiMethod)gParent, new In(index));
+ return BytecodeAnalysisConverter.psiKey((PsiMethod)gParent, new In(index, In.NOT_NULL), md);
}
}
}
-
- return -1;
+ return null;
}
- public static TLongArrayList contractKeys(@NotNull PsiModifierListOwner owner, long primaryKey) throws IOException {
- if (owner instanceof PsiMethod) {
- TLongArrayList result = BytecodeAnalysisConverter.getInstance().mkInOutKeys((PsiMethod)owner, primaryKey);
- result.add(primaryKey);
- return result;
- }
- TLongArrayList result = new TLongArrayList(1);
+ public static ArrayList<HKey> contractKeys(@NotNull PsiMethod owner, HKey primaryKey) {
+ ArrayList<HKey> result = BytecodeAnalysisConverter.mkInOutKeys(owner, primaryKey);
result.add(primaryKey);
return result;
}
- private Annotations loadAnnotations(@NotNull PsiModifierListOwner owner, long key, TLongArrayList allKeys)
- throws IOException, EquationsLimitException {
- Annotations result = new Annotations();
- if (owner instanceof PsiParameter) {
- final Solver solver = new Solver(new ELattice<Value>(Value.NotNull, Value.Top));
- collectEquations(allKeys, solver);
- TLongObjectHashMap<Value> solutions = solver.solve();
- BytecodeAnalysisConverter.getInstance().addParameterAnnotations(solutions, result);
- } else if (owner instanceof PsiMethod) {
- final Solver solver = new Solver(new ELattice<Value>(Value.Bot, Value.Top));
- collectEquations(allKeys, solver);
- TLongObjectHashMap<Value> solutions = solver.solve();
- BytecodeAnalysisConverter.getInstance().addMethodAnnotations(solutions, result, key,
- ((PsiMethod)owner).getParameterList().getParameters().length);
- }
+ private ParameterAnnotations loadParameterAnnotations(@NotNull HKey notNullKey)
+ throws EquationsLimitException {
+
+ final Solver notNullSolver = new Solver(new ELattice<Value>(Value.NotNull, Value.Top));
+ collectEquations(Collections.singletonList(notNullKey), notNullSolver);
+
+ HashMap<HKey, Value> notNullSolutions = notNullSolver.solve();
+ boolean notNull =
+ (Value.NotNull == notNullSolutions.get(notNullKey)) || (Value.NotNull == notNullSolutions.get(notNullKey.mkUnstable()));
+
+ final Solver nullableSolver = new Solver(new ELattice<Value>(Value.Null, Value.Top));
+ final HKey nullableKey = new HKey(notNullKey.key, notNullKey.dirKey + 1, true);
+ collectEquations(Collections.singletonList(nullableKey), nullableSolver);
+ HashMap<HKey, Value> nullableSolutions = nullableSolver.solve();
+ boolean nullable =
+ (Value.Null == nullableSolutions.get(nullableKey)) || (Value.Null == nullableSolutions.get(nullableKey.mkUnstable()));
+ return new ParameterAnnotations(notNull, nullable);
+ }
+
+ private MethodAnnotations loadMethodAnnotations(@NotNull PsiMethod owner, @NotNull HKey key, ArrayList<HKey> allKeys)
+ throws EquationsLimitException {
+ MethodAnnotations result = new MethodAnnotations();
+ final Solver solver = new Solver(new ELattice<Value>(Value.Bot, Value.Top));
+ collectEquations(allKeys, solver);
+ HashMap<HKey, Value> solutions = solver.solve();
+ int arity = owner.getParameterList().getParameters().length;
+ BytecodeAnalysisConverter.addMethodAnnotations(solutions, result, key, arity);
return result;
}
- private void collectEquations(TLongArrayList keys, Solver solver) throws EquationsLimitException {
+ private void collectEquations(List<HKey> keys, Solver solver) throws EquationsLimitException {
GlobalSearchScope librariesScope = ProjectScope.getLibrariesScope(myProject);
- TLongHashSet queued = new TLongHashSet();
- LongStack queue = new LongStack();
+ HashSet<HKey> queued = new HashSet<HKey>();
+ Stack<HKey> queue = new Stack<HKey>();
- for (int i = 0; i < keys.size(); i++) {
- long key = keys.get(i);
+ for (HKey key : keys) {
queue.push(key);
queued.add(key);
- // stable/unstable
- queue.push(-key);
- queued.add(-key);
}
+ HashMap<Bytes, List<HEquations>> cache = new HashMap<Bytes, List<HEquations>>();
FileBasedIndex index = FileBasedIndex.getInstance();
+
while (!queue.empty()) {
if (queued.size() > EQUATIONS_LIMIT) {
throw new EquationsLimitException();
}
ProgressManager.checkCanceled();
- List<IdEquation> equations = index.getValues(BytecodeAnalysisIndex.NAME, queue.pop(), librariesScope);
- for (IdEquation equation : equations) {
- IdResult rhs = equation.rhs;
- solver.addEquation(equation);
- if (rhs instanceof IdPending) {
- IdPending intIdPending = (IdPending)rhs;
- for (IntIdComponent component : intIdPending.delta) {
- for (long depKey : component.ids) {
- if (!queued.contains(depKey)) {
- queue.push(depKey);
- queued.add(depKey);
- }
- // stable/unstable
- long swapped = -depKey;
- if (!queued.contains(swapped)) {
- queue.push(swapped);
- queued.add(swapped);
+ HKey hKey = queue.pop();
+ Bytes bytes = new Bytes(hKey.key);
+
+ List<HEquations> hEquationss = cache.get(bytes);
+ if (hEquationss == null) {
+ hEquationss = index.getValues(BytecodeAnalysisIndex.NAME, bytes, librariesScope);
+ cache.put(bytes, hEquationss);
+ }
+
+ for (HEquations hEquations : hEquationss) {
+ boolean stable = hEquations.stable;
+ for (DirectionResultPair pair : hEquations.results) {
+ int dirKey = pair.directionKey;
+ if (dirKey == hKey.dirKey) {
+ HResult result = pair.hResult;
+
+ solver.addEquation(new HEquation(new HKey(bytes.bytes, dirKey, stable), result));
+ if (result instanceof HPending) {
+ HPending pending = (HPending)result;
+ for (HComponent component : pending.delta) {
+ for (HKey depKey : component.ids) {
+ if (!queued.contains(depKey)) {
+ queue.push(depKey);
+ queued.add(depKey);
+ }
+ }
}
}
}
@@ -249,11 +283,21 @@ public class ProjectBytecodeAnalysis {
}
}
-class Annotations {
+class MethodAnnotations {
// @NotNull keys
- final TLongHashSet notNulls = new TLongHashSet();
+ final HashSet<HKey> notNulls = new HashSet<HKey>();
// @Contracts
- final TLongObjectHashMap<String> contracts = new TLongObjectHashMap<String>();
+ final HashMap<HKey, String> contracts = new HashMap<HKey, String>();
+}
+
+class ParameterAnnotations {
+ final boolean notNull;
+ final boolean nullable;
+
+ ParameterAnnotations(boolean notNull, boolean nullable) {
+ this.notNull = notNull;
+ this.nullable = nullable;
+ }
}
class EquationsLimitException extends Exception {}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Solver.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Solver.java
index 1dec1de8a606..21e749e12b29 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Solver.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Solver.java
@@ -15,10 +15,8 @@
*/
package com.intellij.codeInspection.bytecodeAnalysis;
-import com.intellij.util.containers.LongStack;
-import gnu.trove.TLongHashSet;
-import gnu.trove.TLongIterator;
-import gnu.trove.TLongObjectHashMap;
+import com.intellij.util.ArrayFactory;
+import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.org.objectweb.asm.tree.analysis.AnalyzerException;
@@ -48,88 +46,6 @@ final class ELattice<T extends Enum<T>> {
}
}
-// component specialized for ints
-final class IntIdComponent {
- Value value;
- final long[] ids;
-
- IntIdComponent(Value value, long[] ids) {
- this.value = value;
- this.ids = ids;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- IntIdComponent that = (IntIdComponent)o;
-
- if (!Arrays.equals(ids, that.ids)) return false;
- if (value != that.value) return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- return value.ordinal() + Arrays.hashCode(ids);
- }
-
- public boolean remove(long id) {
- return IdUtils.remove(ids, id);
- }
-
- public boolean isEmpty() {
- return IdUtils.isEmpty(ids);
- }
-
- IntIdComponent copy() {
- return new IntIdComponent(value, ids.clone());
- }
-}
-
-class IdUtils {
- // removed value
- static final long nullId = 0;
-
- static boolean contains(long[] ids, int id) {
- for (long id1 : ids) {
- if (id1 == id) return true;
- }
-
- return false;
- }
-
- static boolean isEmpty(long[] ids) {
- for (long id : ids) {
- if (id != nullId) return false;
- }
- return true;
- }
-
- static IntIdComponent[] toArray(Collection<IntIdComponent> set) {
- IntIdComponent[] result = new IntIdComponent[set.size()];
- int i = 0;
- for (IntIdComponent intIdComponent : set) {
- result[i] = intIdComponent;
- i++;
- }
-
- return result;
- }
-
- static boolean remove(long[] ids, long id) {
- boolean removed = false;
- for (int i = 0; i < ids.length; i++) {
- if (ids[i] == id) {
- ids[i] = nullId;
- removed = true;
- }
- }
- return removed;
- }
-}
class ResultUtil<Id, T extends Enum<T>> {
private final ELattice<T> lattice;
@@ -183,6 +99,55 @@ class ResultUtil<Id, T extends Enum<T>> {
}
}
+class HResultUtil {
+ private static final HKey[] EMPTY_PRODUCT = new HKey[0];
+ private static final ArrayFactory<HComponent> HCOMPONENT_ARRAY_FACTORY = new ArrayFactory<HComponent>() {
+ @NotNull
+ @Override
+ public HComponent[] create(int count) {
+ return new HComponent[count];
+ }
+ };
+ private final ELattice<Value> lattice;
+ final Value top;
+
+ HResultUtil(ELattice<Value> lattice) {
+ this.lattice = lattice;
+ top = lattice.top;
+ }
+
+ HResult join(HResult r1, HResult r2) {
+ if (r1 instanceof HFinal && ((HFinal) r1).value == top) {
+ return r1;
+ }
+ if (r2 instanceof HFinal && ((HFinal) r2).value == top) {
+ return r2;
+ }
+ if (r1 instanceof HFinal && r2 instanceof HFinal) {
+ return new HFinal(lattice.join(((HFinal) r1).value, ((HFinal) r2).value));
+ }
+ if (r1 instanceof HFinal && r2 instanceof HPending) {
+ HFinal f1 = (HFinal)r1;
+ HPending pending = (HPending) r2;
+ HComponent[] delta = new HComponent[pending.delta.length + 1];
+ delta[0] = new HComponent(f1.value, EMPTY_PRODUCT);
+ System.arraycopy(pending.delta, 0, delta, 1, pending.delta.length);
+ return new HPending(delta);
+ }
+ if (r1 instanceof HPending && r2 instanceof HFinal) {
+ HFinal f2 = (HFinal)r2;
+ HPending pending = (HPending) r1;
+ HComponent[] delta = new HComponent[pending.delta.length + 1];
+ delta[0] = new HComponent(f2.value, EMPTY_PRODUCT);
+ System.arraycopy(pending.delta, 0, delta, 1, pending.delta.length);
+ return new HPending(delta);
+ }
+ HPending pending1 = (HPending) r1;
+ HPending pending2 = (HPending) r2;
+ return new HPending(ArrayUtil.mergeArrays(pending1.delta, pending2.delta, HCOMPONENT_ARRAY_FACTORY));
+ }
+}
+
final class Product<K, V> {
@NotNull final V value;
@NotNull final Set<K> ids;
@@ -235,195 +200,150 @@ final class Pending<Id, T> implements Result<Id, T> {
}
-interface IdResult {}
-// this just wrapper, no need for this really
-final class IdFinal implements IdResult {
- final Value value;
- public IdFinal(Value value) {
- this.value = value;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- IdFinal that = (IdFinal)o;
-
- if (value != that.value) return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- return value.ordinal();
- }
+final class Solution<Id, Val> {
+ final Id id;
+ final Val value;
- @Override
- public String toString() {
- return super.toString();
+ Solution(Id id, Val value) {
+ this.id = id;
+ this.value = value;
}
}
-final class IdPending implements IdResult {
- final IntIdComponent[] delta;
-
- IdPending(IntIdComponent[] delta) {
- this.delta = delta;
- }
+final class Equation<Id, T> {
+ final Id id;
+ final Result<Id, T> rhs;
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (!(o instanceof IdPending)) return false;
- IdPending pending = (IdPending)o;
- return Arrays.equals(delta, pending.delta);
+ Equation(Id id, Result<Id, T> rhs) {
+ this.id = id;
+ this.rhs = rhs;
}
@Override
- public int hashCode() {
- return Arrays.hashCode(delta);
- }
-
- IdPending copy() {
- IntIdComponent[] delta1 = new IntIdComponent[delta.length];
- for (int i = 0; i < delta.length; i++) {
- delta1[i] = delta[i].copy();
- }
- return new IdPending(delta1);
+ public String toString() {
+ return "Equation{" + "id=" + id + ", rhs=" + rhs + '}';
}
}
-final class IdEquation {
- final long id;
- final IdResult rhs;
+final class CoreHKey {
+ @NotNull
+ final byte[] key;
+ final int dirKey;
- IdEquation(long id, IdResult rhs) {
- this.id = id;
- this.rhs = rhs;
+ CoreHKey(@NotNull byte[] key, int dirKey) {
+ this.key = key;
+ this.dirKey = dirKey;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
- if (!(o instanceof IdEquation)) return false;
-
- IdEquation equation = (IdEquation)o;
+ if (o == null || getClass() != o.getClass()) return false;
- if (id != equation.id) return false;
- if (!rhs.equals(equation.rhs)) return false;
+ CoreHKey coreHKey = (CoreHKey)o;
+ if (dirKey != coreHKey.dirKey) return false;
+ if (!Arrays.equals(key, coreHKey.key)) return false;
return true;
}
@Override
public int hashCode() {
- return 31 * ((int)(id ^ (id >>> 32))) + rhs.hashCode();
- }
-}
-
-final class Solution<Id, Val> {
- final Id id;
- final Val value;
-
- Solution(Id id, Val value) {
- this.id = id;
- this.value = value;
- }
-}
-
-final class Equation<Id, T> {
- final Id id;
- final Result<Id, T> rhs;
-
- Equation(Id id, Result<Id, T> rhs) {
- this.id = id;
- this.rhs = rhs;
- }
-
- @Override
- public String toString() {
- return "Equation{" + "id=" + id + ", rhs=" + rhs + '}';
+ int result = Arrays.hashCode(key);
+ result = 31 * result + dirKey;
+ return result;
}
}
final class Solver {
- private int size = 0;
private final ELattice<Value> lattice;
- private final TLongObjectHashMap<TLongHashSet> dependencies = new TLongObjectHashMap<TLongHashSet>();
- private final TLongObjectHashMap<IdPending> pending = new TLongObjectHashMap<IdPending>();
- private final TLongObjectHashMap<Value> solved = new TLongObjectHashMap<Value>();
- private final LongStack moving = new LongStack();
+ private final HashMap<HKey, HashSet<HKey>> dependencies = new HashMap<HKey, HashSet<HKey>>();
+ private final HashMap<HKey, HPending> pending = new HashMap<HKey, HPending>();
+ private final HashMap<HKey, Value> solved = new HashMap<HKey, Value>();
+ private final Stack<HKey> moving = new Stack<HKey>();
- int getSize() {
- return size;
- }
+ private final HResultUtil resultUtil;
+ private final HashMap<CoreHKey, HEquation> equations = new HashMap<CoreHKey, HEquation>();
Solver(ELattice<Value> lattice) {
this.lattice = lattice;
+ resultUtil = new HResultUtil(lattice);
+ }
+
+ void addEquation(HEquation equation) {
+ HKey key = equation.key;
+ CoreHKey coreKey = new CoreHKey(key.key, key.dirKey);
+
+ HEquation previousEquation = equations.get(coreKey);
+ if (previousEquation == null) {
+ equations.put(coreKey, equation);
+ } else {
+ HKey joinKey = new HKey(coreKey.key, coreKey.dirKey, equation.key.stable && previousEquation.key.stable);
+ HResult joinResult = resultUtil.join(equation.result, previousEquation.result);
+ HEquation joinEquation = new HEquation(joinKey, joinResult);
+ equations.put(coreKey, joinEquation);
+ }
}
- void addEquation(IdEquation equation) {
- size ++;
- IdResult rhs = equation.rhs;
- if (rhs instanceof IdFinal) {
- solved.put(equation.id, ((IdFinal) rhs).value);
- moving.push(equation.id);
- } else if (rhs instanceof IdPending) {
- IdPending pendResult = ((IdPending)rhs).copy();
- IdResult norm = normalize(pendResult.delta);
- if (norm instanceof IdFinal) {
- solved.put(equation.id, ((IdFinal) norm).value);
- moving.push(equation.id);
+ void queueEquation(HEquation equation) {
+ HResult rhs = equation.result;
+ if (rhs instanceof HFinal) {
+ solved.put(equation.key, ((HFinal) rhs).value);
+ moving.push(equation.key);
+ } else if (rhs instanceof HPending) {
+ HPending pendResult = ((HPending)rhs).copy();
+ HResult norm = normalize(pendResult.delta);
+ if (norm instanceof HFinal) {
+ solved.put(equation.key, ((HFinal) norm).value);
+ moving.push(equation.key);
}
else {
- IdPending pendResult1 = ((IdPending)rhs).copy();
- for (IntIdComponent component : pendResult1.delta) {
- for (long trigger : component.ids) {
- TLongHashSet set = dependencies.get(trigger);
+ HPending pendResult1 = ((HPending)rhs).copy();
+ for (HComponent component : pendResult1.delta) {
+ for (HKey trigger : component.ids) {
+ HashSet<HKey> set = dependencies.get(trigger);
if (set == null) {
- set = new TLongHashSet();
+ set = new HashSet<HKey>();
dependencies.put(trigger, set);
}
- set.add(equation.id);
+ set.add(equation.key);
}
- pending.put(equation.id, pendResult1);
+ pending.put(equation.key, pendResult1);
}
}
}
}
- TLongObjectHashMap<Value> solve() {
+ HashMap<HKey, Value> solve() {
+ for (HEquation hEquation : equations.values()) {
+ queueEquation(hEquation);
+ }
while (!moving.empty()) {
- long id = moving.pop();
+ HKey id = moving.pop();
Value value = solved.get(id);
- boolean stable = id > 0;
- long[] pIds = stable ? new long[]{id, -id} : new long[]{-id, id};
- Value[] pVals = stable ? new Value[]{value, value} : new Value[]{value, lattice.top};
+ HKey[] pIds = id.stable ? new HKey[]{id, id.negate()} : new HKey[]{id.negate(), id};
+ Value[] pVals = id.stable ? new Value[]{value, value} : new Value[]{value, lattice.top};
for (int i = 0; i < pIds.length; i++) {
- long pId = pIds[i];
+ HKey pId = pIds[i];
Value pVal = pVals[i];
- TLongHashSet dIds = dependencies.get(pId);
+ HashSet<HKey> dIds = dependencies.get(pId);
if (dIds == null) {
continue;
}
- TLongIterator dIdsIterator = dIds.iterator();
- while (dIdsIterator.hasNext()) {
- long dId = dIdsIterator.next();
- IdPending pend = pending.remove(dId);
+ for (HKey dId : dIds) {
+ HPending pend = pending.remove(dId);
if (pend != null) {
- IdResult pend1 = substitute(pend, pId, pVal);
- if (pend1 instanceof IdFinal) {
- IdFinal fi = (IdFinal)pend1;
+ HResult pend1 = substitute(pend, pId, pVal);
+ if (pend1 instanceof HFinal) {
+ HFinal fi = (HFinal)pend1;
solved.put(dId, fi.value);
moving.push(dId);
}
else {
- pending.put(dId, (IdPending)pend1);
+ pending.put(dId, (HPending)pend1);
}
}
}
@@ -434,9 +354,9 @@ final class Solver {
}
// substitute id -> value into pending
- IdResult substitute(IdPending pending, long id, Value value) {
- IntIdComponent[] sum = pending.delta;
- for (IntIdComponent intIdComponent : sum) {
+ HResult substitute(@NotNull HPending pending, @NotNull HKey id, @NotNull Value value) {
+ HComponent[] sum = pending.delta;
+ for (HComponent intIdComponent : sum) {
if (intIdComponent.remove(id)) {
intIdComponent.value = lattice.meet(intIdComponent.value, value);
}
@@ -444,17 +364,17 @@ final class Solver {
return normalize(sum);
}
- IdResult normalize(IntIdComponent[] sum) {
+ @NotNull HResult normalize(@NotNull HComponent[] sum) {
Value acc = lattice.bot;
boolean computableNow = true;
- for (IntIdComponent prod : sum) {
+ for (HComponent prod : sum) {
if (prod.isEmpty() || prod.value == lattice.bot) {
acc = lattice.join(acc, prod.value);
} else {
computableNow = false;
}
}
- return (acc == lattice.top || computableNow) ? new IdFinal(acc) : new IdPending(sum);
+ return (acc == lattice.top || computableNow) ? new HFinal(acc) : new HPending(sum);
}
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/ASMUtils.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/ASMUtils.java
new file mode 100644
index 000000000000..a6bfdc38732e
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/ASMUtils.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection.bytecodeAnalysis.asm;
+
+import org.jetbrains.org.objectweb.asm.Type;
+import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue;
+
+/**
+ * @author lambdamix
+ */
+public class ASMUtils {
+ public static final Type THROWABLE_TYPE = Type.getType("java/lang/Throwable");
+ public static final BasicValue THROWABLE_VALUE = new BasicValue(THROWABLE_TYPE);
+
+ public static boolean isReferenceType(Type tp) {
+ int sort = tp.getSort();
+ return sort == Type.OBJECT || sort == Type.ARRAY;
+ }
+
+ public static boolean isBooleanType(Type tp) {
+ return Type.BOOLEAN_TYPE.equals(tp);
+ }
+
+ public static int getSizeFast(String desc) {
+ switch (desc.charAt(0)) {
+ case 'J':
+ case 'D':
+ return 2;
+ default:
+ return 1;
+ }
+ }
+
+ public static int getReturnSizeFast(String methodDesc) {
+ switch (methodDesc.charAt(methodDesc.indexOf(')') + 1)) {
+ case 'J':
+ case 'D':
+ return 2;
+ default:
+ return 1;
+ }
+ }
+
+}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/ControlFlowGraph.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/ControlFlowGraph.java
new file mode 100644
index 000000000000..40a730190d2e
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/ControlFlowGraph.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection.bytecodeAnalysis.asm;
+
+import com.intellij.codeInspection.bytecodeAnalysis.asm.ControlFlowGraph.Edge;
+import gnu.trove.TIntArrayList;
+import org.jetbrains.org.objectweb.asm.tree.MethodNode;
+import org.jetbrains.org.objectweb.asm.tree.analysis.AnalyzerException;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author lambdamix
+ */
+public final class ControlFlowGraph {
+ public static final class Edge {
+ public final int from, to;
+
+ public Edge(int from, int to) {
+ this.from = from;
+ this.to = to;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof Edge)) {
+ return false;
+ }
+ Edge edge = (Edge) o;
+ return from == edge.from && to == edge.to;
+ }
+
+ @Override
+ public int hashCode() {
+ return 31 * from + to;
+ }
+ }
+
+ public final String className;
+ public final MethodNode methodNode;
+ public final int[][] transitions;
+ public final int edgeCount;
+ public final boolean[] errors;
+ public final Set<Edge> errorTransitions;
+
+ ControlFlowGraph(String className, MethodNode methodNode, int[][] transitions, int edgeCount, boolean[] errors, Set<Edge> errorTransitions) {
+ this.className = className;
+ this.methodNode = methodNode;
+ this.transitions = transitions;
+ this.edgeCount = edgeCount;
+ this.errors = errors;
+ this.errorTransitions = errorTransitions;
+ }
+
+ public static ControlFlowGraph build(String className, MethodNode methodNode, boolean jsr) throws AnalyzerException {
+ return jsr ? new ControlFlowBuilder(className, methodNode).buildCFG() : new LiteControlFlowBuilder(className, methodNode).buildCFG();
+ }
+}
+
+final class ControlFlowBuilder extends FramelessAnalyzer {
+ final String className;
+ final MethodNode methodNode;
+ final TIntArrayList[] transitions;
+ final Set<ControlFlowGraph.Edge> errorTransitions;
+ private final boolean[] errors;
+ private int edgeCount;
+
+ ControlFlowBuilder(String className, MethodNode methodNode) {
+ this.className = className;
+ this.methodNode = methodNode;
+ transitions = new TIntArrayList[methodNode.instructions.size()];
+ errors = new boolean[methodNode.instructions.size()];
+ for (int i = 0; i < transitions.length; i++) {
+ transitions[i] = new TIntArrayList();
+ }
+ errorTransitions = new HashSet<Edge>();
+ }
+
+ final ControlFlowGraph buildCFG() throws AnalyzerException {
+ if ((methodNode.access & (ACC_ABSTRACT | ACC_NATIVE)) == 0) {
+ analyze(methodNode);
+ }
+ int[][] resultTransitions = new int[transitions.length][];
+ for (int i = 0; i < resultTransitions.length; i++) {
+ resultTransitions[i] = transitions[i].toNativeArray();
+ }
+ return new ControlFlowGraph(className, methodNode, resultTransitions, edgeCount, errors, errorTransitions);
+ }
+
+ @Override
+ protected final void newControlFlowEdge(int insn, int successor) {
+ if (!transitions[insn].contains(successor)) {
+ transitions[insn].add(successor);
+ edgeCount++;
+ }
+ }
+
+ @Override
+ protected final boolean newControlFlowExceptionEdge(int insn, int successor) {
+ if (!transitions[insn].contains(successor)) {
+ transitions[insn].add(successor);
+ edgeCount++;
+ errorTransitions.add(new Edge(insn, successor));
+ errors[successor] = true;
+ }
+ return true;
+ }
+}
+
+final class LiteControlFlowBuilder extends LiteFramelessAnalyzer {
+ final String className;
+ final MethodNode methodNode;
+ final TIntArrayList[] transitions;
+ final Set<ControlFlowGraph.Edge> errorTransitions;
+ private final boolean[] errors;
+ private int edgeCount;
+
+ LiteControlFlowBuilder(String className, MethodNode methodNode) {
+ this.className = className;
+ this.methodNode = methodNode;
+ transitions = new TIntArrayList[methodNode.instructions.size()];
+ errors = new boolean[methodNode.instructions.size()];
+ for (int i = 0; i < transitions.length; i++) {
+ transitions[i] = new TIntArrayList();
+ }
+ errorTransitions = new HashSet<Edge>();
+ }
+
+ final ControlFlowGraph buildCFG() throws AnalyzerException {
+ if ((methodNode.access & (ACC_ABSTRACT | ACC_NATIVE)) == 0) {
+ analyze(methodNode);
+ }
+ int[][] resultTransitions = new int[transitions.length][];
+ for (int i = 0; i < resultTransitions.length; i++) {
+ resultTransitions[i] = transitions[i].toNativeArray();
+ }
+ return new ControlFlowGraph(className, methodNode, resultTransitions, edgeCount, errors, errorTransitions);
+ }
+
+ @Override
+ protected final void newControlFlowEdge(int insn, int successor) {
+ if (!transitions[insn].contains(successor)) {
+ transitions[insn].add(successor);
+ edgeCount++;
+ }
+ }
+
+ @Override
+ protected final boolean newControlFlowExceptionEdge(int insn, int successor) {
+ if (!transitions[insn].contains(successor)) {
+ transitions[insn].add(successor);
+ edgeCount++;
+ errorTransitions.add(new Edge(insn, successor));
+ errors[successor] = true;
+ }
+ return true;
+ }
+}
+
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/DFSTree.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/DFSTree.java
new file mode 100644
index 000000000000..85bc13fbda96
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/DFSTree.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection.bytecodeAnalysis.asm;
+
+import com.intellij.codeInspection.bytecodeAnalysis.asm.ControlFlowGraph.Edge;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author lambdamix
+ */
+public final class DFSTree {
+ public final int[] preOrder, postOrder;
+ public final Set<Edge> nonBack, back;
+ public final boolean[] loopEnters;
+
+ DFSTree(int[] preOrder,
+ int[] postOrder,
+ Set<Edge> nonBack,
+ Set<Edge> back,
+ boolean[] loopEnters) {
+ this.preOrder = preOrder;
+ this.postOrder = postOrder;
+ this.nonBack = nonBack;
+ this.back = back;
+ this.loopEnters = loopEnters;
+ }
+
+ public final boolean isDescendant(int child, int parent) {
+ return preOrder[parent] <= preOrder[child] && postOrder[child] <= postOrder[parent];
+ }
+
+ // Graphs: Theory and Algorithms. by K. Thulasiraman , M. N. S. Swamy (1992)
+ // 11.7.2 DFS of a directed graph
+ public static DFSTree build(int[][] transitions, int edgeCount) {
+ HashSet<Edge> nonBack = new HashSet<Edge>();
+ HashSet<Edge> back = new HashSet<Edge>();
+
+ boolean[] marked = new boolean[transitions.length];
+ boolean[] scanned = new boolean[transitions.length];
+ int[] preOrder = new int[transitions.length];
+ int[] postOrder = new int[transitions.length];
+
+ int entered = 0;
+ int completed = 0;
+
+ boolean[] loopEnters = new boolean[transitions.length];
+
+ // enter 0
+ entered ++;
+ preOrder[0] = entered;
+ marked[0] = true;
+
+ boolean[] stackFlag = new boolean[edgeCount*2 + 1];
+ int[] stackFrom = new int[edgeCount*2 + 1];
+ int[] stackTo = new int[edgeCount*2 + 1];
+
+ int top = 0;
+
+ // stack.push(new MarkScanned(0));
+ stackFlag[top] = true;
+ stackTo[top] = 0;
+ top++;
+
+ for (int to : transitions[0]) {
+ //stack.push(new ExamineEdge(0, to));
+ stackFlag[top] = false;
+ stackFrom[top] = 0;
+ stackTo[top] = to;
+ top++;
+ }
+
+ while (top > 0) {
+ top--;
+ //Action action = stack.pop();
+ // markScanned
+ if (stackFlag[top]) {
+ completed ++;
+ postOrder[stackTo[top]] = completed;
+ scanned[stackTo[top]] = true;
+ }
+ else {
+ //ExamineEdge examineEdgeAction = (ExamineEdge) action;
+ int from = stackFrom[top];
+ int to = stackTo[top];
+ if (!marked[to]) {
+ nonBack.add(new Edge(from, to));
+ // enter to
+ entered ++;
+ preOrder[to] = entered;
+ marked[to] = true;
+
+ //stack.push(new MarkScanned(to));
+ stackFlag[top] = true;
+ stackTo[top] = to;
+ top++;
+
+ for (int to1 : transitions[to]) {
+ //stack.push(new ExamineEdge(to, to1));
+ stackFlag[top] = false;
+ stackFrom[top] = to;
+ stackTo[top] = to1;
+ top++;
+ }
+ }
+ else if (preOrder[to] > preOrder[from]) {
+ nonBack.add(new Edge(from, to));
+ }
+ else if (preOrder[to] < preOrder[from] && !scanned[to]) {
+ back.add(new Edge(from, to));
+ loopEnters[to] = true;
+ } else {
+ nonBack.add(new Edge(from, to));
+ }
+ }
+ }
+
+ return new DFSTree(preOrder, postOrder, nonBack, back, loopEnters);
+ }
+}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/FramelessAnalyzer.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/FramelessAnalyzer.java
new file mode 100644
index 000000000000..5804723e9ec1
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/FramelessAnalyzer.java
@@ -0,0 +1,362 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection.bytecodeAnalysis.asm;
+
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.org.objectweb.asm.Opcodes;
+import org.jetbrains.org.objectweb.asm.tree.*;
+import org.jetbrains.org.objectweb.asm.tree.analysis.AnalyzerException;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Specialized version of {@link org.jetbrains.org.objectweb.asm.tree.analysis.Analyzer}.
+ * Calculation of fix-point of frames is removed, since frames are not needed to build control flow graph.
+ * So, the main point here is handling of subroutines (jsr) and try-catch-finally blocks.
+ */
+public class FramelessAnalyzer implements Opcodes {
+ static class Subroutine {
+
+ LabelNode start;
+ boolean[] access;
+ List<JumpInsnNode> callers;
+
+ private Subroutine() {
+ }
+
+ Subroutine(@Nullable final LabelNode start, final int maxLocals,
+ @Nullable final JumpInsnNode caller) {
+ this.start = start;
+ this.access = new boolean[maxLocals];
+ this.callers = new ArrayList<JumpInsnNode>();
+ callers.add(caller);
+ }
+
+ public Subroutine copy() {
+ Subroutine result = new Subroutine();
+ result.start = start;
+ result.access = new boolean[access.length];
+ System.arraycopy(access, 0, result.access, 0, access.length);
+ result.callers = new ArrayList<JumpInsnNode>(callers);
+ return result;
+ }
+
+ public boolean merge(final Subroutine subroutine) throws AnalyzerException {
+ boolean changes = false;
+ for (int i = 0; i < access.length; ++i) {
+ if (subroutine.access[i] && !access[i]) {
+ access[i] = true;
+ changes = true;
+ }
+ }
+ if (subroutine.start == start) {
+ for (int i = 0; i < subroutine.callers.size(); ++i) {
+ JumpInsnNode caller = subroutine.callers.get(i);
+ if (!callers.contains(caller)) {
+ callers.add(caller);
+ changes = true;
+ }
+ }
+ }
+ return changes;
+ }
+ }
+ private int n;
+ private InsnList insns;
+ private List<TryCatchBlockNode>[] handlers;
+ private Subroutine[] subroutines;
+ protected boolean[] wasQueued;
+ protected boolean[] queued;
+ protected int[] queue;
+ protected int top;
+
+ public void analyze(final MethodNode m) throws AnalyzerException {
+ n = m.instructions.size();
+ if ((m.access & (ACC_ABSTRACT | ACC_NATIVE)) != 0 || n == 0) {
+ return;
+ }
+ insns = m.instructions;
+ handlers = (List<TryCatchBlockNode>[]) new List<?>[n];
+ subroutines = new Subroutine[n];
+ queued = new boolean[n];
+ wasQueued = new boolean[n];
+ queue = new int[n];
+ top = 0;
+
+ // computes exception handlers for each instruction
+ for (int i = 0; i < m.tryCatchBlocks.size(); ++i) {
+ TryCatchBlockNode tcb = m.tryCatchBlocks.get(i);
+ int begin = insns.indexOf(tcb.start);
+ int end = insns.indexOf(tcb.end);
+ for (int j = begin; j < end; ++j) {
+ List<TryCatchBlockNode> insnHandlers = handlers[j];
+ if (insnHandlers == null) {
+ insnHandlers = new ArrayList<TryCatchBlockNode>();
+ handlers[j] = insnHandlers;
+ }
+ insnHandlers.add(tcb);
+ }
+ }
+
+ // computes the subroutine for each instruction:
+ Subroutine main = new Subroutine(null, m.maxLocals, null);
+ List<AbstractInsnNode> subroutineCalls = new ArrayList<AbstractInsnNode>();
+ Map<LabelNode, Subroutine> subroutineHeads = new HashMap<LabelNode, Subroutine>();
+
+ findSubroutine(0, main, subroutineCalls);
+ while (!subroutineCalls.isEmpty()) {
+ JumpInsnNode jsr = (JumpInsnNode) subroutineCalls.remove(0);
+ Subroutine sub = subroutineHeads.get(jsr.label);
+ if (sub == null) {
+ sub = new Subroutine(jsr.label, m.maxLocals, jsr);
+ subroutineHeads.put(jsr.label, sub);
+ findSubroutine(insns.indexOf(jsr.label), sub, subroutineCalls);
+ } else {
+ sub.callers.add(jsr);
+ }
+ }
+ for (int i = 0; i < n; ++i) {
+ if (subroutines[i] != null && subroutines[i].start == null) {
+ subroutines[i] = null;
+ }
+ }
+
+ merge(0, null);
+ // control flow analysis
+ while (top > 0) {
+ int insn = queue[--top];
+ Subroutine subroutine = subroutines[insn];
+ queued[insn] = false;
+
+ AbstractInsnNode insnNode = null;
+ try {
+ insnNode = m.instructions.get(insn);
+ int insnOpcode = insnNode.getOpcode();
+ int insnType = insnNode.getType();
+
+ if (insnType == AbstractInsnNode.LABEL || insnType == AbstractInsnNode.LINE || insnType == AbstractInsnNode.FRAME) {
+ merge(insn + 1, subroutine);
+ newControlFlowEdge(insn, insn + 1);
+ } else {
+ subroutine = subroutine == null ? null : subroutine.copy();
+
+ if (insnNode instanceof JumpInsnNode) {
+ JumpInsnNode j = (JumpInsnNode) insnNode;
+ if (insnOpcode != GOTO && insnOpcode != JSR) {
+ merge(insn + 1, subroutine);
+ newControlFlowEdge(insn, insn + 1);
+ }
+ int jump = insns.indexOf(j.label);
+ if (insnOpcode == JSR) {
+ merge(jump, new Subroutine(j.label, m.maxLocals, j));
+ } else {
+ merge(jump, subroutine);
+ }
+ newControlFlowEdge(insn, jump);
+ } else if (insnNode instanceof LookupSwitchInsnNode) {
+ LookupSwitchInsnNode lsi = (LookupSwitchInsnNode) insnNode;
+ int jump = insns.indexOf(lsi.dflt);
+ merge(jump, subroutine);
+ newControlFlowEdge(insn, jump);
+ for (int j = 0; j < lsi.labels.size(); ++j) {
+ LabelNode label = lsi.labels.get(j);
+ jump = insns.indexOf(label);
+ merge(jump, subroutine);
+ newControlFlowEdge(insn, jump);
+ }
+ } else if (insnNode instanceof TableSwitchInsnNode) {
+ TableSwitchInsnNode tsi = (TableSwitchInsnNode) insnNode;
+ int jump = insns.indexOf(tsi.dflt);
+ merge(jump, subroutine);
+ newControlFlowEdge(insn, jump);
+ for (int j = 0; j < tsi.labels.size(); ++j) {
+ LabelNode label = tsi.labels.get(j);
+ jump = insns.indexOf(label);
+ merge(jump, subroutine);
+ newControlFlowEdge(insn, jump);
+ }
+ } else if (insnOpcode == RET) {
+ if (subroutine == null) {
+ throw new AnalyzerException(insnNode, "RET instruction outside of a sub routine");
+ }
+ for (int i = 0; i < subroutine.callers.size(); ++i) {
+ JumpInsnNode caller = subroutine.callers.get(i);
+ int call = insns.indexOf(caller);
+ if (wasQueued[call]) {
+ merge(call + 1, subroutines[call], subroutine.access);
+ newControlFlowEdge(insn, call + 1);
+ }
+ }
+ } else if (insnOpcode != ATHROW && (insnOpcode < IRETURN || insnOpcode > RETURN)) {
+ if (subroutine != null) {
+ if (insnNode instanceof VarInsnNode) {
+ int var = ((VarInsnNode) insnNode).var;
+ subroutine.access[var] = true;
+ if (insnOpcode == LLOAD || insnOpcode == DLOAD
+ || insnOpcode == LSTORE
+ || insnOpcode == DSTORE) {
+ subroutine.access[var + 1] = true;
+ }
+ } else if (insnNode instanceof IincInsnNode) {
+ int var = ((IincInsnNode) insnNode).var;
+ subroutine.access[var] = true;
+ }
+ }
+ merge(insn + 1, subroutine);
+ newControlFlowEdge(insn, insn + 1);
+ }
+ }
+
+ List<TryCatchBlockNode> insnHandlers = handlers[insn];
+ if (insnHandlers != null) {
+ for (TryCatchBlockNode tcb : insnHandlers) {
+ newControlFlowExceptionEdge(insn, tcb);
+ merge(insns.indexOf(tcb.handler), subroutine);
+ }
+ }
+ } catch (AnalyzerException e) {
+ throw new AnalyzerException(e.node, "Error at instruction "
+ + insn + ": " + e.getMessage(), e);
+ } catch (Exception e) {
+ throw new AnalyzerException(insnNode, "Error at instruction "
+ + insn + ": " + e.getMessage(), e);
+ }
+ }
+ }
+
+ protected void findSubroutine(int insn, final Subroutine sub,
+ final List<AbstractInsnNode> calls) throws AnalyzerException {
+ while (true) {
+ if (insn < 0 || insn >= n) {
+ throw new AnalyzerException(null, "Execution can fall off end of the code");
+ }
+ if (subroutines[insn] != null) {
+ return;
+ }
+ subroutines[insn] = sub.copy();
+ AbstractInsnNode node = insns.get(insn);
+
+ // calls findSubroutine recursively on normal successors
+ if (node instanceof JumpInsnNode) {
+ if (node.getOpcode() == JSR) {
+ // do not follow a JSR, it leads to another subroutine!
+ calls.add(node);
+ } else {
+ JumpInsnNode jnode = (JumpInsnNode) node;
+ findSubroutine(insns.indexOf(jnode.label), sub, calls);
+ }
+ } else if (node instanceof TableSwitchInsnNode) {
+ TableSwitchInsnNode tsnode = (TableSwitchInsnNode) node;
+ findSubroutine(insns.indexOf(tsnode.dflt), sub, calls);
+ for (int i = tsnode.labels.size() - 1; i >= 0; --i) {
+ LabelNode l = tsnode.labels.get(i);
+ findSubroutine(insns.indexOf(l), sub, calls);
+ }
+ } else if (node instanceof LookupSwitchInsnNode) {
+ LookupSwitchInsnNode lsnode = (LookupSwitchInsnNode) node;
+ findSubroutine(insns.indexOf(lsnode.dflt), sub, calls);
+ for (int i = lsnode.labels.size() - 1; i >= 0; --i) {
+ LabelNode l = lsnode.labels.get(i);
+ findSubroutine(insns.indexOf(l), sub, calls);
+ }
+ }
+
+ // calls findSubroutine recursively on exception handler successors
+ List<TryCatchBlockNode> insnHandlers = handlers[insn];
+ if (insnHandlers != null) {
+ for (int i = 0; i < insnHandlers.size(); ++i) {
+ TryCatchBlockNode tcb = insnHandlers.get(i);
+ findSubroutine(insns.indexOf(tcb.handler), sub, calls);
+ }
+ }
+
+ // if insn does not falls through to the next instruction, return.
+ switch (node.getOpcode()) {
+ case GOTO:
+ case RET:
+ case TABLESWITCH:
+ case LOOKUPSWITCH:
+ case IRETURN:
+ case LRETURN:
+ case FRETURN:
+ case DRETURN:
+ case ARETURN:
+ case RETURN:
+ case ATHROW:
+ return;
+ }
+ insn++;
+ }
+ }
+
+ protected void newControlFlowEdge(final int insn, final int successor) {}
+
+ protected boolean newControlFlowExceptionEdge(final int insn, final int successor) {
+ return true;
+ }
+
+ protected boolean newControlFlowExceptionEdge(final int insn, final TryCatchBlockNode tcb) {
+ return newControlFlowExceptionEdge(insn, insns.indexOf(tcb.handler));
+ }
+
+ // -------------------------------------------------------------------------
+
+ protected void merge(final int insn, @Nullable final Subroutine subroutine) throws AnalyzerException {
+ Subroutine oldSubroutine = subroutines[insn];
+ boolean changes = false;
+
+ if (!wasQueued[insn]) {
+ wasQueued[insn] = true;
+ changes = true;
+ }
+
+ if (oldSubroutine == null) {
+ if (subroutine != null) {
+ subroutines[insn] = subroutine.copy();
+ changes = true;
+ }
+ } else {
+ if (subroutine != null) {
+ changes |= oldSubroutine.merge(subroutine);
+ }
+ }
+ if (changes && !queued[insn]) {
+ queued[insn] = true;
+ queue[top++] = insn;
+ }
+ }
+
+ protected void merge(final int insn, final Subroutine subroutineBeforeJSR, final boolean[] access) throws AnalyzerException {
+ Subroutine oldSubroutine = subroutines[insn];
+ boolean changes = false;
+
+ if (!wasQueued[insn]) {
+ wasQueued[insn] = true;
+ changes = true;
+ }
+
+ if (oldSubroutine != null && subroutineBeforeJSR != null) {
+ changes |= oldSubroutine.merge(subroutineBeforeJSR);
+ }
+ if (changes && !queued[insn]) {
+ queued[insn] = true;
+ queue[top++] = insn;
+ }
+ }
+}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/LeakingParameters.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/LeakingParameters.java
new file mode 100644
index 000000000000..1a7ab15722f9
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/LeakingParameters.java
@@ -0,0 +1,610 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection.bytecodeAnalysis.asm;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.org.objectweb.asm.Type;
+import org.jetbrains.org.objectweb.asm.tree.*;
+import org.jetbrains.org.objectweb.asm.tree.analysis.*;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static org.jetbrains.org.objectweb.asm.Opcodes.*;
+
+/**
+ * @author lambdamix
+ */
+public class LeakingParameters {
+ public final Frame<Value>[] frames;
+ public final boolean[] parameters;
+ public final boolean[] nullableParameters;
+
+ public LeakingParameters(Frame<Value>[] frames, boolean[] parameters, boolean[] nullableParameters) {
+ this.frames = frames;
+ this.parameters = parameters;
+ this.nullableParameters = nullableParameters;
+ }
+
+ public static LeakingParameters build(String className, MethodNode methodNode, boolean jsr) throws AnalyzerException {
+ Frame<ParamsValue>[] frames = jsr ?
+ new Analyzer<ParamsValue>(new ParametersUsage(methodNode)).analyze(className, methodNode) :
+ new LiteAnalyzer<ParamsValue>(new ParametersUsage(methodNode)).analyze(className, methodNode);
+ InsnList insns = methodNode.instructions;
+ LeakingParametersCollector collector = new LeakingParametersCollector(methodNode);
+ for (int i = 0; i < frames.length; i++) {
+ AbstractInsnNode insnNode = insns.get(i);
+ Frame<ParamsValue> frame = frames[i];
+ if (frame != null) {
+ switch (insnNode.getType()) {
+ case AbstractInsnNode.LABEL:
+ case AbstractInsnNode.LINE:
+ case AbstractInsnNode.FRAME:
+ break;
+ default:
+ new Frame<ParamsValue>(frame).execute(insnNode, collector);
+ }
+ }
+ }
+ boolean[] notNullParameters = collector.leaking;
+ boolean[] nullableParameters = collector.nullableLeaking;
+ for (int i = 0; i < nullableParameters.length; i++) {
+ nullableParameters[i] |= notNullParameters[i];
+ }
+ return new LeakingParameters((Frame<Value>[])(Frame<?>[])frames, notNullParameters, nullableParameters);
+ }
+
+ public static LeakingParameters buildFast(String className, MethodNode methodNode, boolean jsr) throws AnalyzerException {
+ IParametersUsage parametersUsage = new IParametersUsage(methodNode);
+ Frame<?>[] frames = jsr ?
+ new Analyzer<IParamsValue>(parametersUsage).analyze(className, methodNode) :
+ new LiteAnalyzer<IParamsValue>(parametersUsage).analyze(className, methodNode);
+ int leakingMask = parametersUsage.leaking;
+ int nullableLeakingMask = parametersUsage.nullableLeaking;
+ boolean[] notNullParameters = new boolean[parametersUsage.arity];
+ boolean[] nullableParameters = new boolean[parametersUsage.arity];
+ for (int i = 0; i < notNullParameters.length; i++) {
+ notNullParameters[i] = (leakingMask & (1 << i)) != 0;
+ nullableParameters[i] = ((leakingMask | nullableLeakingMask) & (1 << i)) != 0;
+ }
+ return new LeakingParameters((Frame<Value>[])frames, notNullParameters, nullableParameters);
+ }
+}
+
+final class ParamsValue implements Value {
+ @NotNull final boolean[] params;
+ final int size;
+
+ ParamsValue(@NotNull boolean[] params, int size) {
+ this.params = params;
+ this.size = size;
+ }
+
+ @Override
+ public int getSize() {
+ return size;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null) return false;
+ ParamsValue that = (ParamsValue)o;
+ return (this.size == that.size && Arrays.equals(this.params, that.params));
+ }
+
+ @Override
+ public int hashCode() {
+ return 31 * Arrays.hashCode(params) + size;
+ }
+}
+
+// specialized version
+final class IParamsValue implements Value {
+ final int params;
+ final int size;
+
+ IParamsValue(int params, int size) {
+ this.params = params;
+ this.size = size;
+ }
+
+ @Override
+ public int getSize() {
+ return size;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null) return false;
+ IParamsValue that = (IParamsValue)o;
+ return (this.size == that.size && this.params == that.params);
+ }
+
+ @Override
+ public int hashCode() {
+ return 31 * params + size;
+ }
+}
+
+class ParametersUsage extends Interpreter<ParamsValue> {
+ final ParamsValue val1;
+ final ParamsValue val2;
+ int called = -1;
+ final int rangeStart;
+ final int rangeEnd;
+ final int arity;
+ final int shift;
+
+ ParametersUsage(MethodNode methodNode) {
+ super(ASM5);
+ arity = Type.getArgumentTypes(methodNode.desc).length;
+ boolean[] emptyParams = new boolean[arity];
+ val1 = new ParamsValue(emptyParams, 1);
+ val2 = new ParamsValue(emptyParams, 2);
+
+ shift = (methodNode.access & ACC_STATIC) == 0 ? 2 : 1;
+ rangeStart = shift;
+ rangeEnd = arity + shift;
+ }
+
+ @Override
+ public ParamsValue newValue(Type type) {
+ if (type == null) return val1;
+ called++;
+ if (type == Type.VOID_TYPE) return null;
+ if (called < rangeEnd && rangeStart <= called && (ASMUtils.isReferenceType(type) || ASMUtils.isBooleanType(type))) {
+ boolean[] params = new boolean[arity];
+ params[called - shift] = true;
+ return type.getSize() == 1 ? new ParamsValue(params, 1) : new ParamsValue(params, 2);
+ }
+ else {
+ return type.getSize() == 1 ? val1 : val2;
+ }
+ }
+
+ @Override
+ public ParamsValue newOperation(final AbstractInsnNode insn) {
+ int size;
+ switch (insn.getOpcode()) {
+ case LCONST_0:
+ case LCONST_1:
+ case DCONST_0:
+ case DCONST_1:
+ size = 2;
+ break;
+ case LDC:
+ Object cst = ((LdcInsnNode) insn).cst;
+ size = cst instanceof Long || cst instanceof Double ? 2 : 1;
+ break;
+ case GETSTATIC:
+ size = Type.getType(((FieldInsnNode) insn).desc).getSize();
+ break;
+ default:
+ size = 1;
+ }
+ return size == 1 ? val1 : val2;
+ }
+
+ @Override
+ public ParamsValue copyOperation(AbstractInsnNode insn, ParamsValue value) {
+ return value;
+ }
+
+ @Override
+ public ParamsValue unaryOperation(AbstractInsnNode insn, ParamsValue value) {
+ int size;
+ switch (insn.getOpcode()) {
+ case CHECKCAST:
+ return value;
+ case LNEG:
+ case DNEG:
+ case I2L:
+ case I2D:
+ case L2D:
+ case F2L:
+ case F2D:
+ case D2L:
+ size = 2;
+ break;
+ case GETFIELD:
+ size = Type.getType(((FieldInsnNode) insn).desc).getSize();
+ break;
+ default:
+ size = 1;
+ }
+ return size == 1 ? val1 : val2;
+ }
+
+ @Override
+ public ParamsValue binaryOperation(AbstractInsnNode insn, ParamsValue value1, ParamsValue value2) {
+ int size;
+ switch (insn.getOpcode()) {
+ case LALOAD:
+ case DALOAD:
+ case LADD:
+ case DADD:
+ case LSUB:
+ case DSUB:
+ case LMUL:
+ case DMUL:
+ case LDIV:
+ case DDIV:
+ case LREM:
+ case DREM:
+ case LSHL:
+ case LSHR:
+ case LUSHR:
+ case LAND:
+ case LOR:
+ case LXOR:
+ size = 2;
+ break;
+ default:
+ size = 1;
+ }
+ return size == 1 ? val1 : val2;
+ }
+
+ @Override
+ public ParamsValue ternaryOperation(AbstractInsnNode insn, ParamsValue value1, ParamsValue value2, ParamsValue value3) {
+ return val1;
+ }
+
+ @Override
+ public ParamsValue naryOperation(AbstractInsnNode insn, List<? extends ParamsValue> values) {
+ int size;
+ int opcode = insn.getOpcode();
+ if (opcode == MULTIANEWARRAY) {
+ size = 1;
+ } else {
+ String desc = (opcode == INVOKEDYNAMIC) ? ((InvokeDynamicInsnNode) insn).desc : ((MethodInsnNode) insn).desc;
+ size = Type.getReturnType(desc).getSize();
+ }
+ return size == 1 ? val1 : val2;
+ }
+
+ @Override
+ public void returnOperation(AbstractInsnNode insn, ParamsValue value, ParamsValue expected) {}
+
+ @Override
+ public ParamsValue merge(ParamsValue v1, ParamsValue v2) {
+ if (v1.equals(v2)) return v1;
+ boolean[] params = new boolean[arity];
+ boolean[] params1 = v1.params;
+ boolean[] params2 = v2.params;
+ for (int i = 0; i < arity; i++) {
+ params[i] = params1[i] || params2[i];
+ }
+ return new ParamsValue(params, Math.min(v1.size, v2.size));
+ }
+}
+
+class IParametersUsage extends Interpreter<IParamsValue> {
+ static final IParamsValue val1 = new IParamsValue(0, 1);
+ static final IParamsValue val2 = new IParamsValue(0, 2);
+ int leaking = 0;
+ int nullableLeaking = 0;
+ int called = -1;
+ final int rangeStart;
+ final int rangeEnd;
+ final int arity;
+ final int shift;
+
+ IParametersUsage(MethodNode methodNode) {
+ super(ASM5);
+ arity = Type.getArgumentTypes(methodNode.desc).length;
+ shift = (methodNode.access & ACC_STATIC) == 0 ? 2 : 1;
+ rangeStart = shift;
+ rangeEnd = arity + shift;
+ }
+
+ @Override
+ public IParamsValue newValue(Type type) {
+ if (type == null) return val1;
+ called++;
+ if (type == Type.VOID_TYPE) return null;
+ if (called < rangeEnd && rangeStart <= called && (ASMUtils.isReferenceType(type) || ASMUtils.isBooleanType(type))) {
+ int n = called - shift;
+ return type.getSize() == 1 ? new IParamsValue(1 << n, 1) : new IParamsValue(1 << n, 2);
+ }
+ else {
+ return type.getSize() == 1 ? val1 : val2;
+ }
+ }
+
+ @Override
+ public IParamsValue newOperation(final AbstractInsnNode insn) {
+ int size;
+ switch (insn.getOpcode()) {
+ case LCONST_0:
+ case LCONST_1:
+ case DCONST_0:
+ case DCONST_1:
+ size = 2;
+ break;
+ case LDC:
+ Object cst = ((LdcInsnNode) insn).cst;
+ size = cst instanceof Long || cst instanceof Double ? 2 : 1;
+ break;
+ case GETSTATIC:
+ size = ASMUtils.getSizeFast(((FieldInsnNode)insn).desc);
+ break;
+ default:
+ size = 1;
+ }
+ return size == 1 ? val1 : val2;
+ }
+
+ @Override
+ public IParamsValue copyOperation(AbstractInsnNode insn, IParamsValue value) {
+ return value;
+ }
+
+ @Override
+ public IParamsValue unaryOperation(AbstractInsnNode insn, IParamsValue value) {
+ int size;
+ switch (insn.getOpcode()) {
+ case CHECKCAST:
+ return value;
+ case LNEG:
+ case DNEG:
+ case I2L:
+ case I2D:
+ case L2D:
+ case F2L:
+ case F2D:
+ case D2L:
+ size = 2;
+ break;
+ case GETFIELD:
+ size = ASMUtils.getSizeFast(((FieldInsnNode)insn).desc);
+ leaking |= value.params;
+ break;
+ case ARRAYLENGTH:
+ case MONITORENTER:
+ case INSTANCEOF:
+ case IRETURN:
+ case ARETURN:
+ case IFNONNULL:
+ case IFNULL:
+ case IFEQ:
+ case IFNE:
+ size = 1;
+ leaking |= value.params;
+ break;
+ default:
+ size = 1;
+ }
+ return size == 1 ? val1 : val2;
+ }
+
+ @Override
+ public IParamsValue binaryOperation(AbstractInsnNode insn, IParamsValue value1, IParamsValue value2) {
+ int size;
+ switch (insn.getOpcode()) {
+ case LALOAD:
+ case DALOAD:
+ size = 2;
+ leaking |= value1.params;
+ break;
+ case LADD:
+ case DADD:
+ case LSUB:
+ case DSUB:
+ case LMUL:
+ case DMUL:
+ case LDIV:
+ case DDIV:
+ case LREM:
+ case DREM:
+ case LSHL:
+ case LSHR:
+ case LUSHR:
+ case LAND:
+ case LOR:
+ case LXOR:
+ size = 2;
+ break;
+ case IALOAD:
+ case FALOAD:
+ case AALOAD:
+ case BALOAD:
+ case CALOAD:
+ case SALOAD:
+ leaking |= value1.params;
+ size = 1;
+ break;
+ case PUTFIELD:
+ leaking |= value1.params;
+ nullableLeaking |= value2.params;
+ size = 1;
+ break;
+ default:
+ size = 1;
+ }
+ return size == 1 ? val1 : val2;
+ }
+
+ @Override
+ public IParamsValue ternaryOperation(AbstractInsnNode insn, IParamsValue value1, IParamsValue value2, IParamsValue value3) {
+ switch (insn.getOpcode()) {
+ case IASTORE:
+ case LASTORE:
+ case FASTORE:
+ case DASTORE:
+ case BASTORE:
+ case CASTORE:
+ case SASTORE:
+ leaking |= value1.params;
+ break;
+ case AASTORE:
+ leaking |= value1.params;
+ nullableLeaking |= value3.params;
+ break;
+ default:
+ }
+ return val1;
+ }
+
+ @Override
+ public IParamsValue naryOperation(AbstractInsnNode insn, List<? extends IParamsValue> values) {
+ int opcode = insn.getOpcode();
+ switch (opcode) {
+ case INVOKESTATIC:
+ case INVOKESPECIAL:
+ case INVOKEVIRTUAL:
+ case INVOKEINTERFACE:
+ for (IParamsValue value : values) {
+ leaking |= value.params;
+ }
+ break;
+ default:
+ }
+ int size;
+ if (opcode == MULTIANEWARRAY) {
+ size = 1;
+ } else {
+ String desc = (opcode == INVOKEDYNAMIC) ? ((InvokeDynamicInsnNode) insn).desc : ((MethodInsnNode) insn).desc;
+ size = ASMUtils.getReturnSizeFast(desc);
+ }
+ return size == 1 ? val1 : val2;
+ }
+
+ @Override
+ public void returnOperation(AbstractInsnNode insn, IParamsValue value, IParamsValue expected) {}
+
+ @Override
+ public IParamsValue merge(IParamsValue v1, IParamsValue v2) {
+ if (v1.equals(v2)) return v1;
+ return new IParamsValue(v1.params | v2.params, Math.min(v1.size, v2.size));
+ }
+}
+
+class LeakingParametersCollector extends ParametersUsage {
+ final boolean[] leaking;
+ final boolean[] nullableLeaking;
+ LeakingParametersCollector(MethodNode methodNode) {
+ super(methodNode);
+ leaking = new boolean[arity];
+ nullableLeaking = new boolean[arity];
+ }
+
+ @Override
+ public ParamsValue unaryOperation(AbstractInsnNode insn, ParamsValue value) {
+ switch (insn.getOpcode()) {
+ case GETFIELD:
+ case ARRAYLENGTH:
+ case MONITORENTER:
+ case INSTANCEOF:
+ case IRETURN:
+ case ARETURN:
+ case IFNONNULL:
+ case IFNULL:
+ case IFEQ:
+ case IFNE:
+ boolean[] params = value.params;
+ for (int i = 0; i < arity; i++) {
+ leaking[i] |= params[i];
+ }
+ break;
+ default:
+ }
+ return super.unaryOperation(insn, value);
+ }
+
+ @Override
+ public ParamsValue binaryOperation(AbstractInsnNode insn, ParamsValue value1, ParamsValue value2) {
+ switch (insn.getOpcode()) {
+ case IALOAD:
+ case LALOAD:
+ case FALOAD:
+ case DALOAD:
+ case AALOAD:
+ case BALOAD:
+ case CALOAD:
+ case SALOAD:
+ boolean[] params = value1.params;
+ for (int i = 0; i < arity; i++) {
+ leaking[i] |= params[i];
+ }
+ break;
+ case PUTFIELD:
+ params = value1.params;
+ for (int i = 0; i < arity; i++) {
+ leaking[i] |= params[i];
+ }
+ params = value2.params;
+ for (int i = 0; i < arity; i++) {
+ nullableLeaking[i] |= params[i];
+ }
+ break;
+ default:
+ }
+ return super.binaryOperation(insn, value1, value2);
+ }
+
+ @Override
+ public ParamsValue ternaryOperation(AbstractInsnNode insn, ParamsValue value1, ParamsValue value2, ParamsValue value3) {
+ switch (insn.getOpcode()) {
+ case IASTORE:
+ case LASTORE:
+ case FASTORE:
+ case DASTORE:
+ case BASTORE:
+ case CASTORE:
+ case SASTORE:
+ boolean[] params = value1.params;
+ for (int i = 0; i < arity; i++) {
+ leaking[i] |= params[i];
+ }
+ break;
+ case AASTORE:
+ params = value1.params;
+ for (int i = 0; i < arity; i++) {
+ leaking[i] |= params[i];
+ }
+ params = value3.params;
+ for (int i = 0; i < arity; i++) {
+ nullableLeaking[i] |= params[i];
+ }
+ break;
+ default:
+ }
+ return super.ternaryOperation(insn, value1, value2, value3);
+ }
+
+ @Override
+ public ParamsValue naryOperation(AbstractInsnNode insn, List<? extends ParamsValue> values) {
+ switch (insn.getOpcode()) {
+ case INVOKESTATIC:
+ case INVOKESPECIAL:
+ case INVOKEVIRTUAL:
+ case INVOKEINTERFACE:
+ for (ParamsValue value : values) {
+ boolean[] params = value.params;
+ for (int i = 0; i < arity; i++) {
+ leaking[i] |= params[i];
+ }
+ }
+ break;
+ default:
+ }
+ return super.naryOperation(insn, values);
+ }
+}
+
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/LiteAnalyzer.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/LiteAnalyzer.java
new file mode 100644
index 000000000000..22961208076b
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/LiteAnalyzer.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection.bytecodeAnalysis.asm;
+
+import org.jetbrains.org.objectweb.asm.Opcodes;
+import org.jetbrains.org.objectweb.asm.Type;
+import org.jetbrains.org.objectweb.asm.tree.*;
+import org.jetbrains.org.objectweb.asm.tree.analysis.AnalyzerException;
+import org.jetbrains.org.objectweb.asm.tree.analysis.Frame;
+import org.jetbrains.org.objectweb.asm.tree.analysis.Interpreter;
+import org.jetbrains.org.objectweb.asm.tree.analysis.Value;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Specialized lite version of {@link org.objectweb.asm.tree.analysis.Analyzer}.
+ * No processing of Subroutines. May be used for methods without JSR/RET instructions.
+ *
+ * @author lambdamix
+ */
+public class LiteAnalyzer<V extends Value> implements Opcodes {
+
+ private final Interpreter<V> interpreter;
+
+ private Frame<V>[] frames;
+
+ private boolean[] queued;
+
+ private int[] queue;
+
+ private int top;
+
+ public LiteAnalyzer(final Interpreter<V> interpreter) {
+ this.interpreter = interpreter;
+ }
+
+ public Frame<V>[] analyze(final String owner, final MethodNode m) throws AnalyzerException {
+ if ((m.access & (ACC_ABSTRACT | ACC_NATIVE)) != 0 || m.instructions.size() == 0) {
+ frames = (Frame<V>[]) new Frame<?>[0];
+ return frames;
+ }
+ int n = m.instructions.size();
+ InsnList insns = m.instructions;
+ List<TryCatchBlockNode>[] handlers = (List<TryCatchBlockNode>[]) new List<?>[n];
+ frames = (Frame<V>[]) new Frame<?>[n];
+ queued = new boolean[n];
+ queue = new int[n];
+ top = 0;
+
+ // computes exception handlers for each instruction
+ for (int i = 0; i < m.tryCatchBlocks.size(); ++i) {
+ TryCatchBlockNode tcb = m.tryCatchBlocks.get(i);
+ int begin = insns.indexOf(tcb.start);
+ int end = insns.indexOf(tcb.end);
+ for (int j = begin; j < end; ++j) {
+ List<TryCatchBlockNode> insnHandlers = handlers[j];
+ if (insnHandlers == null) {
+ insnHandlers = new ArrayList<TryCatchBlockNode>();
+ handlers[j] = insnHandlers;
+ }
+ insnHandlers.add(tcb);
+ }
+ }
+
+ // initializes the data structures for the control flow analysis
+ Frame<V> current = new Frame<V>(m.maxLocals, m.maxStack);
+ Frame<V> handler = new Frame<V>(m.maxLocals, m.maxStack);
+ current.setReturn(interpreter.newValue(Type.getReturnType(m.desc)));
+ Type[] args = Type.getArgumentTypes(m.desc);
+ int local = 0;
+ if ((m.access & ACC_STATIC) == 0) {
+ Type ctype = Type.getObjectType(owner);
+ current.setLocal(local++, interpreter.newValue(ctype));
+ }
+ for (int i = 0; i < args.length; ++i) {
+ current.setLocal(local++, interpreter.newValue(args[i]));
+ if (args[i].getSize() == 2) {
+ current.setLocal(local++, interpreter.newValue(null));
+ }
+ }
+ while (local < m.maxLocals) {
+ current.setLocal(local++, interpreter.newValue(null));
+ }
+ merge(0, current);
+
+ // control flow analysis
+ while (top > 0) {
+ int insn = queue[--top];
+ Frame<V> f = frames[insn];
+ queued[insn] = false;
+
+ AbstractInsnNode insnNode = null;
+ try {
+ insnNode = m.instructions.get(insn);
+ int insnOpcode = insnNode.getOpcode();
+ int insnType = insnNode.getType();
+
+ if (insnType == AbstractInsnNode.LABEL || insnType == AbstractInsnNode.LINE || insnType == AbstractInsnNode.FRAME) {
+ merge(insn + 1, f);
+ } else {
+ current.init(f).execute(insnNode, interpreter);
+
+ if (insnNode instanceof JumpInsnNode) {
+ JumpInsnNode j = (JumpInsnNode) insnNode;
+ if (insnOpcode != GOTO && insnOpcode != JSR) {
+ merge(insn + 1, current);
+ }
+ int jump = insns.indexOf(j.label);
+ merge(jump, current);
+ } else if (insnNode instanceof LookupSwitchInsnNode) {
+ LookupSwitchInsnNode lsi = (LookupSwitchInsnNode) insnNode;
+ int jump = insns.indexOf(lsi.dflt);
+ merge(jump, current);
+ for (int j = 0; j < lsi.labels.size(); ++j) {
+ LabelNode label = lsi.labels.get(j);
+ jump = insns.indexOf(label);
+ merge(jump, current);
+ }
+ } else if (insnNode instanceof TableSwitchInsnNode) {
+ TableSwitchInsnNode tsi = (TableSwitchInsnNode) insnNode;
+ int jump = insns.indexOf(tsi.dflt);
+ merge(jump, current);
+ for (int j = 0; j < tsi.labels.size(); ++j) {
+ LabelNode label = tsi.labels.get(j);
+ jump = insns.indexOf(label);
+ merge(jump, current);
+ }
+ } else if (insnOpcode != ATHROW && (insnOpcode < IRETURN || insnOpcode > RETURN)) {
+ merge(insn + 1, current);
+ }
+ }
+
+ List<TryCatchBlockNode> insnHandlers = handlers[insn];
+ if (insnHandlers != null) {
+ for (int i = 0; i < insnHandlers.size(); ++i) {
+ TryCatchBlockNode tcb = insnHandlers.get(i);
+ int jump = insns.indexOf(tcb.handler);
+ handler.init(f);
+ handler.clearStack();
+ handler.push(interpreter.newValue(ASMUtils.THROWABLE_TYPE));
+ merge(jump, handler);
+ }
+ }
+ } catch (AnalyzerException e) {
+ throw new AnalyzerException(e.node, "Error at instruction " + insn + ": " + e.getMessage(), e);
+ } catch (Exception e) {
+ throw new AnalyzerException(insnNode, "Error at instruction " + insn + ": " + e.getMessage(), e);
+ }
+ }
+
+ return frames;
+ }
+
+ public Frame<V>[] getFrames() {
+ return frames;
+ }
+
+ private void merge(final int insn, final Frame<V> frame) throws AnalyzerException {
+ Frame<V> oldFrame = frames[insn];
+ boolean changes;
+
+ if (oldFrame == null) {
+ frames[insn] = new Frame<V>(frame);
+ changes = true;
+ } else {
+ changes = oldFrame.merge(frame, interpreter);
+ }
+ if (changes && !queued[insn]) {
+ queued[insn] = true;
+ queue[top++] = insn;
+ }
+ }
+
+}
+
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/LiteFramelessAnalyzer.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/LiteFramelessAnalyzer.java
new file mode 100644
index 000000000000..0a9721018862
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/LiteFramelessAnalyzer.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection.bytecodeAnalysis.asm;
+
+import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode;
+import org.jetbrains.org.objectweb.asm.tree.analysis.AnalyzerException;
+
+import java.util.List;
+
+/**
+ * Specialized lite version of {@link FramelessAnalyzer}.
+ * No processing of Subroutines. May be used for methods without JSR/RET instructions.
+ *
+ * @author lambdamix
+ */
+public class LiteFramelessAnalyzer extends FramelessAnalyzer {
+
+ @Override
+ protected void findSubroutine(int insn, FramelessAnalyzer.Subroutine sub, List<AbstractInsnNode> calls) throws AnalyzerException {
+ }
+
+ @Override
+ protected void merge(final int insn, final FramelessAnalyzer.Subroutine subroutine) throws AnalyzerException {
+ if (!wasQueued[insn]) {
+ wasQueued[insn] = true;
+ if (!queued[insn]) {
+ queued[insn] = true;
+ queue[top++] = insn;
+ }
+ }
+ }
+
+ @Override
+ protected void merge(final int insn, final FramelessAnalyzer.Subroutine subroutineBeforeJSR, final boolean[] access) throws AnalyzerException {
+ if (!wasQueued[insn]) {
+ wasQueued[insn] = true;
+ if (!queued[insn]) {
+ queued[insn] = true;
+ queue[top++] = insn;
+ }
+ }
+ }
+}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/OriginsAnalysis.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/OriginsAnalysis.java
new file mode 100644
index 000000000000..e154bf847730
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/OriginsAnalysis.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection.bytecodeAnalysis.asm;
+
+import gnu.trove.TIntArrayList;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.org.objectweb.asm.Opcodes;
+import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode;
+import org.jetbrains.org.objectweb.asm.tree.InsnList;
+import org.jetbrains.org.objectweb.asm.tree.analysis.*;
+
+import java.util.HashSet;
+import java.util.LinkedList;
+
+/**
+ * @author lambdamix
+ */
+public class OriginsAnalysis {
+
+ private static SourceInterpreter ourInterpreter = new SourceInterpreter() {
+ @Override
+ public SourceValue copyOperation(AbstractInsnNode insn, SourceValue value) {
+ return value;
+ }
+ };
+
+ private static class PreValue extends SourceValue {
+ final boolean local;
+ final int slot;
+
+ public PreValue(boolean local, int slot, int size) {
+ super(size);
+ this.local = local;
+ this.slot = slot;
+ }
+ }
+
+ private static class Location {
+ final boolean local;
+ final int slot;
+
+ Location(boolean local, int slot) {
+ this.local = local;
+ this.slot = slot;
+ }
+ }
+
+ private static class InsnLocation extends Location {
+ final int insnIndex;
+
+ private InsnLocation(boolean local, int insnIndex, int slot) {
+ super(local, slot);
+ this.insnIndex = insnIndex;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null) return false;
+ InsnLocation insnLocation = (InsnLocation)o;
+ if (local != insnLocation.local) return false;
+ if (insnIndex != insnLocation.insnIndex) return false;
+ if (slot != insnLocation.slot) return false;
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ // +1 is to avoid collisions
+ int result = 31 * insnIndex + slot + 1;
+ return local ? result : -result;
+ }
+ }
+
+ /**
+ *
+ * @param frames fixpoint of frames
+ * @param instructions method instructions
+ * @param graph method control flow graph
+ * @return array, array[i] == true means that the result of a method execution may originate at an i-th instruction
+ * @throws AnalyzerException
+ */
+ public static boolean[] resultOrigins(Frame<Value>[] frames, InsnList instructions, ControlFlowGraph graph) throws AnalyzerException {
+
+ TIntArrayList[] backTransitions = new TIntArrayList[instructions.size()];
+ for (int i = 0; i < backTransitions.length; i++) {
+ backTransitions[i] = new TIntArrayList();
+ }
+ LinkedList<InsnLocation> queue = new LinkedList<InsnLocation>();
+ HashSet<InsnLocation> queued = new HashSet<InsnLocation>();
+ for (int from = 0; from < instructions.size(); from++) {
+ for (int to : graph.transitions[from]) {
+ TIntArrayList froms = backTransitions[to];
+ froms.add(from);
+ int opcode = instructions.get(to).getOpcode();
+ if (opcode >= Opcodes.IRETURN && opcode <= Opcodes.ARETURN) {
+ InsnLocation sourceLoc = new InsnLocation(false, from, frames[to].getStackSize() - 1);
+ if (queued.add(sourceLoc)) {
+ queue.push(sourceLoc);
+ }
+ }
+ }
+ }
+
+ boolean[] result = new boolean[instructions.size()];
+
+ while (!queue.isEmpty()) {
+ InsnLocation resultLocation = queue.pop();
+
+ int insnIndex = resultLocation.insnIndex;
+ AbstractInsnNode insn = instructions.get(insnIndex);
+ int opcode = insn.getOpcode();
+ Location preLocation = previousLocation(frames[insnIndex], resultLocation, insn);
+ if (preLocation == null) {
+ if (opcode != Opcodes.INVOKEINTERFACE && opcode != Opcodes.GETFIELD && !(opcode >= Opcodes.IALOAD && opcode <= Opcodes.SALOAD)) {
+ result[insnIndex] = true;
+ }
+ } else {
+ TIntArrayList froms = backTransitions[insnIndex];
+ for (int i = 0; i < froms.size(); i++) {
+ InsnLocation preILoc = new InsnLocation(preLocation.local, froms.getQuick(i), preLocation.slot);
+ if (queued.add(preILoc)) {
+ queue.push(preILoc);
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ *
+ * @param frame a start frame with an interesting value
+ * @param location location of an interesting value *after* execution of an instruction
+ * @param insn an executed instruction
+ * @return location of an interesting value *before* execution of an instruction (in the past) or null if it is not traceable
+ * @throws AnalyzerException
+ */
+ @Nullable
+ private static Location previousLocation(Frame<Value> frame, Location location, AbstractInsnNode insn) throws AnalyzerException {
+ int insnType = insn.getType();
+ if (insnType == AbstractInsnNode.LABEL || insnType == AbstractInsnNode.LINE || insnType == AbstractInsnNode.FRAME) {
+ return location;
+ }
+ int opCode = insn.getOpcode();
+ if (location.local && !((opCode >= Opcodes.ISTORE && opCode <= Opcodes.ASTORE) || opCode == Opcodes.IINC)) {
+ return location;
+ }
+ Frame<SourceValue> preFrame = makePreFrame(frame);
+ preFrame.execute(insn, ourInterpreter);
+ if (location.local) {
+ SourceValue preVal = preFrame.getLocal(location.slot);
+ if (preVal instanceof PreValue) {
+ PreValue val = (PreValue)preVal;
+ return new Location(val.local, val.slot);
+ }
+ } else {
+ SourceValue preVal = preFrame.getStack(location.slot);
+ if (preVal instanceof PreValue) {
+ PreValue val = (PreValue)preVal;
+ return new Location(val.local, val.slot);
+ }
+ }
+ return null;
+ }
+
+ private static Frame<SourceValue> makePreFrame(Frame<Value> frame) {
+ Frame<SourceValue> preFrame = new Frame<SourceValue>(frame.getLocals(), frame.getMaxStackSize());
+ for (int i = 0; i < frame.getLocals(); i++) {
+ preFrame.setLocal(i, new PreValue(true, i, frame.getLocal(i).getSize()));
+ }
+ for (int i = 0; i < frame.getStackSize(); i++) {
+ preFrame.push(new PreValue(false, i, frame.getStack(i).getSize()));
+ }
+ return preFrame;
+ }
+}
+
+
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/RichControlFlow.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/RichControlFlow.java
new file mode 100644
index 000000000000..ea8f69c2c870
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/asm/RichControlFlow.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection.bytecodeAnalysis.asm;
+
+import com.intellij.codeInspection.bytecodeAnalysis.asm.ControlFlowGraph.Edge;
+
+import gnu.trove.TIntArrayList;
+import gnu.trove.TIntHashSet;
+import gnu.trove.TIntIterator;
+
+/**
+ * @author lambdamix
+ */
+public final class RichControlFlow {
+ public final ControlFlowGraph controlFlow;
+ public final DFSTree dfsTree;
+
+ public RichControlFlow(ControlFlowGraph controlFlow, DFSTree dfsTree) {
+ this.controlFlow = controlFlow;
+ this.dfsTree = dfsTree;
+ }
+
+ // Tarjan. Testing flow graph reducibility.
+ // Journal of Computer and System Sciences 9.3 (1974): 355-365.
+ public boolean reducible() {
+ if (dfsTree.back.isEmpty()) {
+ return true;
+ }
+ int size = controlFlow.transitions.length;
+ boolean[] loopEnters = dfsTree.loopEnters;
+ TIntHashSet[] cycleIncomings = new TIntHashSet[size];
+ // really this may be array, since dfs already ensures no duplicates
+ TIntArrayList[] nonCycleIncomings = new TIntArrayList[size];
+ int[] collapsedTo = new int[size];
+ int[] queue = new int[size];
+ int top;
+ for (int i = 0; i < size; i++) {
+ if (loopEnters[i]) {
+ cycleIncomings[i] = new TIntHashSet();
+ }
+ nonCycleIncomings[i] = new TIntArrayList();
+ collapsedTo[i] = i;
+ }
+
+ // from whom back connections
+ for (Edge edge : dfsTree.back) {
+ cycleIncomings[edge.to].add(edge.from);
+ }
+ // from whom ordinary connections
+ for (Edge edge : dfsTree.nonBack) {
+ nonCycleIncomings[edge.to].add(edge.from);
+ }
+
+ for (int w = size - 1; w >= 0 ; w--) {
+ top = 0;
+ // NB - it is modified later!
+ TIntHashSet p = cycleIncomings[w];
+ if (p == null) {
+ continue;
+ }
+ TIntIterator iter = p.iterator();
+ while (iter.hasNext()) {
+ queue[top++] = iter.next();
+ }
+
+ while (top > 0) {
+ int x = queue[--top];
+ TIntArrayList incoming = nonCycleIncomings[x];
+ for (int i = 0; i < incoming.size(); i++) {
+ int y1 = collapsedTo[incoming.getQuick(i)];
+ if (!dfsTree.isDescendant(y1, w)) {
+ return false;
+ }
+ if (y1 != w && p.add(y1)) {
+ queue[top++] = y1;
+ }
+ }
+ }
+
+ iter = p.iterator();
+ while (iter.hasNext()) {
+ collapsedTo[iter.next()] = w;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractInference.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractInference.java
index bd207e58a0fe..7037fac8cfea 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractInference.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractInference.java
@@ -27,6 +27,7 @@ import com.intellij.psi.util.CachedValuesManager;
import com.intellij.util.Function;
import com.intellij.util.NullableFunction;
import com.intellij.util.containers.ContainerUtil;
+import com.siyeh.ig.psiutils.SideEffectChecker;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -213,6 +214,16 @@ class ContractInferenceInterpreter {
}
}
+ if (expr instanceof PsiNewExpression) {
+ return toContracts(states, NOT_NULL_VALUE);
+ }
+ if (expr instanceof PsiMethodCallExpression) {
+ PsiMethod method = ((PsiMethodCallExpression)expr).resolveMethod();
+ if (method != null && NullableNotNullManager.isNotNull(method)) {
+ return toContracts(states, NOT_NULL_VALUE);
+ }
+ }
+
final ValueConstraint constraint = getLiteralConstraint(expr);
if (constraint != null) {
return toContracts(states, constraint);
@@ -315,7 +326,7 @@ class ContractInferenceInterpreter {
private List<MethodContract> visitStatements(List<ValueConstraint[]> states, PsiStatement... statements) {
List<MethodContract> result = ContainerUtil.newArrayList();
for (PsiStatement statement : statements) {
- if (statement instanceof PsiBlockStatement && ((PsiBlockStatement)statement).getCodeBlock().getStatements().length == 1) {
+ if (statement instanceof PsiBlockStatement) {
result.addAll(visitStatements(states, ((PsiBlockStatement)statement).getCodeBlock().getStatements()));
}
else if (statement instanceof PsiIfStatement) {
@@ -353,12 +364,36 @@ class ContractInferenceInterpreter {
List<MethodContract> conditionResults = visitExpression(states, ((PsiAssertStatement)statement).getAssertCondition());
result.addAll(toContracts(antecedentsOf(filterReturning(conditionResults, FALSE_VALUE)), THROW_EXCEPTION));
}
+ else if (statement instanceof PsiDeclarationStatement && !mayHaveSideEffects((PsiDeclarationStatement)statement)) {
+ continue;
+ }
+ else if (statement instanceof PsiDoWhileStatement) {
+ result.addAll(visitStatements(states, ((PsiDoWhileStatement)statement).getBody()));
+ }
+ else if (statement instanceof PsiTryStatement) {
+ PsiCodeBlock block = ((PsiTryStatement)statement).getTryBlock();
+ if (block != null) {
+ result.addAll(visitStatements(states, block.getStatements()));
+ }
+ }
break; // visit only the first statement unless it's 'if' whose 'then' always returns and the next statement is effectively 'else'
}
return result;
}
+ private static boolean mayHaveSideEffects(PsiDeclarationStatement statement) {
+ for (PsiElement element : statement.getDeclaredElements()) {
+ if (element instanceof PsiVariable) {
+ PsiExpression initializer = ((PsiVariable)element).getInitializer();
+ if (initializer != null && SideEffectChecker.mayHaveSideEffects(initializer)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
private static boolean alwaysReturns(@Nullable PsiStatement statement) {
if (statement instanceof PsiReturnStatement || statement instanceof PsiThrowStatement) return true;
if (statement instanceof PsiBlockStatement) {
@@ -381,6 +416,7 @@ class ContractInferenceInterpreter {
if (expr.textMatches(PsiKeyword.TRUE)) return TRUE_VALUE;
if (expr.textMatches(PsiKeyword.FALSE)) return FALSE_VALUE;
if (expr.textMatches(PsiKeyword.NULL)) return NULL_VALUE;
+ if (((PsiLiteralExpression)expr).getValue() instanceof String) return NOT_NULL_VALUE;
}
return null;
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java
index 7ef19f2b73d0..7539d7195701 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java
@@ -591,12 +591,14 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
generateBoxingUnboxingInstructionFor(caseExpression, PsiType.INT);
final PsiClass psiClass = PsiUtil.resolveClassInType(caseExpression.getType());
- if (psiClass != null && psiClass.isEnum()) {
+ if (psiClass != null) {
addInstruction(new FieldReferenceInstruction(caseExpression, "switch statement expression"));
- enumValues = new HashSet<PsiEnumConstant>();
- for (PsiField f : psiClass.getFields()) {
- if (f instanceof PsiEnumConstant) {
- enumValues.add((PsiEnumConstant)f);
+ if (psiClass.isEnum()) {
+ enumValues = new HashSet<PsiEnumConstant>();
+ for (PsiField f : psiClass.getFields()) {
+ if (f instanceof PsiEnumConstant) {
+ enumValues.add((PsiEnumConstant)f);
+ }
}
}
} else {
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java
index 1b6d1dfedfec..3f0caf47679e 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java
@@ -640,6 +640,13 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
return true;
}
+ if (dfaLeft == dfaRight) {
+ if (dfaLeft instanceof DfaVariableValue && ((DfaVariableValue)dfaLeft).containsCalls()) {
+ return true;
+ }
+ return !isNegated;
+ }
+
if (isNull(dfaLeft) && isNotNull(dfaRight) || isNull(dfaRight) && isNotNull(dfaLeft)) {
return isNegated;
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaExpressionFactory.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaExpressionFactory.java
index ec9e02fce92d..7ebce779c3a8 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaExpressionFactory.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaExpressionFactory.java
@@ -155,7 +155,7 @@ public class DfaExpressionFactory {
@Nullable
private PsiVariable getArrayIndexVariable(@Nullable PsiExpression indexExpression) {
Object constant = JavaConstantExpressionEvaluator.computeConstantExpression(indexExpression, false);
- if (constant instanceof Integer) {
+ if (constant instanceof Integer && ((Integer)constant).intValue() >= 0) {
PsiVariable mockVar = myMockIndices.get(constant);
if (mockVar == null) {
mockVar = JavaPsiFacade.getElementFactory(indexExpression.getProject()).createField("$array$index$" + constant, PsiType.INT);
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java
index 3030bef32934..840103f5c993 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java
@@ -221,4 +221,8 @@ public class DfaVariableValue extends DfaValue {
return true;
}
+ public boolean containsCalls() {
+ return myVariable instanceof PsiMethod || myQualifier != null && myQualifier.containsCalls();
+ }
+
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/ImplementedAtRuntimeCondition.java b/java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/ImplementedAtRuntimeCondition.java
new file mode 100644
index 000000000000..55918450f481
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/ImplementedAtRuntimeCondition.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection.inheritance;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.psi.PsiClass;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public abstract class ImplementedAtRuntimeCondition {
+ public static final ExtensionPointName<ImplementedAtRuntimeCondition> EP_NAME = ExtensionPointName.create("com.intellij.codeInsight.implementedAtRuntime");
+
+ public abstract boolean isImplementedAtRuntime(@NotNull PsiClass psiClass);
+}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/javaDoc/JavaDocLocalInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/javaDoc/JavaDocLocalInspectionBase.java
index 5d6c4bcb59a1..36d7bc2f17ef 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/javaDoc/JavaDocLocalInspectionBase.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/javaDoc/JavaDocLocalInspectionBase.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -540,7 +540,7 @@ public class JavaDocLocalInspectionBase extends BaseJavaBatchLocalInspectionTool
}
if (required && superMethods.length == 0 && isTagRequired(psiMethod, "@throws") && psiMethod.getThrowsList().getReferencedTypes().length > 0) {
- final Map<PsiClassType, PsiClass> declaredExceptions = new HashMap<PsiClassType, PsiClass>();
+ final Map<PsiClassType, PsiClass> declaredExceptions = new LinkedHashMap<PsiClassType, PsiClass>();
final PsiClassType[] classTypes = psiMethod.getThrowsList().getReferencedTypes();
for (PsiClassType classType : classTypes) {
final PsiClass psiClass = classType.resolve();
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/unnecessaryModuleDependency/UnnecessaryModuleDependencyInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/unnecessaryModuleDependency/UnnecessaryModuleDependencyInspection.java
index f3884b30efeb..e51101c98460 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/unnecessaryModuleDependency/UnnecessaryModuleDependencyInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/unnecessaryModuleDependency/UnnecessaryModuleDependencyInspection.java
@@ -45,7 +45,7 @@ public class UnnecessaryModuleDependencyInspection extends GlobalInspectionTool
if (refEntity instanceof RefModule){
final RefModule refModule = (RefModule)refEntity;
final Module module = refModule.getModule();
- if (module.isDisposed()) return CommonProblemDescriptor.EMPTY_ARRAY;
+ if (module.isDisposed() || !scope.containsModule(module)) return CommonProblemDescriptor.EMPTY_ARRAY;
final ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
final OrderEntry[] declaredDependencies = moduleRootManager.getOrderEntries();
final Module[] declaredModuleDependencies = moduleRootManager.getDependencies();
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/unusedLibraries/UnusedLibrariesInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/unusedLibraries/UnusedLibrariesInspection.java
index 4db11dc0b0d0..6352731e322f 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/unusedLibraries/UnusedLibrariesInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/unusedLibraries/UnusedLibrariesInspection.java
@@ -70,7 +70,7 @@ public class UnusedLibrariesInspection extends GlobalInspectionTool {
if (refEntity instanceof RefModule) {
final RefModule refModule = (RefModule)refEntity;
final Module module = refModule.getModule();
- if (module.isDisposed()) return CommonProblemDescriptor.EMPTY_ARRAY;
+ if (module.isDisposed() || !scope.containsModule(module)) return CommonProblemDescriptor.EMPTY_ARRAY;
final ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
final Set<VirtualFile> usedRoots = refModule.getUserData(UnusedLibraryGraphAnnotator.USED_LIBRARY_ROOTS);
diff --git a/java/java-impl/src/com/intellij/analysis/BaseClassesAnalysisAction.java b/java/java-impl/src/com/intellij/analysis/BaseClassesAnalysisAction.java
index 383e62d40b47..42d3722fbaf3 100644
--- a/java/java-impl/src/com/intellij/analysis/BaseClassesAnalysisAction.java
+++ b/java/java-impl/src/com/intellij/analysis/BaseClassesAnalysisAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -57,6 +57,9 @@ public abstract class BaseClassesAnalysisAction extends BaseAnalysisAction {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
+ if (project.isDisposed()) {
+ return;
+ }
if (!upToDate) {
final int i = Messages.showYesNoCancelDialog(getProject(), AnalysisScopeBundle.message("recompile.confirmation.message"),
AnalysisScopeBundle.message("project.is.out.of.date"), Messages.getWarningIcon());
diff --git a/java/java-impl/src/com/intellij/application/options/JavaIndentOptionsProvider.java b/java/java-impl/src/com/intellij/application/options/JavaIndentOptionsProvider.java
deleted file mode 100644
index d71b71819c84..000000000000
--- a/java/java-impl/src/com/intellij/application/options/JavaIndentOptionsProvider.java
+++ /dev/null
@@ -1,109 +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.application.options;
-
-import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
-import com.intellij.psi.codeStyle.FileTypeIndentOptionsProvider;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.util.PsiUtil;
-import com.intellij.openapi.fileTypes.FileType;
-import com.intellij.openapi.fileTypes.StdFileTypes;
-import com.intellij.pom.java.LanguageLevel;
-import org.jetbrains.annotations.NonNls;
-
-/**
- * @author yole
- */
-public class JavaIndentOptionsProvider implements FileTypeIndentOptionsProvider {
- public CommonCodeStyleSettings.IndentOptions createIndentOptions() {
- return new CommonCodeStyleSettings.IndentOptions();
- }
-
- public FileType getFileType() {
- return StdFileTypes.JAVA;
- }
-
- public IndentOptionsEditor createOptionsEditor() {
- return new JavaIndentOptionsEditor();
- }
-
- @NonNls
- public String getPreviewText() {
- return "public class Foo {\n" +
- " public int[] X = new int[] { 1, 3, 5,\n" +
- " 7, 9, 11};\n" +
- " public void foo(boolean a, int x,\n" +
- " int y, int z) {\n" +
- " a = x == 0 &&\n" +
- " (y == 0 ||\n" +
- " z <= 4) &&\n" +
- " z >= 0;" +
- " label1: do {\n" +
- " try {\n" +
- " if(x > 0) {\n" +
- " int someVariable = a ? \n" +
- " x : \n" +
- " y;\n" +
- " } else if (x < 0) {\n" +
- " int someVariable = (y +\n" +
- " z\n" +
- " );\n" +
- " someVariable = x = \n" +
- " x +\n" +
- " y;\n" +
- " } else {\n" +
- " label2:\n" +
- " for (int i = 0;\n" +
- " i < 5;\n" +
- " i++) doSomething(i);\n" +
- " }\n" +
- " switch(a) {\n" +
- " case 0: \n" +
- " doCase0();\n" +
- " break;\n" +
- " default: \n" +
- " doDefault();\n" +
- " }\n" +
- " }\n" +
- " catch(Exception e) {\n" +
- " processException(e.getMessage(),\n" +
- " x + y, z, a);\n" +
- " }\n" +
- " finally {\n" +
- " processFinally();\n" +
- " }\n" +
- " }while(true);\n" +
- "\n" +
- " if (2 < 3) return;\n" +
- " if (3 < 4)\n" +
- " return;\n" +
- " do x++ while (x < 10000);\n" +
- " while (x < 50000) x++;\n" +
- " for (int i = 0; i < 5; i++) System.out.println(i);\n" +
- " }\n" +
- " private class InnerClass implements I1,\n" +
- " I2 {\n" +
- " public void bar() throws E1,\n" +
- " E2 {\n" +
- " }\n" +
- " }\n" +
- "}";
- }
-
- public void prepareForReformat(final PsiFile psiFile) {
- psiFile.putUserData(PsiUtil.FILE_LANGUAGE_LEVEL_KEY, LanguageLevel.HIGHEST);
- }
-}
diff --git a/java/java-impl/src/com/intellij/codeInsight/CodeInsightUtil.java b/java/java-impl/src/com/intellij/codeInsight/CodeInsightUtil.java
index 9f2b486164ce..ca7c26dbc811 100644
--- a/java/java-impl/src/com/intellij/codeInsight/CodeInsightUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/CodeInsightUtil.java
@@ -16,6 +16,7 @@
package com.intellij.codeInsight;
import com.intellij.codeInsight.completion.AllClassesGetter;
+import com.intellij.codeInsight.completion.CompletionUtil;
import com.intellij.codeInsight.completion.JavaCompletionUtil;
import com.intellij.codeInsight.completion.PrefixMatcher;
import com.intellij.lang.Language;
@@ -33,21 +34,21 @@ import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.ClassInheritorsSearch;
import com.intellij.psi.tree.IElementType;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.psi.util.PsiUtil;
-import com.intellij.psi.util.PsiUtilCore;
-import com.intellij.psi.util.TypeConversionUtil;
+import com.intellij.psi.util.*;
import com.intellij.psi.util.proximity.PsiProximityComparator;
import com.intellij.refactoring.util.RefactoringUtil;
import com.intellij.util.Consumer;
import com.intellij.util.FilteredQuery;
import com.intellij.util.Processor;
import com.intellij.util.Query;
-import com.intellij.psi.util.FileTypeUtils;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
public class CodeInsightUtil {
@Nullable
@@ -283,6 +284,11 @@ public class CodeInsightUtil {
final Processor<PsiClass> inheritorsProcessor =
createInheritorsProcessor(context, baseType, arrayDim, getRawSubtypes, consumer, baseClass, baseSubstitutor);
+
+ addContextTypeArguments(context, baseType, inheritorsProcessor);
+
+ if (baseClass.hasModifierProperty(PsiModifier.FINAL)) return;
+
if (matcher.getPrefix().length() > 2) {
AllClassesGetter.processJavaClasses(matcher, context.getProject(), scope, new Processor<PsiClass>() {
@Override
@@ -307,6 +313,30 @@ public class CodeInsightUtil {
}
+ private static void addContextTypeArguments(final PsiElement context,
+ final PsiClassType baseType,
+ final Processor<PsiClass> inheritorsProcessor) {
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ @Override
+ public void run() {
+ Set<String> usedNames = ContainerUtil.newHashSet();
+ PsiElementFactory factory = JavaPsiFacade.getElementFactory(context.getProject());
+ PsiElement each = context;
+ while (true) {
+ PsiTypeParameterListOwner typed = PsiTreeUtil.getParentOfType(each, PsiTypeParameterListOwner.class);
+ if (typed == null) break;
+ for (PsiTypeParameter parameter : typed.getTypeParameters()) {
+ if (baseType.isAssignableFrom(factory.createType(parameter)) && usedNames.add(parameter.getName())) {
+ inheritorsProcessor.process(CompletionUtil.getOriginalOrSelf(parameter));
+ }
+ }
+
+ each = typed;
+ }
+ }
+ });
+ }
+
public static Processor<PsiClass> createInheritorsProcessor(final PsiElement context, final PsiClassType baseType,
final int arrayDim,
final boolean getRawSubtypes,
diff --git a/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsLineMarkerProvider.java b/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsLineMarkerProvider.java
index 182f79c94bce..e373207222ea 100644
--- a/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsLineMarkerProvider.java
+++ b/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsLineMarkerProvider.java
@@ -91,10 +91,27 @@ public class ExternalAnnotationsLineMarkerProvider implements LineMarkerProvider
private static boolean hasNonCodeAnnotations(@NotNull PsiModifierListOwner element) {
Project project = element.getProject();
PsiAnnotation[] externalAnnotations = ExternalAnnotationsManager.getInstance(project).findExternalAnnotations(element);
- if (externalAnnotations != null && externalAnnotations.length > 0) {
- return true;
+ if (externalAnnotations != null) {
+ for (PsiAnnotation annotation : externalAnnotations) {
+ if (isVisibleAnnotation(annotation)) {
+ return true;
+ }
+ }
+ }
+ for (PsiAnnotation annotation : InferredAnnotationsManager.getInstance(project).findInferredAnnotations(element)) {
+ if (isVisibleAnnotation(annotation)) {
+ return true;
+ }
}
- return InferredAnnotationsManager.getInstance(project).findInferredAnnotations(element).length > 0;
+ return false;
+ }
+
+ private static boolean isVisibleAnnotation(@NotNull PsiAnnotation annotation) {
+ PsiJavaCodeReferenceElement ref = annotation.getNameReferenceElement();
+ if (ref == null) return true;
+
+ PsiElement target = ref.resolve();
+ return !(target instanceof PsiClass) || JavaDocInfoGenerator.isDocumentedAnnotationType((PsiClass)target);
}
@Override
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java
index 5ac14956fe4c..f5e43aa7bcec 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java
@@ -484,7 +484,7 @@ public class JavaCompletionData extends JavaAwareCompletionData {
}
}
- if ((isInsideParameterList(position) || isAtResourceVariableStart(position)) &&
+ if ((isInsideParameterList(position) || isAtResourceVariableStart(position) || isAtCatchVariableStart(position)) &&
!psiElement().afterLeaf(PsiKeyword.FINAL).accepts(position) &&
!AFTER_DOT.accepts(position)) {
result.addElement(TailTypeDecorator.withTail(createKeyword(position, PsiKeyword.FINAL), TailType.HUMBLE_SPACE_BEFORE_WORD));
@@ -673,6 +673,10 @@ public class JavaCompletionData extends JavaAwareCompletionData {
return psiElement().insideStarting(psiElement(PsiTypeElement.class).withParent(PsiResourceList.class)).accepts(position);
}
+ private static boolean isAtCatchVariableStart(PsiElement position) {
+ return psiElement().insideStarting(psiElement(PsiTypeElement.class).withParent(PsiCatchSection.class)).accepts(position);
+ }
+
private static void addBreakContinue(CompletionResultSet result, PsiElement position) {
PsiLoopStatement loop = PsiTreeUtil.getParentOfType(position, PsiLoopStatement.class);
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionSorting.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionSorting.java
index d144a67fcb69..5a18a4b42826 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionSorting.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionSorting.java
@@ -278,10 +278,12 @@ public class JavaCompletionSorting {
@NotNull
@Override
- public Comparable weigh(@NotNull LookupElement item) {
+ public MyResult weigh(@NotNull LookupElement item) {
final Object object = item.getObject();
if (object instanceof PsiClass) {
+ if (object instanceof PsiTypeParameter) return MyResult.typeParameter;
+
if (myTypeParameter != null && object.equals(PsiUtil.resolveClassInType(TypeConversionUtil.typeParameterErasure(myTypeParameter)))) {
return MyResult.exactlyExpected;
}
@@ -340,6 +342,7 @@ public class JavaCompletionSorting {
private enum MyResult {
expectedNoSelect,
+ typeParameter,
exactlyDefault,
ofDefaultType,
exactlyExpected,
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java
index 1112738c5464..8cc9d06aed04 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java
@@ -55,6 +55,7 @@ import com.intellij.util.NullableFunction;
import com.intellij.util.PairConsumer;
import com.intellij.util.PairFunction;
import com.intellij.util.containers.ContainerUtil;
+import com.siyeh.ig.psiutils.SideEffectChecker;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -606,21 +607,7 @@ public class JavaCompletionUtil {
}
public static boolean mayHaveSideEffects(@Nullable final PsiElement element) {
- if (element == null) return false;
- if (element instanceof PsiMethodCallExpression || element instanceof PsiNewExpression) return true;
- if (element instanceof PsiTypeCastExpression) {
- return mayHaveSideEffects(((PsiTypeCastExpression)element).getOperand());
- }
- if (element instanceof PsiArrayAccessExpression) {
- return mayHaveSideEffects(((PsiArrayAccessExpression)element).getArrayExpression());
- }
- if (element instanceof PsiJavaCodeReferenceElement) {
- return mayHaveSideEffects(((PsiJavaCodeReferenceElement)element).getQualifier());
- }
- if (element instanceof PsiParenthesizedExpression) {
- return mayHaveSideEffects(((PsiParenthesizedExpression)element).getExpression());
- }
- return true;
+ return element instanceof PsiExpression && SideEffectChecker.mayHaveSideEffects((PsiExpression)element);
}
public static void insertClassReference(@NotNull PsiClass psiClass, @NotNull PsiFile file, int offset) {
@@ -836,13 +823,16 @@ public class JavaCompletionUtil {
//need to shorten references in type argument list
public static void shortenReference(final PsiFile file, final int offset) throws IncorrectOperationException {
- final PsiDocumentManager manager = PsiDocumentManager.getInstance(file.getProject());
- manager.commitDocument(manager.getDocument(file));
+ Project project = file.getProject();
+ final PsiDocumentManager manager = PsiDocumentManager.getInstance(project);
+ Document document = manager.getDocument(file);
+ manager.commitDocument(document);
final PsiReference ref = file.findReferenceAt(offset);
if (ref != null) {
PsiElement element = ref.getElement();
if (element != null) {
- JavaCodeStyleManager.getInstance(file.getProject()).shortenClassReferences(element);
+ JavaCodeStyleManager.getInstance(project).shortenClassReferences(element);
+ PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(document);
}
}
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaGenerateMemberCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaGenerateMemberCompletionContributor.java
index 351eca4857fd..456c06fe8756 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaGenerateMemberCompletionContributor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaGenerateMemberCompletionContributor.java
@@ -26,6 +26,7 @@ import com.intellij.psi.infos.CandidateInfo;
import com.intellij.psi.util.MethodSignature;
import com.intellij.psi.util.PsiFormatUtil;
import com.intellij.psi.util.PsiFormatUtilBase;
+import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.ui.RowIcon;
import com.intellij.util.VisibilityUtil;
import com.intellij.util.containers.ContainerUtil;
@@ -98,13 +99,12 @@ public class JavaGenerateMemberCompletionContributor {
PsiClass baseClass = baseMethod.getContainingClass();
PsiSubstitutor substitutor = candidate.getSubstitutor();
if (!baseMethod.isConstructor() && baseClass != null && addedSignatures.add(baseMethod.getSignature(substitutor))) {
- result.addElement(createOverridingLookupElement(parent, implemented, baseMethod, baseClass, substitutor));
+ result.addElement(createOverridingLookupElement(implemented, baseMethod, baseClass, substitutor));
}
}
}
- private static LookupElementBuilder createOverridingLookupElement(final PsiClass parent,
- boolean implemented,
+ private static LookupElementBuilder createOverridingLookupElement(boolean implemented,
final PsiMethod baseMethod,
PsiClass baseClass, PsiSubstitutor substitutor) {
@@ -117,6 +117,9 @@ public class JavaGenerateMemberCompletionContributor {
public void handleInsert(InsertionContext context, LookupElement item) {
removeLookupString(context);
+ final PsiClass parent = PsiTreeUtil.findElementOfClassAtOffset(context.getFile(), context.getStartOffset(), PsiClass.class, false);
+ if (parent == null) return;
+
List<PsiMethod> prototypes = OverrideImplementUtil.overrideOrImplementMethod(parent, baseMethod, false);
insertGenerationInfos(context, OverrideImplementUtil.convert2GenerationInfos(prototypes));
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaInheritorsGetter.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaInheritorsGetter.java
index 1a14010ec834..a503de4d93a5 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaInheritorsGetter.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaInheritorsGetter.java
@@ -229,10 +229,7 @@ public class JavaInheritorsGetter extends CompletionProvider<CompletionParameter
//long
for (final PsiClassType type : expectedClassTypes) {
- final PsiClass psiClass = type.resolve();
- if (psiClass != null && !psiClass.hasModifierProperty(PsiModifier.FINAL)) {
- CodeInsightUtil.processSubTypes(type, parameters.getPosition(), false, matcher, consumer);
- }
+ CodeInsightUtil.processSubTypes(type, parameters.getPosition(), false, matcher, consumer);
}
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaMemberNameCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaMemberNameCompletionContributor.java
index a1d4a6f8ac81..bb45d770dea1 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaMemberNameCompletionContributor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaMemberNameCompletionContributor.java
@@ -414,7 +414,7 @@ public class JavaMemberNameCompletionContributor extends CompletionContributor {
outer:
for (int i = 0; i < strings.length; i++) {
String name = strings[i];
- if (!matcher.prefixMatches(name) || !JavaPsiFacade.getInstance(project).getNameHelper().isIdentifier(name, LanguageLevel.HIGHEST)) {
+ if (!matcher.prefixMatches(name) || !PsiNameHelper.getInstance(project).isIdentifier(name, LanguageLevel.HIGHEST)) {
continue;
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java
index 61d8abe18368..d5e04ce3f95a 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java
@@ -158,8 +158,9 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
@Override
public void consume(PsiType type) {
final PsiClass psiClass = PsiUtil.resolveClassInType(type);
- if (psiClass == null) return;
+ if (psiClass == null || psiClass instanceof PsiTypeParameter) return;
+ //noinspection SuspiciousMethodCalls
if (expectedClassTypes.contains(type)) return;
result.addElement(createInstanceofLookupElement(psiClass, parameterizedTypes));
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaColorProvider.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaColorProvider.java
index dfc7169a2777..f74e4431d451 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaColorProvider.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaColorProvider.java
@@ -15,7 +15,6 @@
*/
package com.intellij.codeInsight.daemon.impl;
-import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.editor.ElementColorProvider;
import com.intellij.psi.*;
import com.intellij.psi.impl.JavaConstantExpressionEvaluator;
@@ -32,7 +31,12 @@ import java.awt.*;
public class JavaColorProvider implements ElementColorProvider {
@Override
public Color getColorFrom(@NotNull PsiElement element) {
- if (element instanceof PsiNewExpression && element.getLanguage() == JavaLanguage.INSTANCE) {
+ return getJavaColorFromExpression(element);
+ }
+
+ @Nullable
+ public static Color getJavaColorFromExpression(@Nullable PsiElement element) {
+ if (element instanceof PsiNewExpression) {
final PsiNewExpression expr = (PsiNewExpression)element;
final PsiType type = expr.getType();
if (type != null) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateAnnotationMethodFromUsageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateAnnotationMethodFromUsageFix.java
index 487b6f07c707..5027752e47d0 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateAnnotationMethodFromUsageFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateAnnotationMethodFromUsageFix.java
@@ -44,7 +44,7 @@ public class CreateAnnotationMethodFromUsageFix extends CreateFromUsageBaseFix {
if (call == null || !call.isValid()) return false;
String name = call.getName();
- if (name == null || !JavaPsiFacade.getInstance(call.getProject()).getNameHelper().isIdentifier(name)) return false;
+ if (name == null || !PsiNameHelper.getInstance(call.getProject()).isIdentifier(name)) return false;
if (getAnnotationValueType(call.getValue()) == null) return false;
setText(QuickFixBundle.message("create.method.from.usage.text", name));
return true;
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreatePropertyFromUsageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreatePropertyFromUsageFix.java
index c36c25f4b47b..d1a6031c8bf8 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreatePropertyFromUsageFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreatePropertyFromUsageFix.java
@@ -269,7 +269,7 @@ public class CreatePropertyFromUsageFix extends CreateFromUsageBaseFix implement
@Override
public void run() {
String fieldName = state.getVariableValue(FIELD_VARIABLE).getText();
- if (!JavaPsiFacade.getInstance(project).getNameHelper().isIdentifier(fieldName)) return;
+ if (!PsiNameHelper.getInstance(project).isIdentifier(fieldName)) return;
String fieldType = state.getVariableValue(TYPE_VARIABLE).getText();
PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaTypedHandler.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaTypedHandler.java
index e2dedf5ea3ec..5d2acb275291 100644
--- a/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaTypedHandler.java
+++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaTypedHandler.java
@@ -18,6 +18,9 @@ package com.intellij.codeInsight.editorActions;
import com.intellij.codeInsight.AutoPopupController;
import com.intellij.codeInsight.CodeInsightSettings;
import com.intellij.codeInsight.completion.JavaClassReferenceCompletionContributor;
+import com.intellij.codeInsight.editorActions.smartEnter.JavaSmartEnterProcessor;
+import com.intellij.openapi.command.CommandProcessor;
+import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorModificationUtil;
import com.intellij.openapi.editor.ex.EditorEx;
@@ -125,11 +128,24 @@ public class JavaTypedHandler extends TypedHandlerDelegate {
if (iterator.atEnd() || iterator.getTokenType() == JavaTokenType.RBRACKET || iterator.getTokenType() == JavaTokenType.EQ) {
return Result.CONTINUE;
}
- PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument());
+ Document doc = editor.getDocument();
+ PsiDocumentManager.getInstance(project).commitDocument(doc);
final PsiElement leaf = file.findElementAt(offset);
if (PsiTreeUtil.getParentOfType(leaf, PsiArrayInitializerExpression.class, false, PsiCodeBlock.class, PsiMember.class) != null) {
return Result.CONTINUE;
}
+ PsiElement st = leaf != null ? leaf.getParent() : null;
+ PsiElement prev = offset > 1 ? file.findElementAt(offset - 1) : null;
+ if (CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET && isRparenth(leaf) &&
+ (st instanceof PsiWhileStatement || st instanceof PsiIfStatement) && shouldInsertStatementBody(st, doc, prev)) {
+ CommandProcessor.getInstance().executeCommand(project, new Runnable() {
+ @Override
+ public void run() {
+ new JavaSmartEnterProcessor().process(project, editor, file);
+ }
+ }, "Insert block statement", null);
+ return Result.STOP;
+ }
if (PsiTreeUtil.getParentOfType(leaf, PsiCodeBlock.class, false, PsiMember.class) != null) {
EditorModificationUtil.insertStringAtCaret(editor, "{");
TypedHandler.indentOpenedBrace(project, editor);
@@ -140,6 +156,26 @@ public class JavaTypedHandler extends TypedHandlerDelegate {
return Result.CONTINUE;
}
+ private static boolean shouldInsertStatementBody(@NotNull PsiElement statement, @NotNull Document doc, @Nullable PsiElement prev) {
+ PsiStatement block = statement instanceof PsiWhileStatement ? ((PsiWhileStatement)statement).getBody() : ((PsiIfStatement)statement).getThenBranch();
+ PsiExpression condition = PsiTreeUtil.getChildOfType(statement, PsiExpression.class);
+ PsiExpression latestExpression = PsiTreeUtil.getParentOfType(prev, PsiExpression.class);
+ if (latestExpression instanceof PsiNewExpression && ((PsiNewExpression)latestExpression).getAnonymousClass() == null) return false;
+ return !(block instanceof PsiBlockStatement) && (block == null || startLine(doc, block) != startLine(doc, statement) || condition == null);
+ }
+
+ private static boolean isRparenth(@Nullable PsiElement leaf) {
+ if (leaf == null) return false;
+ if (leaf.getNode().getElementType() == JavaTokenType.RPARENTH) return true;
+ PsiElement next = PsiTreeUtil.nextVisibleLeaf(leaf);
+ if (next == null) return false;
+ return next.getNode().getElementType() == JavaTokenType.RPARENTH;
+ }
+
+ private static int startLine(@NotNull Document doc, @NotNull PsiElement psiElement) {
+ return doc.getLineNumber(psiElement.getTextRange().getStartOffset());
+ }
+
@Override
public Result charTyped(final char c, final Project project, @NotNull final Editor editor, @NotNull final PsiFile file) {
if (myJavaLTTyped) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/folding/impl/JavaElementSignatureProvider.java b/java/java-impl/src/com/intellij/codeInsight/folding/impl/JavaElementSignatureProvider.java
index 1d54cca4833b..54a47f54b6ec 100644
--- a/java/java-impl/src/com/intellij/codeInsight/folding/impl/JavaElementSignatureProvider.java
+++ b/java/java-impl/src/com/intellij/codeInsight/folding/impl/JavaElementSignatureProvider.java
@@ -181,7 +181,7 @@ public class JavaElementSignatureProvider extends AbstractElementSignatureProvid
else if (type.equals("class")) {
String name = tokenizer.nextToken();
- PsiNameHelper nameHelper = JavaPsiFacade.getInstance(file.getProject()).getNameHelper();
+ PsiNameHelper nameHelper = PsiNameHelper.getInstance(file.getProject());
if (nameHelper.isIdentifier(name)) {
int index = 0;
try {
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersHandlerBase.java b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersHandlerBase.java
index f1652470218c..34008a0a72ea 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersHandlerBase.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersHandlerBase.java
@@ -39,11 +39,13 @@ import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.search.LocalSearchScope;
+import com.intellij.util.Function;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import javax.swing.*;
import java.util.ArrayList;
import java.util.List;
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java
index f7972b82c12b..936f587d5fb7 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java
@@ -607,7 +607,7 @@ public class GenerateMembersUtil {
}
@Nullable
- private static PsiMethod annotateOnOverrideImplement(@Nullable PsiClass targetClass, @Nullable PsiMethod generated) {
+ public static PsiMethod annotateOnOverrideImplement(@Nullable PsiClass targetClass, @Nullable PsiMethod generated) {
if (generated == null || targetClass == null) return generated;
if (CodeStyleSettingsManager.getSettings(targetClass.getProject()).INSERT_OVERRIDE_ANNOTATION) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightExceptionsHandlerFactory.java b/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightExceptionsHandlerFactory.java
index d142161400c9..c7bd10cc2b39 100644
--- a/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightExceptionsHandlerFactory.java
+++ b/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightExceptionsHandlerFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,11 +16,11 @@
package com.intellij.codeInsight.highlighting;
import com.intellij.codeInsight.ExceptionUtil;
-import com.intellij.codeInsight.TargetElementUtilBase;
import com.intellij.featureStatistics.FeatureUsageTracker;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.Condition;
import com.intellij.psi.*;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
@@ -29,11 +29,9 @@ import java.util.Collection;
/**
* @author yole
*/
-public class HighlightExceptionsHandlerFactory implements HighlightUsagesHandlerFactory {
+public class HighlightExceptionsHandlerFactory extends HighlightUsagesHandlerFactoryBase {
@Override
- public HighlightUsagesHandlerBase createHighlightUsagesHandler(final Editor editor, final PsiFile file) {
- int offset = TargetElementUtilBase.adjustOffset(file, editor.getDocument(), editor.getCaretModel().getOffset());
- PsiElement target = file.findElementAt(offset);
+ public HighlightUsagesHandlerBase createHighlightUsagesHandler(@NotNull Editor editor, @NotNull PsiFile file, @NotNull PsiElement target) {
if (target instanceof PsiKeyword) {
PsiElement parent = target.getParent();
if (PsiKeyword.TRY.equals(target.getText()) && parent instanceof PsiTryStatement) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightExitPointsHandlerFactory.java b/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightExitPointsHandlerFactory.java
index 4a05420dd354..f9f19a4c26ee 100644
--- a/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightExitPointsHandlerFactory.java
+++ b/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightExitPointsHandlerFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,20 +15,18 @@
*/
package com.intellij.codeInsight.highlighting;
-import com.intellij.codeInsight.TargetElementUtilBase;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiKeyword;
+import org.jetbrains.annotations.NotNull;
/**
* @author yole
*/
-public class HighlightExitPointsHandlerFactory implements HighlightUsagesHandlerFactory {
+public class HighlightExitPointsHandlerFactory extends HighlightUsagesHandlerFactoryBase {
@Override
- public HighlightUsagesHandlerBase createHighlightUsagesHandler(final Editor editor, final PsiFile file) {
- int offset = TargetElementUtilBase.adjustOffset(file, editor.getDocument(), editor.getCaretModel().getOffset());
- PsiElement target = file.findElementAt(offset);
+ public HighlightUsagesHandlerBase createHighlightUsagesHandler(@NotNull Editor editor, @NotNull PsiFile file, @NotNull PsiElement target) {
if (target instanceof PsiKeyword) {
if (PsiKeyword.RETURN.equals(target.getText()) || PsiKeyword.THROW.equals(target.getText())) {
return new HighlightExitPointsHandler(editor, file, target);
diff --git a/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightImportedElementsHandlerFactory.java b/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightImportedElementsHandlerFactory.java
index def7501d93e5..b096aeb40a89 100644
--- a/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightImportedElementsHandlerFactory.java
+++ b/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightImportedElementsHandlerFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,21 +15,19 @@
*/
package com.intellij.codeInsight.highlighting;
-import com.intellij.codeInsight.TargetElementUtilBase;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.*;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author Bas Leijdekkers
*/
-public class HighlightImportedElementsHandlerFactory implements HighlightUsagesHandlerFactory {
+public class HighlightImportedElementsHandlerFactory extends HighlightUsagesHandlerFactoryBase {
@Nullable
@Override
- public HighlightUsagesHandlerBase createHighlightUsagesHandler(Editor editor, PsiFile file) {
- final int offset = TargetElementUtilBase.adjustOffset(file, editor.getDocument(), editor.getCaretModel().getOffset());
- final PsiElement target = file.findElementAt(offset);
+ public HighlightUsagesHandlerBase createHighlightUsagesHandler(@NotNull Editor editor, @NotNull PsiFile file, @NotNull PsiElement target) {
if (!(target instanceof PsiKeyword) || !PsiKeyword.IMPORT.equals(target.getText())) {
return null;
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightOverridingMethodsHandlerFactory.java b/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightOverridingMethodsHandlerFactory.java
index bc9c0a47ce6f..088a17231d33 100644
--- a/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightOverridingMethodsHandlerFactory.java
+++ b/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightOverridingMethodsHandlerFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,18 +15,16 @@
*/
package com.intellij.codeInsight.highlighting;
-import com.intellij.codeInsight.TargetElementUtilBase;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.*;
+import org.jetbrains.annotations.NotNull;
/**
* @author yole
*/
-public class HighlightOverridingMethodsHandlerFactory implements HighlightUsagesHandlerFactory {
+public class HighlightOverridingMethodsHandlerFactory extends HighlightUsagesHandlerFactoryBase {
@Override
- public HighlightUsagesHandlerBase createHighlightUsagesHandler(final Editor editor, final PsiFile file) {
- int offset = TargetElementUtilBase.adjustOffset(file, editor.getDocument(), editor.getCaretModel().getOffset());
- final PsiElement target = file.findElementAt(offset);
+ public HighlightUsagesHandlerBase createHighlightUsagesHandler(@NotNull Editor editor, @NotNull PsiFile file, @NotNull PsiElement target) {
if (target instanceof PsiKeyword && (PsiKeyword.EXTENDS.equals(target.getText()) || PsiKeyword.IMPLEMENTS.equals(target.getText()))) {
PsiElement parent = target.getParent();
if (!(parent instanceof PsiReferenceList)) return null;
diff --git a/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightSuppressedWarningsFactory.java b/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightSuppressedWarningsFactory.java
index df847437854f..4182f003e1bd 100644
--- a/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightSuppressedWarningsFactory.java
+++ b/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightSuppressedWarningsFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
*/
package com.intellij.codeInsight.highlighting;
-import com.intellij.codeInsight.TargetElementUtilBase;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.VirtualFile;
@@ -24,15 +23,14 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiLiteralExpression;
import com.intellij.psi.util.PsiTreeUtil;
+import org.jetbrains.annotations.NotNull;
/**
* @author yole
*/
-public class HighlightSuppressedWarningsFactory implements HighlightUsagesHandlerFactory {
+public class HighlightSuppressedWarningsFactory extends HighlightUsagesHandlerFactoryBase {
@Override
- public HighlightUsagesHandlerBase createHighlightUsagesHandler(final Editor editor, final PsiFile file) {
- int offset = TargetElementUtilBase.adjustOffset(file, editor.getDocument(), editor.getCaretModel().getOffset());
- final PsiElement target = file.findElementAt(offset);
+ public HighlightUsagesHandlerBase createHighlightUsagesHandler(@NotNull Editor editor, @NotNull PsiFile file, @NotNull PsiElement target) {
final PsiAnnotation annotation = PsiTreeUtil.getParentOfType(target, PsiAnnotation.class);
if (annotation != null && Comparing.strEqual(SuppressWarnings.class.getName(), annotation.getQualifiedName())) {
final VirtualFile virtualFile = file.getVirtualFile();
diff --git a/java/java-impl/src/com/intellij/codeInsight/hint/actions/ShowSiblingsAction.java b/java/java-impl/src/com/intellij/codeInsight/hint/actions/ShowSiblingsAction.java
index 8b839e522c24..f46ebb4005ba 100644
--- a/java/java-impl/src/com/intellij/codeInsight/hint/actions/ShowSiblingsAction.java
+++ b/java/java-impl/src/com/intellij/codeInsight/hint/actions/ShowSiblingsAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,15 +17,11 @@ package com.intellij.codeInsight.hint.actions;
import com.intellij.codeInsight.TargetElementUtilBase;
import com.intellij.codeInsight.daemon.impl.PsiElementListNavigator;
-import com.intellij.codeInsight.documentation.DocumentationManager;
import com.intellij.ide.util.MethodCellRenderer;
import com.intellij.ide.util.PsiClassListCellRenderer;
-import com.intellij.openapi.actionSystem.*;
-import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.fileEditor.FileEditor;
-import com.intellij.openapi.fileEditor.FileEditorManager;
-import com.intellij.openapi.fileEditor.TextEditor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.psi.*;
@@ -36,8 +32,6 @@ import com.intellij.util.Consumer;
import org.jetbrains.annotations.Nullable;
public class ShowSiblingsAction extends ShowImplementationsAction {
- private static final Logger LOG = Logger.getInstance("#" + ShowSiblingsAction.class.getName());
-
public ShowSiblingsAction() {
super();
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/MethodParameterInfoHandler.java b/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/MethodParameterInfoHandler.java
index daf2e3002dd2..34c3ff505af7 100644
--- a/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/MethodParameterInfoHandler.java
+++ b/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/MethodParameterInfoHandler.java
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.CodeInsightBundle;
import com.intellij.codeInsight.CodeInsightSettings;
import com.intellij.codeInsight.completion.JavaCompletionUtil;
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
+import com.intellij.codeInsight.javadoc.JavaDocInfoGenerator;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.lang.parameterInfo.*;
import com.intellij.openapi.project.DumbAware;
@@ -450,12 +451,12 @@ public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabAc
final PsiJavaCodeReferenceElement element = annotation.getNameReferenceElement();
if (element != null) {
final PsiElement resolved = element.resolve();
- if (resolved instanceof PsiClass && !AnnotationUtil.isAnnotated((PsiClass)resolved, "java.lang.annotation.Documented", false, true)) {
+ if (resolved instanceof PsiClass && !JavaDocInfoGenerator.isDocumentedAnnotationType(resolved)) {
continue;
}
String referenceName = element.getReferenceName();
- if (shownAnnotations.add(referenceName) || isRepeatableAnnotation(resolved)) {
+ if (shownAnnotations.add(referenceName) || JavaDocInfoGenerator.isRepeatableAnnotationType(resolved)) {
if (lastSize != buffer.length()) buffer.append(" ");
buffer.append("@").append(referenceName);
}
@@ -464,10 +465,6 @@ public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabAc
if (lastSize != buffer.length()) buffer.append(" ");
}
- private static boolean isRepeatableAnnotation(PsiElement resolved) {
- return resolved instanceof PsiClass && !AnnotationUtil.isAnnotated((PsiModifierListOwner)resolved, CommonClassNames.JAVA_LANG_ANNOTATION_REPEATABLE, false, true);
- }
-
@Override
public void updateUI(final Object p, @NotNull final ParameterInfoUIContext context) {
if (p instanceof CandidateInfo) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateClassDialog.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateClassDialog.java
index a9a6d60b759a..1ab1a5246b54 100644
--- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateClassDialog.java
+++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateClassDialog.java
@@ -35,6 +35,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiManager;
+import com.intellij.psi.PsiNameHelper;
import com.intellij.refactoring.MoveDestination;
import com.intellij.refactoring.PackageWrapper;
import com.intellij.refactoring.RefactoringBundle;
@@ -166,7 +167,7 @@ public class CreateClassDialog extends DialogWrapper {
myTfClassName.getDocument().addDocumentListener(new DocumentAdapter() {
@Override
protected void textChanged(DocumentEvent e) {
- getOKAction().setEnabled(JavaPsiFacade.getInstance(myProject).getNameHelper().isIdentifier(myTfClassName.getText()));
+ getOKAction().setEnabled(PsiNameHelper.getInstance(myProject).isIdentifier(myTfClassName.getText()));
}
});
getOKAction().setEnabled(StringUtil.isNotEmpty(myClassName));
diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateFieldFromParameterDialog.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateFieldFromParameterDialog.java
index 73440ba3d66b..83cb3edabf36 100644
--- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateFieldFromParameterDialog.java
+++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateFieldFromParameterDialog.java
@@ -21,10 +21,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
-import com.intellij.psi.JavaPsiFacade;
-import com.intellij.psi.PsiClass;
-import com.intellij.psi.PsiField;
-import com.intellij.psi.PsiType;
+import com.intellij.psi.*;
import com.intellij.refactoring.ui.TypeSelector;
import com.intellij.ui.DocumentAdapter;
import org.jetbrains.annotations.NonNls;
@@ -273,7 +270,7 @@ public class CreateFieldFromParameterDialog extends DialogWrapper {
private void updateOkStatus() {
String text = getEnteredName();
- setOKActionEnabled(JavaPsiFacade.getInstance(myProject).getNameHelper().isIdentifier(text));
+ setOKActionEnabled(PsiNameHelper.getInstance(myProject).isIdentifier(text));
}
@Override
diff --git a/java/java-impl/src/com/intellij/codeInsight/lookup/VariableLookupItem.java b/java/java-impl/src/com/intellij/codeInsight/lookup/VariableLookupItem.java
index 21e32a3e3aeb..d1d6691fca51 100644
--- a/java/java-impl/src/com/intellij/codeInsight/lookup/VariableLookupItem.java
+++ b/java/java-impl/src/com/intellij/codeInsight/lookup/VariableLookupItem.java
@@ -3,10 +3,13 @@ package com.intellij.codeInsight.lookup;
import com.intellij.codeInsight.AutoPopupController;
import com.intellij.codeInsight.TailType;
import com.intellij.codeInsight.completion.*;
+import com.intellij.codeInsight.daemon.impl.JavaColorProvider;
import com.intellij.codeInsight.daemon.impl.analysis.HighlightControlFlowUtil;
import com.intellij.featureStatistics.FeatureUsageTracker;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.RangeMarker;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.RecursionManager;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
@@ -15,9 +18,11 @@ import com.intellij.psi.impl.source.PostprocessReformattingAspect;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.containers.HashMap;
+import com.intellij.util.ui.ColorIcon;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.awt.*;
import java.util.Collection;
/**
@@ -25,10 +30,12 @@ import java.util.Collection;
*/
public class VariableLookupItem extends LookupItem<PsiVariable> implements TypedLookupItem, StaticallyImportable {
@Nullable private final MemberLookupHelper myHelper;
+ private Color myColor;
- public VariableLookupItem(PsiVariable object) {
- super(object, object.getName());
+ public VariableLookupItem(PsiVariable var) {
+ super(var, var.getName());
myHelper = null;
+ myColor = getInitializerColor(var);
}
public VariableLookupItem(PsiField field, boolean shouldImport) {
@@ -37,6 +44,30 @@ public class VariableLookupItem extends LookupItem<PsiVariable> implements Typed
if (!shouldImport) {
forceQualify();
}
+ myColor = getInitializerColor(field);
+ }
+
+ private static Color getInitializerColor(@NotNull PsiVariable var) {
+ PsiElement navigationElement = var.getNavigationElement();
+ if (navigationElement instanceof PsiVariable) {
+ var = (PsiVariable)navigationElement;
+ }
+ return getExpressionColor(var.getInitializer());
+ }
+
+ private static Color getExpressionColor(@Nullable PsiExpression expression) {
+ if (expression instanceof PsiReferenceExpression) {
+ final PsiElement target = ((PsiReferenceExpression)expression).resolve();
+ if (target instanceof PsiVariable) {
+ return RecursionManager.doPreventingRecursion(expression, true, new Computable<Color>() {
+ @Override
+ public Color compute() {
+ return getExpressionColor(((PsiVariable)target).getInitializer());
+ }
+ });
+ }
+ }
+ return JavaColorProvider.getJavaColorFromExpression(expression);
}
@Override
@@ -76,6 +107,9 @@ public class VariableLookupItem extends LookupItem<PsiVariable> implements Typed
if (myHelper != null) {
myHelper.renderElement(presentation, getAttribute(FORCE_QUALIFY) != null ? Boolean.TRUE : null, getSubstitutor());
}
+ if (myColor != null) {
+ presentation.setTypeText("", new ColorIcon(12, myColor));
+ }
}
@Override
diff --git a/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaMethodParameterUnwrapper.java b/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaMethodParameterUnwrapper.java
index 1c1957bcf472..91c2238240ba 100644
--- a/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaMethodParameterUnwrapper.java
+++ b/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaMethodParameterUnwrapper.java
@@ -31,7 +31,10 @@ public class JavaMethodParameterUnwrapper extends JavaUnwrapper {
private static PsiElement adjustElementToTheLeft(PsiElement element) {
if (element instanceof PsiJavaToken && ((PsiJavaToken)element).getTokenType() == JavaTokenType.RPARENTH) {
- return element.getPrevSibling();
+ PsiElement prevSibling = element.getPrevSibling();
+ if (prevSibling != null) {
+ return prevSibling;
+ }
}
return element;
}
diff --git a/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesHandler.java b/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesHandler.java
index 1791fd0d6e8e..5c226b84500b 100644
--- a/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesHandler.java
+++ b/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesHandler.java
@@ -513,7 +513,9 @@ public class JavaFindUsagesHandler extends FindUsagesHandler{
if (!addElementUsages(methods[i], processor, options)) return false;
}
else {
- boolean success = MethodReferencesSearch.search(new MethodReferencesSearch.SearchParameters(method, options.searchScope, true, options.fastTrack))
+ MethodReferencesSearch.SearchParameters parameters =
+ new MethodReferencesSearch.SearchParameters(method, options.searchScope, true, options.fastTrack);
+ boolean success = MethodReferencesSearch.search(parameters)
.forEach(new PsiReferenceProcessorAdapter(new PsiReferenceProcessor() {
@Override
public boolean execute(PsiReference reference) {
@@ -663,16 +665,18 @@ public class JavaFindUsagesHandler extends FindUsagesHandler{
@NotNull final Processor<UsageInfo> processor,
@NotNull final FindUsagesOptions options) {
final SearchScope searchScope = options.searchScope;
+ final PsiClass[] parentClass = new PsiClass[1];
if (element instanceof PsiMethod && ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
@Override
public Boolean compute() {
- return ((PsiMethod)element).isConstructor();
+ PsiMethod method = (PsiMethod)element;
+ parentClass[0] = method.getContainingClass();
+ return method.isConstructor();
}
})) {
PsiMethod method = (PsiMethod)element;
- final PsiClass parentClass = method.getContainingClass();
- if (parentClass != null) {
+ if (parentClass[0] != null) {
boolean strictSignatureSearch =
!(options instanceof JavaMethodFindUsagesOptions) || !((JavaMethodFindUsagesOptions)options).isIncludeOverloadUsages;
return MethodReferencesSearch
diff --git a/java/java-impl/src/com/intellij/ide/actions/CreateClassAction.java b/java/java-impl/src/com/intellij/ide/actions/CreateClassAction.java
index 13c48c2aab77..53fee7a66c0d 100644
--- a/java/java-impl/src/com/intellij/ide/actions/CreateClassAction.java
+++ b/java/java-impl/src/com/intellij/ide/actions/CreateClassAction.java
@@ -65,7 +65,7 @@ public class CreateClassAction extends JavaCreateTemplateInPackageAction<PsiClas
builder.setValidator(new InputValidatorEx() {
@Override
public String getErrorText(String inputString) {
- if (inputString.length() > 0 && !JavaPsiFacade.getInstance(project).getNameHelper().isQualifiedName(inputString)) {
+ if (inputString.length() > 0 && !PsiNameHelper.getInstance(project).isQualifiedName(inputString)) {
return "This is not a valid Java qualified name";
}
return null;
diff --git a/java/java-impl/src/com/intellij/ide/actions/CreatePackageInfoAction.java b/java/java-impl/src/com/intellij/ide/actions/CreatePackageInfoAction.java
index d2dab9f868d2..64a8c1bcfcb5 100644
--- a/java/java-impl/src/com/intellij/ide/actions/CreatePackageInfoAction.java
+++ b/java/java-impl/src/com/intellij/ide/actions/CreatePackageInfoAction.java
@@ -92,7 +92,7 @@ public class CreatePackageInfoAction extends CreateFromTemplateActionBase implem
}
final ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(project).getFileIndex();
final JavaDirectoryService directoryService = JavaDirectoryService.getInstance();
- final PsiNameHelper nameHelper = JavaPsiFacade.getInstance(project).getNameHelper();
+ final PsiNameHelper nameHelper = PsiNameHelper.getInstance(project);
for (PsiDirectory directory : directories) {
if (projectFileIndex.isUnderSourceRootOfType(directory.getVirtualFile(), JavaModuleSourceRootTypes.SOURCES) &&
PsiUtil.isLanguageLevel5OrHigher(directory)) {
diff --git a/java/java-impl/src/com/intellij/ide/actions/JavaCreateTemplateInPackageAction.java b/java/java-impl/src/com/intellij/ide/actions/JavaCreateTemplateInPackageAction.java
index b1397f65526d..63ffccb703b6 100644
--- a/java/java-impl/src/com/intellij/ide/actions/JavaCreateTemplateInPackageAction.java
+++ b/java/java-impl/src/com/intellij/ide/actions/JavaCreateTemplateInPackageAction.java
@@ -37,6 +37,6 @@ public abstract class JavaCreateTemplateInPackageAction<T extends PsiElement> ex
}
String name = pkg.getQualifiedName();
- return StringUtil.isEmpty(name) || JavaPsiFacade.getInstance(directory.getProject()).getNameHelper().isQualifiedName(name);
+ return StringUtil.isEmpty(name) || PsiNameHelper.getInstance(directory.getProject()).isQualifiedName(name);
}
}
diff --git a/java/java-impl/src/com/intellij/ide/util/scopeChooser/HierarchyScopeDescriptorProvider.java b/java/java-impl/src/com/intellij/ide/util/scopeChooser/HierarchyScopeDescriptorProvider.java
index 36ee6dfcdb36..1eda5c607525 100644
--- a/java/java-impl/src/com/intellij/ide/util/scopeChooser/HierarchyScopeDescriptorProvider.java
+++ b/java/java-impl/src/com/intellij/ide/util/scopeChooser/HierarchyScopeDescriptorProvider.java
@@ -21,11 +21,17 @@
package com.intellij.ide.util.scopeChooser;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.wm.ToolWindowId;
+import com.intellij.openapi.wm.ToolWindowManager;
import org.jetbrains.annotations.NotNull;
public class HierarchyScopeDescriptorProvider implements ScopeDescriptorProvider {
@NotNull
public ScopeDescriptor[] getScopeDescriptors(final Project project) {
+ if (Comparing.strEqual(ToolWindowManager.getInstance(project).getActiveToolWindowId(), ToolWindowId.TODO_VIEW)) {
+ return EMPTY;
+ }
return new ScopeDescriptor[]{new ClassHierarchyScopeDescriptor(project)};
}
} \ No newline at end of file
diff --git a/java/java-impl/src/com/intellij/internal/GenerateVisitorByHierarchyAction.java b/java/java-impl/src/com/intellij/internal/GenerateVisitorByHierarchyAction.java
index 5c302e428ce9..0ebb5795d02a 100644
--- a/java/java-impl/src/com/intellij/internal/GenerateVisitorByHierarchyAction.java
+++ b/java/java-impl/src/com/intellij/internal/GenerateVisitorByHierarchyAction.java
@@ -31,7 +31,6 @@ import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.LangDataKeys;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.Document;
@@ -74,8 +73,7 @@ public class GenerateVisitorByHierarchyAction extends AnAction {
final Ref<PsiClass> parentClassRef = Ref.create(null);
final Project project = e.getData(CommonDataKeys.PROJECT);
assert project != null;
- final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
- final PsiNameHelper helper = psiFacade.getNameHelper();
+ final PsiNameHelper helper = PsiNameHelper.getInstance(project);
final PackageChooserDialog dialog = new PackageChooserDialog("Choose Target Package and Hierarchy Root Class", project) {
@Override
diff --git a/java/java-impl/src/com/intellij/internal/StaticIconFieldsAction.java b/java/java-impl/src/com/intellij/internal/StaticIconFieldsAction.java
index 2864db6608e6..7fae15f159b7 100644
--- a/java/java-impl/src/com/intellij/internal/StaticIconFieldsAction.java
+++ b/java/java-impl/src/com/intellij/internal/StaticIconFieldsAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,10 +22,12 @@ package com.intellij.internal;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.LangDataKeys;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Computable;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
@@ -49,19 +51,36 @@ public class StaticIconFieldsAction extends AnAction {
ProgressManager.getInstance().run(new Task.Backgroundable(project, "Searching icons usages") {
@Override
public void run(@NotNull ProgressIndicator indicator) {
- JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
- GlobalSearchScope all = GlobalSearchScope.allScope(project);
- PsiClass allIcons = facade.findClass("com.intellij.icons.AllIcons", all);
+ final JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
+ final GlobalSearchScope all = GlobalSearchScope.allScope(project);
+ PsiClass allIcons = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass>() {
+ @Override
+ public PsiClass compute() {
+ return facade.findClass("com.intellij.icons.AllIcons", all);
+ }
+ });
searchFields(allIcons, view, indicator);
- for (PsiClass iconsClass : facade.findPackage("icons").getClasses(all)) {
+ PsiClass[] classes = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass[]>() {
+ @Override
+ public PsiClass[] compute() {
+ return facade.findPackage("icons").getClasses(all);
+ }
+ });
+ for (PsiClass iconsClass : classes) {
searchFields(iconsClass, view, indicator);
}
}
});
}
- private static void searchFields(PsiClass allIcons, final UsageView view, ProgressIndicator indicator) {
- indicator.setText("Searching for: " + allIcons.getQualifiedName());
+ private static void searchFields(final PsiClass allIcons, final UsageView view, final ProgressIndicator indicator) {
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ @Override
+ public void run() {
+ indicator.setText("Searching for: " + allIcons.getQualifiedName());
+ }
+ });
+
ReferencesSearch.search(allIcons).forEach(new Processor<PsiReference>() {
@Override
public boolean process(PsiReference reference) {
diff --git a/java/java-impl/src/com/intellij/openapi/module/BasePackageParameterFactory.java b/java/java-impl/src/com/intellij/openapi/module/BasePackageParameterFactory.java
index c59ab2c24cb9..81d1dbcc575a 100644
--- a/java/java-impl/src/com/intellij/openapi/module/BasePackageParameterFactory.java
+++ b/java/java-impl/src/com/intellij/openapi/module/BasePackageParameterFactory.java
@@ -22,6 +22,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.JavaPsiFacade;
+import com.intellij.psi.PsiNameHelper;
import com.intellij.psi.PsiPackage;
import com.intellij.psi.impl.PsiNameHelperImpl;
import com.intellij.psi.search.GlobalSearchScope;
@@ -41,7 +42,7 @@ public class BasePackageParameterFactory extends ProjectTemplateParameterFactory
private static final Condition<PsiPackage> PACKAGE_CONDITION = new Condition<PsiPackage>() {
@Override
public boolean value(PsiPackage aPackage) {
- return JavaPsiFacade.getInstance(aPackage.getProject()).getNameHelper().isQualifiedName(aPackage.getQualifiedName()) &&
+ return PsiNameHelper.getInstance(aPackage.getProject()).isQualifiedName(aPackage.getQualifiedName()) &&
Character.isLowerCase(aPackage.getName().charAt(0));
}
};
diff --git a/java/java-impl/src/com/intellij/packageDependencies/ui/PackagePatternProvider.java b/java/java-impl/src/com/intellij/packageDependencies/ui/PackagePatternProvider.java
index c619d2b8e56f..7069d0639267 100644
--- a/java/java-impl/src/com/intellij/packageDependencies/ui/PackagePatternProvider.java
+++ b/java/java-impl/src/com/intellij/packageDependencies/ui/PackagePatternProvider.java
@@ -29,10 +29,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.JavaPsiFacade;
-import com.intellij.psi.PsiClassOwner;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
+import com.intellij.psi.*;
import com.intellij.psi.search.scope.packageSet.PackageSet;
import com.intellij.psi.search.scope.packageSet.PatternPackageSet;
import org.jetbrains.annotations.NonNls;
@@ -101,7 +98,7 @@ public class PackagePatternProvider extends PatternDialectProvider {
final String packageName =
ProjectRootManager.getInstance(element.getProject()).getFileIndex().getPackageNameByDirectory(virtualFile.getParent());
final String name = virtualFile.getNameWithoutExtension();
- if (!JavaPsiFacade.getInstance(element.getProject()).getNameHelper().isIdentifier(name)) return null;
+ if (!PsiNameHelper.getInstance(element.getProject()).isIdentifier(name)) return null;
qName = StringUtil.getQualifiedName(packageName, name);
}
if (qName != null) {
diff --git a/java/java-impl/src/com/intellij/psi/RefResolveServiceImpl.java b/java/java-impl/src/com/intellij/psi/RefResolveServiceImpl.java
index 3655942f97b7..92c6b4349189 100644
--- a/java/java-impl/src/com/intellij/psi/RefResolveServiceImpl.java
+++ b/java/java-impl/src/com/intellij/psi/RefResolveServiceImpl.java
@@ -16,18 +16,23 @@
package com.intellij.psi;
import com.intellij.concurrency.JobLauncher;
+import com.intellij.ide.PowerSaveMode;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationAdapter;
-import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.application.RuntimeInterruptedException;
import com.intellij.openapi.application.ex.ApplicationEx;
import com.intellij.openapi.application.ex.ApplicationUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.module.Module;
+import com.intellij.openapi.progress.EmptyProgressIndicator;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
+import com.intellij.openapi.progress.impl.BackgroundableProcessIndicator;
+import com.intellij.openapi.progress.impl.ProgressManagerImpl;
+import com.intellij.openapi.progress.util.ProgressIndicatorBase;
import com.intellij.openapi.progress.util.ProgressIndicatorUtils;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.IndexNotReadyException;
@@ -37,6 +42,7 @@ import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.EmptyRunnable;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.*;
@@ -71,7 +77,8 @@ import java.io.FileWriter;
import java.io.IOException;
import java.text.DateFormat;
import java.util.*;
-import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
@@ -87,7 +94,7 @@ public class RefResolveServiceImpl extends RefResolveService implements Runnable
private final ApplicationEx myApplication;
private volatile boolean myDisposed;
private volatile boolean upToDate;
- private volatile boolean enabled = true;
+ private final AtomicInteger enableVetoes = new AtomicInteger(); // number of disable() calls. To enable the service, there should be at least corresponding number of enable() calls.
private final FileWriter log;
private final ProjectFileIndex myProjectFileIndex;
@@ -99,6 +106,7 @@ public class RefResolveServiceImpl extends RefResolveService implements Runnable
ApplicationEx application,
ProjectFileIndex projectFileIndex) throws IOException {
super(project);
+ ((FutureTask)resolveProcess).run();
myApplication = application;
myProjectFileIndex = projectFileIndex;
if (ResolveScopeManagerImpl.ENABLED_REF_BACK) {
@@ -154,8 +162,8 @@ public class RefResolveServiceImpl extends RefResolveService implements Runnable
return toVfString(list);
}
- private static String toVfString(@NotNull List<VirtualFile> list) {
- List<VirtualFile> sub = list.subList(0, Math.min(list.size(), 100));
+ private static String toVfString(@NotNull Collection<VirtualFile> list) {
+ List<VirtualFile> sub = new ArrayList<VirtualFile>(list).subList(0, Math.min(list.size(), 100));
return list.size() + " files: " + StringUtil.join(sub, new Function<VirtualFile, String>() {
@Override
public String fun(VirtualFile file) {
@@ -205,6 +213,17 @@ public class RefResolveServiceImpl extends RefResolveService implements Runnable
enable();
}
});
+ messageBus.connect().subscribe(PowerSaveMode.TOPIC, new PowerSaveMode.Listener() {
+ @Override
+ public void powerSaveStateChanged() {
+ if (PowerSaveMode.isEnabled()) {
+ enable();
+ }
+ else {
+ disable();
+ }
+ }
+ });
myApplication.addApplicationListener(new ApplicationAdapter() {
@Override
public void beforeWriteActionStart(Object action) {
@@ -232,17 +251,16 @@ public class RefResolveServiceImpl extends RefResolveService implements Runnable
enable();
}
}, this);
- Disposer.register(this, HeavyProcessLatch.INSTANCE.addListener(new HeavyProcessLatch.HeavyProcessListener() {
+ HeavyProcessLatch.INSTANCE.addListener(this, new HeavyProcessLatch.HeavyProcessListener() {
@Override
public void processStarted() {
- disable();
}
@Override
public void processFinished() {
- enable();
+ wakeUp();
}
- }));
+ });
startThread();
}
@@ -368,6 +386,9 @@ public class RefResolveServiceImpl extends RefResolveService implements Runnable
fileIsResolved.writeTo(new File(getStorageDirectory(), "bitSet"));
}
+ private volatile Future<?> resolveProcess = new FutureTask<Object>(EmptyRunnable.getInstance(), null); // write from EDT only
+ private volatile ProgressIndicator resolveIndicator = new EmptyProgressIndicator();
+
@Override
public void run() {
while (!myDisposed) {
@@ -375,7 +396,7 @@ public class RefResolveServiceImpl extends RefResolveService implements Runnable
synchronized (filesToResolve) {
isEmpty = filesToResolve.isEmpty();
}
- if (!enabled || isEmpty) {
+ if (enableVetoes.get() > 0 || isEmpty || !resolveProcess.isDone() || HeavyProcessLatch.INSTANCE.isRunning()) {
try {
waitForQueue();
}
@@ -384,77 +405,70 @@ public class RefResolveServiceImpl extends RefResolveService implements Runnable
}
continue;
}
+ final Set<VirtualFile> files = countFilesToResolve();
+ if (files.isEmpty()) continue;
+
upToDate = false;
- final CountDownLatch batchProcessedLatch = new CountDownLatch(1);
- ApplicationManager.getApplication().invokeLater(new Runnable() {
+
+ myApplication.invokeLater(new Runnable() {
@Override
public void run() {
- new Task.Backgroundable(myProject, "Resolving files...", true) {
+ if (!resolveProcess.isDone()) return;
+ log("Started to resolve " + files.size() + " files");
+
+ Task.Backgroundable backgroundable = new Task.Backgroundable(myProject, "Resolving files...", true) {
@Override
public void run(@NotNull final ProgressIndicator indicator) {
- if (ApplicationManager.getApplication().isDisposed()) return;
- try {
- processBatch(indicator);
- }
- finally {
- batchProcessedLatch.countDown();
+ if (!myApplication.isDisposed()) {
+ try {
+ processBatch(indicator, files);
+ }
+ catch (RuntimeInterruptedException ignore) {
+ // see future.cancel() in disable()
+ int i = 0;
+ }
}
}
- }.queue();
+ };
+ ProgressIndicator indicator;
+ if (files.size() > 1) {
+ //show progress
+ indicator = new BackgroundableProcessIndicator(backgroundable);
+ }
+ else {
+ indicator = new MyProgress();
+ }
+ resolveIndicator = indicator;
+ resolveProcess = ProgressManagerImpl.runProcessWithProgressAsynchronously(backgroundable, indicator, null);
}
}, myProject.getDisposed());
- try {
- batchProcessedLatch.await();
- }
- catch (InterruptedException e) {
- break;
- }
-
- synchronized (filesToResolve) {
- upToDate = filesToResolve.isEmpty();
- log("upToDate = " + upToDate);
- }
flushLog();
}
}
- private void processBatch(@NotNull final ProgressIndicator indicator) {
- Set<VirtualFile> set;
- int queuedSize;
- synchronized (filesToResolve) {
- queuedSize = filesToResolve.size();
- set = new THashSet<VirtualFile>(queuedSize);
- // someone might have cleared this bit to mark file as processed
- for (VirtualFile file : filesToResolve) {
- if (fileIsInQueue.clear(getAbsId(file))) {
- set.add(file);
- }
- }
- filesToResolve.clear();
- }
+ private volatile int resolvedInPreviousBatch;
+ private void processBatch(@NotNull final ProgressIndicator indicator, @NotNull Set<VirtualFile> files) {
+ assert !myApplication.isDispatchThread();
+ final int resolvedInPreviousBatch = this.resolvedInPreviousBatch;
+ final int totalSize = files.size() + resolvedInPreviousBatch;
final ConcurrentIntObjectMap<int[]> fileToForwardIds = new StripedLockIntObjectConcurrentHashMap<int[]>();
- Set<VirtualFile> files = countAndMarkUnresolved(set, false);
- if (files.isEmpty()) return;
- final int size = files.size();
final Set<VirtualFile> toProcess = Collections.synchronizedSet(files);
- log("Started to resolve "+ size + " files (was queued "+queuedSize+")");
-
indicator.setIndeterminate(false);
ProgressIndicatorUtils.forceWriteActionPriority(indicator, (Disposable)indicator);
long start = System.currentTimeMillis();
Processor<VirtualFile> processor = new Processor<VirtualFile>() {
@Override
public boolean process(VirtualFile file) {
- double fraction = 1 - toProcess.size() * 1.0 / size;
+ double fraction = 1 - toProcess.size() * 1.0 / totalSize;
indicator.setFraction(fraction);
try {
if (file.isDirectory() || !toResolve(file, myProject)) {
return true;
}
int fileId = getAbsId(file);
- int i = size - toProcess.size();
- indicator.setText(i + "/" + size + ": Resolving " + file.getPresentableUrl());
+ int i = totalSize - toProcess.size();
+ indicator.setText(i + "/" + totalSize + ": Resolving " + file.getPresentableUrl());
int[] forwardIds = processFile(file, fileId, indicator);
if (forwardIds == null) {
//queueUpdate(file);
@@ -475,12 +489,34 @@ public class RefResolveServiceImpl extends RefResolveService implements Runnable
.getInstance().invokeConcurrentlyUnderProgress(new ArrayList<VirtualFile>(files), indicator, false, false, processor);
}
finally {
+ this.resolvedInPreviousBatch = toProcess.isEmpty() ? 0 : totalSize - toProcess.size();
queue(toProcess, "re-added after fail. success=" + success);
storeIds(fileToForwardIds);
long end = System.currentTimeMillis();
- log("Resolved batch of " + (size - toProcess.size()) + " from " + size + " files in " + ((end - start) / 1000) + "sec. (Gap: " + storage.gap+")");
+ log("Resolved batch of " + (totalSize - toProcess.size()) + " from " + totalSize + " files in " + ((end - start) / 1000) + "sec. (Gap: " + storage.gap+")");
+ synchronized (filesToResolve) {
+ upToDate = filesToResolve.isEmpty();
+ log("upToDate = " + upToDate);
+ }
+ }
+ }
+
+ @NotNull
+ private Set<VirtualFile> countFilesToResolve() {
+ Set<VirtualFile> set;
+ synchronized (filesToResolve) {
+ int queuedSize = filesToResolve.size();
+ set = new THashSet<VirtualFile>(queuedSize);
+ // someone might have cleared this bit to mark file as processed
+ for (VirtualFile file : filesToResolve) {
+ if (fileIsInQueue.clear(getAbsId(file))) {
+ set.add(file);
+ }
+ }
+ filesToResolve.clear();
}
+ return countAndMarkUnresolved(set, false);
}
private static int getAbsId(@NotNull VirtualFile file) {
@@ -528,12 +564,19 @@ public class RefResolveServiceImpl extends RefResolveService implements Runnable
}
private void enable() {
- enabled = true;
+ // decrement but only if it's positive
+ int vetoes;
+ do {
+ vetoes = enableVetoes.get();
+ if (vetoes == 0) break;
+ } while(!enableVetoes.compareAndSet(vetoes, vetoes-1));
wakeUp();
}
private void disable() {
- enabled = false;
+ //resolveIndicator.cancel();
+ //resolveProcess.cancel(true);
+ enableVetoes.incrementAndGet();
wakeUp();
}
@@ -591,7 +634,7 @@ public class RefResolveServiceImpl extends RefResolveService implements Runnable
assert forwardSize == backwardSize;
// wrap in read action so that sudden quit (in write action) would not interrupt us
- ApplicationManager.getApplication().runReadAction(new Runnable() {
+ myApplication.runReadAction(new Runnable() {
@Override
public void run() {
fileToBackwardIds.forEachEntry(new TIntObjectProcedure<TIntArrayList>() {
@@ -644,7 +687,8 @@ public class RefResolveServiceImpl extends RefResolveService implements Runnable
psiFile.accept(new JavaRecursiveElementWalkingVisitor() {
@Override
public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
- resolveReference(reference, indicator, resolved);
+ indicator.checkCanceled();
+ resolveReference(reference, resolved);
super.visitReferenceElement(reference);
}
@@ -655,7 +699,8 @@ public class RefResolveServiceImpl extends RefResolveService implements Runnable
@Override
public void visitXmlElement(XmlElement element) {
for (PsiReference reference : element.getReferences()) {
- resolveReference(reference, indicator, resolved);
+ indicator.checkCanceled();
+ resolveReference(reference, resolved);
}
super.visitXmlElement(element);
}
@@ -675,8 +720,7 @@ public class RefResolveServiceImpl extends RefResolveService implements Runnable
return forward;
}
- private void resolveReference(@NotNull PsiReference reference, @NotNull ProgressIndicator indicator, @NotNull Set<PsiElement> resolved) {
- indicator.checkCanceled();
+ private void resolveReference(@NotNull PsiReference reference, @NotNull Set<PsiElement> resolved) {
PsiElement element = reference.resolve();
if (element != null) {
resolved.add(element);
@@ -770,4 +814,10 @@ public class RefResolveServiceImpl extends RefResolveService implements Runnable
}
return queued;
}
+
+ private static class MyProgress extends ProgressIndicatorBase implements Disposable{
+ @Override
+ public void dispose() {
+ }
+ }
}
diff --git a/java/java-impl/src/com/intellij/psi/impl/file/PsiJavaDirectoryFactory.java b/java/java-impl/src/com/intellij/psi/impl/file/PsiJavaDirectoryFactory.java
index 83761827f52d..b8823c5b8647 100644
--- a/java/java-impl/src/com/intellij/psi/impl/file/PsiJavaDirectoryFactory.java
+++ b/java/java-impl/src/com/intellij/psi/impl/file/PsiJavaDirectoryFactory.java
@@ -72,6 +72,6 @@ public class PsiJavaDirectoryFactory extends PsiDirectoryFactory {
@Override
public boolean isValidPackageName(String name) {
- return JavaPsiFacade.getInstance(myManager.getProject()).getNameHelper().isQualifiedName(name);
+ return PsiNameHelper.getInstance(myManager.getProject()).isQualifiedName(name);
}
}
diff --git a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReference.java b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReference.java
index 54812c0928e8..02e08e74aa31 100644
--- a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReference.java
+++ b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReference.java
@@ -275,7 +275,7 @@ public class JavaClassReference extends GenericReference implements PsiJavaRefer
final GlobalSearchScope scope = getScope(getElement().getContainingFile());
for (final PsiPackage subPackage : aPackage.getSubPackages(scope)) {
final String shortName = subPackage.getQualifiedName().substring(startOffset);
- if (JavaPsiFacade.getInstance(subPackage.getProject()).getNameHelper().isIdentifier(shortName)) {
+ if (PsiNameHelper.getInstance(subPackage.getProject()).isIdentifier(shortName)) {
list.add(LookupElementBuilder.create(subPackage).withIcon(subPackage.getIcon(Iconable.ICON_FLAG_VISIBILITY)));
}
}
diff --git a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReferenceProvider.java b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReferenceProvider.java
index 6e9e92dc4ff9..c43605e55871 100644
--- a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReferenceProvider.java
+++ b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReferenceProvider.java
@@ -141,8 +141,8 @@ public class JavaClassReferenceProvider extends GenericReferenceProvider impleme
@Override
public PsiPackage fun(final PsiPackage psiPackage) {
final String packageName = psiPackage.getName();
- return JavaPsiFacade.getInstance(psiPackage.getProject()).getNameHelper()
- .isIdentifier(packageName, PsiUtil.getLanguageLevel(psiPackage)) ? psiPackage : null;
+ return PsiNameHelper.getInstance(psiPackage.getProject())
+ .isIdentifier(packageName, PsiUtil.getLanguageLevel(psiPackage)) ? psiPackage : null;
}
});
}
diff --git a/java/java-impl/src/com/intellij/refactoring/anonymousToInner/AnonymousToInnerDialog.java b/java/java-impl/src/com/intellij/refactoring/anonymousToInner/AnonymousToInnerDialog.java
index 80201559ef34..ad2a88c025a3 100644
--- a/java/java-impl/src/com/intellij/refactoring/anonymousToInner/AnonymousToInnerDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/anonymousToInner/AnonymousToInnerDialog.java
@@ -153,7 +153,7 @@ class AnonymousToInnerDialog extends DialogWrapper{
errorString = RefactoringBundle.message("anonymousToInner.no.inner.class.name");
}
else {
- if (!JavaPsiFacade.getInstance(manager.getProject()).getNameHelper().isIdentifier(innerClassName)) {
+ if (!PsiNameHelper.getInstance(manager.getProject()).isIdentifier(innerClassName)) {
errorString = RefactoringMessageUtil.getIncorrectIdentifierMessage(innerClassName);
}
else{
diff --git a/java/java-impl/src/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureDialog.java b/java/java-impl/src/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureDialog.java
index f8e27c444245..4ed36732bdf2 100644
--- a/java/java-impl/src/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureDialog.java
@@ -194,7 +194,7 @@ public class ChangeClassSignatureDialog extends RefactoringDialog {
final Map<String, TypeParameterInfo> infos = new HashMap<String, TypeParameterInfo>();
for (final TypeParameterInfo info : myTypeParameterInfos) {
if (!info.isForExistingParameter() &&
- !JavaPsiFacade.getInstance(myClass.getProject()).getNameHelper().isIdentifier(info.getNewName())) {
+ !PsiNameHelper.getInstance(myClass.getProject()).isIdentifier(info.getNewName())) {
return RefactoringBundle.message("error.wrong.name.input", info.getNewName());
}
final String newName = info.isForExistingParameter() ? parameters[info.getOldParameterIndex()].getName() : info.getNewName();
diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDialog.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDialog.java
index f86b78d1d17e..80941aabfc9e 100644
--- a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDialog.java
@@ -510,7 +510,7 @@ public class JavaChangeSignatureDialog extends ChangeSignatureDialogBase<Paramet
PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
String name = getMethodName();
- if (!JavaPsiFacade.getInstance(manager.getProject()).getNameHelper().isIdentifier(name)) {
+ if (!PsiNameHelper.getInstance(manager.getProject()).isIdentifier(name)) {
return RefactoringMessageUtil.getIncorrectIdentifierMessage(name);
}
@@ -534,7 +534,7 @@ public class JavaChangeSignatureDialog extends ChangeSignatureDialogBase<Paramet
for (int i = 0; i < newParametersNumber; i++) {
final ParameterTableModelItemBase<ParameterInfoImpl> item = parameterInfos.get(i);
- if (!JavaPsiFacade.getInstance(manager.getProject()).getNameHelper().isIdentifier(item.parameter.getName())) {
+ if (!PsiNameHelper.getInstance(manager.getProject()).isIdentifier(item.parameter.getName())) {
return RefactoringMessageUtil.getIncorrectIdentifierMessage(item.parameter.getName());
}
diff --git a/java/java-impl/src/com/intellij/refactoring/copy/CopyClassDialog.java b/java/java-impl/src/com/intellij/refactoring/copy/CopyClassDialog.java
index 02ff65e14b2d..f0a4fee2a073 100644
--- a/java/java-impl/src/com/intellij/refactoring/copy/CopyClassDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/copy/CopyClassDialog.java
@@ -159,7 +159,7 @@ class CopyClassDialog extends DialogWrapper{
final String[] errorString = new String[1];
final PsiManager manager = PsiManager.getInstance(myProject);
- final PsiNameHelper nameHelper = JavaPsiFacade.getInstance(manager.getProject()).getNameHelper();
+ final PsiNameHelper nameHelper = PsiNameHelper.getInstance(manager.getProject());
if (packageName.length() > 0 && !nameHelper.isQualifiedName(packageName)) {
errorString[0] = RefactoringBundle.message("invalid.target.package.name.specified");
} else if (className != null && className.isEmpty()) {
diff --git a/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsDialog.java b/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsDialog.java
index 8905ce202211..6356a17b956c 100644
--- a/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsDialog.java
@@ -472,13 +472,13 @@ public class EncapsulateFieldsDialog extends RefactoringDialog implements Encaps
String name;
if (isToEncapsulateGet()) {
name = myGetterNames[idx];
- if (!JavaPsiFacade.getInstance(manager.getProject()).getNameHelper().isIdentifier(name)) {
+ if (!PsiNameHelper.getInstance(manager.getProject()).isIdentifier(name)) {
return RefactoringMessageUtil.getIncorrectIdentifierMessage(name);
}
}
if (!myFinalMarks[idx] && isToEncapsulateSet()) {
name = mySetterNames[idx];
- if (!JavaPsiFacade.getInstance(manager.getProject()).getNameHelper().isIdentifier(name)) {
+ if (!PsiNameHelper.getInstance(manager.getProject()).isIdentifier(name)) {
return RefactoringMessageUtil.getIncorrectIdentifierMessage(name);
}
}
diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java
index 7bcb0cab6264..f4cfccb496ad 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java
@@ -221,7 +221,7 @@ public class ExtractMethodDialog extends AbstractExtractDialog {
main.add(visibilityAndName, BorderLayout.CENTER);
setOKActionEnabled(false);
- setOKActionEnabled(JavaPsiFacade.getInstance(myProject).getNameHelper().isIdentifier(myNameField.getText()));
+ setOKActionEnabled(PsiNameHelper.getInstance(myProject).isIdentifier(myNameField.getText()));
final JPanel options = new JPanel(new BorderLayout());
options.add(createOptionsPanel(), BorderLayout.WEST);
main.add(options, BorderLayout.SOUTH);
@@ -347,7 +347,7 @@ public class ExtractMethodDialog extends AbstractExtractDialog {
myMakeStatic.setEnabled(!myStaticFlag && myCanBeStatic && !isChainedConstructor());
}
updateSignature();
- setOKActionEnabled(JavaPsiFacade.getInstance(myProject).getNameHelper().isIdentifier(myNameField.getText()) ||
+ setOKActionEnabled(PsiNameHelper.getInstance(myProject).isIdentifier(myNameField.getText()) ||
isChainedConstructor());
}
diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java
index ce52274140bb..c61c29c58ff9 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java
@@ -511,7 +511,7 @@ public class ExtractMethodProcessor implements MatchProvider {
PsiElement prevSibling = PsiTreeUtil.skipSiblingsBackward(myElements[0], PsiWhiteSpace.class);
if (prevSibling instanceof PsiComment && ((PsiComment)prevSibling).getTokenType() == JavaTokenType.END_OF_LINE_COMMENT) {
final String text = StringUtil.decapitalize(StringUtil.capitalizeWords(prevSibling.getText().trim().substring(2), true)).replaceAll(" ", "");
- if (JavaPsiFacade.getInstance(myProject).getNameHelper().isIdentifier(text) && text.length() < 20) {
+ if (PsiNameHelper.getInstance(myProject).isIdentifier(text) && text.length() < 20) {
return text;
}
}
diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectDialog.java b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectDialog.java
index ca64d8d7f954..fddd19bb4630 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectDialog.java
@@ -189,7 +189,7 @@ public class ExtractMethodObjectDialog extends AbstractExtractDialog {
private void update() {
myCbMakeStatic.setEnabled(myCreateInnerClassRb.isSelected() && myCanBeStatic && !myStaticFlag);
updateSignature();
- final PsiNameHelper helper = JavaPsiFacade.getInstance(myProject).getNameHelper();
+ final PsiNameHelper helper = PsiNameHelper.getInstance(myProject);
setOKActionEnabled((myCreateInnerClassRb.isSelected() && helper.isIdentifier(myInnerClassName.getText())) ||
(!myCreateInnerClassRb.isSelected() && helper.isIdentifier(myMethodName.getText())));
}
diff --git a/java/java-impl/src/com/intellij/refactoring/extractSuperclass/JavaExtractSuperBaseDialog.java b/java/java-impl/src/com/intellij/refactoring/extractSuperclass/JavaExtractSuperBaseDialog.java
index f80af85c471f..86089a95e59d 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractSuperclass/JavaExtractSuperBaseDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/extractSuperclass/JavaExtractSuperBaseDialog.java
@@ -27,7 +27,6 @@ import com.intellij.openapi.util.Pass;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
-import com.intellij.psi.impl.ElementPresentationUtil;
import com.intellij.psi.presentation.java.SymbolPresentationUtil;
import com.intellij.refactoring.MoveDestination;
import com.intellij.refactoring.PackageWrapper;
@@ -131,13 +130,12 @@ public abstract class JavaExtractSuperBaseDialog extends ExtractSuperBaseDialog<
@Override
protected void preparePackage() throws OperationFailedException {
final String targetPackageName = getTargetPackageName();
- final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(myProject);
final PsiFile containingFile = mySourceClass.getContainingFile();
final boolean fromDefaultPackage = containingFile instanceof PsiClassOwner && ((PsiClassOwner)containingFile).getPackageName().isEmpty();
- if (!(fromDefaultPackage && StringUtil.isEmpty(targetPackageName)) && !psiFacade.getNameHelper().isQualifiedName(targetPackageName)) {
+ if (!(fromDefaultPackage && StringUtil.isEmpty(targetPackageName)) && !PsiNameHelper.getInstance(myProject).isQualifiedName(targetPackageName)) {
throw new OperationFailedException("Invalid package name: " + targetPackageName);
}
- final PsiPackage aPackage = psiFacade.findPackage(targetPackageName);
+ final PsiPackage aPackage = JavaPsiFacade.getInstance(myProject).findPackage(targetPackageName);
if (aPackage != null) {
final PsiDirectory[] directories = aPackage.getDirectories(mySourceClass.getResolveScope());
if (directories.length >= 1) {
@@ -173,7 +171,7 @@ public abstract class JavaExtractSuperBaseDialog extends ExtractSuperBaseDialog<
@Nullable
@Override
protected String validateName(String name) {
- return JavaPsiFacade.getInstance(myProject).getNameHelper().isIdentifier(name)
+ return PsiNameHelper.getInstance(myProject).isIdentifier(name)
? null
: RefactoringMessageUtil.getIncorrectIdentifierMessage(name);
}
diff --git a/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassDialog.java b/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassDialog.java
index 18e53fb6ece5..9089af1e0f93 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassDialog.java
@@ -166,7 +166,7 @@ class ExtractClassDialog extends RefactoringDialog implements MemberInfoChangeLi
@Override
protected void canRun() throws ConfigurationException {
final Project project = sourceClass.getProject();
- final PsiNameHelper nameHelper = JavaPsiFacade.getInstance(project).getNameHelper();
+ final PsiNameHelper nameHelper = PsiNameHelper.getInstance(project);
final List<PsiMethod> methods = getMethodsToExtract();
final List<PsiField> fields = getFieldsToExtract();
final List<PsiClass> innerClasses = getClassesToExtract();
diff --git a/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassProcessor.java b/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassProcessor.java
index d69352551623..30300db5c322 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassProcessor.java
@@ -229,13 +229,13 @@ public class ExtractClassProcessor extends FixableUsagesRefactoringProcessor {
final String baseName = settings.FIELD_NAME_PREFIX.length() == 0 ? StringUtil.decapitalize(newClassName) : newClassName;
String name = settings.FIELD_NAME_PREFIX + baseName + settings.FIELD_NAME_SUFFIX;
- if (!existsFieldWithName(name) && !JavaPsiFacade.getInstance(project).getNameHelper().isKeyword(name)) {
+ if (!existsFieldWithName(name) && !PsiNameHelper.getInstance(project).isKeyword(name)) {
return name;
}
int counter = 1;
while (true) {
name = settings.FIELD_NAME_PREFIX + baseName + counter + settings.FIELD_NAME_SUFFIX;
- if (!existsFieldWithName(name) && !JavaPsiFacade.getInstance(project).getNameHelper().isKeyword(name)) {
+ if (!existsFieldWithName(name) && !PsiNameHelper.getInstance(project).isKeyword(name)) {
return name;
}
counter++;
diff --git a/java/java-impl/src/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationDialog.java b/java/java-impl/src/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationDialog.java
index b21204e55ef2..32e4992fe744 100644
--- a/java/java-impl/src/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationDialog.java
@@ -108,7 +108,7 @@ public class InheritanceToDelegationDialog extends RefactoringDialog {
@Override
protected void canRun() throws ConfigurationException {
final String fieldName = getFieldName();
- final PsiNameHelper helper = JavaPsiFacade.getInstance(myProject).getNameHelper();
+ final PsiNameHelper helper = PsiNameHelper.getInstance(myProject);
if (!helper.isIdentifier(fieldName)){
throw new ConfigurationException("\'" + fieldName + "\' is invalid field name for delegation");
}
diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java
index b29d02fad178..8ab4fe47ce7d 100644
--- a/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java
@@ -448,7 +448,12 @@ public class InlineMethodProcessor extends BaseRefactoringProcessor {
if (element instanceof PsiReferenceExpression) {
refExprList.add((PsiReferenceExpression)element);
} else if (element instanceof PsiImportStaticReferenceElement) {
- imports2Delete.add(PsiTreeUtil.getParentOfType(element, PsiImportStaticStatement.class));
+ final JavaResolveResult[] resolveResults = ((PsiImportStaticReferenceElement)element).multiResolve(false);
+ if (resolveResults.length < 2) {
+ //no overloads available: ensure broken import are deleted and
+ //unused overloaded imports are deleted by optimize imports helper
+ imports2Delete.add(PsiTreeUtil.getParentOfType(element, PsiImportStaticStatement.class));
+ }
}
else if (JavaLanguage.INSTANCE != element.getLanguage()) {
GenericInlineHandler.inlineReference(usage, myMethod, myInliners);
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceConstantDialog.java b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceConstantDialog.java
index 4bae67e08f16..d39cc8a1035e 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceConstantDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceConstantDialog.java
@@ -320,7 +320,7 @@ class IntroduceConstantDialog extends DialogWrapper {
}
private void updateButtons() {
- setOKActionEnabled(JavaPsiFacade.getInstance(myProject).getNameHelper().isIdentifier(getEnteredName()));
+ setOKActionEnabled(PsiNameHelper.getInstance(myProject).isIdentifier(getEnteredName()));
}
private void targetClassChanged() {
@@ -433,7 +433,7 @@ class IntroduceConstantDialog extends DialogWrapper {
String errorString = null;
if ("".equals(fieldName)) {
errorString = RefactoringBundle.message("no.field.name.specified");
- } else if (!JavaPsiFacade.getInstance(myProject).getNameHelper().isIdentifier(fieldName)) {
+ } else if (!PsiNameHelper.getInstance(myProject).isIdentifier(fieldName)) {
errorString = RefactoringMessageUtil.getIncorrectIdentifierMessage(fieldName);
} else if (newClass != null && !myParentClass.getLanguage().equals(newClass.getLanguage())) {
errorString = RefactoringBundle.message("move.to.different.language", UsageViewUtil.getType(myParentClass),
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldDialog.java b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldDialog.java
index 09c8cbd1a8cf..6f1cd002c9c5 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldDialog.java
@@ -189,7 +189,7 @@ class IntroduceFieldDialog extends DialogWrapper {
}
private void updateButtons() {
- setOKActionEnabled(JavaPsiFacade.getInstance(myProject).getNameHelper().isIdentifier(getEnteredName()));
+ setOKActionEnabled(PsiNameHelper.getInstance(myProject).isIdentifier(getEnteredName()));
}
private String getTypeLabel() {
@@ -240,7 +240,7 @@ class IntroduceFieldDialog extends DialogWrapper {
String errorString = null;
if ("".equals(fieldName)) {
errorString = RefactoringBundle.message("no.field.name.specified");
- } else if (!JavaPsiFacade.getInstance(myProject).getNameHelper().isIdentifier(fieldName)) {
+ } else if (!PsiNameHelper.getInstance(myProject).isIdentifier(fieldName)) {
errorString = RefactoringMessageUtil.getIncorrectIdentifierMessage(fieldName);
}
if (errorString != null) {
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractJavaInplaceIntroducer.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractJavaInplaceIntroducer.java
index 5e610f52e40f..a22a0987bdbb 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractJavaInplaceIntroducer.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractJavaInplaceIntroducer.java
@@ -121,7 +121,7 @@ public abstract class AbstractJavaInplaceIntroducer extends AbstractInplaceIntro
public static String[] appendUnresolvedExprName(String[] names, final PsiExpression expr) {
if (expr instanceof PsiReferenceExpression && ((PsiReferenceExpression)expr).resolve() == null) {
final String name = expr.getText();
- if (JavaPsiFacade.getInstance(expr.getProject()).getNameHelper().isIdentifier(name, LanguageLevel.HIGHEST)) {
+ if (PsiNameHelper.getInstance(expr.getProject()).isIdentifier(name, LanguageLevel.HIGHEST)) {
names = ArrayUtil.mergeArrays(new String[]{name}, names);
}
}
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterDialog.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterDialog.java
index b23b0c465858..2c1fd8376619 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterDialog.java
@@ -281,7 +281,7 @@ public class IntroduceParameterDialog extends RefactoringDialog {
@Override
protected void canRun() throws ConfigurationException {
String name = getParameterName();
- if (name == null || !JavaPsiFacade.getInstance(myProject).getNameHelper().isIdentifier(name)) {
+ if (name == null || !PsiNameHelper.getInstance(myProject).isIdentifier(name)) {
throw new ConfigurationException("\'" + (name != null ? name : "") + "\' is invalid parameter name");
}
}
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableDialog.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableDialog.java
index 99b2d6a096a1..350422dd436b 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableDialog.java
@@ -20,6 +20,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiExpression;
+import com.intellij.psi.PsiNameHelper;
import com.intellij.psi.PsiType;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.codeStyle.SuggestedNameInfo;
@@ -270,7 +271,7 @@ class IntroduceVariableDialog extends DialogWrapper implements IntroduceVariable
private void updateOkStatus() {
String text = getEnteredName();
- setOKActionEnabled(JavaPsiFacade.getInstance(myProject).getNameHelper().isIdentifier(text));
+ setOKActionEnabled(PsiNameHelper.getInstance(myProject).isIdentifier(text));
}
public JComponent getPreferredFocusedComponent() {
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectDialog.java b/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectDialog.java
index 7378c2e57d59..878e686474d1 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectDialog.java
@@ -185,8 +185,7 @@ public class IntroduceParameterObjectDialog extends RefactoringDialog {
@Override
protected void canRun() throws ConfigurationException {
final Project project = sourceMethod.getProject();
- final JavaPsiFacade manager = JavaPsiFacade.getInstance(project);
- final PsiNameHelper nameHelper = manager.getNameHelper();
+ final PsiNameHelper nameHelper = PsiNameHelper.getInstance(project);
final List<PsiParameter> parametersToExtract = getParametersToExtract();
if (parametersToExtract.isEmpty()) {
diff --git a/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeParameterizedStaticDialog.java b/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeParameterizedStaticDialog.java
index fa471dfa3a6e..b08c8d33ca0f 100644
--- a/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeParameterizedStaticDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeParameterizedStaticDialog.java
@@ -256,7 +256,7 @@ public class MakeParameterizedStaticDialog extends AbstractMakeStaticDialog {
setOKActionEnabled(false);
}
else {
- setOKActionEnabled(JavaPsiFacade.getInstance(myProject).getNameHelper().isIdentifier(classParameterName.trim()));
+ setOKActionEnabled(PsiNameHelper.getInstance(myProject).isIdentifier(classParameterName.trim()));
}
}
else
diff --git a/java/java-impl/src/com/intellij/refactoring/migration/EditMigrationEntryDialog.java b/java/java-impl/src/com/intellij/refactoring/migration/EditMigrationEntryDialog.java
index 4ca1a26f449e..6834a09693a8 100644
--- a/java/java-impl/src/com/intellij/refactoring/migration/EditMigrationEntryDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/migration/EditMigrationEntryDialog.java
@@ -132,12 +132,12 @@ public class EditMigrationEntryDialog extends DialogWrapper{
String text = myOldNameField.getText();
text = text.trim();
PsiManager manager = PsiManager.getInstance(myProject);
- if (!JavaPsiFacade.getInstance(manager.getProject()).getNameHelper().isQualifiedName(text)){
+ if (!PsiNameHelper.getInstance(manager.getProject()).isQualifiedName(text)){
isEnabled = false;
}
text = myNewNameField.getText();
text = text.trim();
- if (!JavaPsiFacade.getInstance(manager.getProject()).getNameHelper().isQualifiedName(text)){
+ if (!PsiNameHelper.getInstance(manager.getProject()).isQualifiedName(text)){
isEnabled = false;
}
setOKActionEnabled(isEnabled);
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesDialog.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesDialog.java
index c5caa4c9c240..3bbcf743506c 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesDialog.java
@@ -322,7 +322,7 @@ public class MoveClassesOrPackagesDialog extends RefactoringDialog {
protected void canRun() throws ConfigurationException {
if (isMoveToPackage()) {
String name = getTargetPackage().trim();
- if (name.length() != 0 && !JavaPsiFacade.getInstance(myManager.getProject()).getNameHelper().isQualifiedName(name)) {
+ if (name.length() != 0 && !PsiNameHelper.getInstance(myManager.getProject()).isQualifiedName(name)) {
throw new ConfigurationException("\'" + name + "\' is invalid destination package name");
}
}
@@ -491,7 +491,7 @@ public class MoveClassesOrPackagesDialog extends RefactoringDialog {
@Nullable
private MoveDestination selectDestination() {
final String packageName = getTargetPackage().trim();
- if (packageName.length() > 0 && !JavaPsiFacade.getInstance(myManager.getProject()).getNameHelper().isQualifiedName(packageName)) {
+ if (packageName.length() > 0 && !PsiNameHelper.getInstance(myManager.getProject()).isQualifiedName(packageName)) {
Messages.showErrorDialog(myProject, RefactoringBundle.message("please.enter.a.valid.target.package.name"),
RefactoringBundle.message("move.title"));
return null;
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesProcessor.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesProcessor.java
index 0e02b8f94e28..54ddf03a5c57 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesProcessor.java
@@ -122,7 +122,7 @@ public class MoveClassesOrPackagesProcessor extends BaseRefactoringProcessor {
public boolean verifyValidPackageName() {
String qName = myTargetPackage.getQualifiedName();
if (!StringUtil.isEmpty(qName)) {
- PsiNameHelper helper = JavaPsiFacade.getInstance(myProject).getNameHelper();
+ PsiNameHelper helper = PsiNameHelper.getInstance(myProject);
if (!helper.isQualifiedName(qName)) {
Messages.showMessageDialog(myProject, RefactoringBundle.message("invalid.target.package.name.specified"), "Invalid Package Name",
Messages.getErrorIcon());
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveJavaFileHandler.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveJavaFileHandler.java
index 60619ef4f9ce..92c3bc888f1c 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveJavaFileHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveJavaFileHandler.java
@@ -95,7 +95,7 @@ public class MoveJavaFileHandler extends MoveFileHandler {
final PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(containingDirectory);
if (aPackage != null) {
final String qualifiedName = aPackage.getQualifiedName();
- final PsiNameHelper helper = JavaPsiFacade.getInstance(file.getProject()).getNameHelper();
+ final PsiNameHelper helper = PsiNameHelper.getInstance(file.getProject());
final PsiPackageStatement packageStatement = !StringUtil.isEmptyOrSpaces(qualifiedName) && helper.isQualifiedName(qualifiedName)
? JavaPsiFacade.getElementFactory(file.getProject()).createPackageStatement(qualifiedName)
: null;
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerDialog.java b/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerDialog.java
index dd87120c6770..cb502377f83b 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerDialog.java
@@ -247,7 +247,7 @@ public class MoveInnerDialog extends RefactoringDialog {
message = RefactoringBundle.message("no.class.name.specified");
}
else {
- if (!JavaPsiFacade.getInstance(manager.getProject()).getNameHelper().isIdentifier(className)) {
+ if (!PsiNameHelper.getInstance(manager.getProject()).isIdentifier(className)) {
message = RefactoringMessageUtil.getIncorrectIdentifierMessage(className);
}
else {
@@ -256,7 +256,7 @@ public class MoveInnerDialog extends RefactoringDialog {
message = RefactoringBundle.message("no.parameter.name.specified");
}
else {
- if (!JavaPsiFacade.getInstance(manager.getProject()).getNameHelper().isIdentifier(parameterName)) {
+ if (!PsiNameHelper.getInstance(manager.getProject()).isIdentifier(parameterName)) {
message = RefactoringMessageUtil.getIncorrectIdentifierMessage(parameterName);
}
}
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodDialog.java b/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodDialog.java
index 3afe836ce615..1c058d2fe855 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodDialog.java
@@ -134,7 +134,7 @@ public class MoveInstanceMethodDialog extends MoveInstanceMethodDialogBase {
EditorTextField field = myOldClassParameterNameFields.get(aClass);
if (field.isEnabled()) {
String parameterName = field.getText().trim();
- if (!JavaPsiFacade.getInstance(myMethod.getProject()).getNameHelper().isIdentifier(parameterName)) {
+ if (!PsiNameHelper.getInstance(myMethod.getProject()).isIdentifier(parameterName)) {
Messages
.showErrorDialog(getProject(), RefactoringBundle.message("move.method.enter.a.valid.name.for.parameter"), myRefactoringName);
return;
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMembersDialog.java b/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMembersDialog.java
index ab1bc8a8af0b..a8daa9e733fe 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMembersDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMembersDialog.java
@@ -264,7 +264,7 @@ public class MoveMembersDialog extends RefactoringDialog implements MoveMembersO
return RefactoringBundle.message("no.destination.class.specified");
}
else {
- if (!JavaPsiFacade.getInstance(manager.getProject()).getNameHelper().isQualifiedName(fqName)) {
+ if (!PsiNameHelper.getInstance(manager.getProject()).isQualifiedName(fqName)) {
return RefactoringBundle.message("0.is.not.a.legal.fq.name", fqName);
}
else {
diff --git a/java/java-impl/src/com/intellij/refactoring/rename/DirectoryAsPackageRenameHandler.java b/java/java-impl/src/com/intellij/refactoring/rename/DirectoryAsPackageRenameHandler.java
index 71ec7ebe267b..958572dce0a6 100644
--- a/java/java-impl/src/com/intellij/refactoring/rename/DirectoryAsPackageRenameHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/rename/DirectoryAsPackageRenameHandler.java
@@ -18,10 +18,7 @@ package com.intellij.refactoring.rename;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.JavaDirectoryService;
-import com.intellij.psi.JavaPsiFacade;
-import com.intellij.psi.PsiDirectory;
-import com.intellij.psi.PsiPackage;
+import com.intellij.psi.*;
import com.intellij.refactoring.BaseRefactoringProcessor;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.move.moveClassesOrPackages.MoveDirectoryWithClassesProcessor;
@@ -38,7 +35,7 @@ public class DirectoryAsPackageRenameHandler extends DirectoryAsPackageRenameHan
@Override
protected boolean isIdentifier(String name, Project project) {
- return JavaPsiFacade.getInstance(project).getNameHelper().isIdentifier(name);
+ return PsiNameHelper.getInstance(project).isIdentifier(name);
}
@Override
diff --git a/java/java-impl/src/com/intellij/refactoring/rename/PsiPackageRenameValidator.java b/java/java-impl/src/com/intellij/refactoring/rename/PsiPackageRenameValidator.java
index 2a25f057e82f..29df2ff556b0 100644
--- a/java/java-impl/src/com/intellij/refactoring/rename/PsiPackageRenameValidator.java
+++ b/java/java-impl/src/com/intellij/refactoring/rename/PsiPackageRenameValidator.java
@@ -21,6 +21,7 @@ import com.intellij.patterns.ElementPattern;
import com.intellij.patterns.PlatformPatterns;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiNameHelper;
import com.intellij.psi.PsiPackage;
import com.intellij.psi.impl.file.PsiDirectoryFactory;
import com.intellij.util.ProcessingContext;
@@ -41,7 +42,7 @@ public class PsiPackageRenameValidator implements RenameInputValidatorEx {
if (!PsiDirectoryFactory.getInstance(project).isValidPackageName(newName)) {
return "Not a valid package name";
}
- if (!JavaPsiFacade.getInstance(project).getNameHelper().isIdentifier(newName)) {
+ if (!PsiNameHelper.getInstance(project).isIdentifier(newName)) {
return "Not a valid identifier name";
}
}
diff --git a/java/java-impl/src/com/intellij/refactoring/rename/naming/ConstructorParameterOnFieldRenameRenamer.java b/java/java-impl/src/com/intellij/refactoring/rename/naming/ConstructorParameterOnFieldRenameRenamer.java
index 345b3129defb..67bb13ce81e4 100644
--- a/java/java-impl/src/com/intellij/refactoring/rename/naming/ConstructorParameterOnFieldRenameRenamer.java
+++ b/java/java-impl/src/com/intellij/refactoring/rename/naming/ConstructorParameterOnFieldRenameRenamer.java
@@ -36,7 +36,9 @@ public class ConstructorParameterOnFieldRenameRenamer extends AutomaticRenamer {
}
protected String nameToCanonicalName(@NonNls final String name, final PsiNamedElement element) {
- return JavaCodeStyleManager.getInstance(element.getProject()).variableNameToPropertyName(name, VariableKind.FIELD);
+ final JavaCodeStyleManager javaCodeStyleManager = JavaCodeStyleManager.getInstance(element.getProject());
+ final VariableKind variableKind = element instanceof PsiVariable ? javaCodeStyleManager.getVariableKind((PsiVariable)element) : VariableKind.FIELD;
+ return javaCodeStyleManager.variableNameToPropertyName(name, variableKind);
}
public ConstructorParameterOnFieldRenameRenamer(PsiField aField, String newFieldName) {
diff --git a/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithBuilder/ReplaceConstructorWithBuilderDialog.java b/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithBuilder/ReplaceConstructorWithBuilderDialog.java
index e2354c99812e..41cccd9453ee 100644
--- a/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithBuilder/ReplaceConstructorWithBuilderDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithBuilder/ReplaceConstructorWithBuilderDialog.java
@@ -153,7 +153,7 @@ public class ReplaceConstructorWithBuilderDialog extends RefactoringDialog {
@Override
protected void canRun() throws ConfigurationException {
- final PsiNameHelper nameHelper = JavaPsiFacade.getInstance(myProject).getNameHelper();
+ final PsiNameHelper nameHelper = PsiNameHelper.getInstance(myProject);
for (ParameterData parameterData : myParametersMap.values()) {
if (!nameHelper.isIdentifier(parameterData.getFieldName())) throw new ConfigurationException("\'" + parameterData.getFieldName() + "\' is not a valid field name");
if (!nameHelper.isIdentifier(parameterData.getSetterName())) throw new ConfigurationException("\'" + parameterData.getSetterName() + "\' is not a valid setter name");
diff --git a/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryDialog.java b/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryDialog.java
index 01444d0cee4d..395ff848701d 100644
--- a/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryDialog.java
@@ -202,7 +202,7 @@ public class ReplaceConstructorWithFactoryDialog extends RefactoringDialog {
@Override
protected void canRun() throws ConfigurationException {
final String name = myNameField.getEnteredName();
- final PsiNameHelper nameHelper = JavaPsiFacade.getInstance(myContainingClass.getProject()).getNameHelper();
+ final PsiNameHelper nameHelper = PsiNameHelper.getInstance(myContainingClass.getProject());
if (!nameHelper.isIdentifier(name)) {
throw new ConfigurationException("\'" + name + "\' is invalid factory method name");
}
diff --git a/java/java-impl/src/com/intellij/refactoring/typeCook/TypeCookProcessor.java b/java/java-impl/src/com/intellij/refactoring/typeCook/TypeCookProcessor.java
index 08ad857fe766..4e4e681ea03b 100644
--- a/java/java-impl/src/com/intellij/refactoring/typeCook/TypeCookProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/typeCook/TypeCookProcessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,10 +30,7 @@ import com.intellij.usageView.UsageInfo;
import com.intellij.usageView.UsageViewDescriptor;
import org.jetbrains.annotations.NotNull;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
+import java.util.*;
public class TypeCookProcessor extends BaseRefactoringProcessor {
private PsiElement[] myElements;
@@ -75,7 +72,7 @@ public class TypeCookProcessor extends BaseRefactoringProcessor {
}
}
- final HashSet<PsiElement> changedItems = myResult.getCookedElements();
+ final Set<PsiElement> changedItems = myResult.getCookedElements();
final UsageInfo[] usages = new UsageInfo[changedItems.size()];
int i = 0;
@@ -100,7 +97,7 @@ public class TypeCookProcessor extends BaseRefactoringProcessor {
}
protected void performRefactoring(UsageInfo[] usages) {
- final HashSet<PsiElement> victims = new HashSet<PsiElement>();
+ final Set<PsiElement> victims = new HashSet<PsiElement>();
for (UsageInfo usage : usages) {
victims.add(usage.getElement());
diff --git a/java/java-impl/src/com/intellij/refactoring/typeCook/Util.java b/java/java-impl/src/com/intellij/refactoring/typeCook/Util.java
index e33388e0e8b7..54149613704b 100644
--- a/java/java-impl/src/com/intellij/refactoring/typeCook/Util.java
+++ b/java/java-impl/src/com/intellij/refactoring/typeCook/Util.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -217,7 +217,7 @@ public class Util {
return subst;
}
- public static boolean bindsTypeParameters(PsiType t, HashSet<PsiTypeParameter> params) {
+ public static boolean bindsTypeParameters(PsiType t, Set<PsiTypeParameter> params) {
if (t instanceof PsiWildcardType) {
final PsiWildcardType wct = ((PsiWildcardType)t);
final PsiType bound = wct.getBound();
@@ -286,7 +286,7 @@ public class Util {
PsiSubstitutor theSubst = PsiSubstitutor.EMPTY;
- final HashSet<PsiTypeVariable> cluster = new HashSet<PsiTypeVariable>();
+ final Set<PsiTypeVariable> cluster = new HashSet<PsiTypeVariable>();
for (final PsiTypeParameter parm : aSubst.getSubstitutionMap().keySet()) {
final PsiType type = createParameterizedType(aSubst.substitute(parm), factory, false, context);
diff --git a/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/PsiTypeVariableFactory.java b/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/PsiTypeVariableFactory.java
index e9a53aa68702..95535071b50e 100644
--- a/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/PsiTypeVariableFactory.java
+++ b/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/PsiTypeVariableFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,23 +21,21 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.NotNull;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
+import java.util.*;
/**
* @author db
*/
public class PsiTypeVariableFactory {
private int myCurrent = 0;
- private final LinkedList<HashSet<PsiTypeVariable>> myClusters = new LinkedList<HashSet<PsiTypeVariable>>();
- private final HashMap<Integer, HashSet<PsiTypeVariable>> myVarCluster = new HashMap<Integer, HashSet<PsiTypeVariable>>();
+ private final List<Set<PsiTypeVariable>> myClusters = new LinkedList<Set<PsiTypeVariable>>();
+ private final Map<Integer, Set<PsiTypeVariable>> myVarCluster = new HashMap<Integer, Set<PsiTypeVariable>>();
public final int getNumber() {
return myCurrent;
}
- public final void registerCluster(final HashSet<PsiTypeVariable> cluster) {
+ public final void registerCluster(final Set<PsiTypeVariable> cluster) {
myClusters.add(cluster);
for (final PsiTypeVariable aCluster : cluster) {
@@ -45,11 +43,11 @@ public class PsiTypeVariableFactory {
}
}
- public final LinkedList<HashSet<PsiTypeVariable>> getClusters() {
+ public final List<Set<PsiTypeVariable>> getClusters() {
return myClusters;
}
- public final HashSet<PsiTypeVariable> getClusterOf(final int var) {
+ public final Set<PsiTypeVariable> getClusterOf(final int var) {
return myVarCluster.get(new Integer(var));
}
diff --git a/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/builder/ReductionSystem.java b/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/builder/ReductionSystem.java
index 271c686b7fa9..a23d6d033c74 100644
--- a/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/builder/ReductionSystem.java
+++ b/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/builder/ReductionSystem.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,19 +31,19 @@ import java.util.*;
* @author db
*/
public class ReductionSystem {
- final HashSet<Constraint> myConstraints = new HashSet<Constraint>();
- final HashSet<PsiElement> myElements;
- final HashMap<PsiTypeCastExpression, PsiType> myCastToOperandType;
- final HashMap<PsiElement, PsiType> myTypes;
+ final Set<Constraint> myConstraints = new HashSet<Constraint>();
+ final Set<PsiElement> myElements;
+ final Map<PsiTypeCastExpression, PsiType> myCastToOperandType;
+ final Map<PsiElement, PsiType> myTypes;
final PsiTypeVariableFactory myTypeVariableFactory;
final Project myProject;
final Settings mySettings;
- HashSet<PsiTypeVariable> myBoundVariables;
+ Set<PsiTypeVariable> myBoundVariables;
public ReductionSystem(final Project project,
- final HashSet<PsiElement> elements,
- final HashMap<PsiElement, PsiType> types,
+ final Set<PsiElement> elements,
+ final Map<PsiElement, PsiType> types,
final PsiTypeVariableFactory factory,
final Settings settings) {
myProject = project;
@@ -59,7 +59,7 @@ public class ReductionSystem {
return myProject;
}
- public HashSet<Constraint> getConstraints() {
+ public Set<Constraint> getConstraints() {
return myConstraints;
}
@@ -165,7 +165,7 @@ public class ReductionSystem {
class Node {
int myComponent = -1;
Constraint myConstraint;
- HashSet<Node> myNeighbours = new HashSet<Node>();
+ Set<Node> myNeighbours = new HashSet<Node>();
public Node() {
myConstraint = null;
@@ -189,7 +189,7 @@ public class ReductionSystem {
final Node[] typeVariableNodes = new Node[myTypeVariableFactory.getNumber()];
final Node[] constraintNodes = new Node[myConstraints.size()];
- final HashMap<Constraint, HashSet<PsiTypeVariable>> boundVariables = new HashMap<Constraint, HashSet<PsiTypeVariable>>();
+ final Map<Constraint, Set<PsiTypeVariable>> boundVariables = new HashMap<Constraint, Set<PsiTypeVariable>>();
for (int i = 0; i < typeVariableNodes.length; i++) {
typeVariableNodes[i] = new Node();
@@ -207,7 +207,7 @@ public class ReductionSystem {
int l = 0;
for (final Constraint constraint : myConstraints) {
- final HashSet<PsiTypeVariable> boundVars = new HashSet<PsiTypeVariable>();
+ final Set<PsiTypeVariable> boundVars = new LinkedHashSet<PsiTypeVariable>();
final Node constraintNode = constraintNodes[l++];
new Object() {
@@ -266,9 +266,9 @@ public class ReductionSystem {
}
}
- final LinkedList<HashSet<PsiTypeVariable>> clusters = myTypeVariableFactory.getClusters();
+ List<Set<PsiTypeVariable>> clusters = myTypeVariableFactory.getClusters();
- for (final HashSet<PsiTypeVariable> cluster : clusters) {
+ for (final Set<PsiTypeVariable> cluster : clusters) {
Node prev = null;
for (final PsiTypeVariable variable : cluster) {
@@ -327,7 +327,7 @@ public class ReductionSystem {
return systems;
}
- private void addConstraint(final Constraint constraint, final HashSet<PsiTypeVariable> vars) {
+ private void addConstraint(final Constraint constraint, final Set<PsiTypeVariable> vars) {
if (myBoundVariables == null) {
myBoundVariables = vars;
}
@@ -342,7 +342,7 @@ public class ReductionSystem {
return myTypeVariableFactory;
}
- public HashSet<PsiTypeVariable> getBoundVariables() {
+ public Set<PsiTypeVariable> getBoundVariables() {
return myBoundVariables;
}
diff --git a/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/builder/Result.java b/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/builder/Result.java
index 31e67a451e7f..a74fc23261e3 100644
--- a/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/builder/Result.java
+++ b/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/builder/Result.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,9 +25,9 @@ import com.intellij.refactoring.typeCook.deductive.resolver.Binding;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NonNls;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
+import java.util.Set;
/**
* @author db
@@ -35,10 +35,10 @@ import java.util.Map;
public class Result {
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.typeCook.deductive.builder.Result");
- private final HashSet<PsiElement> myVictims;
- private final HashMap<PsiElement, PsiType> myTypes;
+ private final Set<PsiElement> myVictims;
+ private final Map<PsiElement, PsiType> myTypes;
private final Settings mySettings;
- private final HashMap<PsiTypeCastExpression, PsiType> myCastToOperandType;
+ private final Map<PsiTypeCastExpression, PsiType> myCastToOperandType;
private int myCookedNumber = -1;
private int myCastsRemoved = -1;
@@ -92,10 +92,10 @@ public class Result {
return originalType;
}
- public HashSet<PsiElement> getCookedElements() {
+ public Set<PsiElement> getCookedElements() {
myCookedNumber = 0;
- final HashSet<PsiElement> set = new HashSet<PsiElement>();
+ final Set<PsiElement> set = new HashSet<PsiElement>();
for (final PsiElement element : myVictims) {
final PsiType originalType = Util.getType(element);
@@ -137,7 +137,7 @@ public class Result {
return false;
}
- public void apply(final HashSet<PsiElement> victims) {
+ public void apply(final Set<PsiElement> victims) {
for (final PsiElement element : victims) {
if (element instanceof PsiTypeCastExpression && myCastToOperandType.containsKey(element)) {
final PsiTypeCastExpression cast = ((PsiTypeCastExpression)element);
diff --git a/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/builder/SystemBuilder.java b/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/builder/SystemBuilder.java
index 2cd9045ba121..8b0514143ba6 100644
--- a/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/builder/SystemBuilder.java
+++ b/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/builder/SystemBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,6 +37,7 @@ import com.intellij.util.containers.HashMap;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
+import java.util.Set;
/**
* Created by IntelliJ IDEA.
@@ -49,11 +50,11 @@ public class SystemBuilder {
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.typeCook.deductive.builder.SystemBuilder");
private final PsiManager myManager;
- private final HashMap<PsiElement, Boolean> myMethodCache;
- private final HashMap<PsiParameter, PsiParameter> myParameters;
- private final HashMap<PsiMethod, PsiMethod> myMethods;
- private final HashMap<PsiElement, PsiType> myTypes;
- private final HashSet<PsiAnchor> myVisitedConstructions;
+ private final Map<PsiElement, Boolean> myMethodCache;
+ private final Map<PsiParameter, PsiParameter> myParameters;
+ private final Map<PsiMethod, PsiMethod> myMethods;
+ private final Map<PsiElement, PsiType> myTypes;
+ private final Set<PsiAnchor> myVisitedConstructions;
private final Settings mySettings;
private final PsiTypeVariableFactory myTypeVariableFactory;
private final Project myProject;
@@ -70,11 +71,11 @@ public class SystemBuilder {
myTypeVariableFactory = new PsiTypeVariableFactory();
}
- private HashSet<PsiElement> collect(final PsiElement[] scopes) {
+ private Set<PsiElement> collect(final PsiElement[] scopes) {
return new VictimCollector(scopes, mySettings).getVictims();
}
- private boolean verifyMethod(final PsiElement element, final HashSet<PsiElement> victims, final PsiSearchHelper helper) {
+ private boolean verifyMethod(final PsiElement element, final Set<PsiElement> victims, final PsiSearchHelper helper) {
PsiMethod method;
PsiParameter parameter = null;
int index = 0;
@@ -352,7 +353,7 @@ public class SystemBuilder {
final PsiExpression qualifier =
expr instanceof PsiMethodCallExpression ? ((PsiMethodCallExpression)expr).getMethodExpression().getQualifierExpression() : null;
- final HashSet<PsiTypeParameter> typeParameters = new HashSet<PsiTypeParameter>(Arrays.asList(methodTypeParameters));
+ final Set<PsiTypeParameter> typeParameters = new HashSet<PsiTypeParameter>(Arrays.asList(methodTypeParameters));
PsiSubstitutor qualifierSubstitutor = PsiSubstitutor.EMPTY;
PsiSubstitutor supertypeSubstitutor = PsiSubstitutor.EMPTY;
@@ -397,7 +398,7 @@ public class SystemBuilder {
}
}
- final HashMap<PsiTypeParameter, PsiType> mapping = new HashMap<PsiTypeParameter, PsiType>();
+ final Map<PsiTypeParameter, PsiType> mapping = new HashMap<PsiTypeParameter, PsiType>();
for (int i = 0; i < Math.min(parameters.length, arguments.length); i++) {
final PsiType argumentType = evaluateType(arguments[i], system);
@@ -913,7 +914,7 @@ public class SystemBuilder {
return build(collect(scopes));
}
- public ReductionSystem build(final HashSet<PsiElement> victims) {
+ public ReductionSystem build(final Set<PsiElement> victims) {
final PsiSearchHelper helper = PsiSearchHelper.SERVICE.getInstance(myManager.getProject());
ReductionSystem system = new ReductionSystem(myProject, victims, myTypes, myTypeVariableFactory, mySettings);
diff --git a/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/resolver/Binding.java b/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/resolver/Binding.java
index 54901124c3c1..88286517e4f1 100644
--- a/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/resolver/Binding.java
+++ b/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/resolver/Binding.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@ package com.intellij.refactoring.typeCook.deductive.resolver;
import com.intellij.psi.PsiType;
import com.intellij.psi.PsiTypeVariable;
-import java.util.HashSet;
+import java.util.Set;
/**
* @author db
@@ -47,7 +47,7 @@ public abstract class Binding {
public abstract void merge(Binding b, boolean removeObject);
- public abstract HashSet<PsiTypeVariable> getBoundVariables();
+ public abstract Set<PsiTypeVariable> getBoundVariables();
public abstract int getWidth();
diff --git a/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/resolver/BindingFactory.java b/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/resolver/BindingFactory.java
index 49525a67de44..14b9a1715050 100644
--- a/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/resolver/BindingFactory.java
+++ b/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/resolver/BindingFactory.java
@@ -33,7 +33,6 @@ import com.intellij.util.IncorrectOperationException;
import gnu.trove.TIntObjectHashMap;
import gnu.trove.TObjectProcedure;
-import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.Set;
@@ -45,7 +44,7 @@ import java.util.Set;
public class BindingFactory {
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.typeCook.deductive.resolver.BindingFactory");
- private final HashSet<PsiTypeVariable> myBoundVariables;
+ private final Set<PsiTypeVariable> myBoundVariables;
private final Project myProject;
private final PsiTypeVariableFactory myFactory;
@@ -95,7 +94,7 @@ public class BindingFactory {
myBindings.put(index, type);
if (type instanceof Bottom) {
- final HashSet<PsiTypeVariable> cluster = myFactory.getClusterOf(index);
+ final Set<PsiTypeVariable> cluster = myFactory.getClusterOf(index);
if (cluster != null) {
for (PsiTypeVariable var : cluster) {
@@ -540,7 +539,7 @@ public class BindingFactory {
if (removeObject &&
javaLangObject.equals(type)) {
- final HashSet<PsiTypeVariable> cluster = myFactory.getClusterOf(var.getIndex());
+ final Set<PsiTypeVariable> cluster = myFactory.getClusterOf(var.getIndex());
if (cluster != null) {
for (final PsiTypeVariable war : cluster) {
@@ -560,7 +559,7 @@ public class BindingFactory {
}
}
- public HashSet<PsiTypeVariable> getBoundVariables() {
+ public Set<PsiTypeVariable> getBoundVariables() {
return myBoundVariables;
}
@@ -663,7 +662,7 @@ public class BindingFactory {
Binding unify(PsiType x, PsiType y);
}
- public Binding balance(final PsiType x, final PsiType y, final Balancer balancer, final HashSet<Constraint> constraints) {
+ public Binding balance(final PsiType x, final PsiType y, final Balancer balancer, final Set<Constraint> constraints) {
final int indicator = (x instanceof PsiTypeVariable ? 1 : 0) + (y instanceof PsiTypeVariable ? 2 : 0);
switch (indicator) {
@@ -878,7 +877,7 @@ public class BindingFactory {
}
}
- public Binding riseWithWildcard(final PsiType x, final PsiType y, final HashSet<Constraint> constraints) {
+ public Binding riseWithWildcard(final PsiType x, final PsiType y, final Set<Constraint> constraints) {
final Binding binding = balance(x, y, new Balancer() {
public Binding varType(final PsiTypeVariable x, final PsiType y) {
if (y instanceof Bottom) {
@@ -941,7 +940,7 @@ public class BindingFactory {
return binding != null ? binding.reduceRecursive() : null;
}
- public Binding rise(final PsiType x, final PsiType y, final HashSet<Constraint> constraints) {
+ public Binding rise(final PsiType x, final PsiType y, final Set<Constraint> constraints) {
final Binding binding = balance(x, y, new Balancer() {
public Binding varType(final PsiTypeVariable x, final PsiType y) {
if (y instanceof Bottom || y instanceof PsiWildcardType) {
@@ -977,7 +976,7 @@ public class BindingFactory {
return binding != null ? binding.reduceRecursive() : null;
}
- public Binding sink(final PsiType x, final PsiType y, final HashSet<Constraint> constraints) {
+ public Binding sink(final PsiType x, final PsiType y, final Set<Constraint> constraints) {
return balance(x, y, new Balancer() {
public Binding varType(final PsiTypeVariable x, final PsiType y) {
return create(x, y);
@@ -1141,7 +1140,7 @@ public class BindingFactory {
return new BindingImpl();
}
- public HashSet<PsiTypeVariable> getBoundVariables() {
+ public Set<PsiTypeVariable> getBoundVariables() {
return myBoundVariables;
}
}
diff --git a/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/resolver/ResolverTree.java b/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/resolver/ResolverTree.java
index 7279b6d4a0d0..a58e0561c449 100644
--- a/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/resolver/ResolverTree.java
+++ b/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/resolver/ResolverTree.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,6 +28,7 @@ import com.intellij.refactoring.typeCook.deductive.PsiExtendedTypeVisitor;
import com.intellij.refactoring.typeCook.deductive.builder.Constraint;
import com.intellij.refactoring.typeCook.deductive.builder.ReductionSystem;
import com.intellij.refactoring.typeCook.deductive.builder.Subtype;
+import com.intellij.util.containers.EmptyIterator;
import com.intellij.util.graph.DFSTBuilder;
import com.intellij.util.graph.Graph;
import gnu.trove.TIntArrayList;
@@ -51,7 +52,7 @@ public class ResolverTree {
private final Settings mySettings;
private boolean mySolutionFound = false;
- private HashSet<Constraint> myConstraints;
+ private Set<Constraint> myConstraints;
public ResolverTree(final ReductionSystem system) {
myBindingFactory = new BindingFactory(system);
@@ -65,7 +66,7 @@ public class ResolverTree {
reduceCyclicVariables();
}
- private ResolverTree(final ResolverTree parent, final HashSet<Constraint> constraints, final Binding binding) {
+ private ResolverTree(final ResolverTree parent, final Set<Constraint> constraints, final Binding binding) {
myBindingFactory = parent.myBindingFactory;
myCurrentBinding = binding;
mySolutions = parent.mySolutions;
@@ -76,7 +77,7 @@ public class ResolverTree {
}
private static class PsiTypeVarCollector extends PsiExtendedTypeVisitor {
- final HashSet<PsiTypeVariable> mySet = new HashSet<PsiTypeVariable>();
+ final Set<PsiTypeVariable> mySet = new HashSet<PsiTypeVariable>();
@Override
public Object visitTypeVariable(final PsiTypeVariable var) {
@@ -85,7 +86,7 @@ public class ResolverTree {
return null;
}
- public HashSet<PsiTypeVariable> getSet(final PsiType type) {
+ public Set<PsiTypeVariable> getSet(final PsiType type) {
type.accept(this);
return mySet;
}
@@ -120,14 +121,14 @@ public class ResolverTree {
return result;
}
- private void setDegree(final HashSet<PsiTypeVariable> set, TObjectIntHashMap<PsiTypeVariable> result) {
+ private void setDegree(final Set<PsiTypeVariable> set, TObjectIntHashMap<PsiTypeVariable> result) {
for (final PsiTypeVariable var : set) {
result.increment(var);
}
}
- private HashSet<Constraint> apply(final Binding b) {
- final HashSet<Constraint> result = new HashSet<Constraint>();
+ private Set<Constraint> apply(final Binding b) {
+ final Set<Constraint> result = new HashSet<Constraint>();
for (final Constraint constr : myConstraints) {
result.add(constr.apply(b));
@@ -136,8 +137,8 @@ public class ResolverTree {
return result;
}
- private HashSet<Constraint> apply(final Binding b, final HashSet<Constraint> additional) {
- final HashSet<Constraint> result = new HashSet<Constraint>();
+ private Set<Constraint> apply(final Binding b, final Set<Constraint> additional) {
+ final Set<Constraint> result = new HashSet<Constraint>();
for (final Constraint constr : myConstraints) {
result.add(constr.apply(b));
@@ -156,18 +157,18 @@ public class ResolverTree {
return newBinding == null ? null : new ResolverTree(this, apply(b), newBinding);
}
- private ResolverTree applyRule(final Binding b, final HashSet<Constraint> additional) {
+ private ResolverTree applyRule(final Binding b, final Set<Constraint> additional) {
final Binding newBinding = b != null ? myCurrentBinding.compose(b) : null;
return newBinding == null ? null : new ResolverTree(this, apply(b, additional), newBinding);
}
private void reduceCyclicVariables() {
- final HashSet<PsiTypeVariable> nodes = new HashSet<PsiTypeVariable>();
- final HashSet<Constraint> candidates = new HashSet<Constraint>();
+ final Set<PsiTypeVariable> nodes = new HashSet<PsiTypeVariable>();
+ final Set<Constraint> candidates = new HashSet<Constraint>();
- final HashMap<PsiTypeVariable, HashSet<PsiTypeVariable>> ins = new HashMap<PsiTypeVariable, HashSet<PsiTypeVariable>>();
- final HashMap<PsiTypeVariable, HashSet<PsiTypeVariable>> outs = new HashMap<PsiTypeVariable, HashSet<PsiTypeVariable>>();
+ final Map<PsiTypeVariable, Set<PsiTypeVariable>> ins = new HashMap<PsiTypeVariable, Set<PsiTypeVariable>>();
+ final Map<PsiTypeVariable, Set<PsiTypeVariable>> outs = new HashMap<PsiTypeVariable, Set<PsiTypeVariable>>();
for (final Constraint constraint : myConstraints) {
final PsiType left = constraint.getLeft();
@@ -182,11 +183,11 @@ public class ResolverTree {
nodes.add(leftVar);
nodes.add(rightVar);
- final HashSet<PsiTypeVariable> in = ins.get(leftVar);
- final HashSet<PsiTypeVariable> out = outs.get(rightVar);
+ Set<PsiTypeVariable> in = ins.get(leftVar);
+ Set<PsiTypeVariable> out = outs.get(rightVar);
if (in == null) {
- final HashSet<PsiTypeVariable> newIn = new HashSet<PsiTypeVariable>();
+ final Set<PsiTypeVariable> newIn = new HashSet<PsiTypeVariable>();
newIn.add(rightVar);
@@ -197,7 +198,7 @@ public class ResolverTree {
}
if (out == null) {
- final HashSet<PsiTypeVariable> newOut = new HashSet<PsiTypeVariable>();
+ final Set<PsiTypeVariable> newOut = new HashSet<PsiTypeVariable>();
newOut.add(leftVar);
@@ -217,10 +218,10 @@ public class ResolverTree {
@Override
public Iterator<PsiTypeVariable> getIn(final PsiTypeVariable n) {
- final HashSet<PsiTypeVariable> in = ins.get(n);
+ final Set<PsiTypeVariable> in = ins.get(n);
if (in == null) {
- return new HashSet<PsiTypeVariable>().iterator();
+ return EmptyIterator.getInstance();
}
return in.iterator();
@@ -228,10 +229,10 @@ public class ResolverTree {
@Override
public Iterator<PsiTypeVariable> getOut(final PsiTypeVariable n) {
- final HashSet<PsiTypeVariable> out = outs.get(n);
+ final Set<PsiTypeVariable> out = outs.get(n);
if (out == null) {
- return new HashSet<PsiTypeVariable>().iterator();
+ return EmptyIterator.getInstance();
}
return out.iterator();
@@ -240,7 +241,7 @@ public class ResolverTree {
});
final TIntArrayList sccs = dfstBuilder.getSCCs();
- final HashMap<PsiTypeVariable, Integer> index = new HashMap<PsiTypeVariable, Integer>();
+ final Map<PsiTypeVariable, Integer> index = new HashMap<PsiTypeVariable, Integer>();
sccs.forEach(new TIntProcedure() {
int myTNumber = 0;
@@ -284,9 +285,9 @@ public class ResolverTree {
private void reduceTypeType(final Constraint constr) {
final PsiType left = constr.getLeft();
final PsiType right = constr.getRight();
- final HashSet<Constraint> addendumRise = new HashSet<Constraint>();
- final HashSet<Constraint> addendumSink = new HashSet<Constraint>();
- final HashSet<Constraint> addendumWcrd = new HashSet<Constraint>();
+ final Set<Constraint> addendumRise = new HashSet<Constraint>();
+ final Set<Constraint> addendumSink = new HashSet<Constraint>();
+ final Set<Constraint> addendumWcrd = new HashSet<Constraint>();
int numSons = 0;
Binding riseBinding = myBindingFactory.rise(left, right, addendumRise);
@@ -356,7 +357,7 @@ public class ResolverTree {
private void fillTypeRange(final PsiType lowerBound,
final PsiType upperBound,
- final HashSet<PsiType> holder) {
+ final Set<PsiType> holder) {
if (lowerBound instanceof PsiClassType && upperBound instanceof PsiClassType) {
final PsiClassType.ClassResolveResult resultLower = ((PsiClassType)lowerBound).resolveGenerics();
final PsiClassType.ClassResolveResult resultUpper = ((PsiClassType)upperBound).resolveGenerics();
@@ -385,7 +386,7 @@ public class ResolverTree {
}
private PsiType[] getTypeRange(final PsiType lowerBound, final PsiType upperBound) {
- final HashSet<PsiType> range = new HashSet<PsiType>();
+ Set<PsiType> range = new HashSet<PsiType>();
range.add(lowerBound);
range.add(upperBound);
@@ -464,8 +465,8 @@ public class ResolverTree {
reduceCyclicVariables();
}
- final HashMap<PsiTypeVariable, Constraint> myTypeVarConstraints = new HashMap<PsiTypeVariable, Constraint>();
- final HashMap<PsiTypeVariable, Constraint> myVarTypeConstraints = new HashMap<PsiTypeVariable, Constraint>();
+ final Map<PsiTypeVariable, Constraint> myTypeVarConstraints = new HashMap<PsiTypeVariable, Constraint>();
+ final Map<PsiTypeVariable, Constraint> myVarTypeConstraints = new HashMap<PsiTypeVariable, Constraint>();
for (final Constraint constr : myConstraints) {
final PsiType left = constr.getLeft();
@@ -530,7 +531,7 @@ public class ResolverTree {
final PsiType right = constr.getRight();
if (!(left instanceof PsiTypeVariable) && right instanceof PsiTypeVariable) {
- final HashSet<PsiTypeVariable> bound = new PsiTypeVarCollector().getSet(left);
+ Set<PsiTypeVariable> bound = new PsiTypeVarCollector().getSet(left);
if (bound.contains(right)) {
myConstraints.remove(constr);
@@ -561,10 +562,10 @@ public class ResolverTree {
//T1 < a < b < ...
{
- final HashSet<PsiTypeVariable> haveLeftBound = new HashSet<PsiTypeVariable>();
+ Set<PsiTypeVariable> haveLeftBound = new HashSet<PsiTypeVariable>();
Constraint target = null;
- final HashSet<PsiTypeVariable> boundVariables = new HashSet<PsiTypeVariable>();
+ Set<PsiTypeVariable> boundVariables = new HashSet<PsiTypeVariable>();
for (final Constraint constr : myConstraints) {
final PsiType leftType = constr.getLeft();
diff --git a/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/util/VictimCollector.java b/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/util/VictimCollector.java
index 5b2354563ed9..9af367c9fbd1 100644
--- a/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/util/VictimCollector.java
+++ b/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/util/VictimCollector.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,13 +19,14 @@ import com.intellij.psi.*;
import com.intellij.refactoring.typeCook.Settings;
import com.intellij.refactoring.typeCook.Util;
-import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Set;
/**
* @author db
*/
public class VictimCollector extends Visitor {
- final HashSet<PsiElement> myVictims = new HashSet<PsiElement>();
+ final Set<PsiElement> myVictims = new LinkedHashSet<PsiElement>();
final PsiElement[] myElements;
final Settings mySettings;
@@ -106,7 +107,7 @@ public class VictimCollector extends Visitor {
}
}
- public HashSet<PsiElement> getVictims() {
+ public Set<PsiElement> getVictims() {
for (PsiElement element : myElements) {
element.accept(this);
}
diff --git a/java/java-impl/src/com/intellij/refactoring/util/ParameterTablePanel.java b/java/java-impl/src/com/intellij/refactoring/util/ParameterTablePanel.java
index 83fba883184c..7a427b9fc56f 100644
--- a/java/java-impl/src/com/intellij/refactoring/util/ParameterTablePanel.java
+++ b/java/java-impl/src/com/intellij/refactoring/util/ParameterTablePanel.java
@@ -310,7 +310,7 @@ public abstract class ParameterTablePanel extends JPanel {
case PARAMETER_NAME_COLUMN: {
VariableData data = getVariableData()[rowIndex];
String name = (String)aValue;
- if (JavaPsiFacade.getInstance(myProject).getNameHelper().isIdentifier(name)) {
+ if (PsiNameHelper.getInstance(myProject).isIdentifier(name)) {
data.name = name;
}
updateSignature();
diff --git a/java/java-impl/src/com/intellij/refactoring/util/duplicates/MethodDuplicatesHandler.java b/java/java-impl/src/com/intellij/refactoring/util/duplicates/MethodDuplicatesHandler.java
index 876617b516e4..4bd3d6db70a5 100644
--- a/java/java-impl/src/com/intellij/refactoring/util/duplicates/MethodDuplicatesHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/util/duplicates/MethodDuplicatesHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,13 +28,14 @@ import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.module.Module;
-import com.intellij.openapi.module.ModuleUtil;
+import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectUtil;
import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.Computable;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.psi.*;
@@ -71,7 +72,7 @@ public class MethodDuplicatesHandler implements RefactoringActionHandler {
}
final AnalysisScope scope = new AnalysisScope(file);
- final Module module = ModuleUtil.findModuleForPsiElement(file);
+ final Module module = ModuleUtilCore.findModuleForPsiElement(file);
final BaseAnalysisActionDialog dlg = new BaseAnalysisActionDialog(RefactoringBundle.message("replace.method.duplicates.scope.chooser.title", REFACTORING_NAME),
RefactoringBundle.message("replace.method.duplicates.scope.chooser.message"),
project, scope, module != null ? module.getName() : null, false,
@@ -134,13 +135,18 @@ public class MethodDuplicatesHandler implements RefactoringActionHandler {
}
final Map<PsiMember, Set<Module>> memberWithModulesMap = new HashMap<PsiMember, Set<Module>>();
- for (PsiMember member : members) {
- final Module module = ModuleUtil.findModuleForPsiElement(member);
+ for (final PsiMember member : members) {
+ final Module module = ApplicationManager.getApplication().runReadAction(new Computable<Module>() {
+ @Override
+ public Module compute() {
+ return ModuleUtilCore.findModuleForPsiElement(member);
+ }
+ });
if (module != null) {
final HashSet<Module> dependencies = new HashSet<Module>();
ApplicationManager.getApplication().runReadAction(new Runnable() {
public void run() {
- ModuleUtil.collectModulesDependsOn(module, dependencies);
+ ModuleUtilCore.collectModulesDependsOn(module, dependencies);
}
});
memberWithModulesMap.put(member, dependencies);
@@ -158,7 +164,7 @@ public class MethodDuplicatesHandler implements RefactoringActionHandler {
progressIndicator.setText2(ProjectUtil.calcRelativeToProjectPath(virtualFile, project));
}
}
- final Module targetModule = ModuleUtil.findModuleForPsiElement(file);
+ final Module targetModule = ModuleUtilCore.findModuleForPsiElement(file);
if (targetModule == null) return;
for (Map.Entry<PsiMember, Set<Module>> entry : memberWithModulesMap.entrySet()) {
final Set<Module> dependencies = entry.getValue();
diff --git a/java/java-impl/src/com/intellij/refactoring/wrapreturnvalue/WrapReturnValueDialog.java b/java/java-impl/src/com/intellij/refactoring/wrapreturnvalue/WrapReturnValueDialog.java
index ac9b65950590..e7918134afe5 100644
--- a/java/java-impl/src/com/intellij/refactoring/wrapreturnvalue/WrapReturnValueDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/wrapreturnvalue/WrapReturnValueDialog.java
@@ -107,8 +107,7 @@ class WrapReturnValueDialog extends RefactoringDialog {
@Override
protected void canRun() throws ConfigurationException {
final Project project = sourceMethod.getProject();
- final JavaPsiFacade manager = JavaPsiFacade.getInstance(project);
- final PsiNameHelper nameHelper = manager.getNameHelper();
+ final PsiNameHelper nameHelper = PsiNameHelper.getInstance(project);
if (myCreateInnerClassButton.isSelected()) {
final String innerClassName = getInnerClassName().trim();
if (!nameHelper.isIdentifier(innerClassName)) throw new ConfigurationException("\'" + innerClassName + "\' is invalid inner class name");
diff --git a/java/java-impl/src/com/intellij/slicer/SliceLeafAnalyzer.java b/java/java-impl/src/com/intellij/slicer/SliceLeafAnalyzer.java
index d59129174520..a08464fbd7ce 100644
--- a/java/java-impl/src/com/intellij/slicer/SliceLeafAnalyzer.java
+++ b/java/java-impl/src/com/intellij/slicer/SliceLeafAnalyzer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -244,7 +244,7 @@ public class SliceLeafAnalyzer {
final SliceNodeGuide guide = new SliceNodeGuide(treeStructure);
WalkingState<SliceNode> walkingState = new WalkingState<SliceNode>(guide) {
@Override
- public void visit(@NotNull SliceNode element) {
+ public void visit(@NotNull final SliceNode element) {
element.calculateDupNode();
node(element, map).clear();
SliceNode duplicate = element.getDuplicate();
@@ -252,20 +252,21 @@ public class SliceLeafAnalyzer {
node(element, map).addAll(node(duplicate, map));
}
else {
- final SliceUsage sliceUsage = element.getValue();
-
- Collection<? extends AbstractTreeNode> children = element.getChildren();
- if (children.isEmpty()) {
- PsiElement value = ApplicationManager.getApplication().runReadAction(new Computable<PsiElement>() {
- @Override
- public PsiElement compute() {
- return sliceUsage.indexNesting == 0 ? sliceUsage.getElement() : null;
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ @Override
+ public void run() {
+ final SliceUsage sliceUsage = element.getValue();
+
+ Collection<? extends AbstractTreeNode> children = element.getChildren();
+ if (children.isEmpty()) {
+ PsiElement value = sliceUsage.indexNesting == 0 ? sliceUsage.getElement() : null;
+ if (value != null) {
+ node(element, map).addAll(ContainerUtil.singleton(value, LEAF_ELEMENT_EQUALITY));
+ }
}
- });
- if (value != null) {
- node(element, map).addAll(ContainerUtil.singleton(value, LEAF_ELEMENT_EQUALITY));
}
- }
+ });
+
super.visit(element);
}
}
diff --git a/java/java-impl/src/com/intellij/slicer/SliceNullnessAnalyzer.java b/java/java-impl/src/com/intellij/slicer/SliceNullnessAnalyzer.java
index b65932aeaa81..ba6f8602ba46 100644
--- a/java/java-impl/src/com/intellij/slicer/SliceNullnessAnalyzer.java
+++ b/java/java-impl/src/com/intellij/slicer/SliceNullnessAnalyzer.java
@@ -170,7 +170,7 @@ public class SliceNullnessAnalyzer {
final SliceLeafAnalyzer.SliceNodeGuide guide = new SliceLeafAnalyzer.SliceNodeGuide(treeStructure);
WalkingState<SliceNode> walkingState = new WalkingState<SliceNode>(guide) {
@Override
- public void visit(@NotNull SliceNode element) {
+ public void visit(@NotNull final SliceNode element) {
element.calculateDupNode();
node(element, map).clear();
SliceNode duplicate = element.getDuplicate();
@@ -178,11 +178,10 @@ public class SliceNullnessAnalyzer {
node(element, map).add(node(duplicate, map));
}
else {
- final SliceUsage sliceUsage = element.getValue();
final PsiElement value = ApplicationManager.getApplication().runReadAction(new Computable<PsiElement>() {
@Override
public PsiElement compute() {
- return sliceUsage.getElement();
+ return element.getValue().getElement();
}
});
Nullness nullness = ApplicationManager.getApplication().runReadAction(new Computable<Nullness>() {
@@ -198,7 +197,13 @@ public class SliceNullnessAnalyzer {
group(element, map, NullAnalysisResult.NOT_NULLS).add(value);
}
else {
- Collection<? extends AbstractTreeNode> children = element.getChildren();
+ Collection<? extends AbstractTreeNode> children = ApplicationManager.getApplication().runReadAction(
+ new Computable<Collection<? extends AbstractTreeNode>>() {
+ @Override
+ public Collection<? extends AbstractTreeNode> compute() {
+ return element.getChildren();
+ }
+ });
if (children.isEmpty()) {
group(element, map, NullAnalysisResult.UNKNOWNS).add(value);
}
diff --git a/java/java-impl/src/com/intellij/slicer/SliceUsage.java b/java/java-impl/src/com/intellij/slicer/SliceUsage.java
index b8d5a34c3c61..ef68b0d6a28e 100644
--- a/java/java-impl/src/com/intellij/slicer/SliceUsage.java
+++ b/java/java-impl/src/com/intellij/slicer/SliceUsage.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ import com.intellij.analysis.AnalysisScope;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.util.Computable;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiSubstitutor;
import com.intellij.usageView.UsageInfo;
@@ -68,7 +69,12 @@ public class SliceUsage extends UsageInfo2UsageAdapter {
}
public void processChildren(@NotNull Processor<SliceUsage> processor) {
- final PsiElement element = getElement();
+ final PsiElement element = ApplicationManager.getApplication().runReadAction(new Computable<PsiElement>() {
+ @Override
+ public PsiElement compute() {
+ return getElement();
+ }
+ });
ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
indicator.checkCanceled();
diff --git a/java/java-impl/src/com/intellij/testIntegration/createTest/CreateTestDialog.java b/java/java-impl/src/com/intellij/testIntegration/createTest/CreateTestDialog.java
index 5be9ce379705..a620938830ef 100644
--- a/java/java-impl/src/com/intellij/testIntegration/createTest/CreateTestDialog.java
+++ b/java/java-impl/src/com/intellij/testIntegration/createTest/CreateTestDialog.java
@@ -185,7 +185,7 @@ public class CreateTestDialog extends DialogWrapper {
myTargetClassNameField.getDocument().addDocumentListener(new DocumentAdapter() {
@Override
public void documentChanged(DocumentEvent e) {
- getOKAction().setEnabled(JavaPsiFacade.getInstance(myProject).getNameHelper().isIdentifier(getClassName()));
+ getOKAction().setEnabled(PsiNameHelper.getInstance(myProject).isIdentifier(getClassName()));
}
});
diff --git a/java/java-impl/src/com/intellij/testIntegration/createTest/JavaTestGenerator.java b/java/java-impl/src/com/intellij/testIntegration/createTest/JavaTestGenerator.java
index abde9233f535..fd96a06d6cd4 100644
--- a/java/java-impl/src/com/intellij/testIntegration/createTest/JavaTestGenerator.java
+++ b/java/java-impl/src/com/intellij/testIntegration/createTest/JavaTestGenerator.java
@@ -28,6 +28,7 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
@@ -63,12 +64,17 @@ public class JavaTestGenerator implements TestGenerator {
if (targetClass == null) {
return null;
}
- addSuperClass(targetClass, project, d.getSuperClassName());
+ final TestFramework frameworkDescriptor = d.getSelectedTestFrameworkDescriptor();
+ final String defaultSuperClass = frameworkDescriptor.getDefaultSuperClass();
+ final String superClassName = d.getSuperClassName();
+ if (!Comparing.strEqual(superClassName, defaultSuperClass)) {
+ addSuperClass(targetClass, project, superClassName);
+ }
Editor editor = CodeInsightUtil.positionCursor(project, targetClass.getContainingFile(), targetClass.getLBrace());
addTestMethods(editor,
targetClass,
- d.getSelectedTestFrameworkDescriptor(),
+ frameworkDescriptor,
d.getSelectedMethods(),
d.shouldGeneratedBefore(),
d.shouldGeneratedAfter());
@@ -135,7 +141,7 @@ public class JavaTestGenerator implements TestGenerator {
private static void addSuperClass(PsiClass targetClass, Project project, String superClassName) throws IncorrectOperationException {
if (superClassName == null) return;
final PsiReferenceList extendsList = targetClass.getExtendsList();
- if (extendsList == null || extendsList.getReferencedTypes().length > 0) return;
+ if (extendsList == null) return;
PsiElementFactory ef = JavaPsiFacade.getInstance(project).getElementFactory();
PsiJavaCodeReferenceElement superClassRef;
@@ -147,7 +153,12 @@ public class JavaTestGenerator implements TestGenerator {
else {
superClassRef = ef.createFQClassNameReferenceElement(superClassName, GlobalSearchScope.allScope(project));
}
- extendsList.add(superClassRef);
+ final PsiJavaCodeReferenceElement[] referenceElements = extendsList.getReferenceElements();
+ if (referenceElements.length == 0) {
+ extendsList.add(superClassRef);
+ } else {
+ referenceElements[0].replace(superClassRef);
+ }
}
@Nullable
diff --git a/java/java-indexing-api/src/com/intellij/psi/search/searches/AllOverridingMethodsSearch.java b/java/java-indexing-api/src/com/intellij/psi/search/searches/AllOverridingMethodsSearch.java
index 4cc0cdf9642f..32067d077a48 100644
--- a/java/java-indexing-api/src/com/intellij/psi/search/searches/AllOverridingMethodsSearch.java
+++ b/java/java-indexing-api/src/com/intellij/psi/search/searches/AllOverridingMethodsSearch.java
@@ -23,6 +23,7 @@ import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.SearchScope;
+import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.EmptyQuery;
import com.intellij.util.Query;
import com.intellij.util.QueryExecutor;
@@ -63,6 +64,6 @@ public class AllOverridingMethodsSearch extends ExtensibleQueryFactory<Pair<PsiM
}
public static Query<Pair<PsiMethod, PsiMethod>> search(final PsiClass aClass) {
- return search(aClass, GlobalSearchScope.allScope(aClass.getProject()));
+ return search(aClass, GlobalSearchScope.allScope(PsiUtilCore.getProjectInReadAction(aClass)));
}
}
diff --git a/java/java-indexing-api/src/com/intellij/psi/search/searches/AnnotatedMembersSearch.java b/java/java-indexing-api/src/com/intellij/psi/search/searches/AnnotatedMembersSearch.java
index 14e37a51b86f..f6003eb12fb5 100644
--- a/java/java-indexing-api/src/com/intellij/psi/search/searches/AnnotatedMembersSearch.java
+++ b/java/java-indexing-api/src/com/intellij/psi/search/searches/AnnotatedMembersSearch.java
@@ -19,6 +19,7 @@ import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMember;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.SearchScope;
+import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.Query;
import org.jetbrains.annotations.NotNull;
@@ -34,6 +35,6 @@ public class AnnotatedMembersSearch {
}
public static Query<PsiMember> search(@NotNull PsiClass annotationClass) {
- return search(annotationClass, GlobalSearchScope.allScope(annotationClass.getProject()));
+ return search(annotationClass, GlobalSearchScope.allScope(PsiUtilCore.getProjectInReadAction(annotationClass)));
}
}
diff --git a/java/java-indexing-api/src/com/intellij/psi/search/searches/AnnotatedPackagesSearch.java b/java/java-indexing-api/src/com/intellij/psi/search/searches/AnnotatedPackagesSearch.java
index 17e3fa0f617c..69548d5ff317 100644
--- a/java/java-indexing-api/src/com/intellij/psi/search/searches/AnnotatedPackagesSearch.java
+++ b/java/java-indexing-api/src/com/intellij/psi/search/searches/AnnotatedPackagesSearch.java
@@ -19,6 +19,7 @@ import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiPackage;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.SearchScope;
+import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.Query;
import org.jetbrains.annotations.NotNull;
@@ -53,6 +54,6 @@ public class AnnotatedPackagesSearch extends ExtensibleQueryFactory<PsiPackage,
}
public static Query<PsiPackage> search(@NotNull PsiClass annotationClass) {
- return search(annotationClass, GlobalSearchScope.allScope(annotationClass.getProject()));
+ return search(annotationClass, GlobalSearchScope.allScope(PsiUtilCore.getProjectInReadAction(annotationClass)));
}
} \ No newline at end of file
diff --git a/java/java-indexing-api/src/com/intellij/psi/search/searches/AnnotationTargetsSearch.java b/java/java-indexing-api/src/com/intellij/psi/search/searches/AnnotationTargetsSearch.java
index c177985396a9..0b42ceae1709 100644
--- a/java/java-indexing-api/src/com/intellij/psi/search/searches/AnnotationTargetsSearch.java
+++ b/java/java-indexing-api/src/com/intellij/psi/search/searches/AnnotationTargetsSearch.java
@@ -21,6 +21,7 @@ import com.intellij.psi.PsiModifierListOwner;
import com.intellij.psi.PsiPackage;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.SearchScope;
+import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.MergeQuery;
import com.intellij.util.Query;
import org.jetbrains.annotations.NotNull;
@@ -58,6 +59,6 @@ public class AnnotationTargetsSearch {
}
public static Query<PsiModifierListOwner> search(@NotNull PsiClass annotationClass) {
- return search(annotationClass, GlobalSearchScope.allScope(annotationClass.getProject()));
+ return search(annotationClass, GlobalSearchScope.allScope(PsiUtilCore.getProjectInReadAction(annotationClass)));
}
} \ No newline at end of file
diff --git a/java/java-indexing-api/src/com/intellij/psi/search/searches/ClassInheritorsSearch.java b/java/java-indexing-api/src/com/intellij/psi/search/searches/ClassInheritorsSearch.java
index e07692008ff9..cc6bf9d3044d 100644
--- a/java/java-indexing-api/src/com/intellij/psi/search/searches/ClassInheritorsSearch.java
+++ b/java/java-indexing-api/src/com/intellij/psi/search/searches/ClassInheritorsSearch.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressIndicatorProvider;
+import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Pair;
@@ -28,6 +29,7 @@ import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.PsiSearchScopeUtil;
import com.intellij.psi.search.SearchScope;
+import com.intellij.psi.util.PsiUtilCore;
import com.intellij.reference.SoftReference;
import com.intellij.util.Processor;
import com.intellij.util.Query;
@@ -188,7 +190,8 @@ public class ClassInheritorsSearch extends ExtensibleQueryFactory<PsiClass, Clas
}
});
if (CommonClassNames.JAVA_LANG_OBJECT.equals(qname)) {
- return AllClassesSearch.search(searchScope, baseClass.getProject(), parameters.getNameCondition()).forEach(new Processor<PsiClass>() {
+ Project project = PsiUtilCore.getProjectInReadAction(baseClass);
+ return AllClassesSearch.search(searchScope, project, parameters.getNameCondition()).forEach(new Processor<PsiClass>() {
@Override
public boolean process(final PsiClass aClass) {
ProgressIndicatorProvider.checkCanceled();
@@ -250,7 +253,7 @@ public class ClassInheritorsSearch extends ExtensibleQueryFactory<PsiClass, Clas
}
};
stack.push(Pair.create(createHardReference(baseClass), qname));
- final GlobalSearchScope projectScope = GlobalSearchScope.allScope(baseClass.getProject());
+ final GlobalSearchScope projectScope = GlobalSearchScope.allScope(PsiUtilCore.getProjectInReadAction(baseClass));
final JavaPsiFacade facade = JavaPsiFacade.getInstance(projectScope.getProject());
while (!stack.isEmpty()) {
ProgressIndicatorProvider.checkCanceled();
diff --git a/java/java-indexing-api/src/com/intellij/psi/search/searches/DirectClassInheritorsSearch.java b/java/java-indexing-api/src/com/intellij/psi/search/searches/DirectClassInheritorsSearch.java
index da798a15ed3b..1a98d0c167d3 100644
--- a/java/java-indexing-api/src/com/intellij/psi/search/searches/DirectClassInheritorsSearch.java
+++ b/java/java-indexing-api/src/com/intellij/psi/search/searches/DirectClassInheritorsSearch.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@ import com.intellij.psi.PsiAnonymousClass;
import com.intellij.psi.PsiClass;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.SearchScope;
+import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.FilteredQuery;
import com.intellij.util.Query;
import com.intellij.util.QueryExecutor;
@@ -73,7 +74,7 @@ public class DirectClassInheritorsSearch extends ExtensibleQueryFactory<PsiClass
private DirectClassInheritorsSearch() {}
public static Query<PsiClass> search(final PsiClass aClass) {
- return search(aClass, GlobalSearchScope.allScope(aClass.getProject()));
+ return search(aClass, GlobalSearchScope.allScope(PsiUtilCore.getProjectInReadAction(aClass)));
}
public static Query<PsiClass> search(final PsiClass aClass, SearchScope scope) {
diff --git a/java/java-indexing-api/src/com/intellij/psi/search/searches/FunctionalExpressionSearch.java b/java/java-indexing-api/src/com/intellij/psi/search/searches/FunctionalExpressionSearch.java
index 8ad915c5ed95..f729579a5782 100644
--- a/java/java-indexing-api/src/com/intellij/psi/search/searches/FunctionalExpressionSearch.java
+++ b/java/java-indexing-api/src/com/intellij/psi/search/searches/FunctionalExpressionSearch.java
@@ -15,7 +15,9 @@
*/
package com.intellij.psi.search.searches;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.util.Computable;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiFunctionalExpression;
import com.intellij.psi.PsiMethod;
@@ -23,6 +25,7 @@ import com.intellij.psi.PsiModifier;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.PsiSearchHelper;
import com.intellij.psi.search.SearchScope;
+import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.EmptyQuery;
import com.intellij.util.Query;
import com.intellij.util.QueryExecutor;
@@ -36,7 +39,7 @@ public class FunctionalExpressionSearch extends ExtensibleQueryFactory<PsiFuncti
private final PsiClass myElementToSearch;
private final SearchScope myScope;
- public SearchParameters(PsiClass aClass, SearchScope scope) {
+ public SearchParameters(@NotNull PsiClass aClass, @NotNull SearchScope scope) {
myElementToSearch = aClass;
myScope = scope;
}
@@ -52,23 +55,28 @@ public class FunctionalExpressionSearch extends ExtensibleQueryFactory<PsiFuncti
}
}
- public static Query<PsiFunctionalExpression> search(final PsiClass aClass, SearchScope scope) {
+ public static Query<PsiFunctionalExpression> search(@NotNull final PsiClass aClass, @NotNull SearchScope scope) {
return INSTANCE.createUniqueResultsQuery(new SearchParameters(aClass, scope));
}
- public static Query<PsiFunctionalExpression> search(final PsiMethod psiMethod) {
- return search(psiMethod, GlobalSearchScope.allScope(psiMethod.getProject()));
+ public static Query<PsiFunctionalExpression> search(@NotNull final PsiMethod psiMethod) {
+ return search(psiMethod, GlobalSearchScope.allScope(PsiUtilCore.getProjectInReadAction(psiMethod)));
}
- public static Query<PsiFunctionalExpression> search(final PsiMethod psiMethod, SearchScope scope) {
- if (!psiMethod.hasModifierProperty(PsiModifier.STATIC) && !psiMethod.hasModifierProperty(PsiModifier.DEFAULT)) {
- return INSTANCE.createUniqueResultsQuery(new SearchParameters(psiMethod.getContainingClass(), scope));
- }
+ public static Query<PsiFunctionalExpression> search(@NotNull final PsiMethod psiMethod, @NotNull final SearchScope scope) {
+ return ApplicationManager.getApplication().runReadAction(new Computable<Query<PsiFunctionalExpression>>() {
+ @Override
+ public Query<PsiFunctionalExpression> compute() {
+ if (!psiMethod.hasModifierProperty(PsiModifier.STATIC) && !psiMethod.hasModifierProperty(PsiModifier.DEFAULT)) {
+ return INSTANCE.createUniqueResultsQuery(new SearchParameters(psiMethod.getContainingClass(), scope));
+ }
- return EmptyQuery.getEmptyQuery();
+ return EmptyQuery.getEmptyQuery();
+ }
+ });
}
- public static Query<PsiFunctionalExpression> search(final PsiClass aClass) {
- return search(aClass, GlobalSearchScope.allScope(aClass.getProject()));
+ public static Query<PsiFunctionalExpression> search(@NotNull final PsiClass aClass) {
+ return search(aClass, GlobalSearchScope.allScope(PsiUtilCore.getProjectInReadAction(aClass)));
}
}
diff --git a/java/java-indexing-api/src/com/intellij/psi/search/searches/MethodReferencesSearch.java b/java/java-indexing-api/src/com/intellij/psi/search/searches/MethodReferencesSearch.java
index 5dd9726db029..e6b0e19e9701 100644
--- a/java/java-indexing-api/src/com/intellij/psi/search/searches/MethodReferencesSearch.java
+++ b/java/java-indexing-api/src/com/intellij/psi/search/searches/MethodReferencesSearch.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,11 @@
package com.intellij.psi.search.searches;
import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiReference;
import com.intellij.psi.search.*;
+import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.*;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
@@ -98,11 +100,12 @@ public static void searchOptimized(final PsiMethod method, SearchScope scope, fi
final SearchRequestCollector requests = parameters.getOptimizer();
- return uniqueResults(new MergeQuery<PsiReference>(result, new SearchRequestQuery(parameters.getMethod().getProject(), requests)));
+ Project project = PsiUtilCore.getProjectInReadAction(parameters.getMethod());
+ return uniqueResults(new MergeQuery<PsiReference>(result, new SearchRequestQuery(project, requests)));
}
public static Query<PsiReference> search(final PsiMethod method, final boolean strictSignatureSearch) {
- return search(method, GlobalSearchScope.allScope(method.getProject()), strictSignatureSearch);
+ return search(method, GlobalSearchScope.allScope(PsiUtilCore.getProjectInReadAction(method)), strictSignatureSearch);
}
public static Query<PsiReference> search(final PsiMethod method) {
diff --git a/java/java-indexing-impl/src/com/intellij/codeInsight/navigation/MethodImplementationsSearch.java b/java/java-indexing-impl/src/com/intellij/codeInsight/navigation/MethodImplementationsSearch.java
index f77b536f7876..9a5f5ac4ddc1 100644
--- a/java/java-indexing-impl/src/com/intellij/codeInsight/navigation/MethodImplementationsSearch.java
+++ b/java/java-indexing-impl/src/com/intellij/codeInsight/navigation/MethodImplementationsSearch.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,10 +28,11 @@ import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
+import java.util.List;
public class MethodImplementationsSearch implements QueryExecutor<PsiElement, DefinitionsScopedSearch.SearchParameters> {
@Override
- public boolean execute(final @NotNull DefinitionsScopedSearch.SearchParameters queryParameters, final @NotNull Processor<PsiElement> consumer) {
+ public boolean execute(@NotNull final DefinitionsScopedSearch.SearchParameters queryParameters, @NotNull final Processor<PsiElement> consumer) {
final PsiElement sourceElement = queryParameters.getElement();
if (sourceElement instanceof PsiMethod) {
return processImplementations((PsiMethod)sourceElement, consumer, queryParameters.getScope());
@@ -49,12 +50,12 @@ public class MethodImplementationsSearch implements QueryExecutor<PsiElement, De
})) {
return false;
}
- final ArrayList<PsiMethod> methods = new ArrayList<PsiMethod>();
+ List<PsiMethod> methods = new ArrayList<PsiMethod>();
getOverridingMethods(psiMethod, methods, searchScope);
return ContainerUtil.process(methods, consumer);
}
- public static void getOverridingMethods(PsiMethod method, ArrayList<PsiMethod> list, SearchScope scope) {
+ public static void getOverridingMethods(PsiMethod method, List<PsiMethod> list, SearchScope scope) {
for (PsiMethod psiMethod : OverridingMethodsSearch.search(method, scope, true)) {
list.add(psiMethod);
}
@@ -63,7 +64,7 @@ public class MethodImplementationsSearch implements QueryExecutor<PsiElement, De
@SuppressWarnings("UnusedDeclaration")
@Deprecated
public static PsiMethod[] getMethodImplementations(final PsiMethod method, SearchScope scope) {
- ArrayList<PsiMethod> result = new ArrayList<PsiMethod>();
+ List<PsiMethod> result = new ArrayList<PsiMethod>();
getOverridingMethods(method, result, scope);
return result.toArray(new PsiMethod[result.size()]);
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/file/impl/JavaFileManagerImpl.java b/java/java-indexing-impl/src/com/intellij/psi/impl/file/impl/JavaFileManagerImpl.java
index 1b14c8ff462d..0c2087893e04 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/file/impl/JavaFileManagerImpl.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/file/impl/JavaFileManagerImpl.java
@@ -179,7 +179,7 @@ public class JavaFileManagerImpl implements JavaFileManager, Disposable {
// See IDEADEV-5626
final VirtualFile root = ProjectRootManager.getInstance(myManager.getProject()).getFileIndex().getClassRootForFile(vFile);
VirtualFile parent = vFile.getParent();
- final PsiNameHelper nameHelper = JavaPsiFacade.getInstance(myManager.getProject()).getNameHelper();
+ final PsiNameHelper nameHelper = PsiNameHelper.getInstance(myManager.getProject());
while (parent != null && !Comparing.equal(parent, root)) {
if (!nameHelper.isIdentifier(parent.getName())) return false;
parent = parent.getParent();
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/AnnotatedElementsSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/AnnotatedElementsSearcher.java
index dec2dccb341e..53fa2eb48604 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/AnnotatedElementsSearcher.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/AnnotatedElementsSearcher.java
@@ -18,7 +18,6 @@ package com.intellij.psi.impl.search;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.Computable;
import com.intellij.psi.*;
-import com.intellij.psi.impl.PsiManagerImpl;
import com.intellij.psi.impl.java.stubs.index.JavaAnnotationIndex;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.LocalSearchScope;
@@ -50,7 +49,12 @@ public class AnnotatedElementsSearcher implements QueryExecutor<PsiModifierListO
});
assert annotationFQN != null;
- final PsiManagerImpl psiManager = (PsiManagerImpl)annClass.getManager();
+ final PsiManager psiManager = ApplicationManager.getApplication().runReadAction(new Computable<PsiManager>() {
+ @Override
+ public PsiManager compute() {
+ return annClass.getManager();
+ }
+ });
final SearchScope useScope = p.getScope();
final Class<? extends PsiModifierListOwner>[] types = p.getTypes();
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/AnnotatedPackagesSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/AnnotatedPackagesSearcher.java
index 4437b3f49e51..51565a81e5f4 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/AnnotatedPackagesSearcher.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/AnnotatedPackagesSearcher.java
@@ -19,15 +19,15 @@
*/
package com.intellij.psi.impl.search;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
+import com.intellij.openapi.util.Computable;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
-import com.intellij.psi.impl.PsiManagerImpl;
import com.intellij.psi.impl.java.stubs.index.JavaAnnotationIndex;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.PsiSearchHelper;
-import com.intellij.psi.search.SearchScope;
import com.intellij.psi.search.searches.AnnotatedPackagesSearch;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.Processor;
@@ -44,49 +44,67 @@ public class AnnotatedPackagesSearcher implements QueryExecutor<PsiPackage, Anno
final PsiClass annClass = p.getAnnotationClass();
assert annClass.isAnnotationType() : "Annotation type should be passed to annotated packages search";
- final String annotationFQN = annClass.getQualifiedName();
+ final String annotationFQN = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
+ @Override
+ public String compute() {
+ return annClass.getQualifiedName();
+ }
+ });
assert annotationFQN != null;
- final PsiManagerImpl psiManager = (PsiManagerImpl)annClass.getManager();
- final SearchScope useScope = p.getScope();
+ final PsiManager psiManager = ApplicationManager.getApplication().runReadAction(new Computable<PsiManager>() {
+ @Override
+ public PsiManager compute() {
+ return annClass.getManager();
+ }
+ });
+ final GlobalSearchScope useScope = (GlobalSearchScope)p.getScope();
- final String annotationShortName = annClass.getName();
+ final String annotationShortName = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
+ @Override
+ public String compute() {
+ return annClass.getName();
+ }
+ });
assert annotationShortName != null;
- final GlobalSearchScope scope = useScope instanceof GlobalSearchScope ? (GlobalSearchScope)useScope : null;
-
- final Collection<PsiAnnotation> annotations = JavaAnnotationIndex.getInstance().get(annotationShortName, psiManager.getProject(), scope);
- for (PsiAnnotation annotation : annotations) {
- PsiModifierList modlist = (PsiModifierList)annotation.getParent();
- final PsiElement owner = modlist.getParent();
- if (!(owner instanceof PsiClass)) continue;
- PsiClass candidate = (PsiClass)owner;
- if (!"package-info".equals(candidate.getName())) continue;
-
- LOG.assertTrue(candidate.isValid());
-
- final PsiJavaCodeReferenceElement ref = annotation.getNameReferenceElement();
- if (ref == null) continue;
-
- if (!psiManager.areElementsEquivalent(ref.resolve(), annClass)) continue;
- if (useScope instanceof GlobalSearchScope &&
- !((GlobalSearchScope)useScope).contains(candidate.getContainingFile().getVirtualFile())) {
- continue;
- }
- final String qname = candidate.getQualifiedName();
- if (qname != null && !consumer.process(JavaPsiFacade.getInstance(psiManager.getProject()).findPackage(
- qname.substring(0, qname.lastIndexOf('.'))))) {
- return false;
- }
+ final Collection<PsiAnnotation> annotations = JavaAnnotationIndex.getInstance().get(annotationShortName, psiManager.getProject(),
+ useScope);
+
+ for (final PsiAnnotation annotation : annotations) {
+ boolean accepted = ApplicationManager.getApplication().runReadAction(new Computable<Boolean>(){
+ @Override
+ public Boolean compute() {
+ PsiModifierList modlist = (PsiModifierList)annotation.getParent();
+ final PsiElement owner = modlist.getParent();
+ if ((owner instanceof PsiClass)) {
+ PsiClass candidate = (PsiClass)owner;
+ if ("package-info".equals(candidate.getName())) {
+ LOG.assertTrue(candidate.isValid());
+ final PsiJavaCodeReferenceElement ref = annotation.getNameReferenceElement();
+ if (ref != null && psiManager.areElementsEquivalent(ref.resolve(), annClass) &&
+ useScope.contains(candidate.getContainingFile().getVirtualFile())) {
+ final String qname = candidate.getQualifiedName();
+ if (qname != null && !consumer.process(JavaPsiFacade.getInstance(psiManager.getProject()).findPackage(
+ qname.substring(0, qname.lastIndexOf('.'))))) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+ });
+ if (!accepted) return false;
}
PsiSearchHelper helper = PsiSearchHelper.SERVICE.getInstance(psiManager.getProject());
final GlobalSearchScope infoFilesFilter = new PackageInfoFilesOnly();
GlobalSearchScope infoFiles =
- useScope instanceof GlobalSearchScope ? ((GlobalSearchScope)useScope).intersectWith(infoFilesFilter) : infoFilesFilter;
+ useScope.intersectWith(infoFilesFilter);
- final boolean[] wantmore = {true};
+ final boolean[] wantMore = {true};
helper.processAllFilesWithWord(annotationShortName, infoFiles, new Processor<PsiFile>() {
@Override
public boolean process(final PsiFile psiFile) {
@@ -103,12 +121,12 @@ public class AnnotatedPackagesSearcher implements QueryExecutor<PsiPackage, Anno
if (!psiManager.areElementsEquivalent(ref.resolve(), annClass)) return true;
- wantmore[0] = consumer.process(JavaPsiFacade.getInstance(psiManager.getProject()).findPackage(stmt.getPackageName()));
- return wantmore[0];
+ wantMore[0] = consumer.process(JavaPsiFacade.getInstance(psiManager.getProject()).findPackage(stmt.getPackageName()));
+ return wantMore[0];
}
}, true);
- return wantmore[0];
+ return wantMore[0];
}
private static class PackageInfoFilesOnly extends GlobalSearchScope {
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaAllOverridingMethodsSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaAllOverridingMethodsSearcher.java
index 35ec8b2800e7..f8f824b77c95 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaAllOverridingMethodsSearcher.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaAllOverridingMethodsSearcher.java
@@ -15,6 +15,8 @@
*/
package com.intellij.psi.impl.search;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.*;
import com.intellij.psi.search.SearchScope;
@@ -39,11 +41,18 @@ public class JavaAllOverridingMethodsSearcher implements QueryExecutor<Pair<PsiM
public boolean execute(@NotNull final AllOverridingMethodsSearch.SearchParameters p, @NotNull final Processor<Pair<PsiMethod, PsiMethod>> consumer) {
final PsiClass psiClass = p.getPsiClass();
- PsiMethod[] methodsArray = psiClass.getMethods();
- final List<PsiMethod> methods = new ArrayList<PsiMethod>(methodsArray.length);
- for (PsiMethod method : methodsArray) {
- if (PsiUtil.canBeOverriden(method)) methods.add(method);
- }
+ final List<PsiMethod> methods = ApplicationManager.getApplication().runReadAction(new Computable<List<PsiMethod>>() {
+ @Override
+ public List<PsiMethod> compute() {
+ PsiMethod[] methodsArray = psiClass.getMethods();
+ final List<PsiMethod> methods = new ArrayList<PsiMethod>(methodsArray.length);
+ for (PsiMethod method : methodsArray) {
+ if (PsiUtil.canBeOverriden(method)) methods.add(method);
+ }
+ return methods;
+ }
+ });
+
final SearchScope scope = p.getScope();
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaDirectInheritorsSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaDirectInheritorsSearcher.java
index fb012672660d..287d43f4cf2d 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaDirectInheritorsSearcher.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaDirectInheritorsSearcher.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,12 +17,12 @@ package com.intellij.psi.impl.search;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.progress.ProgressIndicatorProvider;
+import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
-import com.intellij.psi.impl.PsiManagerImpl;
import com.intellij.psi.impl.java.stubs.index.JavaAnonymousClassBaseRefOccurenceIndex;
import com.intellij.psi.impl.java.stubs.index.JavaSuperClassNameOccurenceIndex;
import com.intellij.psi.search.EverythingGlobalScope;
@@ -31,6 +31,7 @@ import com.intellij.psi.search.SearchScope;
import com.intellij.psi.search.searches.AllClassesSearch;
import com.intellij.psi.search.searches.DirectClassInheritorsSearch;
import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.Processor;
import com.intellij.util.QueryExecutor;
import com.intellij.util.containers.ContainerUtil;
@@ -49,7 +50,6 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor<PsiClass, Dir
@Override
public boolean execute(@NotNull final DirectClassInheritorsSearch.SearchParameters p, @NotNull final Processor<PsiClass> consumer) {
final PsiClass aClass = p.getClassToProcess();
- final PsiManagerImpl psiManager = (PsiManagerImpl)aClass.getManager();
final SearchScope useScope = ApplicationManager.getApplication().runReadAction(new Computable<SearchScope>() {
@Override
@@ -65,13 +65,13 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor<PsiClass, Dir
}
});
+ final Project project = PsiUtilCore.getProjectInReadAction(aClass);
if (CommonClassNames.JAVA_LANG_OBJECT.equals(qualifiedName)) {
//[pasynkov]: WTF?
//final SearchScope scope = useScope.intersectWith(GlobalSearchScope.notScope(GlobalSearchScope.getScopeRestrictedByFileTypes(
// GlobalSearchScope.allScope(psiManager.getProject()), StdFileTypes.JSP, StdFileTypes.JSPX)));
- final SearchScope scope = useScope;
- return AllClassesSearch.search(scope, aClass.getProject()).forEach(new Processor<PsiClass>() {
+ return AllClassesSearch.search(useScope, project).forEach(new Processor<PsiClass>() {
@Override
public boolean process(final PsiClass psiClass) {
if (psiClass.isInterface()) {
@@ -90,7 +90,7 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor<PsiClass, Dir
});
}
- final GlobalSearchScope scope = useScope instanceof GlobalSearchScope ? (GlobalSearchScope)useScope : new EverythingGlobalScope(psiManager.getProject());
+ final GlobalSearchScope scope = useScope instanceof GlobalSearchScope ? (GlobalSearchScope)useScope : new EverythingGlobalScope(project);
final String searchKey = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
@Override
public String compute() {
@@ -104,15 +104,20 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor<PsiClass, Dir
Collection<PsiReferenceList> candidates = ApplicationManager.getApplication().runReadAction(new Computable<Collection<PsiReferenceList>>() {
@Override
public Collection<PsiReferenceList> compute() {
- return JavaSuperClassNameOccurenceIndex.getInstance().get(searchKey, psiManager.getProject(), scope);
+ return JavaSuperClassNameOccurenceIndex.getInstance().get(searchKey, project, scope);
}
});
Map<String, List<PsiClass>> classes = new HashMap<String, List<PsiClass>>();
- for (PsiReferenceList referenceList : candidates) {
+ for (final PsiReferenceList referenceList : candidates) {
ProgressIndicatorProvider.checkCanceled();
- final PsiClass candidate = (PsiClass)referenceList.getParent();
+ final PsiClass candidate = (PsiClass)ApplicationManager.getApplication().runReadAction(new Computable<PsiElement>() {
+ @Override
+ public PsiElement compute() {
+ return referenceList.getParent();
+ }
+ });
if (!checkInheritance(p, aClass, candidate)) continue;
String fqn = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
@@ -137,7 +142,7 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor<PsiClass, Dir
Collection<PsiAnonymousClass> anonymousCandidates = ApplicationManager.getApplication().runReadAction(new Computable<Collection<PsiAnonymousClass>>() {
@Override
public Collection<PsiAnonymousClass> compute() {
- return JavaAnonymousClassBaseRefOccurenceIndex.getInstance().get(searchKey, psiManager.getProject(), scope);
+ return JavaAnonymousClassBaseRefOccurenceIndex.getInstance().get(searchKey, project, scope);
}
});
@@ -148,7 +153,13 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor<PsiClass, Dir
if (!consumer.process(candidate)) return false;
}
- if (aClass.isEnum()) {
+ boolean isEnum = ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
+ @Override
+ public Boolean compute() {
+ return aClass.isEnum();
+ }
+ });
+ if (isEnum) {
// abstract enum can be subclassed in the body
PsiField[] fields = ApplicationManager.getApplication().runReadAction(new Computable<PsiField[]>() {
@Override
@@ -189,10 +200,10 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor<PsiClass, Dir
// if there is a class from the same jar, prefer it
boolean sameJarClassFound = false;
- VirtualFile jarFile = PsiUtil.getJarFile(aClass);
+ VirtualFile jarFile = getJarFile(aClass);
if (jarFile != null) {
for (PsiClass sameNamedClass : sameNamedClasses) {
- boolean fromSameJar = Comparing.equal(PsiUtil.getJarFile(sameNamedClass), jarFile);
+ boolean fromSameJar = Comparing.equal(getJarFile(sameNamedClass), jarFile);
if (fromSameJar) {
sameJarClassFound = true;
if (!consumer.process(sameNamedClass)) return false;
@@ -202,4 +213,13 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor<PsiClass, Dir
return sameJarClassFound || ContainerUtil.process(sameNamedClasses, consumer);
}
+
+ private static VirtualFile getJarFile(final PsiClass aClass) {
+ return ApplicationManager.getApplication().runReadAction(new Computable<VirtualFile>() {
+ @Override
+ public VirtualFile compute() {
+ return PsiUtil.getJarFile(aClass);
+ }
+ });
+ }
}
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaFunctionalExpressionSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaFunctionalExpressionSearcher.java
index 2ee2cc2d8123..e7da21e37b51 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaFunctionalExpressionSearcher.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaFunctionalExpressionSearcher.java
@@ -27,6 +27,7 @@ import com.intellij.psi.search.searches.FunctionalExpressionSearch;
import com.intellij.psi.search.searches.MethodReferencesSearch;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.Processor;
import com.intellij.util.QueryExecutor;
import org.jetbrains.annotations.NotNull;
@@ -36,15 +37,15 @@ import java.util.Collection;
public class JavaFunctionalExpressionSearcher implements QueryExecutor<PsiFunctionalExpression, FunctionalExpressionSearch.SearchParameters> {
@Override
- public boolean execute(final @NotNull FunctionalExpressionSearch.SearchParameters queryParameters,
- final @NotNull Processor<PsiFunctionalExpression> consumer) {
+ public boolean execute(@NotNull final FunctionalExpressionSearch.SearchParameters queryParameters,
+ @NotNull final Processor<PsiFunctionalExpression> consumer) {
final PsiClass aClass = queryParameters.getElementToSearch();
- if (!ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
+ if (ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
@Override
public Boolean compute() {
- return LambdaUtil.isFunctionalClass(aClass);
+ return !LambdaUtil.isFunctionalClass(aClass) || !PsiUtil.isLanguageLevel8OrHigher(aClass);
}
- }) || !PsiUtil.isLanguageLevel8OrHigher(aClass)) {
+ })) {
return true;
}
return collectFunctionalExpressions(aClass, ApplicationManager.getApplication().runReadAction(new Computable<SearchScope>() {
@@ -64,8 +65,13 @@ public class JavaFunctionalExpressionSearcher implements QueryExecutor<PsiFuncti
return aClass.getUseScope();
}
});
- final SearchScope useScope = searchScope.intersectWith(classScope);
- final Project project = aClass.getProject();
+ final SearchScope useScope = ApplicationManager.getApplication().runReadAction(new Computable<SearchScope>() {
+ @Override
+ public SearchScope compute() {
+ return searchScope.intersectWith(classScope);
+ }
+ });
+ final Project project = PsiUtilCore.getProjectInReadAction(aClass);
final GlobalSearchScope scope = useScope instanceof GlobalSearchScope ? (GlobalSearchScope)useScope : new EverythingGlobalScope(project);
final Collection<PsiMethod> lambdaCandidates = ApplicationManager.getApplication().runReadAction(new Computable<Collection<PsiMethod>>() {
@Override
@@ -76,16 +82,16 @@ public class JavaFunctionalExpressionSearcher implements QueryExecutor<PsiFuncti
}
});
for (PsiMethod psiMethod : lambdaCandidates) {
- for (PsiReference ref : MethodReferencesSearch.search(psiMethod, scope, false)) {
- final PsiElement refElement = ref.getElement();
- if (refElement != null) {
- final PsiElement candidateElement = refElement.getParent();
- if (candidateElement instanceof PsiCallExpression) {
- final PsiExpressionList argumentList = ((PsiCallExpression)candidateElement).getArgumentList();
- if (argumentList != null) {
- final Boolean accepted = ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
- @Override
- public Boolean compute() {
+ for (final PsiReference ref : MethodReferencesSearch.search(psiMethod, scope, false)) {
+ boolean accepted = ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
+ @Override
+ public Boolean compute() {
+ final PsiElement refElement = ref.getElement();
+ if (refElement != null) {
+ final PsiElement candidateElement = refElement.getParent();
+ if (candidateElement instanceof PsiCallExpression) {
+ final PsiExpressionList argumentList = ((PsiCallExpression)candidateElement).getArgumentList();
+ if (argumentList != null) {
final PsiExpression[] args = argumentList.getExpressions();
for (PsiExpression arg : args) {
if (arg instanceof PsiFunctionalExpression) {
@@ -96,57 +102,66 @@ public class JavaFunctionalExpressionSearcher implements QueryExecutor<PsiFuncti
}
}
}
- return true;
}
- });
- if (!accepted) return false;
+ }
}
+ return true;
}
- }
+ });
+ if (!accepted) return false;
}
}
- for (PsiReference reference : ReferencesSearch.search(aClass, scope)) {
- final PsiElement element = reference.getElement();
- if (element != null) {
- final PsiElement parent = element.getParent();
- if (parent instanceof PsiTypeElement) {
- final PsiElement gParent = parent.getParent();
- if (gParent instanceof PsiVariable) {
- final PsiExpression initializer = PsiUtil.skipParenthesizedExprDown(((PsiVariable)gParent).getInitializer());
- if (initializer instanceof PsiFunctionalExpression) {
- if (!consumer.process((PsiFunctionalExpression)initializer)) return false;
- }
- for (PsiReference varRef : ReferencesSearch.search(parent, scope)) {
- final PsiElement varElement = varRef.getElement();
- if (varElement != null) {
- final PsiElement varElementParent = varElement.getParent();
- if (varElementParent instanceof PsiAssignmentExpression &&
- ((PsiAssignmentExpression)varElementParent).getLExpression() == varElement) {
- final PsiExpression rExpression = PsiUtil.skipParenthesizedExprDown(((PsiAssignmentExpression)varElementParent).getRExpression());
- if (rExpression instanceof PsiFunctionalExpression) {
- if (!consumer.process((PsiFunctionalExpression)rExpression)) return false;
+ for (final PsiReference reference : ReferencesSearch.search(aClass, scope)) {
+ boolean accepted = ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
+ @Override
+ public Boolean compute() {
+ final PsiElement element = reference.getElement();
+ if (element != null) {
+ final PsiElement parent = element.getParent();
+ if (parent instanceof PsiTypeElement) {
+ final PsiElement gParent = parent.getParent();
+ if (gParent instanceof PsiVariable) {
+ final PsiExpression initializer = PsiUtil.skipParenthesizedExprDown(((PsiVariable)gParent).getInitializer());
+ if (initializer instanceof PsiFunctionalExpression) {
+ if (!consumer.process((PsiFunctionalExpression)initializer)) return false;
+ }
+ for (PsiReference varRef : ReferencesSearch.search(parent, scope)) {
+ final PsiElement varElement = varRef.getElement();
+ if (varElement != null) {
+ final PsiElement varElementParent = varElement.getParent();
+ if (varElementParent instanceof PsiAssignmentExpression &&
+ ((PsiAssignmentExpression)varElementParent).getLExpression() == varElement) {
+ final PsiExpression rExpression = PsiUtil.skipParenthesizedExprDown(((PsiAssignmentExpression)varElementParent).getRExpression());
+ if (rExpression instanceof PsiFunctionalExpression) {
+ if (!consumer.process((PsiFunctionalExpression)rExpression)) return false;
+ }
+ }
}
}
- }
- }
- } else if (gParent instanceof PsiMethod) {
- final PsiReturnStatement[] returnStatements = ApplicationManager.getApplication().runReadAction(
- new Computable<PsiReturnStatement[]>() {
- @Override
- public PsiReturnStatement[] compute() {
- return PsiUtil.findReturnStatements((PsiMethod)gParent);
+ } else if (gParent instanceof PsiMethod) {
+ final PsiReturnStatement[] returnStatements = ApplicationManager.getApplication().runReadAction(
+ new Computable<PsiReturnStatement[]>() {
+ @Override
+ public PsiReturnStatement[] compute() {
+ return PsiUtil.findReturnStatements((PsiMethod)gParent);
+ }
+ });
+ for (PsiReturnStatement returnStatement : returnStatements) {
+ final PsiExpression returnValue = returnStatement.getReturnValue();
+ if (returnValue instanceof PsiFunctionalExpression) {
+ if (!consumer.process((PsiFunctionalExpression)returnValue)) return false;
+ }
}
- });
- for (PsiReturnStatement returnStatement : returnStatements) {
- final PsiExpression returnValue = returnStatement.getReturnValue();
- if (returnValue instanceof PsiFunctionalExpression) {
- if (!consumer.process((PsiFunctionalExpression)returnValue)) return false;
}
}
}
+
+ return true;
}
- }
+ });
+ if (!accepted) return false;
+
}
return true;
}
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodDeepestSuperSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodDeepestSuperSearcher.java
index ece2108b072c..933998344add 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodDeepestSuperSearcher.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodDeepestSuperSearcher.java
@@ -1,5 +1,22 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.intellij.psi.impl.search;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.util.Computable;
import com.intellij.psi.PsiMethod;
import com.intellij.util.Processor;
import com.intellij.util.QueryExecutor;
@@ -23,12 +40,17 @@ public class MethodDeepestSuperSearcher implements QueryExecutor<PsiMethod, PsiM
return findDeepestSuperOrSelfSignature(method, methods, null, consumer);
}
- private static boolean findDeepestSuperOrSelfSignature(PsiMethod method,
+ private static boolean findDeepestSuperOrSelfSignature(final PsiMethod method,
Set<PsiMethod> set,
Set<PsiMethod> guard,
Processor<PsiMethod> processor) {
if (guard != null && !guard.add(method)) return true;
- PsiMethod[] supers = method.findSuperMethods();
+ PsiMethod[] supers = ApplicationManager.getApplication().runReadAction(new Computable<PsiMethod[]>() {
+ @Override
+ public PsiMethod[] compute() {
+ return method.findSuperMethods();
+ }
+ });
if (supers.length == 0 && set.add(method) && !processor.process(method)) {
return false;
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodSuperSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodSuperSearcher.java
index d65e80e7f997..acb5faae4947 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodSuperSearcher.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodSuperSearcher.java
@@ -1,6 +1,23 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.intellij.psi.impl.search;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.Computable;
import com.intellij.psi.*;
import com.intellij.psi.search.searches.SuperMethodsSearch;
import com.intellij.psi.util.InheritanceUtil;
@@ -22,18 +39,23 @@ public class MethodSuperSearcher implements QueryExecutor<MethodSignatureBackedB
public boolean execute(@NotNull final SuperMethodsSearch.SearchParameters queryParameters, @NotNull final Processor<MethodSignatureBackedByPsiMethod> consumer) {
final PsiClass parentClass = queryParameters.getPsiClass();
final PsiMethod method = queryParameters.getMethod();
- HierarchicalMethodSignature signature = method.getHierarchicalMethodSignature();
+ return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
+ @Override
+ public Boolean compute() {
+ HierarchicalMethodSignature signature = method.getHierarchicalMethodSignature();
- final boolean checkBases = queryParameters.isCheckBases();
- final boolean allowStaticMethod = queryParameters.isAllowStaticMethod();
- final List<HierarchicalMethodSignature> supers = signature.getSuperSignatures();
- for (HierarchicalMethodSignature superSignature : supers) {
- if (MethodSignatureUtil.isSubsignature(superSignature, signature)) {
- if (!addSuperMethods(superSignature, method, parentClass, allowStaticMethod, checkBases, consumer)) return false;
- }
- }
+ final boolean checkBases = queryParameters.isCheckBases();
+ final boolean allowStaticMethod = queryParameters.isAllowStaticMethod();
+ final List<HierarchicalMethodSignature> supers = signature.getSuperSignatures();
+ for (HierarchicalMethodSignature superSignature : supers) {
+ if (MethodSignatureUtil.isSubsignature(superSignature, signature)) {
+ if (!addSuperMethods(superSignature, method, parentClass, allowStaticMethod, checkBases, consumer)) return false;
+ }
+ }
- return true;
+ return true;
+ }
+ });
}
private static boolean addSuperMethods(final HierarchicalMethodSignature signature,
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/PsiAnnotationMethodReferencesSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/PsiAnnotationMethodReferencesSearcher.java
index 50f10caef9cb..b5a6fc58d425 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/PsiAnnotationMethodReferencesSearcher.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/PsiAnnotationMethodReferencesSearcher.java
@@ -1,5 +1,22 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.intellij.psi.impl.search;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.util.Computable;
import com.intellij.psi.*;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiUtil;
@@ -16,10 +33,24 @@ public class PsiAnnotationMethodReferencesSearcher implements QueryExecutor<PsiR
@Override
public boolean execute(@NotNull final ReferencesSearch.SearchParameters p, @NotNull final Processor<PsiReference> consumer) {
final PsiElement refElement = p.getElementToSearch();
- if (PsiUtil.isAnnotationMethod(refElement)) {
- PsiMethod method = (PsiMethod)refElement;
- if (PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.equals(method.getName()) && method.getParameterList().getParametersCount() == 0) {
- final Query<PsiReference> query = ReferencesSearch.search(method.getContainingClass(), p.getScope(), p.isIgnoreAccessScope());
+ boolean isAnnotation = ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
+ @Override
+ public Boolean compute() {
+ return PsiUtil.isAnnotationMethod(refElement);
+ }
+ });
+ if (isAnnotation) {
+ final PsiMethod method = (PsiMethod)refElement;
+ PsiClass containingClass = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass>() {
+ @Override
+ public PsiClass compute() {
+ boolean isValueMethod =
+ PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.equals(method.getName()) && method.getParameterList().getParametersCount() == 0;
+ return isValueMethod ? method.getContainingClass() : null;
+ }
+ });
+ if (containingClass != null) {
+ final Query<PsiReference> query = ReferencesSearch.search(containingClass, p.getScope(), p.isIgnoreAccessScope());
return query.forEach(createImplicitDefaultAnnotationMethodConsumer(consumer));
}
}
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/SimpleAccessorReferenceSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/SimpleAccessorReferenceSearcher.java
index 16870688e738..e047db8b992a 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/SimpleAccessorReferenceSearcher.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/SimpleAccessorReferenceSearcher.java
@@ -54,7 +54,6 @@ public class SimpleAccessorReferenceSearcher extends QueryExecutorBase<PsiRefere
for (CustomPropertyScopeProvider provider : Extensions.getExtensions(CustomPropertyScopeProvider.EP_NAME)) {
additional = additional.union(provider.getScope(method.getProject()));
}
- assert propertyName != null;
final SearchScope propScope = scope.intersectWith(method.getUseScope()).intersectWith(additional);
collector.searchWord(propertyName, propScope, UsageSearchContext.IN_FOREIGN_LANGUAGES, true, method);
}
diff --git a/java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java b/java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java
index 78f29c4c8488..4e47c4466813 100644
--- a/java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java
+++ b/java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java
@@ -21,6 +21,7 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.ArrayUtil;
import gnu.trove.THashSet;
+import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -328,6 +329,7 @@ public class AnnotationUtil {
* @param annotations annotations qualified names or patterns. Patterns can have '*' at the end
* @return <code>true</code> if annotated of at least one annotation from the annotations list
*/
+ @Contract("null,_ -> false")
public static boolean checkAnnotatedUsingPatterns(@Nullable PsiModifierListOwner owner, @NotNull Collection<String> annotations) {
final PsiModifierList modList;
if (owner == null || (modList = owner.getModifierList()) == null) return false;
diff --git a/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java b/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java
index 52888f123215..c835a4171f74 100644
--- a/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java
@@ -153,7 +153,7 @@ public class GenericsUtil {
PsiType type2,
Set<Couple<PsiType>> compared,
PsiManager manager,
- PsiClass nestedLayer,
+ PsiClass nestedLayer,
PsiTypeParameter parameter) {
Couple<PsiType> types = Couple.of(type1, type2);
if (compared.contains(types)) {
@@ -549,6 +549,14 @@ public class GenericsUtil {
return false;
}
}
+
+ final PsiClass extendsBoundClass = PsiUtil.resolveClassInClassTypeOnly(extendsBound);
+ final PsiClass boundBoundClass = PsiUtil.resolveClassInClassTypeOnly(boundBound);
+ if (boundBoundClass != null && extendsBoundClass != null && !boundBoundClass.isInterface() && !extendsBoundClass.isInterface()) {
+ return !InheritanceUtil.isInheritorOrSelf(boundBoundClass, extendsBoundClass, true) &&
+ !InheritanceUtil.isInheritorOrSelf(extendsBoundClass, boundBoundClass, true);
+ }
+
return !TypeConversionUtil.areTypesConvertible(boundBound, extendsBound) &&
!TypeConversionUtil.areTypesConvertible(extendsBound, boundBound);
}
diff --git a/java/java-psi-api/src/com/intellij/psi/JVMElementFactory.java b/java/java-psi-api/src/com/intellij/psi/JVMElementFactory.java
index 1b4be9766b6f..e6c38aa5a186 100644
--- a/java/java-psi-api/src/com/intellij/psi/JVMElementFactory.java
+++ b/java/java-psi-api/src/com/intellij/psi/JVMElementFactory.java
@@ -307,3 +307,4 @@ public interface JVMElementFactory {
*/
boolean isValidLocalVariableName(@NotNull String name);
}
+
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiCapturedWildcardType.java b/java/java-psi-api/src/com/intellij/psi/PsiCapturedWildcardType.java
index 8130b864ad9a..c94709ee164a 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiCapturedWildcardType.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiCapturedWildcardType.java
@@ -28,6 +28,8 @@ public class PsiCapturedWildcardType extends PsiType.Stub {
@NotNull private final PsiElement myContext;
@Nullable private final PsiTypeParameter myParameter;
+ private PsiType myUpperBound;
+
@NotNull
public static PsiCapturedWildcardType create(@NotNull PsiWildcardType existential, @NotNull PsiElement context) {
return create(existential, context, null);
@@ -40,11 +42,28 @@ public class PsiCapturedWildcardType extends PsiType.Stub {
return new PsiCapturedWildcardType(existential, context, parameter);
}
- private PsiCapturedWildcardType(@NotNull PsiWildcardType existential, @NotNull PsiElement context, @Nullable PsiTypeParameter parameter) {
+ private PsiCapturedWildcardType(@NotNull PsiWildcardType existential,
+ @NotNull PsiElement context,
+ @Nullable PsiTypeParameter parameter) {
super(PsiAnnotation.EMPTY_ARRAY);
myExistential = existential;
myContext = context;
myParameter = parameter;
+ if (parameter != null) {
+ final PsiClassType[] boundTypes = parameter.getExtendsListTypes();
+ if (boundTypes.length > 0) {
+ PsiType result = null;
+ for (PsiType type : boundTypes) {
+ if (result == null) {
+ result = type;
+ }
+ else {
+ result = GenericsUtil.getGreatestLowerBound(result, type);
+ }
+ }
+ myUpperBound = result;
+ }
+ }
}
@Override
@@ -128,10 +147,14 @@ public class PsiCapturedWildcardType extends PsiType.Stub {
return PsiWildcardType.createSuper(myContext.getManager(), ((PsiCapturedWildcardType)bound).getUpperBound());
}
else {
- return PsiType.getJavaLangObject(myContext.getManager(), getResolveScope());
+ return myUpperBound != null ? myUpperBound : PsiType.getJavaLangObject(myContext.getManager(), getResolveScope());
}
}
+ public void setUpperBound(PsiType upperBound) {
+ myUpperBound = upperBound;
+ }
+
@NotNull
public PsiWildcardType getWildcard() {
return myExistential;
@@ -141,4 +164,8 @@ public class PsiCapturedWildcardType extends PsiType.Stub {
public PsiElement getContext() {
return myContext;
}
+
+ public PsiTypeParameter getTypeParameter() {
+ return myParameter;
+ }
}
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java b/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java
index 0b0e09684128..9729425dee81 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java
@@ -323,7 +323,9 @@ public class PsiMethodReferenceUtil {
final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType);
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
final MethodSignature signature = interfaceMethod != null ? interfaceMethod.getSignature(LambdaUtil.getSubstitutor(interfaceMethod, resolveResult)) : null;
- LOG.assertTrue(signature != null);
+ if (signature == null) {
+ return false;
+ }
final PsiType[] parameterTypes = signature.getParameterTypes();
final QualifierResolveResult qualifierResolveResult = getQualifierResolveResult(methodRef);
return (method.getParameterList().getParametersCount() + 1 == parameterTypes.length ||
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiNameHelper.java b/java/java-psi-api/src/com/intellij/psi/PsiNameHelper.java
index 747f4f8034c3..888f1c24bf11 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiNameHelper.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiNameHelper.java
@@ -31,8 +31,6 @@ import static com.intellij.util.ObjectUtils.notNull;
/**
* Service for validating and parsing Java identifiers.
- *
- * @see com.intellij.psi.JavaPsiFacade#getNameHelper()
*/
public abstract class PsiNameHelper {
diff --git a/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java b/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java
index a69e11a9d3cc..b38bb494c1e7 100644
--- a/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java
@@ -722,7 +722,7 @@ public final class PsiUtil extends PsiUtilCore {
}
public static void checkIsIdentifier(@NotNull PsiManager manager, String text) throws IncorrectOperationException{
- if (!JavaPsiFacade.getInstance(manager.getProject()).getNameHelper().isIdentifier(text)){
+ if (!PsiNameHelper.getInstance(manager.getProject()).isIdentifier(text)){
throw new IncorrectOperationException(PsiBundle.message("0.is.not.an.identifier", text) );
}
}
diff --git a/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java b/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java
index 42f1494bad2e..d7a60cc4cb88 100644
--- a/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java
@@ -862,6 +862,14 @@ public class TypeConversionUtil {
if (left instanceof PsiPrimitiveType && !PsiType.NULL.equals(left)) {
return right instanceof PsiClassType && isAssignable(left, right);
}
+
+ if (left instanceof PsiIntersectionType) {
+ for (PsiType lConjunct : ((PsiIntersectionType)left).getConjuncts()) {
+ if (!boxingConversionApplicable(lConjunct, right)) return false;
+ }
+ return true;
+ }
+
return left instanceof PsiClassType
&& right instanceof PsiPrimitiveType
&& !PsiType.NULL.equals(right)
diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java b/java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java
index 05b516e47ee5..966504719826 100644
--- a/java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java
+++ b/java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java
@@ -49,21 +49,20 @@ import java.util.concurrent.ConcurrentMap;
public abstract class BaseExternalAnnotationsManager extends ExternalAnnotationsManager {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.BaseExternalAnnotationsManager");
+ @SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
@NotNull private static final List<PsiFile> NULL_LIST = new ArrayList<PsiFile>(0);
@NotNull
private final ConcurrentMap<VirtualFile, List<PsiFile>> myExternalAnnotations = new ConcurrentSoftValueHashMap<VirtualFile, List<PsiFile>>(10, 0.75f, 2);
protected final PsiManager myPsiManager;
- @SuppressWarnings("UnusedDeclaration")
- private final LowMemoryWatcher myLowMemoryWatcher = LowMemoryWatcher.register(new Runnable() {
- @Override
- public void run() {
- dropCache();
- }
- });
-
public BaseExternalAnnotationsManager(final PsiManager psiManager) {
myPsiManager = psiManager;
+ LowMemoryWatcher.register(new Runnable() {
+ @Override
+ public void run() {
+ dropCache();
+ }
+ }, psiManager.getProject());
}
@Nullable
diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java b/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java
index e2de5a55e0b3..f4154bc4fe1a 100644
--- a/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java
+++ b/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java
@@ -843,8 +843,8 @@ public abstract class JavaFoldingBuilderBase extends CustomFoldingBuilder implem
FoldingGroup group = FoldingGroup.newGroup("lambda");
final String prettySpace = oneLine ? " " : "";
foldElements.add(new NamedFoldingDescriptor(expression, closureStart, rangeStart, group, lambdas + prettySpace));
- if (rbrace != null && rangeEnd + 1 < closureEnd) {
- foldElements.add(new NamedFoldingDescriptor(rbrace, rangeEnd, closureEnd, group, prettySpace + "}"));
+ if (classRBrace != null && rangeEnd + 1 < closureEnd) {
+ foldElements.add(new NamedFoldingDescriptor(classRBrace, rangeEnd, closureEnd, group, prettySpace + "}"));
}
addCodeBlockFolds(body, foldElements, processedComments, document, quick);
diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java b/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java
index f2b9583c49b0..1f642b18d1b1 100644
--- a/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java
+++ b/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java
@@ -45,6 +45,7 @@ import com.intellij.util.ArrayUtil;
import com.intellij.util.ArrayUtilRt;
import com.intellij.util.Function;
import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.xml.util.XmlStringUtil;
import org.jdom.Document;
import org.jdom.Element;
@@ -720,14 +721,21 @@ public class JavaDocInfoGenerator {
boolean generateLink, boolean splitAnnotations) {
PsiManager manager = owner.getManager();
+ Set<String> shownAnnotations = ContainerUtil.newHashSet();
+
for (PsiAnnotation annotation : annotations) {
final PsiJavaCodeReferenceElement nameReferenceElement = annotation.getNameReferenceElement();
if (nameReferenceElement == null) continue;
final PsiElement resolved = nameReferenceElement.resolve();
boolean inferred = AnnotationUtil.isInferredAnnotation(annotation);
+
+ if (!(shownAnnotations.add(annotation.getQualifiedName()) || isRepeatableAnnotationType(resolved))) {
+ continue;
+ }
+
if (resolved instanceof PsiClass) {
final PsiClass annotationType = (PsiClass)resolved;
- if (AnnotationUtil.isAnnotated(annotationType, "java.lang.annotation.Documented", false)) {
+ if (isDocumentedAnnotationType(annotationType)) {
if (inferred) buffer.append("<i>");
final PsiClassType type = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createType(annotationType, PsiSubstitutor.EMPTY);
buffer.append("@");
@@ -770,6 +778,14 @@ public class JavaDocInfoGenerator {
}
}
+ public static boolean isDocumentedAnnotationType(@Nullable PsiElement annotationType) {
+ return annotationType instanceof PsiClass && AnnotationUtil.isAnnotated((PsiClass)annotationType, "java.lang.annotation.Documented", false);
+ }
+
+ public static boolean isRepeatableAnnotationType(@Nullable PsiElement annotationType) {
+ return annotationType instanceof PsiClass && AnnotationUtil.isAnnotated((PsiClass)annotationType, CommonClassNames.JAVA_LANG_ANNOTATION_REPEATABLE, false, true);
+ }
+
private void generateMethodParameterJavaDoc(@NonNls StringBuilder buffer, PsiParameter parameter, boolean generatePrologueAndEpilogue) {
if (generatePrologueAndEpilogue)
generatePrologue(buffer);
diff --git a/java/java-psi-impl/src/com/intellij/lang/java/parser/ReferenceParser.java b/java/java-psi-impl/src/com/intellij/lang/java/parser/ReferenceParser.java
index e18b1b5b5dab..c6c8e71fbca1 100644
--- a/java/java-psi-impl/src/com/intellij/lang/java/parser/ReferenceParser.java
+++ b/java/java-psi-impl/src/com/intellij/lang/java/parser/ReferenceParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -66,7 +66,7 @@ public class ReferenceParser {
final TypeInfo typeInfo = parseTypeInfo(builder, flags, false);
if (typeInfo != null) {
- assert notSet(flags, DISJUNCTIONS|CONJUNCTIONS) : "don't not set both flags simultaneously";
+ assert notSet(flags, DISJUNCTIONS|CONJUNCTIONS) : "don't set both flags simultaneously";
final IElementType operator = isSet(flags, DISJUNCTIONS) ? JavaTokenType.OR : isSet(flags, CONJUNCTIONS) ? JavaTokenType.AND : null;
if (operator != null && builder.getTokenType() == operator) {
diff --git a/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowAnalyzer.java b/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowAnalyzer.java
index da32b64ea092..b8f810611201 100644
--- a/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowAnalyzer.java
+++ b/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowAnalyzer.java
@@ -204,7 +204,7 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
ProgressIndicatorProvider.checkCanceled();
ControlFlowSubRange subRange = entry.getValue();
PsiElement element = entry.getKey();
- myControlFlowFactory.registerSubRange(element, subRange, myEvaluateConstantIfCondition, myPolicy);
+ myControlFlowFactory.registerSubRange(element, subRange, myEvaluateConstantIfCondition, myEnabledShortCircuit, myPolicy);
}
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowFactory.java b/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowFactory.java
index 2ba1906c422c..3159193bce4f 100644
--- a/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowFactory.java
+++ b/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowFactory.java
@@ -62,19 +62,29 @@ public class ControlFlowFactory {
cachedFlows.clear();
}
+ @Deprecated
public void registerSubRange(final PsiElement codeFragment, final ControlFlowSubRange flow, final boolean evaluateConstantIfConfition,
final ControlFlowPolicy policy) {
- registerControlFlow(codeFragment, flow, evaluateConstantIfConfition, policy);
+ registerSubRange(codeFragment, flow, evaluateConstantIfConfition, true, policy);
+ }
+
+ public void registerSubRange(final PsiElement codeFragment,
+ final ControlFlowSubRange flow,
+ final boolean evaluateConstantIfConfition,
+ boolean enableShortCircuit, final ControlFlowPolicy policy) {
+ registerControlFlow(codeFragment, flow, evaluateConstantIfConfition, enableShortCircuit, policy);
}
private static class ControlFlowContext {
private final ControlFlowPolicy policy;
private final boolean evaluateConstantIfCondition;
+ private final boolean enableShortCircuit;
private final long modificationCount;
private final ControlFlow controlFlow;
- private ControlFlowContext(boolean evaluateConstantIfCondition, @NotNull ControlFlowPolicy policy, long modificationCount, @NotNull ControlFlow controlFlow) {
+ private ControlFlowContext(boolean evaluateConstantIfCondition, boolean enableShortCircuit, @NotNull ControlFlowPolicy policy, long modificationCount, @NotNull ControlFlow controlFlow) {
this.evaluateConstantIfCondition = evaluateConstantIfCondition;
+ this.enableShortCircuit = enableShortCircuit;
this.policy = policy;
this.modificationCount = modificationCount;
this.controlFlow = controlFlow;
@@ -96,9 +106,10 @@ public class ControlFlowFactory {
return result;
}
- public boolean isFor(@NotNull ControlFlowPolicy policy, final boolean evaluateConstantIfCondition, long modificationCount) {
+ public boolean isFor(@NotNull ControlFlowPolicy policy, final boolean evaluateConstantIfCondition, final boolean enableShortCircuit, long modificationCount) {
if (modificationCount != this.modificationCount) return false;
if (!policy.equals(this.policy)) return false;
+ if (enableShortCircuit != this.enableShortCircuit) return false;
// optimization: when no constant condition were computed, both control flows are the same
if (!controlFlow.isConstantConditionOccurred()) return true;
@@ -107,7 +118,7 @@ public class ControlFlowFactory {
}
private boolean isFor(@NotNull ControlFlowContext that) {
- return isFor(that.policy, that.evaluateConstantIfCondition, that.modificationCount);
+ return isFor(that.policy, that.evaluateConstantIfCondition, that.enableShortCircuit, that.modificationCount);
}
}
@@ -129,28 +140,30 @@ public class ControlFlowFactory {
final long modificationCount = element.getManager().getModificationTracker().getModificationCount();
ConcurrentList<ControlFlowContext> cached = getOrCreateCachedFlowsForElement(element);
for (ControlFlowContext context : cached) {
- if (context.isFor(policy, evaluateConstantIfCondition,modificationCount)) return context.controlFlow;
+ if (context.isFor(policy, evaluateConstantIfCondition, enableShortCircuit, modificationCount)) return context.controlFlow;
}
ControlFlow controlFlow = new ControlFlowAnalyzer(element, policy, enableShortCircuit, evaluateConstantIfCondition).buildControlFlow();
- ControlFlowContext context = createContext(evaluateConstantIfCondition, policy, controlFlow, modificationCount);
+ ControlFlowContext context = createContext(evaluateConstantIfCondition, enableShortCircuit, policy, controlFlow, modificationCount);
cached.addIfAbsent(context);
return controlFlow;
}
@NotNull
private static ControlFlowContext createContext(final boolean evaluateConstantIfCondition,
+ boolean enableShortCircuit,
@NotNull ControlFlowPolicy policy,
@NotNull ControlFlow controlFlow,
final long modificationCount) {
- return new ControlFlowContext(evaluateConstantIfCondition, policy, modificationCount,controlFlow);
+ return new ControlFlowContext(evaluateConstantIfCondition, enableShortCircuit, policy, modificationCount,controlFlow);
}
private void registerControlFlow(@NotNull PsiElement element,
@NotNull ControlFlow flow,
boolean evaluateConstantIfCondition,
+ boolean enableShortCircuit,
@NotNull ControlFlowPolicy policy) {
final long modificationCount = element.getManager().getModificationTracker().getModificationCount();
- ControlFlowContext controlFlowContext = createContext(evaluateConstantIfCondition, policy, flow, modificationCount);
+ ControlFlowContext controlFlowContext = createContext(evaluateConstantIfCondition, enableShortCircuit, policy, flow, modificationCount);
ConcurrentList<ControlFlowContext> cached = getOrCreateCachedFlowsForElement(element);
cached.addIfAbsent(controlFlowContext);
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java
index 7c597e495f2e..9c9525aef859 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java
@@ -80,14 +80,14 @@ public class PsiSubstitutorImpl implements PsiSubstitutor {
}
private boolean containsInMap(PsiTypeParameter typeParameter) {
- if (typeParameter instanceof LightTypeParameter) {
+ if (typeParameter instanceof LightTypeParameter && ((LightTypeParameter)typeParameter).useDelegateToSubstitute()) {
typeParameter = ((LightTypeParameter)typeParameter).getDelegate();
}
return mySubstitutionMap.containsKey(typeParameter);
}
private PsiType getFromMap(@NotNull PsiTypeParameter typeParameter) {
- if (typeParameter instanceof LightTypeParameter) {
+ if (typeParameter instanceof LightTypeParameter && ((LightTypeParameter)typeParameter).useDelegateToSubstitute()) {
typeParameter = ((LightTypeParameter)typeParameter).getDelegate();
}
return mySubstitutionMap.get(typeParameter);
@@ -394,7 +394,7 @@ public class PsiSubstitutorImpl implements PsiSubstitutor {
}
}
}
- } else if (substituted instanceof PsiWildcardType && ((PsiWildcardType)substituted).isSuper()) {
+ } else if (substituted instanceof PsiWildcardType && ((PsiWildcardType)substituted).isSuper() && !(oldSubstituted instanceof PsiCapturedWildcardType)) {
final PsiType erasure = TypeConversionUtil.erasure(((PsiWildcardType)substituted).getBound());
if (erasure != null) {
final PsiType[] boundTypes = typeParameter.getExtendsListTypes();
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/file/PsiPackageImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/file/PsiPackageImpl.java
index c188c3a38013..9129052bf74f 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/file/PsiPackageImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/file/PsiPackageImpl.java
@@ -263,7 +263,6 @@ public class PsiPackageImpl extends PsiPackageBase implements PsiPackage, Querya
processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, this);
ElementClassHint classHint = processor.getHint(ElementClassHint.KEY);
- final JavaPsiFacade facade = getFacade();
final Condition<String> nameCondition = processor.getHint(JavaCompletionHints.NAME_FILTER);
if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.CLASS)) {
@@ -291,7 +290,7 @@ public class PsiPackageImpl extends PsiPackageBase implements PsiPackage, Querya
for (PsiPackage pack : packs) {
final String packageName = pack.getName();
if (packageName == null) continue;
- if (!facade.getNameHelper().isIdentifier(packageName, PsiUtil.getLanguageLevel(this))) {
+ if (!PsiNameHelper.getInstance(myManager.getProject()).isIdentifier(packageName, PsiUtil.getLanguageLevel(this))) {
continue;
}
if (!processor.execute(pack, state)) {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/light/LightTypeParameter.java b/java/java-psi-impl/src/com/intellij/psi/impl/light/LightTypeParameter.java
index 6775a64c59ef..3cd347648a07 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/light/LightTypeParameter.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/light/LightTypeParameter.java
@@ -79,6 +79,10 @@ public class LightTypeParameter extends LightClass implements PsiTypeParameter {
return getDelegate().addAnnotation(qualifiedName);
}
+ public boolean useDelegateToSubstitute() {
+ return true;
+ }
+
@Override
public String toString() {
return "PsiTypeParameter:" + getName();
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/FunctionalInterfaceParameterizationUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/FunctionalInterfaceParameterizationUtil.java
index b4b188c772cc..9742e0f28608 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/FunctionalInterfaceParameterizationUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/FunctionalInterfaceParameterizationUtil.java
@@ -36,7 +36,7 @@ public class FunctionalInterfaceParameterizationUtil {
}
if (classType instanceof PsiClassType) {
for (PsiType type : ((PsiClassType)classType).getParameters()) {
- if (type instanceof PsiWildcardType || type instanceof PsiCapturedWildcardType) {
+ if (type instanceof PsiWildcardType) {
return true;
}
}
@@ -94,7 +94,8 @@ public class FunctionalInterfaceParameterizationUtil {
final InferenceSession session = new InferenceSession(typeParameters, PsiSubstitutor.EMPTY, expr.getManager(), expr);
for (int i = 0; i < targetMethodParams.length; i++) {
- session.addConstraint(new TypeEqualityConstraint(lambdaParams[i].getType(), targetMethodParams[i].getType()));
+ session.addConstraint(new TypeEqualityConstraint(lambdaParams[i].getType(),
+ session.substituteWithInferenceVariables(targetMethodParams[i].getType())));
}
if (!session.repeatInferencePhases(false)) {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java
index 9766122e31d0..9c8b8b4772b3 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java
@@ -89,28 +89,6 @@ public class InferenceIncorporationPhase {
upDown(lowerBounds, eqBounds, substitutor);
upUp(upperBounds);
-
- for (PsiType eqBound : eqBounds) {
- if (mySession.isProperType(eqBound)) {
- for (PsiType upperBound : upperBounds) {
- if (!mySession.isProperType(upperBound)) {
- addConstraint(new StrictSubtypingConstraint(substitutor.substitute(upperBound), eqBound));
- }
- }
-
- for (PsiType lowerBound : lowerBounds) {
- if (!mySession.isProperType(lowerBound)) {
- addConstraint(new StrictSubtypingConstraint(eqBound, substitutor.substitute(lowerBound)));
- }
- }
-
- for (PsiType otherEqBound : eqBounds) {
- if (eqBound != otherEqBound && !mySession.isProperType(otherEqBound)) {
- addConstraint(new TypeEqualityConstraint(substitutor.substitute(otherEqBound), eqBound));
- }
- }
- }
- }
}
for (Pair<PsiTypeParameter[], PsiClassType> capture : myCaptures) {
@@ -135,7 +113,7 @@ public class InferenceIncorporationPhase {
if (aType instanceof PsiWildcardType) {
for (PsiType eqBound : eqBounds) {
- if (mySession.isProperType(eqBound)) return false;
+ if (mySession.getInferenceVariable(eqBound) == null) return false;
}
final PsiClassType[] paramBounds = parameters[i].getExtendsListTypes();
@@ -143,15 +121,15 @@ public class InferenceIncorporationPhase {
if (!((PsiWildcardType)aType).isBounded()) {
for (PsiType upperBound : upperBounds) {
- if (mySession.isProperType(upperBound)) {
+ if (mySession.getInferenceVariable(upperBound) == null) {
for (PsiClassType paramBound : paramBounds) {
- addConstraint(new StrictSubtypingConstraint(upperBound, paramBound));
+ addConstraint(new StrictSubtypingConstraint(upperBound, mySession.substituteWithInferenceVariables(paramBound)));
}
}
}
for (PsiType lowerBound : lowerBounds) {
- if (mySession.isProperType(lowerBound)) return false;
+ if (mySession.getInferenceVariable(lowerBound) == null) return false;
}
} else if (((PsiWildcardType)aType).isExtends()) {
@@ -159,19 +137,19 @@ public class InferenceIncorporationPhase {
final PsiType extendsBound = ((PsiWildcardType)aType).getExtendsBound();
for (PsiType upperBound : upperBounds) {
- if (mySession.isProperType(upperBound)) {
+ if (mySession.getInferenceVariable(upperBound) == null) {
if (paramBounds.length == 1 && paramBounds[0].equalsToText(CommonClassNames.JAVA_LANG_OBJECT) || paramBounds.length == 0) {
addConstraint(new StrictSubtypingConstraint(upperBound, extendsBound));
} else if (extendsBound.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) {
for (PsiClassType paramBound : paramBounds) {
- addConstraint(new StrictSubtypingConstraint(upperBound, paramBound));
+ addConstraint(new StrictSubtypingConstraint(upperBound, mySession.substituteWithInferenceVariables(paramBound)));
}
}
}
}
for (PsiType lowerBound : lowerBounds) {
- if (mySession.isProperType(lowerBound)) return false;
+ if (mySession.getInferenceVariable(lowerBound) == null) return false;
}
} else {
@@ -179,15 +157,15 @@ public class InferenceIncorporationPhase {
final PsiType superBound = ((PsiWildcardType)aType).getSuperBound();
for (PsiType upperBound : upperBounds) {
- if (mySession.isProperType(upperBound)) {
+ if (mySession.getInferenceVariable(upperBound) == null) {
for (PsiClassType paramBound : paramBounds) {
- addConstraint(new StrictSubtypingConstraint(paramBound, upperBound));
+ addConstraint(new StrictSubtypingConstraint(mySession.substituteWithInferenceVariables(paramBound), upperBound));
}
}
}
for (PsiType lowerBound : lowerBounds) {
- if (mySession.isProperType(lowerBound)) {
+ if (mySession.getInferenceVariable(lowerBound) == null) {
addConstraint(new StrictSubtypingConstraint(lowerBound, superBound));
}
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java
index 27e34f00a25f..35db6c29bc0c 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java
@@ -15,10 +15,12 @@
*/
package com.intellij.psi.impl.source.resolve.graphInference;
+import com.intellij.ide.highlighter.JavaFileType;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.impl.source.resolve.graphInference.constraints.*;
@@ -42,8 +44,14 @@ public class InferenceSession {
public static final Key<PsiType> LOWER_BOUND = Key.create("LowBound");
private static final Key<Boolean> ERASED = Key.create("UNCHECKED_CONVERSION");
+ private static final Function<Pair<PsiType, PsiType>, PsiType> UPPER_BOUND_FUNCTION = new Function<Pair<PsiType, PsiType>, PsiType>() {
+ @Override
+ public PsiType fun(Pair<PsiType, PsiType> pair) {
+ return GenericsUtil.getGreatestLowerBound(pair.first, pair.second);
+ }
+ };
- private final Map<PsiTypeParameter, InferenceVariable> myInferenceVariables = new LinkedHashMap<PsiTypeParameter, InferenceVariable>();
+ private final Set<InferenceVariable> myInferenceVariables = new LinkedHashSet<InferenceVariable>();
private final List<ConstraintFormula> myConstraints = new ArrayList<ConstraintFormula>();
private final Set<ConstraintFormula> myConstraintsCopy = new HashSet<ConstraintFormula>();
@@ -56,8 +64,14 @@ public class InferenceSession {
private final InferenceIncorporationPhase myIncorporationPhase = new InferenceIncorporationPhase(this);
private final PsiElement myContext;
-
- private final PsiTypeParameter[] myParamsToInfer;
+
+ private PsiSubstitutor myInferenceSubstitution = PsiSubstitutor.EMPTY;
+ private Map<PsiElement, InferenceSession> myNestedSessions = new HashMap<PsiElement, InferenceSession>();
+ public void registerNestedSession(InferenceSession session) {
+ propagateVariables(session.getInferenceVariables());
+ myNestedSessions.put(session.getContext(), session);
+ myNestedSessions.putAll(session.myNestedSessions);
+ }
public InferenceSession(PsiTypeParameter[] typeParams,
PsiType[] leftTypes,
@@ -70,13 +84,12 @@ public class InferenceSession {
myContext = context;
initBounds(typeParams);
- myParamsToInfer = typeParams;
LOG.assertTrue(leftTypes.length == rightTypes.length);
for (int i = 0; i < leftTypes.length; i++) {
final PsiType rightType = mySiteSubstitutor.substitute(rightTypes[i]);
if (rightType != null) {
- addConstraint(new TypeCompatibilityConstraint(leftTypes[i], rightType));
+ addConstraint(new TypeCompatibilityConstraint(substituteWithInferenceVariables(leftTypes[i]), substituteWithInferenceVariables(rightType)));
}
}
}
@@ -90,11 +103,6 @@ public class InferenceSession {
myContext = context;
initBounds(typeParams);
- myParamsToInfer = typeParams;
- }
-
- public PsiTypeParameter[] getParamsToInfer() {
- return myParamsToInfer;
}
public void initExpressionConstraints(PsiParameter[] parameters, PsiExpression[] args, PsiElement parent, PsiMethod method) {
@@ -117,7 +125,7 @@ public class InferenceSession {
for (int i = 0; i < args.length; i++) {
if (args[i] != null && isPertinentToApplicability(args[i], method)) {
PsiType parameterType = getParameterType(parameters, i, mySiteSubstitutor, varargs);
- addConstraint(new ExpressionCompatibilityConstraint(args[i], parameterType));
+ addConstraint(new ExpressionCompatibilityConstraint(args[i], substituteWithInferenceVariables(parameterType)));
}
}
}
@@ -213,7 +221,7 @@ public class InferenceSession {
final MethodCandidateInfo.CurrentCandidateProperties properties = getCurrentProperties(parent);
if (!repeatInferencePhases(true)) {
//inferred result would be checked as candidate won't be applicable
- return resolveSubset(myInferenceVariables.values(), mySiteSubstitutor);
+ return resolveSubset(myInferenceVariables, mySiteSubstitutor);
}
if (properties != null && !properties.isApplicabilityCheck()) {
@@ -235,20 +243,17 @@ public class InferenceSession {
}
}
- final PsiSubstitutor substitutor = resolveBounds(myInferenceVariables.values(), mySiteSubstitutor);
+ final PsiSubstitutor substitutor = resolveBounds(myInferenceVariables, mySiteSubstitutor);
if (substitutor != null) {
if (myContext != null) {
myContext.putUserData(ERASED, myErased);
}
mySiteSubstitutor = substitutor;
- for (PsiTypeParameter parameter : substitutor.getSubstitutionMap().keySet()) {
- final InferenceVariable variable = getInferenceVariable(parameter);
- if (variable != null) {
- variable.setInstantiation(substitutor.substitute(parameter));
- }
+ for (InferenceVariable variable : myInferenceVariables) {
+ variable.setInstantiation(substitutor.substitute(variable.getParameter()));
}
} else {
- return resolveSubset(myInferenceVariables.values(), mySiteSubstitutor);
+ return resolveSubset(myInferenceVariables, mySiteSubstitutor);
}
return prepareSubstitution();
@@ -262,12 +267,16 @@ public class InferenceSession {
boolean varargs, boolean toplevel) {
for (int i = 0; i < args.length; i++) {
if (args[i] != null) {
- PsiType parameterType = getParameterType(parameters, i, siteSubstitutor, varargs);
+ InferenceSession session = myNestedSessions.get(PsiTreeUtil.getParentOfType(args[i], PsiCallExpression.class));
+ if (session == null) {
+ session = this;
+ }
+ PsiType parameterType = session.substituteWithInferenceVariables(getParameterType(parameters, i, siteSubstitutor, varargs));
if (!isPertinentToApplicability(args[i], parentMethod)) {
additionalConstraints.add(new ExpressionCompatibilityConstraint(args[i], parameterType));
}
additionalConstraints.add(new CheckedExceptionCompatibilityConstraint(args[i], parameterType));
- if (args[i] instanceof PsiCallExpression) {
+ if (args[i] instanceof PsiCallExpression && PsiPolyExpressionUtil.isPolyExpression(args[i])) {
//If the expression is a poly class instance creation expression (15.9) or a poly method invocation expression (15.12),
//the set contains all constraint formulas that would appear in the set C when determining the poly expression's invocation type.
final PsiCallExpression callExpression = (PsiCallExpression)args[i];
@@ -299,18 +308,18 @@ public class InferenceSession {
return callExpression.resolveMethodGenerics();
}
};
- final JavaResolveResult result = expression == null
+ MethodCandidateInfo.CurrentCandidateProperties properties = MethodCandidateInfo.getCurrentMethod(argumentList);
+ final JavaResolveResult result = properties != null ? null :
+ expression == null
? computableResolve.compute()
: PsiResolveHelper.ourGraphGuard.doPreventingRecursion(expression, false, computableResolve);
- if (result instanceof MethodCandidateInfo) {
- final PsiMethod method = ((MethodCandidateInfo)result).getElement();
- //need to get type parameters for 2 level nested expressions (they won't be covered by expression constraints on this level?!)
- initBounds(method.getTypeParameters());
+ final PsiMethod method = result instanceof MethodCandidateInfo ? ((MethodCandidateInfo)result).getElement() : properties != null ? properties.getMethod() : null;
+ if (method != null) {
final PsiExpression[] newArgs = argumentList.getExpressions();
final PsiParameter[] newParams = method.getParameterList().getParameters();
if (newParams.length > 0) {
- collectAdditionalConstraints(newParams, newArgs, method, ((MethodCandidateInfo)result).getSiteSubstitutor(),
- additionalConstraints, ((MethodCandidateInfo)result).isVarargs(), false);
+ collectAdditionalConstraints(newParams, newArgs, method, result != null ? ((MethodCandidateInfo)result).getSiteSubstitutor() : properties.getSubstitutor(),
+ additionalConstraints, result != null ? ((MethodCandidateInfo)result).isVarargs() : properties.isVarargs(), false);
}
}
}
@@ -321,14 +330,14 @@ public class InferenceSession {
for (InferenceVariable variable : variables) {
final PsiType equalsBound = getEqualsBound(variable, substitutor);
if (!(equalsBound instanceof PsiPrimitiveType)) {
- substitutor = substitutor.put(variable.getParameter(), equalsBound);
+ substitutor = substitutor.put(variable, equalsBound);
}
}
return substitutor;
}
private PsiSubstitutor prepareSubstitution() {
- for (InferenceVariable inferenceVariable : myInferenceVariables.values()) {
+ for (InferenceVariable inferenceVariable : myInferenceVariables) {
final PsiTypeParameter typeParameter = inferenceVariable.getParameter();
PsiType instantiation = inferenceVariable.getInstantiation();
if (instantiation == PsiType.NULL) {
@@ -340,33 +349,24 @@ public class InferenceSession {
return mySiteSubstitutor;
}
- private boolean isInsideRecursiveCall(PsiTypeParameter parameter) {
- final PsiTypeParameterListOwner parameterOwner = parameter.getOwner();
- if (myContext != null && PsiTreeUtil.isAncestor(parameterOwner, myContext, true)) {
- final PsiModifierListOwner staticContainer = PsiUtil.getEnclosingStaticElement(myContext, null);
- if (staticContainer == null || PsiTreeUtil.isAncestor(staticContainer, parameterOwner, false)) {
- return true;
- }
- }
- return false;
+ public void initBounds(PsiTypeParameter... typeParameters) {
+ initBounds(myContext, typeParameters);
}
- public boolean initBounds(PsiTypeParameter... typeParameters) {
- return initBounds(myContext, typeParameters);
- }
-
- public boolean initBounds(PsiElement context, PsiTypeParameter... typeParameters) {
- boolean sameMethodCall = false;
+ public InferenceVariable[] initBounds(PsiElement context, PsiTypeParameter... typeParameters) {
+ List<InferenceVariable> result = new ArrayList<InferenceVariable>(typeParameters.length);
for (PsiTypeParameter parameter : typeParameters) {
- if (myInferenceVariables.containsKey(parameter)) {
- sameMethodCall = true;
- continue;
- }
InferenceVariable variable = new InferenceVariable(context, parameter);
+ result.add(variable);
+ myInferenceSubstitution = myInferenceSubstitution.put(parameter,
+ JavaPsiFacade.getElementFactory(variable.getProject()).createType(variable));
+ }
+ for (InferenceVariable variable : result) {
+ PsiTypeParameter parameter = variable.getParameter();
boolean added = false;
final PsiClassType[] extendsListTypes = parameter.getExtendsListTypes();
for (PsiType classType : extendsListTypes) {
- classType = mySiteSubstitutor.substitute(classType);
+ classType = substituteWithInferenceVariables(mySiteSubstitutor.substitute(classType));
if (isProperType(classType)) {
added = true;
}
@@ -376,9 +376,9 @@ public class InferenceSession {
variable.addBound(PsiType.getJavaLangObject(parameter.getManager(), parameter.getResolveScope()),
InferenceBound.UPPER);
}
- myInferenceVariables.put(parameter, variable);
}
- return sameMethodCall;
+ myInferenceVariables.addAll(result);
+ return result.toArray(new InferenceVariable[result.size()]);
}
private void initReturnTypeConstraint(PsiMethod method, final PsiCallExpression context) {
@@ -393,7 +393,7 @@ public class InferenceSession {
}
for (PsiClassType thrownType : method.getThrowsList().getReferencedTypes()) {
- final InferenceVariable variable = getInferenceVariable(thrownType);
+ final InferenceVariable variable = getInferenceVariable(substituteWithInferenceVariables(thrownType));
if (variable != null) {
variable.setThrownBound();
}
@@ -401,6 +401,7 @@ public class InferenceSession {
}
public void registerReturnTypeConstraints(PsiType returnType, PsiType targetType) {
+ returnType = substituteWithInferenceVariables(returnType);
final InferenceVariable inferenceVariable = shouldResolveAndInstantiate(returnType, targetType);
if (inferenceVariable != null) {
final PsiSubstitutor substitutor = resolveSubset(Collections.singletonList(inferenceVariable), mySiteSubstitutor);
@@ -416,17 +417,9 @@ public class InferenceSession {
if (psiClass != null) {
LOG.assertTrue(returnType instanceof PsiClassType);
final PsiTypeParameter[] typeParameters = psiClass.getTypeParameters();
- PsiSubstitutor subst = PsiSubstitutor.EMPTY;
- final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(psiClass.getProject());
- PsiTypeParameter[] copy = new PsiTypeParameter[typeParameters.length];
- for (int i = 0; i < typeParameters.length; i++) {
- PsiTypeParameter typeParameter = typeParameters[i];
- copy[i] = elementFactory.createTypeParameterFromText("rCopy" + typeParameter.getName(), null);
- initBounds(myContext, copy[i]);
- subst = subst.put(typeParameter, elementFactory.createType(copy[i]));
- }
- final PsiType substitutedCapture = PsiUtil.captureToplevelWildcards(subst.substitute(returnType), myContext);
- myIncorporationPhase.addCapture(copy, (PsiClassType)returnType);
+ InferenceVariable[] copy = initBounds(myContext, typeParameters);
+ final PsiType substitutedCapture = PsiUtil.captureToplevelWildcards(returnType, myContext);
+ myIncorporationPhase.addCapture(copy, (PsiClassType)substituteWithInferenceVariables(returnType));
addConstraint(new TypeCompatibilityConstraint(targetType, substitutedCapture));
}
} else {
@@ -584,8 +577,8 @@ public class InferenceSession {
public InferenceVariable getInferenceVariable(PsiType psiType) {
final PsiClass psiClass = PsiUtil.resolveClassInClassTypeOnly(psiType);
- if (psiClass instanceof PsiTypeParameter) {
- return myInferenceVariables.get(psiClass);
+ if (psiClass instanceof InferenceVariable) {
+ return (InferenceVariable)psiClass;
}
return null;
}
@@ -694,7 +687,13 @@ public class InferenceSession {
while (!allVars.isEmpty()) {
final List<InferenceVariable> vars = InferenceVariablesOrder.resolveOrder(allVars, this);
if (!myIncorporationPhase.hasCaptureConstraints(vars)) {
- final PsiSubstitutor firstSubstitutor = resolveSubset(vars, substitutor);
+ PsiSubstitutor firstSubstitutor = resolveSubset(vars, substitutor);
+ if (firstSubstitutor != null) {
+ final Set<PsiTypeParameter> parameters = firstSubstitutor.getSubstitutionMap().keySet();
+ if (GenericsUtil.findTypeParameterWithBoundError(parameters.toArray(new PsiTypeParameter[parameters.size()]), firstSubstitutor, myContext, true) != null) {
+ firstSubstitutor = null;
+ }
+ }
if (firstSubstitutor != null) {
substitutor = firstSubstitutor;
allVars.removeAll(vars);
@@ -703,73 +702,102 @@ public class InferenceSession {
}
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(getManager().getProject());
- for (InferenceVariable var : vars) {
- final PsiTypeParameter parameter = var.getParameter();
- final PsiTypeParameter copy = elementFactory.createTypeParameterFromText("z" + parameter.getName(), null);
- final PsiType lub = getLowerBound(var, substitutor);
- final PsiType glb = getUpperBound(var, substitutor);
- final InferenceVariable zVariable = new InferenceVariable(var.getCallContext(), copy);
- zVariable.addBound(glb, InferenceBound.UPPER);
+ final PsiTypeParameter[] freshParameters = createFreshVariables(vars);
+ for (int i = 0; i < freshParameters.length; i++) {
+ PsiTypeParameter parameter = freshParameters[i];
+ final InferenceVariable var = vars.get(i);
+ final PsiType lub = getLowerBound(var, PsiSubstitutor.EMPTY);
if (lub != PsiType.NULL) {
- if (!TypeConversionUtil.isAssignable(glb, lub)) {
- return null;
+ for (PsiClassType upperBoundType : parameter.getExtendsListTypes()) {
+ if (!TypeConversionUtil.isAssignable(upperBoundType, lub)) {
+ return null;
+ }
}
- copy.putUserData(LOWER_BOUND, lub);
- zVariable.addBound(lub, InferenceBound.LOWER);
+ parameter.putUserData(LOWER_BOUND, lub);
}
- myInferenceVariables.put(copy, zVariable);
- allVars.add(zVariable);
- var.addBound(elementFactory.createType(copy), InferenceBound.EQ);
+ var.addBound(elementFactory.createType(parameter), InferenceBound.EQ);
}
myIncorporationPhase.forgetCaptures(vars);
- if (!myIncorporationPhase.incorporate()) {
+ if (!repeatInferencePhases(true)) {
return null;
}
}
return substitutor;
}
- private PsiType getLowerBound(InferenceVariable var, PsiSubstitutor substitutor) {
- return composeBound(var, InferenceBound.LOWER, new Function<Pair<PsiType, PsiType>, PsiType>() {
+ private PsiTypeParameter[] createFreshVariables(final List<InferenceVariable> vars) {
+ final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(getManager().getProject());
+
+ PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
+ final PsiTypeParameter[] yVars = new PsiTypeParameter[vars.size()];
+ for (int i = 0; i < vars.size(); i++) {
+ InferenceVariable var = vars.get(i);
+ final PsiTypeParameter parameter = var.getParameter();
+ yVars[i] = elementFactory.createTypeParameterFromText(getFreshVariableName(var), parameter);
+ substitutor = substitutor.put(var, elementFactory.createType(yVars[i]));
+ }
+
+
+ final PsiSubstitutor ySubstitutor = substitutor;
+ final String classText = "class I<" + StringUtil.join(vars, new Function<InferenceVariable, String>() {
@Override
- public PsiType fun(Pair<PsiType, PsiType> pair) {
- return GenericsUtil.getLeastUpperBound(pair.first, pair.second, myManager);
- }
- }, substitutor);
+ public String fun(InferenceVariable variable) {
+ final PsiType glb = composeBound(variable, InferenceBound.UPPER, UPPER_BOUND_FUNCTION, ySubstitutor, true);
+ return getFreshVariableName(variable) + " extends " + glb.getInternalCanonicalText();
+ }
+ }, ", ") + ">{}";
+
+ final PsiFile file =
+ PsiFileFactory.getInstance(getManager().getProject()).createFileFromText("inference_dummy.java", JavaFileType.INSTANCE, classText);
+ LOG.assertTrue(file instanceof PsiJavaFile, classText);
+ final PsiClass[] classes = ((PsiJavaFile)file).getClasses();
+ LOG.assertTrue(classes.length == 1, classText);
+ return classes[0].getTypeParameters();
+ }
+
+ private static String getFreshVariableName(InferenceVariable var) {
+ return var.getName();
}
private PsiSubstitutor resolveSubset(Collection<InferenceVariable> vars, PsiSubstitutor substitutor) {
for (InferenceVariable var : vars) {
LOG.assertTrue(var.getInstantiation() == PsiType.NULL);
final PsiTypeParameter typeParameter = var.getParameter();
+ if (substitutor.getSubstitutionMap().containsKey(typeParameter) && var.getCallContext() != myContext) {
+ continue;//todo
+ }
+
final PsiType eqBound = getEqualsBound(var, substitutor);
if (eqBound != PsiType.NULL && eqBound instanceof PsiPrimitiveType) continue;
- final PsiType lub = eqBound != PsiType.NULL && (myErased || eqBound != null) ? eqBound : getLowerBound(var, substitutor);
- if (lub != PsiType.NULL) {
- substitutor = substitutor.put(typeParameter, lub);
- }
- else if (var.isThrownBound() && isThrowable(var.getBounds(InferenceBound.UPPER))) {
- final PsiClassType runtimeException = PsiType.getJavaLangRuntimeException(myManager, GlobalSearchScope.allScope(myManager.getProject()));
- substitutor = substitutor.put(typeParameter, runtimeException);
- }
- else {
- if (substitutor.getSubstitutionMap().get(typeParameter) != null) continue;
- substitutor = substitutor.put(typeParameter, myErased ? null : getUpperBound(var, substitutor));
+ PsiType type = eqBound != PsiType.NULL && (myErased || eqBound != null) ? eqBound : getLowerBound(var, substitutor);
+ if (type == PsiType.NULL) {
+ if (var.isThrownBound() && isThrowable(var.getBounds(InferenceBound.UPPER))) {
+ type = PsiType.getJavaLangRuntimeException(myManager, GlobalSearchScope.allScope(myManager.getProject()));
+ }
+ else {
+ if (substitutor.getSubstitutionMap().get(typeParameter) != null) continue;
+ type = myErased ? null : getUpperBound(var, substitutor);
+ }
}
+ substitutor = substitutor.put(typeParameter, type);
}
return substitutor;
}
- private PsiType getUpperBound(InferenceVariable var, PsiSubstitutor substitutor) {
- return composeBound(var, InferenceBound.UPPER, new Function<Pair<PsiType, PsiType>, PsiType>() {
+ private PsiType getLowerBound(InferenceVariable var, PsiSubstitutor substitutor) {
+ return composeBound(var, InferenceBound.LOWER, new Function<Pair<PsiType, PsiType>, PsiType>() {
@Override
public PsiType fun(Pair<PsiType, PsiType> pair) {
- return GenericsUtil.getGreatestLowerBound(pair.first, pair.second);
+ return GenericsUtil.getLeastUpperBound(pair.first, pair.second, myManager);
}
}, substitutor);
}
+ private PsiType getUpperBound(InferenceVariable var, PsiSubstitutor substitutor) {
+ return composeBound(var, InferenceBound.UPPER, UPPER_BOUND_FUNCTION, substitutor);
+ }
+
public PsiType getEqualsBound(InferenceVariable var, PsiSubstitutor substitutor) {
return composeBound(var, InferenceBound.EQ, new Function<Pair<PsiType, PsiType>, PsiType>() {
@Override
@@ -783,16 +811,19 @@ public class InferenceSession {
InferenceBound boundType,
Function<Pair<PsiType, PsiType>, PsiType> fun,
PsiSubstitutor substitutor) {
+ return composeBound(variable, boundType, fun, substitutor, false);
+ }
+
+ private PsiType composeBound(InferenceVariable variable,
+ InferenceBound boundType,
+ Function<Pair<PsiType, PsiType>, PsiType> fun,
+ PsiSubstitutor substitutor,
+ boolean includeNonProperBounds) {
final List<PsiType> lowerBounds = variable.getBounds(boundType);
PsiType lub = PsiType.NULL;
- List<PsiType> dTypes = new ArrayList<PsiType>();
for (PsiType lowerBound : lowerBounds) {
lowerBound = substituteNonProperBound(lowerBound, substitutor);
- final HashSet<InferenceVariable> dependencies = new HashSet<InferenceVariable>();
- collectDependencies(lowerBound, dependencies);
- if (dependencies.size() == 1 && dependencies.contains(variable) && isInsideRecursiveCall(dependencies)) {
- lub = JavaPsiFacade.getElementFactory(myManager.getProject()).createType(variable.getParameter());
- } else if (dependencies.isEmpty() || isInsideRecursiveCall(dependencies)) {
+ if (includeNonProperBounds || isProperType(lowerBound)) {
if (lub == PsiType.NULL) {
lub = lowerBound;
}
@@ -804,13 +835,6 @@ public class InferenceSession {
return lub;
}
- private boolean isInsideRecursiveCall(HashSet<InferenceVariable> dependencies) {
- for (InferenceVariable dependency : dependencies) {
- if (!isInsideRecursiveCall(dependency.getParameter())) return false;
- }
- return true;
- }
-
public PsiManager getManager() {
return myManager;
}
@@ -820,7 +844,7 @@ public class InferenceSession {
}
public Collection<InferenceVariable> getInferenceVariables() {
- return myInferenceVariables.values();
+ return myInferenceVariables;
}
public void addConstraint(ConstraintFormula constraint) {
@@ -829,10 +853,6 @@ public class InferenceSession {
}
}
- public Collection<PsiTypeParameter> getTypeParams() {
- return myInferenceVariables.keySet();
- }
-
private boolean proceedWithAdditionalConstraints(Set<ConstraintFormula> additionalConstraints) {
final PsiSubstitutor siteSubstitutor = mySiteSubstitutor;
@@ -855,7 +875,7 @@ public class InferenceSession {
}
//resolve input variables
- PsiSubstitutor substitutor = resolveSubset(varsToResolve, retrieveNonPrimitiveEqualsBounds(getInferenceVariables()).putAll(siteSubstitutor));
+ PsiSubstitutor substitutor = resolveSubset(varsToResolve, siteSubstitutor);
if (substitutor == null) {
return false;
}
@@ -972,7 +992,7 @@ public class InferenceSession {
for (int i = 0; i < functionalMethodParameters.length; i++) {
final PsiType pType = signature.getParameterTypes()[i];
- addConstraint(new TypeCompatibilityConstraint(getParameterType(parameters, i, PsiSubstitutor.EMPTY, varargs),
+ addConstraint(new TypeCompatibilityConstraint(substituteWithInferenceVariables(getParameterType(parameters, i, PsiSubstitutor.EMPTY, varargs)),
PsiImplUtil.normalizeWildcardTypeByPosition(pType, reference)));
}
}
@@ -1003,11 +1023,11 @@ public class InferenceSession {
final PsiType qType = JavaPsiFacade.getElementFactory(method.getProject()).createType(containingClass, psiSubstitutor);
- addConstraint(new TypeCompatibilityConstraint(qType, pType));
+ addConstraint(new TypeCompatibilityConstraint(substituteWithInferenceVariables(qType), pType));
for (int i = 0; i < signature.getParameterTypes().length - 1; i++) {
final PsiType interfaceParamType = signature.getParameterTypes()[i + 1];
- addConstraint(new TypeCompatibilityConstraint(getParameterType(parameters, i, PsiSubstitutor.EMPTY, varargs),
+ addConstraint(new TypeCompatibilityConstraint(substituteWithInferenceVariables(getParameterType(parameters, i, PsiSubstitutor.EMPTY, varargs)),
PsiImplUtil.normalizeWildcardTypeByPosition(interfaceParamType, reference)));
}
}
@@ -1020,7 +1040,7 @@ public class InferenceSession {
}
public InferenceVariable getInferenceVariable(PsiTypeParameter parameter) {
- return myInferenceVariables.get(parameter);
+ return parameter instanceof InferenceVariable && myInferenceVariables.contains(parameter) ? (InferenceVariable)parameter : null;
}
/**
@@ -1031,10 +1051,11 @@ public class InferenceSession {
PsiExpression[] args,
PsiElement context,
boolean varargs) {
- final InferenceSession session = new InferenceSession(PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY, m2.getManager(), context);
+ List<PsiTypeParameter> params = new ArrayList<PsiTypeParameter>();
for (PsiTypeParameter param : PsiUtil.typeParametersIterable(m2)) {
- session.initBounds(context, param);
+ params.add(param);
}
+ final InferenceSession session = new InferenceSession(params.toArray(new PsiTypeParameter[params.size()]), PsiSubstitutor.EMPTY, m2.getManager(), context);
final PsiParameter[] parameters1 = m1.getParameterList().getParameters();
final PsiParameter[] parameters2 = m2.getParameterList().getParameters();
@@ -1045,7 +1066,7 @@ public class InferenceSession {
final int paramsLength = !varargs ? parameters1.length : parameters1.length - 1;
for (int i = 0; i < paramsLength; i++) {
PsiType sType = getParameterType(parameters1, i, PsiSubstitutor.EMPTY, false);
- PsiType tType = getParameterType(parameters2, i, PsiSubstitutor.EMPTY, varargs);
+ PsiType tType = session.substituteWithInferenceVariables(getParameterType(parameters2, i, PsiSubstitutor.EMPTY, varargs));
if (session.isProperType(sType) && session.isProperType(tType)) {
if (!TypeConversionUtil.isAssignable(tType, sType)) {
return false;
@@ -1063,7 +1084,7 @@ public class InferenceSession {
if (varargs) {
PsiType sType = getParameterType(parameters1, paramsLength, PsiSubstitutor.EMPTY, true);
- PsiType tType = getParameterType(parameters2, paramsLength, PsiSubstitutor.EMPTY, true);
+ PsiType tType = session.substituteWithInferenceVariables(getParameterType(parameters2, paramsLength, PsiSubstitutor.EMPTY, true));
session.addConstraint(new StrictSubtypingConstraint(tType, sType));
}
@@ -1257,25 +1278,6 @@ public class InferenceSession {
return myIncorporationPhase.hasCaptureConstraints(Arrays.asList(inferenceVariable));
}
- public void liftBounds(PsiElement context, Collection<InferenceVariable> variables) {
- for (InferenceVariable variable : variables) {
- final PsiTypeParameter parameter = variable.getParameter();
- final InferenceVariable inferenceVariable = getInferenceVariable(parameter);
- if (inferenceVariable != null) {
- final PsiElement callContext = inferenceVariable.getCallContext();
- if (context.equals(callContext) || myContext.equals(callContext)) {
- for (InferenceBound boundType : InferenceBound.values()) {
- for (PsiType bound : variable.getBounds(boundType)) {
- inferenceVariable.addBound(bound, boundType);
- }
- }
- }
- } else {
- myInferenceVariables.put(parameter, variable);
- }
- }
- }
-
public static boolean wasUncheckedConversionPerformed(PsiElement call) {
final Boolean erased = call.getUserData(ERASED);
return erased != null && erased.booleanValue();
@@ -1284,4 +1286,20 @@ public class InferenceSession {
public PsiElement getContext() {
return myContext;
}
+
+ public void propagateVariables(Collection<InferenceVariable> variables) {
+ myInferenceVariables.addAll(variables);
+ }
+
+ public PsiType substituteWithInferenceVariables(PsiType type) {
+ return myInferenceSubstitution.substitute(type);
+ }
+
+ public PsiType startWithFreshVars(PsiType type) {
+ PsiSubstitutor s = PsiSubstitutor.EMPTY;
+ for (InferenceVariable variable : myInferenceVariables) {
+ s = s.put(variable, JavaPsiFacade.getElementFactory(variable.getProject()).createType(variable.getParameter()));
+ }
+ return s.substitute(type);
+ }
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariable.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariable.java
index 6bc9e0b89871..8d91b620f798 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariable.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariable.java
@@ -15,9 +15,7 @@
*/
package com.intellij.psi.impl.source.resolve.graphInference;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiType;
-import com.intellij.psi.PsiTypeParameter;
+import com.intellij.psi.*;
import com.intellij.psi.impl.light.LightTypeParameter;
import java.util.*;
@@ -139,6 +137,11 @@ public class InferenceVariable extends LightTypeParameter {
}
@Override
+ public boolean useDelegateToSubstitute() {
+ return false;
+ }
+
+ @Override
public String toString() {
return getDelegate().toString();
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/PsiGraphInferenceHelper.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/PsiGraphInferenceHelper.java
index b4c971b3b469..28ad946275e9 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/PsiGraphInferenceHelper.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/PsiGraphInferenceHelper.java
@@ -67,12 +67,12 @@ public class PsiGraphInferenceHelper implements PsiInferenceHelper {
if (typeParameters.length == 0) return PsiSubstitutor.EMPTY;
InferenceSession session = new InferenceSession(typeParameters, leftTypes, rightTypes, PsiSubstitutor.EMPTY, myManager, null);
for (PsiType leftType : leftTypes) {
- if (!session.isProperType(leftType)) {
+ if (!session.isProperType(session.substituteWithInferenceVariables(leftType))) {
return session.infer();
}
}
for (PsiType rightType : rightTypes) {
- if (!session.isProperType(rightType)) {
+ if (!session.isProperType(session.substituteWithInferenceVariables(rightType))) {
return session.infer();
}
}
@@ -105,10 +105,11 @@ public class PsiGraphInferenceHelper implements PsiInferenceHelper {
rightTypes = new PsiType[]{param};
}
final InferenceSession inferenceSession = new InferenceSession(new PsiTypeParameter[]{typeParam}, leftTypes, rightTypes, PsiSubstitutor.EMPTY, myManager, null);
- if (inferenceSession.isProperType(param) && inferenceSession.isProperType(arg)) {
+ if (inferenceSession.isProperType(inferenceSession.substituteWithInferenceVariables(param)) &&
+ inferenceSession.isProperType(inferenceSession.substituteWithInferenceVariables(arg))) {
boolean proceed = false;
for (PsiClassType classType : typeParam.getExtendsListTypes()) {
- if (!inferenceSession.isProperType(classType)) {
+ if (!inferenceSession.isProperType(inferenceSession.substituteWithInferenceVariables(classType))) {
proceed = true;
break;
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java
index 82b320ae99f3..b59cf70bdb69 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java
@@ -19,16 +19,12 @@ import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
import com.intellij.psi.impl.source.resolve.graphInference.InferenceVariable;
import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil;
-import com.intellij.psi.impl.source.tree.java.PsiMethodCallExpressionImpl;
import com.intellij.psi.infos.MethodCandidateInfo;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
-import com.intellij.util.containers.ContainerUtil;
-import com.intellij.util.containers.HashSet;
import org.jetbrains.annotations.NotNull;
-import java.util.Collection;
-import java.util.Iterator;
+import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@@ -94,7 +90,11 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm
if (method != null && !method.isConstructor()) {
returnType = method.getReturnType();
if (returnType != null) {
- typeParams = method.getTypeParameters();
+ List<PsiTypeParameter> params = new ArrayList<PsiTypeParameter>();
+ for (PsiTypeParameter parameter : PsiUtil.typeParametersIterable(method)) {
+ params.add(parameter);
+ }
+ typeParams = params.toArray(new PsiTypeParameter[params.size()]);
}
} else if (myExpression instanceof PsiNewExpression) { //default constructor
final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)myExpression).getClassOrAnonymousClassReference();
@@ -108,38 +108,8 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm
}
if (typeParams != null) {
-
- final Set<PsiTypeParameter> oldBounds = ContainerUtil.newHashSet(session.getParamsToInfer());
- final boolean sameMethodCall = session.initBounds(myExpression, typeParams);
- PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
- final HashSet<InferenceVariable> variables = new HashSet<InferenceVariable>();
- session.collectDependencies(returnType, variables);
- final PsiTypeParameter[] params = new PsiTypeParameter[typeParams.length];
- for (int i = 0; i < typeParams.length; i++) {
- if (variables.contains(session.getInferenceVariable(typeParams[i]))) {
- params[i] = JavaPsiFacade.getElementFactory(myExpression.getProject()).createTypeParameterFromText("copyOf" + myExpression.hashCode() + typeParams[i].getName(), null);
- substitutor = substitutor.put(typeParams[i], JavaPsiFacade.getElementFactory(myExpression.getProject()).createType(params[i]));
- }
- else {
- params[i] = typeParams[i];
- }
- }
- PsiSubstitutor siteSubstitutor = PsiSubstitutor.EMPTY;
- if (method != null && !method.isConstructor()) {
- if (resolveResult instanceof MethodCandidateInfo) {
- siteSubstitutor = ((MethodCandidateInfo)resolveResult).getSiteSubstitutor();
- }
- else if (candidateProperties != null) {
- siteSubstitutor = candidateProperties.getSubstitutor();
- }
- }
- for (PsiTypeParameter typeParameter : siteSubstitutor.getSubstitutionMap().keySet()) {
- substitutor = substitutor.put(typeParameter, substitutor.substitute(siteSubstitutor.substitute(typeParameter)));
- }
-
- final Collection<PsiTypeParameter> params1 = session.getTypeParams();
- final InferenceSession callSession = new InferenceSession(params, substitutor, myExpression.getManager(), myExpression);
- callSession.initBounds(session.getContext(), params1.toArray(new PsiTypeParameter[params1.size()]));
+ final InferenceSession callSession = new InferenceSession(typeParams, PsiSubstitutor.EMPTY, myExpression.getManager(), myExpression);
+ callSession.propagateVariables(session.getInferenceVariables());
if (method != null) {
final PsiExpression[] args = argumentList.getExpressions();
final PsiParameter[] parameters = method.getParameterList().getParameters();
@@ -150,27 +120,12 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm
if (!accepted) {
return false;
}
- callSession.registerReturnTypeConstraints(
- method != null && !PsiUtil.isRawSubstitutor(method, siteSubstitutor) ? siteSubstitutor.substitute(returnType) : returnType,
- substitutor.substitute(returnType));
+ callSession.registerReturnTypeConstraints(returnType, myT);
if (callSession.repeatInferencePhases(true)) {
- final Collection<InferenceVariable> inferenceVariables = callSession.getInferenceVariables();
- if (sameMethodCall) {
- for (Iterator<InferenceVariable> iterator = inferenceVariables.iterator(); iterator.hasNext(); ) {
- InferenceVariable variable = iterator.next();
- if (oldBounds.contains(variable.getParameter())) {
- iterator.remove();
- }
- }
- }
- session.liftBounds(myExpression, inferenceVariables);
+ session.registerNestedSession(callSession);
} else {
return false;
}
- final PsiType capturedReturnType = myExpression instanceof PsiMethodCallExpression
- ? PsiMethodCallExpressionImpl.captureReturnType((PsiMethodCallExpression)myExpression, method, returnType, substitutor)
- : substitutor.substitute(returnType);
- constraints.add(new TypeCompatibilityConstraint(myT, capturedReturnType));
}
}
return true;
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/LambdaExpressionCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/LambdaExpressionCompatibilityConstraint.java
index cbed2ea59491..c282481e79c0 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/LambdaExpressionCompatibilityConstraint.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/LambdaExpressionCompatibilityConstraint.java
@@ -45,7 +45,7 @@ public class LambdaExpressionCompatibilityConstraint implements ConstraintFormul
constraints.add(new StrictSubtypingConstraint(myT, groundTargetType));
} else {
for (PsiParameter parameter : parameters) {
- if (!session.isProperType(substitutor.substitute(parameter.getType()))) {
+ if (!session.isProperType(session.substituteWithInferenceVariables(substitutor.substitute(parameter.getType())))) {
return false;
}
}
@@ -62,7 +62,7 @@ public class LambdaExpressionCompatibilityConstraint implements ConstraintFormul
if (returnExpressions.isEmpty() && !myExpression.isValueCompatible()) { //not value-compatible
return false;
}
- returnType = substitutor.substitute(returnType);
+ returnType = session.substituteWithInferenceVariables(substitutor.substitute(returnType));
if (!session.isProperType(returnType)) {
for (PsiExpression returnExpression : returnExpressions) {
constraints.add(new ExpressionCompatibilityConstraint(returnExpression, returnType));
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java
index eefd040b2a99..fbfd8195fc11 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java
@@ -93,11 +93,13 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
if (targetParameters.length == parameters.length + 1) {
specialCase(session, constraints, substitutor, targetParameters, true);
for (int i = 1; i < targetParameters.length; i++) {
- constraints.add(new TypeCompatibilityConstraint(psiSubstitutor.substitute(parameters[i - 1].getType()), substitutor.substitute(targetParameters[i].getType())));
+ constraints.add(new TypeCompatibilityConstraint(session.substituteWithInferenceVariables(psiSubstitutor.substitute(parameters[i - 1].getType())),
+ substitutor.substitute(targetParameters[i].getType())));
}
} else if (targetParameters.length == parameters.length) {
for (int i = 0; i < targetParameters.length; i++) {
- constraints.add(new TypeCompatibilityConstraint(psiSubstitutor.substitute(parameters[i].getType()), substitutor.substitute(targetParameters[i].getType())));
+ constraints.add(new TypeCompatibilityConstraint(session.substituteWithInferenceVariables(psiSubstitutor.substitute(parameters[i].getType())),
+ substitutor.substitute(targetParameters[i].getType())));
}
} else {
return false;
@@ -108,12 +110,13 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
}
if (applicableMethodReturnType != null) {
- constraints.add(new TypeCompatibilityConstraint(returnType, psiSubstitutor.substitute(applicableMethodReturnType)));
- } else if (applicableMember instanceof PsiClass || applicableMember instanceof PsiMethod && ((PsiMethod)applicableMember).isConstructor()) {
+ constraints.add(new TypeCompatibilityConstraint(returnType,
+ session.substituteWithInferenceVariables(psiSubstitutor.substitute(applicableMethodReturnType))));
+ }
+ else if (applicableMember instanceof PsiClass || applicableMember instanceof PsiMethod && ((PsiMethod)applicableMember).isConstructor()) {
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(applicableMember.getProject());
-
if (containingClass != null) {
- final PsiClassType classType = elementFactory.createType(containingClass, psiSubstitutor);
+ final PsiType classType = session.substituteWithInferenceVariables(elementFactory.createType(containingClass, psiSubstitutor));
constraints.add(new TypeCompatibilityConstraint(returnType, classType));
}
}
@@ -122,7 +125,7 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
}
final Map<PsiMethodReferenceExpression, PsiType> map = PsiMethodReferenceUtil.getFunctionalTypeMap();
- final PsiType added = map.put(myExpression, groundTargetType);
+ final PsiType added = map.put(myExpression, session.startWithFreshVars(groundTargetType));
final JavaResolveResult resolve;
try {
resolve = myExpression.advancedResolve(true);
@@ -205,7 +208,7 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
PsiPolyExpressionUtil.mentionsTypeParameters(referencedMethodReturnType, ContainerUtil.newHashSet(containingClass.getTypeParameters()))) { //todo specification bug?
specialCase(session, constraints, substitutor, targetParameters, false);
}
- constraints.add(new TypeCompatibilityConstraint(returnType, psiSubstitutor.substitute(referencedMethodReturnType)));
+ constraints.add(new TypeCompatibilityConstraint(returnType, session.substituteWithInferenceVariables(psiSubstitutor.substitute(referencedMethodReturnType))));
}
return true;
@@ -241,7 +244,8 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
final PsiClass qualifierClass = PsiUtil.resolveClassInType(qualifierType);
if (qualifierClass != null) {
session.initBounds(qualifierClass.getTypeParameters());
- constraints.add(new StrictSubtypingConstraint(qualifierType, substitutor.substitute(targetParameters[0].getType())));
+ constraints.add(new StrictSubtypingConstraint(session.substituteWithInferenceVariables(qualifierType),
+ session.substituteWithInferenceVariables(substitutor.substitute(targetParameters[0].getType()))));
}
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/MethodReferenceResolver.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/MethodReferenceResolver.java
index 29525add1549..661d59105046 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/MethodReferenceResolver.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/MethodReferenceResolver.java
@@ -68,7 +68,7 @@ public class MethodReferenceResolver implements ResolveCache.PolyVariantContextR
if (interfaceMethod != null) {
final PsiClassType returnType = composeReturnType(containingClass, substitutor);
final InferenceSession session = new InferenceSession(containingClass.getTypeParameters(), substitutor, reference.getManager(), null);
- if (!(session.isProperType(returnType) && session.isProperType(interfaceMethodReturnType))) {
+ if (!(session.isProperType(session.substituteWithInferenceVariables(returnType)) && session.isProperType(interfaceMethodReturnType))) {
session.registerReturnTypeConstraints(returnType, interfaceMethodReturnType);
substitutor = session.infer();
}
@@ -116,13 +116,6 @@ public class MethodReferenceResolver implements ResolveCache.PolyVariantContextR
private PsiSubstitutor inferTypeArguments() {
if (interfaceMethod == null) return substitutor;
final InferenceSession session = new InferenceSession(method.getTypeParameters(), substitutor, reference.getManager(), reference);
-
- //lift parameters from outer call
- final CurrentCandidateProperties methodSubstitutorPair = MethodCandidateInfo.getCurrentMethod(reference.getParent());
- if (methodSubstitutorPair != null) {
- session.initBounds(methodSubstitutorPair.getMethod().getTypeParameters());
- }
-
final PsiSubstitutor psiSubstitutor = session.collectApplicabilityConstraints(reference, this, functionalInterfaceType);
if (psiSubstitutor != null) {
return psiSubstitutor;
@@ -133,6 +126,10 @@ public class MethodReferenceResolver implements ResolveCache.PolyVariantContextR
}
if (interfaceMethodReturnType != PsiType.VOID && interfaceMethodReturnType != null) {
+ if (method.isConstructor()) {
+ //todo
+ session.initBounds(reference, method.getContainingClass().getTypeParameters());
+ }
final PsiType returnType = method.isConstructor() ? composeReturnType(containingClass, substitutor) : method.getReturnType();
if (returnType != null) {
session.registerReturnTypeConstraints(returnType, interfaceMethodReturnType);
diff --git a/java/java-runtime/src/com/intellij/rt/debugger/DefaultMethodInvoker.java b/java/java-runtime/src/com/intellij/rt/debugger/DefaultMethodInvoker.java
new file mode 100644
index 000000000000..da01203c09f7
--- /dev/null
+++ b/java/java-runtime/src/com/intellij/rt/debugger/DefaultMethodInvoker.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.rt.debugger;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * @author egor
+ */
+public class DefaultMethodInvoker {
+
+ // only methods without arguments for now
+ public static Object invoke(Object obj, String name)
+ throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+
+ Method method = obj.getClass().getMethod(name, null);
+ if (method != null) {
+ method.setAccessible(true);
+ Object res = method.invoke(obj, null);
+ method.setAccessible(false);
+ return res;
+ }
+ return null;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/completion/keywords/finalInCatch.java b/java/java-tests/testData/codeInsight/completion/keywords/finalInCatch.java
new file mode 100644
index 000000000000..6346b73dd045
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completion/keywords/finalInCatch.java
@@ -0,0 +1,7 @@
+public class StructuredConfigKey {
+ {
+ try {
+
+ } catch (<caret>)
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/completion/keywords/finalInIncompleteCatch.java b/java/java-tests/testData/codeInsight/completion/keywords/finalInIncompleteCatch.java
new file mode 100644
index 000000000000..0cdeb4962618
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completion/keywords/finalInIncompleteCatch.java
@@ -0,0 +1,7 @@
+public class StructuredConfigKey {
+ {
+ try {
+
+ } catch (<caret>
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/completion/smartType/SuggestTypeParametersInTypeArgumentList.java b/java/java-tests/testData/codeInsight/completion/smartType/SuggestTypeParametersInTypeArgumentList.java
new file mode 100644
index 000000000000..0bc90adbf7a3
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completion/smartType/SuggestTypeParametersInTypeArgumentList.java
@@ -0,0 +1,8 @@
+class StringEx<T extends String> {
+}
+class Outer<T extends String> {
+ static class CompletionTest<T extends String> {
+ private StringEx<<caret>> myString;
+ }
+}
+
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/ParameterBoundsWithCapturedWildcard.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/ParameterBoundsWithCapturedWildcard.java
new file mode 100644
index 000000000000..c7cb266321c5
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/ParameterBoundsWithCapturedWildcard.java
@@ -0,0 +1,5 @@
+class Test<T > {
+ public static interface EventListener<V extends String> {}
+ public void addListener (EventListener<<error descr="Type parameter '? extends T' is not within its bound; should extend 'java.lang.String'">? extends T</error>> listener) {}
+ public void addListener1(EventListener<? super T> listener) {}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/SuperCaptureSubstitutionWhenTypeParameterHasUpperBounds.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/SuperCaptureSubstitutionWhenTypeParameterHasUpperBounds.java
new file mode 100644
index 000000000000..4eaf810dad4f
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/SuperCaptureSubstitutionWhenTypeParameterHasUpperBounds.java
@@ -0,0 +1,30 @@
+class Test<T > {
+ interface Event{}
+
+ interface EventListener<V extends Event> {
+ void handleEvent(V event);
+ }
+
+ public void addListener(EventListener<? super T> listener) {
+ EventListener<? extends Event> localListener = listener;
+ <error descr="Incompatible types. Found: 'Test.EventListener<capture<? super T>>', required: 'Test.EventListener<? super Test.Event>'">EventListener<? super Event> localListener1 = listener;</error>
+ }
+}
+
+class Test1 {
+
+ public static class Entity<E extends Entity<E>> {
+
+ public final <T, V extends EntityVisitor<? super E, T>> T handle(final V visitor) {
+ return visitor.handle(this);
+ }
+
+ }
+
+ public interface EntityVisitor<E extends Entity<E>, T> {
+
+ T handle(Entity<? extends E> e);
+
+ }
+
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA110947.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA110947.java
index 5f7ac80942a2..e895159a5762 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA110947.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA110947.java
@@ -9,7 +9,7 @@ abstract class ProcedureService {
abstract <C extends Command<Result>> Class<? extends Procedure<Command<Result>>> getProcedure(Class<C> cmd);
public <C extends Command<Result>> void execute(Class<? extends Command> aClass) {
- Class<Procedure<Command<Result>>> procedureClass = getProcedure(aClass);
+ <error descr="Incompatible types. Found: 'java.lang.Class<capture<? extends Procedure<Command<Result>>>>', required: 'java.lang.Class<Procedure<Command<Result>>>'">Class<Procedure<Command<Result>>> procedureClass = getProcedure(aClass);</error>
<error descr="Incompatible types. Found: 'java.lang.Class<capture<? extends Command>>', required: 'java.lang.Class<Command>'">Class<Command> c = aClass;</error>
<error descr="Incompatible types. Found: 'java.lang.Class<capture<? extends Command>>', required: 'java.lang.Class<C>'">Class<C> c1 = aClass;</error>
}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA128333.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA128333.java
new file mode 100644
index 000000000000..24bc5b3ab1fe
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA128333.java
@@ -0,0 +1,24 @@
+import java.util.*;
+import java.lang.annotation.Annotation;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+abstract class WithAnn {
+
+ {
+ map((Class<? extends Annotation> ann) -> getAnnotation(ann));
+ map(this::getAnnotation);
+ }
+
+ abstract <A> A getAnnotation(Class<A> annotationClass);
+ abstract <R> void map(Function<Class<? extends Annotation>, ? extends R> mapper);
+}
+
+class Test {
+ private void it(final Set<Class<? extends String>> set) {
+ set.forEach((clazz) -> bind(clazz));
+ }
+
+ protected <T> void bind(Class<T> clazz) {}
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SuperWildcardWithBoundPromotion.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SuperWildcardWithBoundPromotion.java
index f1a533020e34..33dd56b27183 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SuperWildcardWithBoundPromotion.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SuperWildcardWithBoundPromotion.java
@@ -20,7 +20,7 @@ class Bug2<T extends Integer>{
}
void bug1(Parametrized<? super T> param) {
- <error descr="Inferred type 'capture<? super T>' for type parameter 'I' is not within its bound; should extend 'java.lang.Number'">foo(param)</error>;
+ foo(param);
}
@@ -35,7 +35,7 @@ class Test {
}
void bug1(Parametrized<? super T> param) {
- <error descr="Inferred type 'java.io.Serializable' for type parameter 'I' is not within its bound; should extend 'java.lang.Number'">foo(param)</error>;
+ <error descr="Inferred type 'capture<? super T>' for type parameter 'I' is not within its bound; should extend 'java.lang.Number'">foo(param)</error>;
}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/WildcardsBoundsIntersection.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/WildcardsBoundsIntersection.java
index 6385fe5d125e..cf8ad1c9fb9f 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/WildcardsBoundsIntersection.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/WildcardsBoundsIntersection.java
@@ -10,6 +10,6 @@ class Node<NodeTypeT extends NodeType> {
class Main {
public static void main(NodeProperty<NumberExpression, Integer> nval, Node<? extends NodeType> expr) {
- int val = expr.get<error descr="'get(NodeProperty<? super capture<? extends NodeType>,java.lang.Integer>)' in 'Node' cannot be applied to '(NodeProperty<NumberExpression,java.lang.Integer>)'">(nval)</error>;
+ int val = expr.get<error descr="'get(NodeProperty<? super capture<? extends NodeType>,java.lang.Object>)' in 'Node' cannot be applied to '(NodeProperty<NumberExpression,java.lang.Integer>)'">(nval)</error>;
}
}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/CyclicParamsDependency.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/CyclicParamsDependency.java
new file mode 100644
index 000000000000..927165e23e9c
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/CyclicParamsDependency.java
@@ -0,0 +1,18 @@
+import java.util.List;
+
+class Sample {
+ <T extends List<K>, K extends List<T>> T foo(){
+ <error descr="Incompatible types. Found: 'K', required: 'T'">T t = foo().get(0);</error>
+ <error descr="Incompatible types. Found: 'K', required: 'K'">K k = foo().get(0);</error>
+
+ <error descr="Incompatible types. Found: 'T', required: 'T'">T t1 = foo().get(0).get(0);</error>
+
+ String s = foo();
+ <error descr="Incompatible types. Found: 'K', required: 'java.lang.String'">String s1 = foo().get(0);</error>
+ return null;
+ }
+
+ {
+ foo();
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/IDEA126163.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/IDEA126163.java
new file mode 100644
index 000000000000..7869663fb863
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/IDEA126163.java
@@ -0,0 +1,29 @@
+class Test {
+
+ public static void main( String[] args ) throws Exception {
+ Checker.assertThat("", Utils.is(Utils.notNullValue()));
+ }
+}
+
+interface Util<T> {
+}
+
+class Utils {
+ static <T> Util<T> is( Util<T> util ) {
+ return null;
+ }
+
+ static <T> Util<T> is( T t ) {
+ return null;
+ }
+
+ static <T> Util<T> notNullValue() {
+ return null;
+ }
+}
+
+class Checker {
+ static <T> void assertThat(T actual, Util<T> util) {
+ }
+}
+
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/IDEA128101.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/IDEA128101.java
index 42be49b62f04..ac00e0bae517 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/IDEA128101.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/IDEA128101.java
@@ -22,8 +22,8 @@ class TestIDEA128101 {
construct(String.class, createPath(integerAttribute), createPath(stringAttribute));
construct1<error descr="Cannot resolve method 'construct1(java.lang.Class<java.lang.String>, TestIDEA128101.Path<java.lang.Integer>, TestIDEA128101.Path<java.lang.String>)'">(String.class, createPath(integerAttribute), createPath(stringAttribute))</error>;
construct2(String.class, createPath(integerAttribute), createPath(stringAttribute));
- <error descr="Type parameter K has incompatible upper bounds: Integer and String">construct3(String.class, createPath(integerAttribute), createPath(stringAttribute));</error>
- <error descr="Type parameter K has incompatible upper bounds: Integer and String">construct4(String.class, createPath(integerAttribute), createPath(stringAttribute));</error>
+ construct3<error descr="Cannot resolve method 'construct3(java.lang.Class<java.lang.String>, TestIDEA128101.Path<java.lang.Integer>, TestIDEA128101.Path<java.lang.String>)'">(String.class, createPath(integerAttribute), createPath(stringAttribute))</error>;
+ construct4(String.class, createPath(integerAttribute), createPath<error descr="'createPath(TestIDEA128101.Attribute<Y>)' in 'TestIDEA128101' cannot be applied to '(TestIDEA128101.Attribute<java.lang.String>)'">(stringAttribute)</error>);
}
}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/IDEA128766.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/IDEA128766.java
new file mode 100644
index 000000000000..715b158d2cdd
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/IDEA128766.java
@@ -0,0 +1,21 @@
+class Test {
+
+ static class TKey<T> {}
+
+ public interface Getter {
+ <T> T getValue(TKey<T> key);
+ }
+
+ public static <TK extends TKey<?>> TK getAKey(TK tKeySuffix) {
+ return tKeySuffix;
+ }
+
+ static final TKey<Double> KEY_D = new TKey<>();
+ public static void f(Getter getter) {
+ double d1 = getter.getValue(KEY_D);
+ double d2 = getter.getValue(getAKey(KEY_D));
+ TKey<Double> aKey = getAKey(KEY_D);
+ double d3 = getter.getValue(aKey);
+ }
+}
+
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/InfiniteTypes.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/InfiniteTypes.java
new file mode 100644
index 000000000000..2f6d975261e4
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/InfiniteTypes.java
@@ -0,0 +1,9 @@
+class Test {
+
+ public static void main(String[] args) {
+ multiBound("test");
+ multiBound(null);
+ }
+
+ static <E extends Comparable<E> & CharSequence> void multiBound(E e) {}
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/SOEDuringInferenceFromParamBounds.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/SOEDuringInferenceFromParamBounds.java
index 3f26bbc1ef56..90e8efb23b5d 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/SOEDuringInferenceFromParamBounds.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/SOEDuringInferenceFromParamBounds.java
@@ -3,5 +3,5 @@ import java.util.Map;
public class SOE {
public static <K extends M, M extends Map<K,M>> M foo() {return null;}
- public static <K1 extends M1, M1 extends Map<K1,M1>> Map<K1, M1> foo1() {return <error descr="Inferred type 'java.util.Map<K1,M1>' for type parameter 'M' is not within its bound; should implement 'java.util.Map<java.util.Map<K1,M1>,java.util.Map<K1,M1>>'">foo()</error>;}
+ public static <K1 extends M1, M1 extends Map<K1,M1>> Map<K1, M1> foo1() {<error descr="Incompatible types. Found: 'M', required: 'java.util.Map<K1,M1>'">return foo();</error>}
}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/SameMethodNestedChainedCallsNearFunctionInterfaces.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/SameMethodNestedChainedCallsNearFunctionInterfaces.java
new file mode 100644
index 000000000000..d8e931915013
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/SameMethodNestedChainedCallsNearFunctionInterfaces.java
@@ -0,0 +1,87 @@
+import java.util.*;
+import java.util.function.BiFunction;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+class Test
+{
+ public static class K<T>
+ {
+ private final T head;
+ private final K<T> tail;
+
+ public K(T head, K<T> tail)
+ {
+ this.head = head;
+ this.tail = tail;
+ }
+ }
+
+ public static class P<U>
+ {
+ public <B, C> P<C> biMap(P<B> that, BiFunction<U, B, C> f)
+ {
+ return null;
+ }
+ }
+
+ public static <A> P<K<A>> f(K<P<A>> x)
+ {
+ return x.head.biMap(f(x.tail), K::new);
+ }
+}
+
+class A<T>
+{
+ public A(Supplier<T> arg0, Supplier<A<T>> arg1){}
+
+ static <S> A<S> make(S[] s)
+ {
+ return helpMake(0, s);
+ }
+
+ static <S> A<S> helpMake(int offset, S[] s)
+ {
+ return new A<>(() -> s[offset], () -> helpMake(offset + 1, s));
+ }
+}
+
+interface MultivaluedMap<K, V> extends Map<K, List<V>> {
+
+ void putSingle(K var1, V var2);
+
+ void add(K var1, V var2);
+
+ V getFirst(K var1);
+}
+
+
+class Headers {
+ private final Map<String, List<String>> headers;
+
+ public Headers(Map<String, List<String>> headers) {
+ this.headers = headers;
+ }
+
+ public Headers(MultivaluedMap<String, Object> multimap) {
+ this.headers = multimap.entrySet()
+ .stream()
+ .collect(
+ Collectors.toMap(
+ Map.Entry::getKey,
+ x -> x.getValue()
+ .stream()
+ .map(Object::toString)
+ .collect(Collectors.toList())
+ )
+ );
+ }
+}
+
+class IDEA128245 {
+ public void testCollectors(final Stream<Map.Entry<String, Set<String>>> stream,
+ Stream<Integer> integerStream) {
+ stream.collect(Collectors.toMap(Map.Entry::getKey, entry -> integerStream.collect(Collectors.toSet())));
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/AdditionalConstraints3Level.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/AdditionalConstraints3Level.java
new file mode 100644
index 000000000000..3e4ef6f955e5
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/AdditionalConstraints3Level.java
@@ -0,0 +1,15 @@
+import java.util.List;
+import java.util.function.Function;
+
+abstract class Sample {
+ abstract <T> T id (T t);
+ abstract <R> void foo(List<R> c);
+ abstract <U> List<U> bar(Function<String, U> m);
+
+ {
+ foo(bar(this::id));
+ foo(bar(id(i -> i)));
+
+ Function<String, String> s = id(this::id);
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/WildcardParametrization.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/WildcardParametrization.java
new file mode 100644
index 000000000000..d1adfe4a9ee1
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/WildcardParametrization.java
@@ -0,0 +1,19 @@
+
+import java.util.function.Function;
+
+class IdeaTest {
+ class Test<K>{}
+
+ public void checkAnnotationsPresent() {
+ Function<Test<? extends Annotation>, Annotation> mapper = this::getAnnotation;
+ Function<Test<? extends Annotation>, ? extends Annotation> mapper1 = this::getAnnotation;
+ }
+
+ public <A extends Annotation> A getAnnotation(Test<A> annotationClass) {
+ return null;
+ }
+
+ static class Annotation{}
+
+
+}
diff --git a/java/java-tests/testData/codeInsight/typing/fixIfByBraceCompositeCondition_after.java b/java/java-tests/testData/codeInsight/typing/fixIfByBraceCompositeCondition_after.java
new file mode 100644
index 000000000000..d57959a1485a
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/typing/fixIfByBraceCompositeCondition_after.java
@@ -0,0 +1,5 @@
+class C {
+ boolean f() {
+ if (f() && new Object(){<caret>)
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/typing/fixIfByBraceCompositeCondition_before.java b/java/java-tests/testData/codeInsight/typing/fixIfByBraceCompositeCondition_before.java
new file mode 100644
index 000000000000..9718c041c2e0
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/typing/fixIfByBraceCompositeCondition_before.java
@@ -0,0 +1,5 @@
+class C {
+ boolean f() {
+ if (f() && new Object()<caret>)
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/typing/fixIfByBraceNewObject_after.java b/java/java-tests/testData/codeInsight/typing/fixIfByBraceNewObject_after.java
new file mode 100644
index 000000000000..f85e4d676ead
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/typing/fixIfByBraceNewObject_after.java
@@ -0,0 +1,5 @@
+class C {
+ boolean f() {
+ if (new Object(){<caret>)
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/typing/fixIfByBraceNewObject_before.java b/java/java-tests/testData/codeInsight/typing/fixIfByBraceNewObject_before.java
new file mode 100644
index 000000000000..f536c7eba9a3
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/typing/fixIfByBraceNewObject_before.java
@@ -0,0 +1,5 @@
+class C {
+ boolean f() {
+ if (new Object()<caret>)
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/typing/fixIfByBrace_after.java b/java/java-tests/testData/codeInsight/typing/fixIfByBrace_after.java
new file mode 100644
index 000000000000..f17312c07aa6
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/typing/fixIfByBrace_after.java
@@ -0,0 +1,7 @@
+class C {
+ boolean f() {
+ if (f()) {
+ <caret>
+ }
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/typing/fixIfByBrace_before.java b/java/java-tests/testData/codeInsight/typing/fixIfByBrace_before.java
new file mode 100644
index 000000000000..017a62e874f3
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/typing/fixIfByBrace_before.java
@@ -0,0 +1,5 @@
+class C {
+ boolean f() {
+ if (f()<caret>)
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/typing/fixWhileByBrace_after.java b/java/java-tests/testData/codeInsight/typing/fixWhileByBrace_after.java
new file mode 100644
index 000000000000..92e28bfe1542
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/typing/fixWhileByBrace_after.java
@@ -0,0 +1,7 @@
+class C {
+ boolean f() {
+ while (f()) {
+ <caret>
+ }
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/typing/fixWhileByBrace_before.java b/java/java-tests/testData/codeInsight/typing/fixWhileByBrace_before.java
new file mode 100644
index 000000000000..a254dee776db
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/typing/fixWhileByBrace_before.java
@@ -0,0 +1,5 @@
+class C {
+ boolean f() {
+ while (f()<caret>)
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/awt/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/awt/annotations.xml
index 0314b02a4d7b..2e75eb0e3c6c 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/awt/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/awt/annotations.xml
@@ -1,4 +1,10 @@
<root>
+ <item name="java.awt.Component boolean action(java.awt.Event, java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Component boolean action(java.awt.Event, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.awt.Component boolean action(java.awt.Event, java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;false;_,!null-&gt;false;_,null-&gt;false;null,_-&gt;false&quot;"/>
@@ -18,6 +24,12 @@
<item name="java.awt.Component boolean eventEnabled(java.awt.AWTEvent) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.awt.Component boolean gotFocus(java.awt.Event, java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Component boolean gotFocus(java.awt.Event, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.awt.Component boolean gotFocus(java.awt.Event, java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;false;_,!null-&gt;false;_,null-&gt;false;null,_-&gt;false&quot;"/>
@@ -26,46 +38,85 @@
<item name="java.awt.Component boolean handleEvent(java.awt.Event) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.awt.Component boolean imageUpdate(java.awt.Image, int, int, int, int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Component boolean isFocusCycleRoot(java.awt.Container) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Component boolean isSameOrAncestorOf(java.awt.Component, boolean) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Component boolean keyDown(java.awt.Event, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.awt.Component boolean keyDown(java.awt.Event, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;false;null,_-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="java.awt.Component boolean keyUp(java.awt.Event, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.awt.Component boolean keyUp(java.awt.Event, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;false;null,_-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="java.awt.Component boolean lostFocus(java.awt.Event, java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Component boolean lostFocus(java.awt.Event, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.awt.Component boolean lostFocus(java.awt.Event, java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;false;_,!null-&gt;false;_,null-&gt;false;null,_-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="java.awt.Component boolean mouseDown(java.awt.Event, int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.awt.Component boolean mouseDown(java.awt.Event, int, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_,_-&gt;false;null,_,_-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="java.awt.Component boolean mouseDrag(java.awt.Event, int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.awt.Component boolean mouseDrag(java.awt.Event, int, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_,_-&gt;false;null,_,_-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="java.awt.Component boolean mouseEnter(java.awt.Event, int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.awt.Component boolean mouseEnter(java.awt.Event, int, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_,_-&gt;false;null,_,_-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="java.awt.Component boolean mouseExit(java.awt.Event, int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.awt.Component boolean mouseExit(java.awt.Event, int, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_,_-&gt;false;null,_,_-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="java.awt.Component boolean mouseMove(java.awt.Event, int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.awt.Component boolean mouseMove(java.awt.Event, int, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_,_-&gt;false;null,_,_-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="java.awt.Component boolean mouseUp(java.awt.Event, int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.awt.Component boolean mouseUp(java.awt.Event, int, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_,_-&gt;false;null,_,_-&gt;false&quot;"/>
@@ -93,6 +144,9 @@
<item name="java.awt.Component java.awt.Dimension getMaximumSize()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.awt.Component java.awt.Dimension getSize(java.awt.Dimension) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.awt.Component java.awt.Dimension getSize(java.awt.Dimension)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null;null-&gt;!null&quot;"/>
@@ -107,6 +161,9 @@
<item name="java.awt.Component java.awt.Dimension size()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.awt.Component java.awt.Point getLocation(java.awt.Point) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.awt.Component java.awt.Point getLocation(java.awt.Point)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null;null-&gt;!null&quot;"/>
@@ -124,6 +181,9 @@
<item name="java.awt.Component java.awt.Rectangle bounds()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.awt.Component java.awt.Rectangle getBounds(java.awt.Rectangle) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.awt.Component java.awt.Rectangle getBounds(java.awt.Rectangle)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null;null-&gt;!null&quot;"/>
@@ -134,6 +194,9 @@
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="java.awt.Component java.awt.image.VolatileImage createVolatileImage(int, int, java.awt.ImageCapabilities) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.awt.Component java.lang.String paramString()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -146,9 +209,48 @@
<item name="java.awt.Component void add(java.awt.PopupMenu) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.awt.Component void addComponentListener(java.awt.event.ComponentListener) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Component void addFocusListener(java.awt.event.FocusListener) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Component void addHierarchyBoundsListener(java.awt.event.HierarchyBoundsListener) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Component void addHierarchyListener(java.awt.event.HierarchyListener) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Component void addInputMethodListener(java.awt.event.InputMethodListener) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Component void addKeyListener(java.awt.event.KeyListener) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Component void addMouseListener(java.awt.event.MouseListener) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Component void addMouseMotionListener(java.awt.event.MouseMotionListener) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Component void addMouseWheelListener(java.awt.event.MouseWheelListener) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Component void addPropertyChangeListener(java.beans.PropertyChangeListener) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Component void addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.awt.Component void applyComponentOrientation(java.awt.ComponentOrientation) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.awt.Component void autoProcessMouseWheel(java.awt.event.MouseWheelEvent) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Component void checkGD(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.awt.Component void createBufferStrategy(int, java.awt.BufferCapabilities) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -161,9 +263,54 @@
<item name="java.awt.Component void list(java.io.PrintWriter, int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.awt.Component void paint(java.awt.Graphics) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Component void paintHeavyweightComponents(java.awt.Graphics) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Component void printHeavyweightComponents(java.awt.Graphics) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Component void processEvent(java.awt.AWTEvent) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.awt.Component void readObject(java.io.ObjectInputStream) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.awt.Component void removeComponentListener(java.awt.event.ComponentListener) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Component void removeFocusListener(java.awt.event.FocusListener) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Component void removeHierarchyBoundsListener(java.awt.event.HierarchyBoundsListener) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Component void removeHierarchyListener(java.awt.event.HierarchyListener) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Component void removeInputMethodListener(java.awt.event.InputMethodListener) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Component void removeKeyListener(java.awt.event.KeyListener) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Component void removeMouseListener(java.awt.event.MouseListener) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Component void removeMouseMotionListener(java.awt.event.MouseMotionListener) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Component void removeMouseWheelListener(java.awt.event.MouseWheelListener) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Component void removePropertyChangeListener(java.beans.PropertyChangeListener) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Component void removePropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.awt.Component void resize(java.awt.Dimension) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -185,16 +332,28 @@
<item name="java.awt.Container boolean eventEnabled(java.awt.AWTEvent) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.awt.Container boolean isAncestorOf(java.awt.Component) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.awt.Container boolean isAncestorOf(java.awt.Component)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="java.awt.Container boolean isFocusCycleRoot(java.awt.Container) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Container boolean isRemoveNotifyNeeded(java.awt.Component, java.awt.Container, java.awt.Container) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.awt.Container boolean isRemoveNotifyNeeded(java.awt.Component, java.awt.Container, java.awt.Container)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,_,null-&gt;false;_,null,_-&gt;false;null,_,_-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="java.awt.Container int getComponentZOrder(java.awt.Component) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.awt.Container java.awt.Component add(java.awt.Component)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null;null-&gt;null&quot;"/>
@@ -225,12 +384,21 @@
<item name="java.awt.Container java.lang.String paramString()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.awt.Container void addContainerListener(java.awt.event.ContainerListener) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.awt.Container void addDelicately(java.awt.Component, java.awt.Container, int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.awt.Container void addImpl(java.awt.Component, java.lang.Object, int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.awt.Container void addPropertyChangeListener(java.beans.PropertyChangeListener) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Container void addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.awt.Container void applyComponentOrientation(java.awt.ComponentOrientation) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -252,15 +420,24 @@
<item name="java.awt.Container void list(java.io.PrintWriter, int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.awt.Container void processEvent(java.awt.AWTEvent) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.awt.Container void readObject(java.io.ObjectInputStream) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.awt.Container void remove(java.awt.Component) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.awt.Container void removeContainerListener(java.awt.event.ContainerListener) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.awt.Container void removeDelicately(java.awt.Component, java.awt.Container, int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.awt.Container void reparentChild(java.awt.Component) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.awt.Container void reparentTraverse(java.awt.peer.ContainerPeer, java.awt.Container) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -273,6 +450,9 @@
<item name="java.awt.Dimension Dimension(java.awt.Dimension) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.awt.Dimension boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.awt.Dimension boolean equals(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -290,6 +470,9 @@
<item name="java.awt.Frame java.lang.String constructComponentName()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.awt.Frame void init(java.lang.String, java.awt.GraphicsConfiguration) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.awt.Frame void readObject(java.io.ObjectInputStream) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -305,6 +488,9 @@
<item name="java.awt.Window Window(java.awt.Window, java.awt.GraphicsConfiguration) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.awt.Window boolean dispatchMouseWheelToAncestor(java.awt.event.MouseWheelEvent) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.awt.Window boolean dispatchMouseWheelToAncestor(java.awt.event.MouseWheelEvent)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;false;null-&gt;false&quot;"/>
@@ -324,21 +510,63 @@
<item name="java.awt.Window java.lang.String constructComponentName()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.awt.Window void addOwnedWindow(java.lang.ref.WeakReference) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Window void addPropertyChangeListener(java.beans.PropertyChangeListener) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Window void addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Window void addWindowFocusListener(java.awt.event.WindowFocusListener) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Window void addWindowListener(java.awt.event.WindowListener) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Window void addWindowStateListener(java.awt.event.WindowStateListener) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.awt.Window void connectOwnedWindow(java.awt.Window) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.awt.Window void deliverMouseWheelToAncestor(java.awt.event.MouseWheelEvent) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.awt.Window void dispatchEventImpl(java.awt.AWTEvent) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.awt.Window void ownedInit(java.awt.Window) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.awt.Window void postProcessKeyEvent(java.awt.event.KeyEvent) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.awt.Window void preProcessKeyEvent(java.awt.event.KeyEvent) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.awt.Window void processEvent(java.awt.AWTEvent) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.awt.Window void readObject(java.io.ObjectInputStream) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.awt.Window void removeOwnedWindow(java.lang.ref.WeakReference) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Window void removeWindowFocusListener(java.awt.event.WindowFocusListener) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Window void removeWindowListener(java.awt.event.WindowListener) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Window void removeWindowStateListener(java.awt.event.WindowStateListener) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.awt.Window void setCursor(java.awt.Cursor) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.awt.Window void writeObject(java.io.ObjectOutputStream) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/beans/beancontext/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/beans/beancontext/annotations.xml
index 60214de88d04..ce4e092e389f 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/beans/beancontext/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/beans/beancontext/annotations.xml
@@ -43,6 +43,9 @@
<item name="java.beans.beancontext.BeanContextServicesSupport void bcsPreSerializationHook(java.io.ObjectOutputStream) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.beans.beancontext.BeanContextServicesSupport void childJustRemovedHook(java.lang.Object, java.beans.beancontext.BeanContextSupport.BCSChild) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.beans.beancontext.BeanContextServicesSupport void childJustRemovedHook(java.lang.Object, java.beans.beancontext.BeanContextSupport.BCSChild) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/io/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/io/annotations.xml
index 868b0f3f11c0..521adcf48636 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/io/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/io/annotations.xml
@@ -62,6 +62,9 @@
<item name="java.io.DataInputStream void readFully(byte[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.io.File File(java.io.File, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.io.File File(java.io.File, java.lang.String) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -71,12 +74,21 @@
<item name="java.io.File File(java.lang.String, java.io.File) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.io.File File(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.io.File File(java.lang.String, java.lang.String) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.io.File File(java.net.URI) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.io.File boolean checkAndCreate(java.lang.String, java.lang.SecurityManager) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.io.File boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.io.File boolean equals(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -85,15 +97,33 @@
<item name="java.io.File java.io.File createTempFile(java.lang.String, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.io.File java.io.File createTempFile(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.io.File java.io.File createTempFile(java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.io.File java.io.File createTempFile(java.lang.String, java.lang.String, java.io.File) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.io.File java.io.File createTempFile(java.lang.String, java.lang.String, java.io.File) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.io.File java.io.File createTempFile(java.lang.String, java.lang.String, java.io.File) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.io.File java.io.File createTempFile(java.lang.String, java.lang.String, java.io.File)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.io.File java.io.File generateFile(java.lang.String, java.lang.String, java.io.File) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.io.File java.io.File generateFile(java.lang.String, java.lang.String, java.io.File) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.io.File java.io.File generateFile(java.lang.String, java.lang.String, java.io.File) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.io.File java.io.File generateFile(java.lang.String, java.lang.String, java.io.File)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -103,12 +133,26 @@
<item name="java.io.File java.io.File getCanonicalFile()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.io.File java.io.File[] listFiles(java.io.FileFilter) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.io.File java.io.File[] listFiles(java.io.FilenameFilter) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.io.File java.lang.String getName()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.io.File java.lang.String slashify(java.lang.String, boolean) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.io.File java.lang.String slashify(java.lang.String, boolean)">
+ <annotation name="org.jetbrains.annotations.Contract">
+ <val val="&quot;!null,_-&gt;!null&quot;"/>
+ </annotation>
+ </item>
+ <item name="java.io.File java.lang.String[] list(java.io.FilenameFilter) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.io.File java.net.URI toURI()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -124,21 +168,45 @@
<item name="java.io.FileInputStream FileInputStream(java.io.FileDescriptor) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.io.FileInputStream FileInputStream(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.io.FileInputStream int read(byte[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.io.FileNotFoundException FileNotFoundException(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.io.FileNotFoundException FileNotFoundException(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.io.FileOutputStream FileOutputStream(java.io.FileDescriptor) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.io.FileOutputStream FileOutputStream(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.io.FileOutputStream FileOutputStream(java.lang.String, boolean) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.io.FileOutputStream void write(byte[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.io.FileReader FileReader(java.io.FileDescriptor) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.io.FileReader FileReader(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.io.FileWriter FileWriter(java.io.FileDescriptor) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.io.FileWriter FileWriter(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.io.FileWriter FileWriter(java.lang.String, boolean) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.io.FilterOutputStream void write(byte[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -213,6 +281,9 @@
<item name="java.io.ObjectInputStream void access$500(java.io.ObjectInputStream) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.io.ObjectInputStream void defaultReadFields(java.lang.Object, java.io.ObjectStreamClass) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.io.ObjectInputStream void defaultReadFields(java.lang.Object, java.io.ObjectStreamClass) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -225,6 +296,9 @@
<item name="java.io.ObjectInputStream void readFully(byte[], int, int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.io.ObjectInputStream void readSerialData(java.lang.Object, java.io.ObjectStreamClass) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.io.ObjectInputStream void readSerialData(java.lang.Object, java.io.ObjectStreamClass) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -239,6 +313,12 @@
<item name="java.io.ObjectOutputStream void access$100(java.io.ObjectOutputStream, java.lang.Object, boolean) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.io.ObjectOutputStream void annotateClass(java.lang.Class) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.io.ObjectOutputStream void annotateProxyClass(java.lang.Class) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.io.ObjectOutputStream void defaultWriteFields(java.lang.Object, java.io.ObjectStreamClass) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -254,6 +334,9 @@
<item name="java.io.ObjectOutputStream void writeArray(java.lang.Object, java.io.ObjectStreamClass, boolean) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.io.ObjectOutputStream void writeClassDesc(java.io.ObjectStreamClass, boolean) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.io.ObjectOutputStream void writeClassDescriptor(java.io.ObjectStreamClass) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -269,6 +352,9 @@
<item name="java.io.ObjectOutputStream void writeNonProxyDesc(java.io.ObjectStreamClass, boolean) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.io.ObjectOutputStream void writeObjectOverride(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.io.ObjectOutputStream void writeOrdinaryObject(java.lang.Object, java.io.ObjectStreamClass, boolean) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -278,6 +364,9 @@
<item name="java.io.ObjectOutputStream void writeSerialData(java.lang.Object, java.io.ObjectStreamClass) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.io.ObjectOutputStream void writeTypeString(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.io.OutputStream void write(byte[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -323,24 +412,54 @@
<item name="java.io.PrintStream PrintStream(java.io.OutputStream, boolean, java.lang.String) 2">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.io.PrintStream PrintStream(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.io.PrintStream PrintStream(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.io.PrintStream PrintStream(java.lang.String, java.lang.String) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.io.PrintStream java.io.PrintStream append(char)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.io.PrintStream java.io.PrintStream append(java.lang.CharSequence) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.io.PrintStream java.io.PrintStream append(java.lang.CharSequence)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.io.PrintStream java.io.PrintStream append(java.lang.CharSequence, int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.io.PrintStream java.io.PrintStream append(java.lang.CharSequence, int, int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.io.PrintStream java.io.PrintStream format(java.lang.String, java.lang.Object...)">
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
+ <item name="java.io.PrintStream java.io.PrintStream format(java.util.Locale, java.lang.String, java.lang.Object...)">
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
<item name="java.io.PrintStream void init(java.io.OutputStreamWriter) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.io.PrintStream void print(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.io.PrintStream void print(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.io.PrintStream void println(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.io.RandomAccessFile RandomAccessFile(java.io.File, java.lang.String) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.io.RandomAccessFile RandomAccessFile(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.io.RandomAccessFile RandomAccessFile(java.lang.String, java.lang.String) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -377,9 +496,15 @@
<item name="java.io.Writer java.io.Writer append(char)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.io.Writer java.io.Writer append(java.lang.CharSequence) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.io.Writer java.io.Writer append(java.lang.CharSequence)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.io.Writer java.io.Writer append(java.lang.CharSequence, int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.io.Writer java.io.Writer append(java.lang.CharSequence, int, int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/lang/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/lang/annotations.xml
index 8d157485ada1..4862b313a917 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/lang/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/lang/annotations.xml
@@ -29,9 +29,24 @@
<item name="java.lang.AbstractStringBuilder java.lang.AbstractStringBuilder append(int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.AbstractStringBuilder java.lang.AbstractStringBuilder append(java.lang.CharSequence) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.lang.AbstractStringBuilder java.lang.AbstractStringBuilder append(java.lang.CharSequence, int, int)">
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
+ <item name="java.lang.AbstractStringBuilder java.lang.AbstractStringBuilder append(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.lang.AbstractStringBuilder java.lang.AbstractStringBuilder append(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.AbstractStringBuilder java.lang.AbstractStringBuilder append(java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.AbstractStringBuilder java.lang.AbstractStringBuilder append(java.lang.StringBuffer) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.AbstractStringBuilder java.lang.AbstractStringBuilder append(java.lang.StringBuffer)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null&quot;"/>
@@ -64,6 +79,18 @@
<item name="java.lang.AbstractStringBuilder java.lang.AbstractStringBuilder insert(int, char[], int, int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.AbstractStringBuilder java.lang.AbstractStringBuilder insert(int, java.lang.CharSequence) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.lang.AbstractStringBuilder java.lang.AbstractStringBuilder insert(int, java.lang.CharSequence, int, int)">
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
+ <item name="java.lang.AbstractStringBuilder java.lang.AbstractStringBuilder insert(int, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.lang.AbstractStringBuilder java.lang.AbstractStringBuilder insert(int, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.AbstractStringBuilder java.lang.AbstractStringBuilder insert(int, java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -73,19 +100,37 @@
<item name="java.lang.AbstractStringBuilder java.lang.AbstractStringBuilder replace(int, int, java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.AbstractStringBuilder java.lang.AbstractStringBuilder reverse()">
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
<item name="java.lang.AbstractStringBuilder java.lang.String substring(int, int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.AssertionError AssertionError(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.lang.Boolean Boolean(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.lang.Boolean boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.Boolean boolean equals(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="java.lang.Boolean boolean parseBoolean(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.Boolean boolean parseBoolean(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="java.lang.Boolean boolean toBoolean(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.Boolean boolean toBoolean(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -97,6 +142,9 @@
<item name="java.lang.Boolean int compareTo(java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.Boolean java.lang.Boolean valueOf(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.Boolean java.lang.String toString()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -106,6 +154,9 @@
<item name="java.lang.Byte Byte(java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.Byte boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.Byte boolean equals(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -147,6 +198,9 @@
<item name="java.lang.Byte java.lang.String toString(byte)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.Character boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.Character boolean equals(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -196,6 +250,12 @@
<val val="&quot;!null-&gt;!null;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="java.lang.Class boolean access$100(java.lang.Object[], java.lang.Object[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.lang.Class boolean access$100(java.lang.Object[], java.lang.Object[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.Class boolean access$202(boolean)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;false-&gt;false;true-&gt;true&quot;"/>
@@ -206,6 +266,12 @@
<val val="&quot;false-&gt;false;true-&gt;true&quot;"/>
</annotation>
</item>
+ <item name="java.lang.Class boolean arrayContentsEq(java.lang.Object[], java.lang.Object[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.lang.Class boolean arrayContentsEq(java.lang.Object[], java.lang.Object[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.Class boolean isAnnotationPresent(java.lang.Class&lt;? extends java.lang.annotation.Annotation&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -220,6 +286,9 @@
<item name="java.lang.Class java.lang.Class&lt;? extends U&gt; asSubclass(java.lang.Class&lt;U&gt;)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.Class java.lang.String argumentTypesToString(java.lang.Class[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.Class java.lang.String argumentTypesToString(java.lang.Class[])">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -234,6 +303,15 @@
<item name="java.lang.Class java.lang.String toString()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.Class java.lang.reflect.Constructor&lt;T&gt; getConstructor(java.lang.Class...) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.lang.Class java.lang.reflect.Constructor&lt;T&gt; getConstructor0(java.lang.Class[], int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.lang.Class java.lang.reflect.Constructor&lt;T&gt; getDeclaredConstructor(java.lang.Class...) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.Class java.lang.reflect.Constructor[] copyConstructors(java.lang.reflect.Constructor[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -255,9 +333,15 @@
<item name="java.lang.Class java.lang.reflect.Field[] copyFields(java.lang.reflect.Field[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.Class java.lang.reflect.Field[] privateGetPublicFields(java.util.Set) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.Class java.lang.reflect.Method getDeclaredMethod(java.lang.String, java.lang.Class...) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.Class java.lang.reflect.Method getDeclaredMethod(java.lang.String, java.lang.Class...) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.Class java.lang.reflect.Method getMethod(java.lang.String, java.lang.Class...) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -270,15 +354,27 @@
<item name="java.lang.Class java.lang.reflect.Method searchMethods(java.lang.reflect.Method[], java.lang.String, java.lang.Class[]) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.Class java.lang.reflect.Method searchMethods(java.lang.reflect.Method[], java.lang.String, java.lang.Class[]) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.Class java.lang.reflect.Method[] copyMethods(java.lang.reflect.Method[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.lang.Class void addAll(java.util.Collection, java.lang.reflect.Field[]) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.Class void checkMemberAccess(int, java.lang.ClassLoader) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.ClassLoader boolean compareCerts(java.security.cert.Certificate[], java.security.cert.Certificate[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.ClassLoader boolean compareCerts(java.security.cert.Certificate[], java.security.cert.Certificate[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.lang.ClassLoader boolean isAncestor(java.lang.ClassLoader) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.ClassLoader boolean loadLibrary0(java.lang.Class, java.io.File)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,null-&gt;false&quot;"/>
@@ -287,6 +383,9 @@
<item name="java.lang.ClassLoader java.lang.Package definePackage(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.net.URL)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.ClassLoader java.lang.String findLibrary(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.ClassLoader java.lang.String findLibrary(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;null;null-&gt;null&quot;"/>
@@ -295,11 +394,17 @@
<item name="java.lang.ClassLoader java.lang.String[] initializePath(java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.ClassLoader java.net.URL findResource(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.ClassLoader java.net.URL findResource(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;null;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="java.lang.ClassLoader java.util.Enumeration findResources(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.ClassLoader java.util.Enumeration findResources(java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -318,6 +423,9 @@
<item name="java.lang.ClassLoader void setSigners(java.lang.Class, java.lang.Object[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.Double boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.Double boolean equals(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -338,12 +446,18 @@
<item name="java.lang.Enum T valueOf(java.lang.Class&lt;T&gt;, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.Enum boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.Enum int compareTo(E) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.lang.Enum int compareTo(java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.Float boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.Float boolean equals(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -364,6 +478,9 @@
<item name="java.lang.Integer Integer(java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.Integer boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.Integer boolean equals(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -434,6 +551,9 @@
<item name="java.lang.Long Long(java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.Long boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.Long boolean equals(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -498,15 +618,24 @@
<item name="java.lang.Long void getChars(long, int, char[]) 2">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.NumberFormatException java.lang.NumberFormatException forInputString(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.NumberFormatException java.lang.NumberFormatException forInputString(java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.Object boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.Object java.lang.String toString()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.lang.Short Short(java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.Short boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.Short boolean equals(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -605,6 +734,12 @@
<item name="java.lang.String boolean endsWith(java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.String boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.lang.String boolean equalsIgnoreCase(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.String boolean regionMatches(boolean, int, java.lang.String, int, int) 2">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -662,6 +797,9 @@
<item name="java.lang.String java.lang.String copyValueOf(char[], int, int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.String java.lang.String replace(char, char)">
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
<item name="java.lang.String java.lang.String replace(java.lang.CharSequence, java.lang.CharSequence) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -674,15 +812,30 @@
<item name="java.lang.String java.lang.String substring(int, int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.String java.lang.String toLowerCase()">
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
<item name="java.lang.String java.lang.String toLowerCase(java.util.Locale) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.String java.lang.String toLowerCase(java.util.Locale)">
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
<item name="java.lang.String java.lang.String toString()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.String java.lang.String toUpperCase()">
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
<item name="java.lang.String java.lang.String toUpperCase(java.util.Locale) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.String java.lang.String toUpperCase(java.util.Locale)">
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
+ <item name="java.lang.String java.lang.String trim()">
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
<item name="java.lang.String java.lang.String valueOf(boolean)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -704,6 +857,9 @@
<item name="java.lang.String java.lang.String valueOf(int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.String java.lang.String valueOf(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.String java.lang.String valueOf(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;!null&quot;"/>
@@ -715,6 +871,9 @@
<item name="java.lang.String void checkBounds(byte[], int, int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.String.CaseInsensitiveComparator CaseInsensitiveComparator(java.lang.String.1) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.String.CaseInsensitiveComparator int compare(java.lang.String, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -763,18 +922,30 @@
<item name="java.lang.StringBuffer java.lang.AbstractStringBuilder append(int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.StringBuffer java.lang.AbstractStringBuilder append(java.lang.CharSequence) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.StringBuffer java.lang.AbstractStringBuilder append(java.lang.CharSequence)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.lang.StringBuffer java.lang.AbstractStringBuilder append(java.lang.CharSequence, int, int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.StringBuffer java.lang.AbstractStringBuilder append(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.StringBuffer java.lang.AbstractStringBuilder append(java.lang.Object)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.StringBuffer java.lang.AbstractStringBuilder append(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.StringBuffer java.lang.AbstractStringBuilder append(java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.StringBuffer java.lang.AbstractStringBuilder append(java.lang.StringBuffer) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.StringBuffer java.lang.AbstractStringBuilder append(java.lang.StringBuffer)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -817,15 +988,24 @@
<item name="java.lang.StringBuffer java.lang.AbstractStringBuilder insert(int, int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.StringBuffer java.lang.AbstractStringBuilder insert(int, java.lang.CharSequence) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.StringBuffer java.lang.AbstractStringBuilder insert(int, java.lang.CharSequence)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.lang.StringBuffer java.lang.AbstractStringBuilder insert(int, java.lang.CharSequence, int, int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.StringBuffer java.lang.AbstractStringBuilder insert(int, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.StringBuffer java.lang.AbstractStringBuilder insert(int, java.lang.Object)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.StringBuffer java.lang.AbstractStringBuilder insert(int, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.StringBuffer java.lang.AbstractStringBuilder insert(int, java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -844,6 +1024,9 @@
<item name="java.lang.StringBuffer java.lang.Appendable append(char)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.StringBuffer java.lang.Appendable append(java.lang.CharSequence) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.StringBuffer java.lang.Appendable append(java.lang.CharSequence)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -886,18 +1069,30 @@
<item name="java.lang.StringBuffer java.lang.StringBuffer append(int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.StringBuffer java.lang.StringBuffer append(java.lang.CharSequence) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.StringBuffer java.lang.StringBuffer append(java.lang.CharSequence)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.lang.StringBuffer java.lang.StringBuffer append(java.lang.CharSequence, int, int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.StringBuffer java.lang.StringBuffer append(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.StringBuffer java.lang.StringBuffer append(java.lang.Object)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.StringBuffer java.lang.StringBuffer append(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.StringBuffer java.lang.StringBuffer append(java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.StringBuffer java.lang.StringBuffer append(java.lang.StringBuffer) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.StringBuffer java.lang.StringBuffer append(java.lang.StringBuffer)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -940,15 +1135,24 @@
<item name="java.lang.StringBuffer java.lang.StringBuffer insert(int, int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.StringBuffer java.lang.StringBuffer insert(int, java.lang.CharSequence) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.StringBuffer java.lang.StringBuffer insert(int, java.lang.CharSequence)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.lang.StringBuffer java.lang.StringBuffer insert(int, java.lang.CharSequence, int, int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.StringBuffer java.lang.StringBuffer insert(int, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.StringBuffer java.lang.StringBuffer insert(int, java.lang.Object)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.StringBuffer java.lang.StringBuffer insert(int, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.StringBuffer java.lang.StringBuffer insert(int, java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -1012,18 +1216,30 @@
<item name="java.lang.StringBuilder java.lang.AbstractStringBuilder append(int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.StringBuilder java.lang.AbstractStringBuilder append(java.lang.CharSequence) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.StringBuilder java.lang.AbstractStringBuilder append(java.lang.CharSequence)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.lang.StringBuilder java.lang.AbstractStringBuilder append(java.lang.CharSequence, int, int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.StringBuilder java.lang.AbstractStringBuilder append(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.StringBuilder java.lang.AbstractStringBuilder append(java.lang.Object)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.StringBuilder java.lang.AbstractStringBuilder append(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.StringBuilder java.lang.AbstractStringBuilder append(java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.StringBuilder java.lang.AbstractStringBuilder append(java.lang.StringBuffer) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.StringBuilder java.lang.AbstractStringBuilder append(java.lang.StringBuffer)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -1066,15 +1282,24 @@
<item name="java.lang.StringBuilder java.lang.AbstractStringBuilder insert(int, int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.StringBuilder java.lang.AbstractStringBuilder insert(int, java.lang.CharSequence) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.StringBuilder java.lang.AbstractStringBuilder insert(int, java.lang.CharSequence)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.lang.StringBuilder java.lang.AbstractStringBuilder insert(int, java.lang.CharSequence, int, int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.StringBuilder java.lang.AbstractStringBuilder insert(int, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.StringBuilder java.lang.AbstractStringBuilder insert(int, java.lang.Object)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.StringBuilder java.lang.AbstractStringBuilder insert(int, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.StringBuilder java.lang.AbstractStringBuilder insert(int, java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -1093,6 +1318,9 @@
<item name="java.lang.StringBuilder java.lang.Appendable append(char)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.StringBuilder java.lang.Appendable append(java.lang.CharSequence) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.StringBuilder java.lang.Appendable append(java.lang.CharSequence)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -1126,21 +1354,36 @@
<item name="java.lang.StringBuilder java.lang.StringBuilder append(int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.StringBuilder java.lang.StringBuilder append(java.lang.CharSequence) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.StringBuilder java.lang.StringBuilder append(java.lang.CharSequence)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.lang.StringBuilder java.lang.StringBuilder append(java.lang.CharSequence, int, int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.StringBuilder java.lang.StringBuilder append(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.StringBuilder java.lang.StringBuilder append(java.lang.Object)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.StringBuilder java.lang.StringBuilder append(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.StringBuilder java.lang.StringBuilder append(java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.StringBuilder java.lang.StringBuilder append(java.lang.StringBuffer) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.StringBuilder java.lang.StringBuilder append(java.lang.StringBuffer)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.StringBuilder java.lang.StringBuilder append(java.lang.StringBuilder) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.StringBuilder java.lang.StringBuilder append(java.lang.StringBuilder)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -1183,15 +1426,24 @@
<item name="java.lang.StringBuilder java.lang.StringBuilder insert(int, int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.StringBuilder java.lang.StringBuilder insert(int, java.lang.CharSequence) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.StringBuilder java.lang.StringBuilder insert(int, java.lang.CharSequence)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.lang.StringBuilder java.lang.StringBuilder insert(int, java.lang.CharSequence, int, int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.StringBuilder java.lang.StringBuilder insert(int, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.StringBuilder java.lang.StringBuilder insert(int, java.lang.Object)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.StringBuilder java.lang.StringBuilder insert(int, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.StringBuilder java.lang.StringBuilder insert(int, java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -1228,6 +1480,12 @@
<item name="java.lang.System void checkKey(java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.System void setProperties(java.util.Properties) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.lang.System void setSecurityManager0(java.lang.SecurityManager) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.System.2 sun.reflect.ConstantPool getConstantPool(java.lang.Class) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -1246,12 +1504,24 @@
<item name="java.lang.Thread Thread(java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.Thread Thread(java.lang.ThreadGroup, java.lang.Runnable) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.lang.Thread Thread(java.lang.ThreadGroup, java.lang.Runnable, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.Thread Thread(java.lang.ThreadGroup, java.lang.Runnable, java.lang.String) 2">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.Thread Thread(java.lang.ThreadGroup, java.lang.Runnable, java.lang.String, long) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.Thread Thread(java.lang.ThreadGroup, java.lang.Runnable, java.lang.String, long) 2">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.Thread Thread(java.lang.ThreadGroup, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.Thread Thread(java.lang.ThreadGroup, java.lang.String) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -1261,12 +1531,18 @@
<item name="java.lang.Thread java.lang.String toString()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.Thread void init(java.lang.ThreadGroup, java.lang.Runnable, java.lang.String, long) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.Thread void init(java.lang.ThreadGroup, java.lang.Runnable, java.lang.String, long) 2">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.lang.Thread void setName(java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.ThreadLocal T childValue(T) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.ThreadLocal int access$400(java.lang.ThreadLocal) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -1291,6 +1567,9 @@
<item name="java.lang.ThreadLocal.ThreadLocalMap ThreadLocalMap(java.lang.ThreadLocal.ThreadLocalMap, java.lang.ThreadLocal.1) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.ThreadLocal.ThreadLocalMap ThreadLocalMap(java.lang.ThreadLocal.ThreadLocalMap, java.lang.ThreadLocal.1) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.ThreadLocal.ThreadLocalMap java.lang.ThreadLocal.ThreadLocalMap.Entry access$000(java.lang.ThreadLocal.ThreadLocalMap, java.lang.ThreadLocal) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -1300,6 +1579,12 @@
<item name="java.lang.ThreadLocal.ThreadLocalMap java.lang.ThreadLocal.ThreadLocalMap.Entry getEntry(java.lang.ThreadLocal) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.ThreadLocal.ThreadLocalMap java.lang.ThreadLocal.ThreadLocalMap.Entry getEntryAfterMiss(java.lang.ThreadLocal, int, java.lang.ThreadLocal.ThreadLocalMap.Entry) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.lang.ThreadLocal.ThreadLocalMap java.lang.ThreadLocal.ThreadLocalMap.Entry getEntryAfterMiss(java.lang.ThreadLocal, int, java.lang.ThreadLocal.ThreadLocalMap.Entry) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.ThreadLocal.ThreadLocalMap java.lang.ThreadLocal.ThreadLocalMap.Entry getEntryAfterMiss(java.lang.ThreadLocal, int, java.lang.ThreadLocal.ThreadLocalMap.Entry)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,_,null-&gt;null&quot;"/>
@@ -1329,6 +1614,9 @@
<item name="java.lang.Throwable void printEnclosedStackTrace(java.lang.Throwable.PrintStreamOrWriter, java.lang.StackTraceElement[], java.lang.String, java.lang.String, java.util.Set&lt;java.lang.Throwable&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.Throwable void printEnclosedStackTrace(java.lang.Throwable.PrintStreamOrWriter, java.lang.StackTraceElement[], java.lang.String, java.lang.String, java.util.Set&lt;java.lang.Throwable&gt;) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.Throwable void printEnclosedStackTrace(java.lang.Throwable.PrintStreamOrWriter, java.lang.StackTraceElement[], java.lang.String, java.lang.String, java.util.Set&lt;java.lang.Throwable&gt;) 4">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -1344,4 +1632,7 @@
<item name="java.lang.Throwable void writeObject(java.io.ObjectOutputStream) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.Throwable.PrintStreamOrWriter PrintStreamOrWriter(java.lang.Throwable.1) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
</root>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/lang/invoke/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/lang/invoke/annotations.xml
index f800dab8c906..42a07af318e1 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/lang/invoke/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/lang/invoke/annotations.xml
@@ -8,6 +8,15 @@
<item name="java.lang.invoke.AdapterMethodHandle AdapterMethodHandle(java.lang.invoke.MethodHandle, java.lang.invoke.MethodType, long, java.lang.invoke.AdapterMethodHandle.1) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.AdapterMethodHandle AdapterMethodHandle(java.lang.invoke.MethodHandle, java.lang.invoke.MethodType, long, java.lang.invoke.AdapterMethodHandle.1) 3">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.lang.invoke.AdapterMethodHandle boolean canBoxArgument(java.lang.Class&lt;?&gt;, java.lang.Class&lt;?&gt;) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.lang.invoke.AdapterMethodHandle boolean canBoxArgument(java.lang.Class&lt;?&gt;, java.lang.Class&lt;?&gt;) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.AdapterMethodHandle boolean canBoxArgument(java.lang.Class&lt;?&gt;, java.lang.Class&lt;?&gt;)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;false;_,!null-&gt;false;_,null-&gt;false;null,_-&gt;false&quot;"/>
@@ -75,6 +84,9 @@
<val val="&quot;_,null,_,_-&gt;false;null,_,_,_-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="java.lang.invoke.AdapterMethodHandle byte basicType(java.lang.Class&lt;?&gt;) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.AdapterMethodHandle int diffReturnTypes(java.lang.invoke.MethodType, java.lang.invoke.MethodType, boolean) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -87,9 +99,21 @@
<item name="java.lang.invoke.AdapterMethodHandle int diffTypes(java.lang.invoke.MethodType, java.lang.invoke.MethodType, boolean) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.AdapterMethodHandle int type2size(java.lang.Class&lt;?&gt;) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.AdapterMethodHandle java.lang.String toString()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.AdapterMethodHandle java.lang.invoke.MethodHandle makeBoxArgument(java.lang.invoke.MethodType, java.lang.invoke.MethodHandle, int, java.lang.Class&lt;?&gt;) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.lang.invoke.AdapterMethodHandle java.lang.invoke.MethodHandle makeBoxArgument(java.lang.invoke.MethodType, java.lang.invoke.MethodHandle, int, java.lang.Class&lt;?&gt;) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.lang.invoke.AdapterMethodHandle java.lang.invoke.MethodHandle makeBoxArgument(java.lang.invoke.MethodType, java.lang.invoke.MethodHandle, int, java.lang.Class&lt;?&gt;) 3">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.AdapterMethodHandle java.lang.invoke.MethodHandle makeBoxArgument(java.lang.invoke.MethodType, java.lang.invoke.MethodHandle, int, java.lang.Class&lt;?&gt;)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_,_,_-&gt;null;_,!null,_,_-&gt;null;_,_,_,!null-&gt;null;_,_,_,null-&gt;null;_,null,_,_-&gt;null;null,_,_,_-&gt;null&quot;"/>
@@ -172,12 +196,18 @@
<item name="java.lang.invoke.BoundMethodHandle BoundMethodHandle(java.lang.invoke.DirectMethodHandle, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.BoundMethodHandle BoundMethodHandle(java.lang.invoke.DirectMethodHandle, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.BoundMethodHandle BoundMethodHandle(java.lang.invoke.MethodHandle) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.lang.invoke.BoundMethodHandle BoundMethodHandle(java.lang.invoke.MethodHandle, java.lang.Object, int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.BoundMethodHandle BoundMethodHandle(java.lang.invoke.MethodHandle, java.lang.Object, int) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.BoundMethodHandle BoundMethodHandle(java.lang.invoke.MethodType, java.lang.Object, int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -187,9 +217,18 @@
<item name="java.lang.invoke.BoundMethodHandle BoundMethodHandle(java.lang.invoke.MethodType, java.lang.invoke.MethodHandle, java.lang.Object, int) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.BoundMethodHandle BoundMethodHandle(java.lang.invoke.MethodType, java.lang.invoke.MethodHandle, java.lang.Object, int) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.lang.invoke.BoundMethodHandle java.lang.Object bindPrimitiveArgument(java.lang.Object, java.lang.invoke.MethodHandle, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.BoundMethodHandle java.lang.Object bindPrimitiveArgument(java.lang.Object, java.lang.invoke.MethodHandle, int) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.BoundMethodHandle java.lang.Object checkReferenceArgument(java.lang.Object, java.lang.invoke.MethodHandle, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.BoundMethodHandle java.lang.Object checkReferenceArgument(java.lang.Object, java.lang.invoke.MethodHandle, int) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -198,6 +237,9 @@
<val val="&quot;!null,_,_-&gt;!null;null,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="java.lang.invoke.BoundMethodHandle java.lang.RuntimeException badBoundArgumentException(java.lang.Object, java.lang.invoke.MethodHandle, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.BoundMethodHandle java.lang.RuntimeException badBoundArgumentException(java.lang.Object, java.lang.invoke.MethodHandle, int) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -229,6 +271,12 @@
<item name="java.lang.invoke.CallSite java.lang.invoke.CallSite makeSite(java.lang.invoke.MethodHandle, java.lang.String, java.lang.invoke.MethodType, java.lang.Object, java.lang.invoke.MemberName, int) 4">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.CallSite java.lang.invoke.WrongMethodTypeException wrongTargetType(java.lang.invoke.MethodHandle, java.lang.invoke.MethodType) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.lang.invoke.CallSite java.lang.invoke.WrongMethodTypeException wrongTargetType(java.lang.invoke.MethodHandle, java.lang.invoke.MethodType) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.CallSite java.lang.invoke.WrongMethodTypeException wrongTargetType(java.lang.invoke.MethodHandle, java.lang.invoke.MethodType)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -238,12 +286,21 @@
<item name="java.lang.invoke.CallSite void checkTargetChange(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.CallSite void initializeFromJVM(java.lang.String, java.lang.invoke.MethodType, java.lang.invoke.MemberName, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.lang.invoke.CallSite void initializeFromJVM(java.lang.String, java.lang.invoke.MethodType, java.lang.invoke.MemberName, int) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.CallSite void maybeReBoxElements(java.lang.Object[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.lang.invoke.ConstantCallSite ConstantCallSite(java.lang.invoke.MethodHandle) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.ConstantCallSite void setTarget(java.lang.invoke.MethodHandle) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.DirectMethodHandle DirectMethodHandle(java.lang.invoke.MethodType, java.lang.invoke.MemberName, boolean, java.lang.Class&lt;?&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -259,6 +316,12 @@
<item name="java.lang.invoke.FilterGeneric java.lang.invoke.FilterGeneric of(java.lang.invoke.FilterGeneric.Kind, int, java.lang.invoke.MethodType, java.lang.invoke.MethodType) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.FilterGeneric java.lang.invoke.FilterGeneric.Adapter buildAdapterFromBytecodes(java.lang.invoke.MethodType, java.lang.invoke.FilterGeneric.Kind, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.lang.invoke.FilterGeneric java.lang.invoke.FilterGeneric.Adapter buildAdapterFromBytecodes(java.lang.invoke.MethodType, java.lang.invoke.FilterGeneric.Kind, int) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.FilterGeneric java.lang.invoke.FilterGeneric.Adapter findAdapter(java.lang.invoke.MethodType, java.lang.invoke.FilterGeneric.Kind, int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -323,6 +386,9 @@
<item name="java.lang.invoke.FilterGeneric.Adapter Adapter(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.FilterGeneric.Adapter java.lang.Class&lt;? extends java.lang.invoke.FilterGeneric.Adapter&gt; findSubClass(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.FilterGeneric.F0 F0(java.lang.invoke.MethodHandle) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -578,6 +644,9 @@
<item name="java.lang.invoke.FilterGeneric.Kind java.lang.String invokerName(int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.FilterOneArgument java.lang.invoke.MethodHandle make(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.FilterOneArgument java.lang.invoke.MethodHandle make(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;!null;_,!null-&gt;!null&quot;"/>
@@ -592,6 +661,9 @@
<item name="java.lang.invoke.FromGeneric java.lang.invoke.FromGeneric of(java.lang.invoke.MethodType) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.FromGeneric java.lang.invoke.FromGeneric.Adapter buildAdapterFromBytecodes(java.lang.invoke.MethodType) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.FromGeneric java.lang.invoke.FromGeneric.Adapter findAdapter(java.lang.invoke.MethodType) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -751,6 +823,9 @@
<item name="java.lang.invoke.FromGeneric.Adapter Adapter(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.FromGeneric.Adapter java.lang.Class&lt;? extends java.lang.invoke.FromGeneric.Adapter&gt; findSubClass(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.InvokeGeneric boolean returnConversionNeeded(java.lang.invoke.MethodType, java.lang.invoke.MethodHandle) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -762,6 +837,12 @@
<item name="java.lang.invoke.InvokeGeneric java.lang.String toString()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.InvokeGeneric java.lang.invoke.MethodHandle addReturnConversion(java.lang.invoke.MethodHandle, java.lang.Class&lt;?&gt;) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.lang.invoke.InvokeGeneric java.lang.invoke.MethodHandle addReturnConversion(java.lang.invoke.MethodHandle, java.lang.Class&lt;?&gt;) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.InvokeGeneric java.lang.invoke.MethodHandle dispatch(java.lang.invoke.MethodType, java.lang.invoke.MethodHandle) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -812,6 +893,12 @@
<item name="java.lang.invoke.MemberName int access$200(java.lang.invoke.MemberName) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.MemberName java.lang.IllegalAccessException makeAccessException(java.lang.String, java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.lang.invoke.MemberName java.lang.IllegalAccessException makeAccessException(java.lang.String, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.MemberName java.lang.IllegalAccessException makeAccessException(java.lang.String, java.lang.Object)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -826,6 +913,9 @@
<val val="&quot;_,!null-&gt;!null;_,null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="java.lang.invoke.MemberName java.lang.ReflectiveOperationException makeAccessException(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.MemberName java.lang.ReflectiveOperationException makeAccessException(java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -840,6 +930,9 @@
<val val="&quot;_,!null-&gt;!null;_,null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="java.lang.invoke.MemberName java.lang.String getName(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.MemberName java.lang.String getName(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;!null&quot;"/>
@@ -851,6 +944,9 @@
<item name="java.lang.invoke.MemberName.Factory java.lang.invoke.MemberName resolveOrNull(java.lang.invoke.MemberName, boolean, java.lang.Class&lt;?&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.MemberName.Factory java.util.List&lt;java.lang.invoke.MemberName&gt; getMembers(java.lang.Class&lt;?&gt;, java.lang.String, java.lang.Object, int, java.lang.Class&lt;?&gt;) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.MethodHandle MethodHandle(java.lang.invoke.MethodType) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -878,6 +974,9 @@
<item name="java.lang.invoke.MethodHandleImpl java.lang.invoke.MethodHandle accessField(java.lang.invoke.MemberName, boolean, java.lang.Class&lt;?&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.MethodHandleImpl java.lang.invoke.MethodHandle accessField(java.lang.invoke.MemberName, boolean, java.lang.Class&lt;?&gt;) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.MethodHandleImpl java.lang.invoke.MethodHandle accessField(java.lang.invoke.MemberName, boolean, java.lang.Class&lt;?&gt;)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -890,9 +989,18 @@
<item name="java.lang.invoke.MethodHandleImpl java.lang.invoke.MethodHandle bindArgument(java.lang.invoke.MethodHandle, int, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.MethodHandleImpl java.lang.invoke.MethodHandle bindArgument(java.lang.invoke.MethodHandle, int, java.lang.Object) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.MethodHandleImpl java.lang.invoke.MethodHandle bindArgument(java.lang.invoke.MethodHandle, int, java.lang.Object)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.MethodHandleImpl java.lang.invoke.MethodHandle bindReceiver(java.lang.invoke.MethodHandle, java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.lang.invoke.MethodHandleImpl java.lang.invoke.MethodHandle bindReceiver(java.lang.invoke.MethodHandle, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.MethodHandleImpl java.lang.invoke.MethodHandle bindReceiver(java.lang.invoke.MethodHandle, java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;null&quot;"/>
@@ -940,6 +1048,9 @@
<item name="java.lang.invoke.MethodHandleImpl java.lang.invoke.MethodHandle spreadArguments(java.lang.invoke.MethodHandle, java.lang.invoke.MethodType, int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.MethodHandleImpl sun.invoke.empty.Empty throwException(T) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.MethodHandleImpl.AllocateObject AllocateObject(java.lang.invoke.MethodHandle, java.lang.Class&lt;C&gt;, java.lang.invoke.MethodHandle) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -1078,21 +1189,36 @@
<item name="java.lang.invoke.MethodHandleNatives void raiseException(int, java.lang.Object, java.lang.Object) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.MethodHandleNatives void raiseException(int, java.lang.Object, java.lang.Object) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.MethodHandleStatics java.lang.Error uncaughtException(java.lang.Exception)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.lang.invoke.MethodHandleStatics java.lang.RuntimeException newIllegalArgumentException(java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.MethodHandleStatics java.lang.RuntimeException newIllegalArgumentException(java.lang.String, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.MethodHandleStatics java.lang.RuntimeException newIllegalArgumentException(java.lang.String, java.lang.Object)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.lang.invoke.MethodHandleStatics java.lang.RuntimeException newIllegalStateException(java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.MethodHandleStatics java.lang.RuntimeException newIllegalStateException(java.lang.String, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.MethodHandleStatics java.lang.RuntimeException newIllegalStateException(java.lang.String, java.lang.Object)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.MethodHandleStatics java.lang.String addTypeString(java.lang.Object, java.lang.invoke.MethodHandle) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.lang.invoke.MethodHandleStatics java.lang.String addTypeString(java.lang.Object, java.lang.invoke.MethodHandle) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.MethodHandleStatics java.lang.String addTypeString(java.lang.Object, java.lang.invoke.MethodHandle)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,!null-&gt;!null;null,_-&gt;!null&quot;"/>
@@ -1101,12 +1227,21 @@
<item name="java.lang.invoke.MethodHandleStatics java.lang.String getNameString(java.lang.invoke.MethodHandle)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.MethodHandleStatics java.lang.String getNameString(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.MethodHandleStatics java.lang.String getNameString(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.MethodHandleStatics java.lang.String getNameString(java.lang.invoke.MethodHandle, java.lang.invoke.MethodType) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.MethodHandleStatics java.lang.String getNameString(java.lang.invoke.MethodHandle, java.lang.invoke.MethodType)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.MethodHandleStatics java.lang.String message(java.lang.String, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.MethodHandleStatics java.lang.String message(java.lang.String, java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;!null;_,!null-&gt;!null&quot;"/>
@@ -1127,6 +1262,9 @@
<item name="java.lang.invoke.MethodHandles boolean isObjectMethod(java.lang.reflect.Method) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.MethodHandles boolean isWrapperInstance(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.MethodHandles java.lang.Class&lt;?&gt; wrapperInstanceType(java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -1136,6 +1274,15 @@
<item name="java.lang.invoke.MethodHandles java.lang.Object callObjectMethod(java.lang.Object, java.lang.reflect.Method, java.lang.Object[]) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.MethodHandles java.lang.RuntimeException misMatchedTypes(java.lang.String, java.lang.invoke.MethodType, java.lang.invoke.MethodType) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.lang.invoke.MethodHandles java.lang.RuntimeException misMatchedTypes(java.lang.String, java.lang.invoke.MethodType, java.lang.invoke.MethodType) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.lang.invoke.MethodHandles java.lang.RuntimeException misMatchedTypes(java.lang.String, java.lang.invoke.MethodType, java.lang.invoke.MethodType) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.MethodHandles java.lang.RuntimeException misMatchedTypes(java.lang.String, java.lang.invoke.MethodType, java.lang.invoke.MethodType)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -1277,6 +1424,12 @@
<item name="java.lang.invoke.MethodHandles void checkReorder(int[], java.lang.invoke.MethodType, java.lang.invoke.MethodType) 2">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.MethodHandles.1 java.lang.Object getArg(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.lang.invoke.MethodHandles.1 java.lang.Object invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.MethodHandles.1 java.lang.Object invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[]) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -1425,6 +1578,9 @@
<item name="java.lang.invoke.MethodType MethodType(java.lang.Class&lt;?&gt;, java.lang.Class&lt;?&gt;[]) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.MethodType boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.MethodType boolean equals(java.lang.invoke.MethodType) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -1512,6 +1668,9 @@
<item name="java.lang.invoke.MethodTypeForm MethodTypeForm(java.lang.invoke.MethodType) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.MethodTypeForm boolean hasTwoArgSlots(java.lang.Class&lt;?&gt;) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.MethodTypeForm int[] primsAtEndOrder(java.lang.invoke.MethodType) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -1529,6 +1688,9 @@
<item name="java.lang.invoke.MethodTypeForm java.lang.invoke.MethodType canonicalize(java.lang.invoke.MethodType, int, int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.MethodTypeForm java.lang.invoke.MethodType reorderParameters(java.lang.invoke.MethodType, int[], java.lang.Class&lt;?&gt;[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.MethodTypeForm java.lang.invoke.MethodType reorderParameters(java.lang.invoke.MethodType, int[], java.lang.Class&lt;?&gt;[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_,_-&gt;null&quot;"/>
@@ -1572,6 +1734,12 @@
<item name="java.lang.invoke.SpreadGeneric java.lang.invoke.SpreadGeneric of(java.lang.invoke.MethodType, int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.SpreadGeneric java.lang.invoke.SpreadGeneric.Adapter buildAdapterFromBytecodes(java.lang.invoke.MethodType, int, java.lang.invoke.MethodHandle[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.lang.invoke.SpreadGeneric java.lang.invoke.SpreadGeneric.Adapter buildAdapterFromBytecodes(java.lang.invoke.MethodType, int, java.lang.invoke.MethodHandle[]) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.SpreadGeneric java.lang.invoke.SpreadGeneric.Adapter findAdapter(java.lang.invoke.SpreadGeneric, java.lang.invoke.MethodHandle[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -1583,6 +1751,9 @@
<item name="java.lang.invoke.SpreadGeneric.Adapter Adapter(java.lang.invoke.SpreadGeneric, java.lang.invoke.MethodHandle) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.SpreadGeneric.Adapter java.lang.Class&lt;? extends java.lang.invoke.SpreadGeneric.Adapter&gt; findSubClass(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.SpreadGeneric.S0 S0(java.lang.invoke.SpreadGeneric, java.lang.invoke.MethodHandle) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -1719,6 +1890,9 @@
<item name="java.lang.invoke.ToGeneric java.lang.invoke.ToGeneric of(java.lang.invoke.MethodType) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.ToGeneric java.lang.invoke.ToGeneric.Adapter buildAdapterFromBytecodes(java.lang.invoke.MethodType) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.ToGeneric java.lang.invoke.ToGeneric.Adapter findAdapter(java.lang.invoke.MethodType) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -1863,6 +2037,9 @@
<item name="java.lang.invoke.ToGeneric.Adapter Adapter(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.lang.invoke.ToGeneric.Adapter java.lang.Class&lt;? extends java.lang.invoke.ToGeneric.Adapter&gt; findSubClass(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.lang.invoke.VolatileCallSite VolatileCallSite(java.lang.invoke.MethodHandle) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/net/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/net/annotations.xml
index 6c410bc4ed65..be6006068f41 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/net/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/net/annotations.xml
@@ -38,6 +38,9 @@
<item name="java.net.DatagramSocket DatagramSocket(java.net.DatagramSocketImpl) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.net.DatagramSocket DatagramSocket(java.net.SocketAddress) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.net.DatagramSocket void connect(java.net.InetAddress, int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -53,6 +56,12 @@
<item name="java.net.DatagramSocket void send(java.net.DatagramPacket) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.net.DatagramSocket void setDatagramSocketImplFactory(java.net.DatagramSocketImplFactory) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.InetAddress boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.net.InetAddress boolean equals(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;false;null-&gt;false&quot;"/>
@@ -90,6 +99,12 @@
<item name="java.net.InetAddress java.net.InetAddress getByAddress(java.lang.String, byte[])">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.net.InetAddress java.net.InetAddress getByName(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.InetAddress java.net.InetAddress[] getAllByName(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.net.InetAddress java.net.InetAddress[] getAllByName(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;!null&quot;"/>
@@ -121,24 +136,138 @@
<item name="java.net.ServerSocket void implAccept(java.net.Socket) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.net.ServerSocket void setSocketFactory(java.net.SocketImplFactory) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.Socket Socket(java.lang.String, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.Socket Socket(java.lang.String, int, boolean) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.Socket Socket(java.lang.String, int, java.net.InetAddress, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.Socket Socket(java.net.InetAddress, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.Socket Socket(java.net.InetAddress, int, boolean) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.Socket Socket(java.net.InetAddress, int, java.net.InetAddress, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.net.Socket Socket(java.net.SocketAddress, java.net.SocketAddress, boolean) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.net.Socket java.lang.String toString()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.net.Socket void bind(java.net.SocketAddress) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.net.Socket void connect(java.net.SocketAddress, int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.net.Socket void setSocketImplFactory(java.net.SocketImplFactory) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI URI(java.lang.String, java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI URI(java.lang.String, java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI URI(java.lang.String, java.lang.String, java.lang.String) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI URI(java.lang.String, java.lang.String, java.lang.String, int, java.lang.String, java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI URI(java.lang.String, java.lang.String, java.lang.String, int, java.lang.String, java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI URI(java.lang.String, java.lang.String, java.lang.String, int, java.lang.String, java.lang.String, java.lang.String) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI URI(java.lang.String, java.lang.String, java.lang.String, int, java.lang.String, java.lang.String, java.lang.String) 4">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI URI(java.lang.String, java.lang.String, java.lang.String, int, java.lang.String, java.lang.String, java.lang.String) 5">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI URI(java.lang.String, java.lang.String, java.lang.String, int, java.lang.String, java.lang.String, java.lang.String) 6">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI URI(java.lang.String, java.lang.String, java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI URI(java.lang.String, java.lang.String, java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI URI(java.lang.String, java.lang.String, java.lang.String, java.lang.String) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI URI(java.lang.String, java.lang.String, java.lang.String, java.lang.String) 3">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI URI(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI URI(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI URI(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI URI(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String) 3">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI URI(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String) 4">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI boolean equal(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI boolean equal(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI boolean equalIgnoringCase(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI boolean equalIgnoringCase(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.net.URI int access$2502(java.net.URI, int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.net.URI int compare(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI int compare(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI int compareIgnoringCase(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI int compareIgnoringCase(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.net.URI int compareTo(java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.net.URI int compareTo(java.net.URI) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.net.URI int hash(int, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI int hashIgnoringCase(int, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.net.URI int join(char[], int[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -255,6 +384,30 @@
<item name="java.net.URI java.lang.String resolvePath(java.lang.String, java.lang.String, boolean) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.net.URI java.lang.String toString(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, int, java.lang.String, java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI java.lang.String toString(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, int, java.lang.String, java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI java.lang.String toString(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, int, java.lang.String, java.lang.String, java.lang.String) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI java.lang.String toString(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, int, java.lang.String, java.lang.String, java.lang.String) 3">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI java.lang.String toString(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, int, java.lang.String, java.lang.String, java.lang.String) 4">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI java.lang.String toString(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, int, java.lang.String, java.lang.String, java.lang.String) 6">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI java.lang.String toString(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, int, java.lang.String, java.lang.String, java.lang.String) 7">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI java.lang.String toString(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, int, java.lang.String, java.lang.String, java.lang.String) 8">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.net.URI java.lang.String toString(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, int, java.lang.String, java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -303,9 +456,45 @@
<item name="java.net.URI long lowMask(java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.net.URI void appendAuthority(java.lang.StringBuffer, java.lang.String, java.lang.String, java.lang.String, int) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI void appendAuthority(java.lang.StringBuffer, java.lang.String, java.lang.String, java.lang.String, int) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI void appendAuthority(java.lang.StringBuffer, java.lang.String, java.lang.String, java.lang.String, int) 3">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.net.URI void appendEscape(java.lang.StringBuffer, byte) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.net.URI void appendFragment(java.lang.StringBuffer, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI void appendSchemeSpecificPart(java.lang.StringBuffer, java.lang.String, java.lang.String, java.lang.String, java.lang.String, int, java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI void appendSchemeSpecificPart(java.lang.StringBuffer, java.lang.String, java.lang.String, java.lang.String, java.lang.String, int, java.lang.String, java.lang.String) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI void appendSchemeSpecificPart(java.lang.StringBuffer, java.lang.String, java.lang.String, java.lang.String, java.lang.String, int, java.lang.String, java.lang.String) 3">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI void appendSchemeSpecificPart(java.lang.StringBuffer, java.lang.String, java.lang.String, java.lang.String, java.lang.String, int, java.lang.String, java.lang.String) 4">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI void appendSchemeSpecificPart(java.lang.StringBuffer, java.lang.String, java.lang.String, java.lang.String, java.lang.String, int, java.lang.String, java.lang.String) 6">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI void appendSchemeSpecificPart(java.lang.StringBuffer, java.lang.String, java.lang.String, java.lang.String, java.lang.String, int, java.lang.String, java.lang.String) 7">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI void checkPath(java.lang.String, java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URI void checkPath(java.lang.String, java.lang.String, java.lang.String) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.net.URI void maybeAddLeadingDot(char[], int[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -345,6 +534,9 @@
<item name="java.net.URL URL(java.net.URL, java.lang.String, java.net.URLStreamHandler) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.net.URL boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.net.URL boolean equals(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -368,6 +560,9 @@
<item name="java.net.URL void set(java.lang.String, java.lang.String, int, java.lang.String, java.lang.String) 3">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.net.URL void setURLStreamHandlerFactory(java.net.URLStreamHandlerFactory) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.net.URL void writeObject(java.io.ObjectOutputStream) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -380,11 +575,17 @@
<item name="java.net.URLConnection java.lang.String getContentHandlerPkgPrefixes()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.net.URLConnection java.lang.String getDefaultRequestProperty(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.net.URLConnection java.lang.String getDefaultRequestProperty(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;null;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="java.net.URLConnection java.lang.String getHeaderField(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.net.URLConnection java.lang.String getHeaderField(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;null;null-&gt;null&quot;"/>
@@ -393,6 +594,9 @@
<item name="java.net.URLConnection java.lang.String guessContentTypeFromStream(java.io.InputStream) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.net.URLConnection java.lang.String stripOffParameters(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.net.URLConnection java.lang.String stripOffParameters(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null;null-&gt;null&quot;"/>
@@ -416,6 +620,18 @@
<item name="java.net.URLConnection void addRequestProperty(java.lang.String, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.net.URLConnection void setContentHandlerFactory(java.net.ContentHandlerFactory) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URLConnection void setDefaultRequestProperty(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URLConnection void setDefaultRequestProperty(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.net.URLConnection void setFileNameMap(java.net.FileNameMap) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.net.URLConnection void setRequestProperty(java.lang.String, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/security/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/security/annotations.xml
index 756cbfcdd13e..597b80fe0d3f 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/security/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/security/annotations.xml
@@ -1,4 +1,7 @@
<root>
+ <item name="java.security.Identity boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.security.Identity boolean identityEquals(java.security.Identity) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -22,11 +25,17 @@
<item name="java.security.Identity void addCertificate(java.security.Certificate) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.security.Policy java.security.PermissionCollection getPermissions(java.security.ProtectionDomain) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.security.Policy java.security.PermissionCollection getPermissions(java.security.ProtectionDomain)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;!null&quot;"/>
</annotation>
</item>
+ <item name="java.security.Policy void addStaticPerms(java.security.PermissionCollection, java.security.PermissionCollection) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.security.Policy void initPolicy(java.security.Policy) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -45,6 +54,9 @@
<item name="java.security.Provider void implPutAll(java.util.Map) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.security.Provider void implRemoveService(java.security.Provider.Service) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.security.Provider void parseLegacyPut(java.lang.String, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -72,6 +84,15 @@
<item name="java.security.Security boolean isCriterionSatisfied(java.security.Provider, java.lang.String, java.lang.String, java.lang.String, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.security.Security boolean isCriterionSatisfied(java.security.Provider, java.lang.String, java.lang.String, java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.security.Security boolean isCriterionSatisfied(java.security.Provider, java.lang.String, java.lang.String, java.lang.String, java.lang.String) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.security.Security boolean isCriterionSatisfied(java.security.Provider, java.lang.String, java.lang.String, java.lang.String, java.lang.String) 3">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.security.Security boolean isStandardAttr(java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -81,9 +102,24 @@
<item name="java.security.Security int insertProviderAt(java.security.Provider, int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.security.Security java.io.File securityPropFile(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.security.Security java.io.File securityPropFile(java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.security.Security java.lang.Object[] getImpl(java.lang.String, java.lang.String, java.lang.String) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.security.Security java.lang.Object[] getImpl(java.lang.String, java.lang.String, java.lang.String, java.lang.Object) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.security.Security java.lang.String getAlgorithmProperty(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.security.Security java.lang.String getAlgorithmProperty(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.security.Security java.lang.String getProviderProperty(java.lang.String, java.security.Provider) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -111,9 +147,21 @@
<item name="java.security.Security java.util.LinkedHashSet getAllQualifyingCandidates(java.lang.String, java.lang.String, java.security.Provider[]) 2">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.security.Security java.util.LinkedHashSet getProvidersNotUsingCache(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.security.Provider[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.security.Security java.util.LinkedHashSet getProvidersNotUsingCache(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.security.Provider[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.security.Security java.util.LinkedHashSet getProvidersNotUsingCache(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.security.Provider[]) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.security.Security java.util.LinkedHashSet getProvidersNotUsingCache(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.security.Provider[]) 4">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.security.Security java.util.Set getAlgorithms(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.security.Security void invalidateSMCache(java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/sql/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/sql/annotations.xml
index 2aaa71e67f39..1938616b2fff 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/sql/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/sql/annotations.xml
@@ -1,10 +1,37 @@
<root>
+ <item name="java.sql.BatchUpdateException BatchUpdateException(int[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.sql.BatchUpdateException BatchUpdateException(int[], java.lang.Throwable) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.sql.BatchUpdateException BatchUpdateException(java.lang.String, int[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.sql.BatchUpdateException BatchUpdateException(java.lang.String, int[], java.lang.Throwable) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.sql.BatchUpdateException BatchUpdateException(java.lang.String, java.lang.String, int, int[]) 3">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.sql.BatchUpdateException BatchUpdateException(java.lang.String, java.lang.String, int, int[], java.lang.Throwable) 3">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.sql.BatchUpdateException BatchUpdateException(java.lang.String, java.lang.String, int[]) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.sql.BatchUpdateException BatchUpdateException(java.lang.String, java.lang.String, int[], java.lang.Throwable) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.sql.Date java.lang.String toString()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.sql.Date java.sql.Date valueOf(java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.sql.DriverInfo boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.sql.DriverInfo boolean equals(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -13,11 +40,20 @@
<item name="java.sql.DriverInfo java.lang.String toString()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.sql.DriverManager boolean isDriverAllowed(java.sql.Driver, java.lang.Class&lt;?&gt;) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.sql.DriverManager boolean isDriverAllowed(java.sql.Driver, java.lang.Class&lt;?&gt;) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.sql.DriverManager boolean isDriverAllowed(java.sql.Driver, java.lang.Class&lt;?&gt;)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="java.sql.DriverManager boolean isDriverAllowed(java.sql.Driver, java.lang.ClassLoader) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.sql.DriverManager boolean isDriverAllowed(java.sql.Driver, java.lang.ClassLoader)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;false&quot;"/>
@@ -29,15 +65,30 @@
<item name="java.sql.DriverManager java.sql.Connection getConnection(java.lang.String, java.lang.String, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.sql.DriverManager java.sql.Connection getConnection(java.lang.String, java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.sql.DriverManager java.sql.Connection getConnection(java.lang.String, java.lang.String, java.lang.String) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.sql.DriverManager java.sql.Connection getConnection(java.lang.String, java.util.Properties) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.sql.DriverManager java.sql.Connection getConnection(java.lang.String, java.util.Properties, java.lang.Class&lt;?&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.sql.DriverManager void deregisterDriver(java.sql.Driver) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.sql.DriverManager void registerDriver(java.sql.Driver) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.sql.DriverManager void setLogStream(java.io.PrintStream) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.sql.DriverManager void setLogWriter(java.io.PrintWriter) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.sql.SQLException java.util.Iterator&lt;java.lang.Throwable&gt; iterator()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -50,6 +101,9 @@
<item name="java.sql.Time java.sql.Time valueOf(java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.sql.Timestamp boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.sql.Timestamp boolean equals(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/util/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/util/annotations.xml
index 363b81c827b4..5e73e2012e79 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/util/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/util/annotations.xml
@@ -2,15 +2,27 @@
<item name="java.util.AbstractCollection T[] toArray(T[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.AbstractCollection boolean add(E) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.AbstractCollection boolean addAll(java.util.Collection&lt;? extends E&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.AbstractCollection boolean contains(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.AbstractCollection boolean containsAll(java.util.Collection&lt;?&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.AbstractCollection boolean remove(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.AbstractCollection java.lang.String toString()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.AbstractList E set(int, E) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.AbstractList boolean add(E)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;true;null-&gt;true&quot;"/>
@@ -19,6 +31,15 @@
<item name="java.util.AbstractList boolean addAll(int, java.util.Collection&lt;? extends E&gt;) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.AbstractList boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.AbstractList int indexOf(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.AbstractList int lastIndexOf(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.AbstractList java.lang.String outOfBoundsMsg(int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -31,6 +52,33 @@
<item name="java.util.AbstractList java.util.ListIterator&lt;E&gt; listIterator(int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.AbstractList void add(int, E) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.AbstractList.Itr Itr(java.util.AbstractList, java.util.AbstractList.1) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.AbstractMap V get(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.AbstractMap V put(K, V) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.AbstractMap V put(K, V) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.AbstractMap V remove(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.AbstractMap boolean containsKey(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.AbstractMap boolean containsValue(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.AbstractMap boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.AbstractMap java.lang.String toString()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -46,6 +94,12 @@
<item name="java.util.AbstractMap.SimpleEntry SimpleEntry(java.util.Map.Entry&lt;K,V&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.AbstractMap.SimpleEntry boolean eq(java.lang.Object, java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.AbstractMap.SimpleEntry boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.AbstractMap.SimpleEntry boolean equals(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -65,6 +119,9 @@
<item name="java.util.AbstractSequentialList boolean addAll(int, java.util.Collection&lt;? extends E&gt;) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.AbstractSet boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.AbstractSet boolean removeAll(java.util.Collection&lt;?&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -85,6 +142,15 @@
<item name="java.util.ArrayList boolean addAll(java.util.Collection&lt;? extends E&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.ArrayList boolean remove(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.ArrayList int indexOf(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.ArrayList int lastIndexOf(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.ArrayList java.lang.Object[] toArray()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -97,9 +163,72 @@
<item name="java.util.Arrays T[] cloneSubarray(T[], int, int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Arrays boolean deepEquals(java.lang.Object[], java.lang.Object[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Arrays boolean deepEquals(java.lang.Object[], java.lang.Object[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Arrays boolean equals(boolean[], boolean[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Arrays boolean equals(boolean[], boolean[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Arrays boolean equals(byte[], byte[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Arrays boolean equals(byte[], byte[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Arrays boolean equals(char[], char[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Arrays boolean equals(char[], char[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Arrays boolean equals(double[], double[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Arrays boolean equals(double[], double[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Arrays boolean equals(float[], float[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Arrays boolean equals(float[], float[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Arrays boolean equals(int[], int[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Arrays boolean equals(int[], int[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Arrays boolean equals(java.lang.Object[], java.lang.Object[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Arrays boolean equals(java.lang.Object[], java.lang.Object[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Arrays boolean equals(long[], long[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Arrays boolean equals(long[], long[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Arrays boolean equals(short[], short[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Arrays boolean equals(short[], short[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Arrays int binarySearch(T[], T, java.util.Comparator&lt;? super T&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Arrays int binarySearch(T[], T, java.util.Comparator&lt;? super T&gt;) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Arrays int binarySearch(byte[], byte) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -124,6 +253,36 @@
<item name="java.util.Arrays int binarySearch(short[], short) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Arrays int deepHashCode(java.lang.Object[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Arrays int hashCode(boolean[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Arrays int hashCode(byte[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Arrays int hashCode(char[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Arrays int hashCode(double[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Arrays int hashCode(float[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Arrays int hashCode(int[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Arrays int hashCode(java.lang.Object[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Arrays int hashCode(long[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Arrays int hashCode(short[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Arrays int med3(byte[], int, int, int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -145,33 +304,63 @@
<item name="java.util.Arrays int med3(short[], int, int, int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Arrays java.lang.String deepToString(java.lang.Object[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Arrays java.lang.String deepToString(java.lang.Object[])">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Arrays java.lang.String toString(boolean[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Arrays java.lang.String toString(boolean[])">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Arrays java.lang.String toString(byte[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Arrays java.lang.String toString(byte[])">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Arrays java.lang.String toString(char[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Arrays java.lang.String toString(char[])">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Arrays java.lang.String toString(double[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Arrays java.lang.String toString(double[])">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Arrays java.lang.String toString(float[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Arrays java.lang.String toString(float[])">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Arrays java.lang.String toString(int[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Arrays java.lang.String toString(int[])">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Arrays java.lang.String toString(java.lang.Object[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Arrays java.lang.String toString(java.lang.Object[])">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Arrays java.lang.String toString(long[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Arrays java.lang.String toString(long[])">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Arrays java.lang.String toString(short[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Arrays java.lang.String toString(short[])">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -181,6 +370,9 @@
<item name="java.util.Arrays java.util.List&lt;T&gt; asList(T...)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Arrays void deepToString(java.lang.Object[], java.lang.StringBuilder, java.util.Set&lt;java.lang.Object[]&gt;) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Arrays void deepToString(java.lang.Object[], java.lang.StringBuilder, java.util.Set&lt;java.lang.Object[]&gt;) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -241,9 +433,15 @@
<item name="java.util.Arrays void sort(T[], int, int, java.util.Comparator&lt;? super T&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Arrays void sort(T[], int, int, java.util.Comparator&lt;? super T&gt;) 3">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Arrays void sort(T[], java.util.Comparator&lt;? super T&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Arrays void sort(T[], java.util.Comparator&lt;? super T&gt;) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Arrays void sort(byte[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -319,16 +517,28 @@
<item name="java.util.Arrays.ArrayList ArrayList(E[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Arrays.ArrayList int indexOf(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Calendar boolean after(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Calendar boolean after(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="java.util.Calendar boolean before(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Calendar boolean before(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="java.util.Calendar boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Calendar java.lang.String toString()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -377,12 +587,18 @@
<item name="java.util.Collections T max(java.util.Collection&lt;? extends T&gt;, java.util.Comparator&lt;? super T&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Collections T max(java.util.Collection&lt;? extends T&gt;, java.util.Comparator&lt;? super T&gt;) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Collections T min(java.util.Collection&lt;? extends T&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.util.Collections T min(java.util.Collection&lt;? extends T&gt;, java.util.Comparator&lt;? super T&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Collections T min(java.util.Collection&lt;? extends T&gt;, java.util.Comparator&lt;? super T&gt;) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Collections boolean addAll(java.util.Collection&lt;? super T&gt;, T...) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -392,18 +608,30 @@
<item name="java.util.Collections boolean disjoint(java.util.Collection&lt;?&gt;, java.util.Collection&lt;?&gt;) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Collections boolean eq(java.lang.Object, java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Collections boolean replaceAll(java.util.List&lt;T&gt;, T, T) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Collections boolean replaceAll(java.util.List&lt;T&gt;, T, T) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Collections int binarySearch(java.util.List&lt;? extends T&gt;, T, java.util.Comparator&lt;? super T&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Collections int binarySearch(java.util.List&lt;? extends T&gt;, T, java.util.Comparator&lt;? super T&gt;) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Collections int binarySearch(java.util.List&lt;? extends java.lang.Comparable&lt;? super T&gt;&gt;, T) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.util.Collections int frequency(java.util.Collection&lt;?&gt;, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Collections int frequency(java.util.Collection&lt;?&gt;, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Collections int indexOfSubList(java.util.List&lt;?&gt;, java.util.List&lt;?&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -455,6 +683,9 @@
<item name="java.util.Collections java.util.Collection&lt;T&gt; unmodifiableCollection(java.util.Collection&lt;? extends T&gt;)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Collections java.util.Comparator&lt;T&gt; reverseOrder(java.util.Comparator&lt;T&gt;) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Collections java.util.Enumeration&lt;T&gt; enumeration(java.util.Collection&lt;T&gt;)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -632,6 +863,9 @@
<item name="java.util.Collections void sort(java.util.List&lt;T&gt;, java.util.Comparator&lt;? super T&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Collections void sort(java.util.List&lt;T&gt;, java.util.Comparator&lt;? super T&gt;) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Collections void swap(java.lang.Object[], int, int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -664,6 +898,9 @@
<item name="java.util.Collections.CheckedCollection java.util.Iterator&lt;E&gt; iterator()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Collections.CheckedCollection void typeCheck(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Collections.CheckedList CheckedList(java.util.List&lt;E&gt;, java.lang.Class&lt;E&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -700,9 +937,21 @@
<item name="java.util.Collections.CheckedMap void putAll(java.util.Map&lt;? extends K,? extends V&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Collections.CheckedMap void typeCheck(java.lang.Object, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Collections.CheckedMap.CheckedEntrySet T[] toArray(T[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Collections.CheckedMap.CheckedEntrySet boolean add(java.util.Map.Entry&lt;K,V&gt;) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Collections.CheckedMap.CheckedEntrySet boolean addAll(java.util.Collection&lt;? extends java.util.Map.Entry&lt;K,V&gt;&gt;) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Collections.CheckedMap.CheckedEntrySet boolean contains(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Collections.CheckedMap.CheckedEntrySet boolean contains(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -711,6 +960,12 @@
<item name="java.util.Collections.CheckedMap.CheckedEntrySet boolean containsAll(java.util.Collection&lt;?&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Collections.CheckedMap.CheckedEntrySet boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Collections.CheckedMap.CheckedEntrySet boolean remove(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Collections.CheckedMap.CheckedEntrySet boolean remove(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -725,6 +980,9 @@
<item name="java.util.Collections.CheckedMap.CheckedEntrySet.1 java.util.Map.Entry&lt;K,V&gt; next()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Collections.CheckedMap.CheckedEntrySet.CheckedEntry boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Collections.CheckedMap.CheckedEntrySet.CheckedEntry java.lang.String badValueMsg(java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -782,12 +1040,21 @@
<item name="java.util.Collections.CopiesList T[] toArray(T[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Collections.CopiesList boolean contains(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Collections.CopiesList java.lang.Object[] toArray()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.util.Collections.CopiesList java.util.List&lt;E&gt; subList(int, int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Collections.EmptyIterator EmptyIterator(java.util.Collections.1) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Collections.EmptyList EmptyList(java.util.Collections.1) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Collections.EmptyList T[] toArray(T[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -796,6 +1063,9 @@
<val val="&quot;!null-&gt;!null&quot;"/>
</annotation>
</item>
+ <item name="java.util.Collections.EmptyList boolean contains(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Collections.EmptyList boolean contains(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;false;null-&gt;false&quot;"/>
@@ -804,6 +1074,9 @@
<item name="java.util.Collections.EmptyList boolean containsAll(java.util.Collection&lt;?&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Collections.EmptyList boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Collections.EmptyList boolean equals(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -812,26 +1085,50 @@
<item name="java.util.Collections.EmptyList java.lang.Object[] toArray()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Collections.EmptyListIterator void add(E) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Collections.EmptyListIterator void set(E) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Collections.EmptyMap EmptyMap(java.util.Collections.1) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Collections.EmptyMap V get(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Collections.EmptyMap V get(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;null;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="java.util.Collections.EmptyMap boolean containsKey(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Collections.EmptyMap boolean containsKey(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;false;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="java.util.Collections.EmptyMap boolean containsValue(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Collections.EmptyMap boolean containsValue(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;false;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="java.util.Collections.EmptyMap boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Collections.EmptyMap boolean equals(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="java.util.Collections.EmptySet EmptySet(java.util.Collections.1) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Collections.EmptySet T[] toArray(T[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -840,6 +1137,9 @@
<val val="&quot;!null-&gt;!null&quot;"/>
</annotation>
</item>
+ <item name="java.util.Collections.EmptySet boolean contains(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Collections.EmptySet boolean contains(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;false;null-&gt;false&quot;"/>
@@ -854,15 +1154,33 @@
<item name="java.util.Collections.ReverseComparator int compare(java.lang.Comparable&lt;java.lang.Object&gt;, java.lang.Comparable&lt;java.lang.Object&gt;) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Collections.ReverseComparator2 boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Collections.SetFromMap SetFromMap(java.util.Map&lt;E,java.lang.Boolean&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.util.Collections.SetFromMap void readObject(java.io.ObjectInputStream) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Collections.SingletonList boolean contains(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Collections.SingletonList java.util.Iterator&lt;E&gt; iterator()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Collections.SingletonMap V get(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Collections.SingletonMap boolean containsKey(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Collections.SingletonMap boolean containsValue(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Collections.SingletonSet boolean contains(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Collections.SingletonSet java.util.Iterator&lt;E&gt; iterator()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -926,12 +1244,33 @@
<item name="java.util.Collections.UnmodifiableCollection UnmodifiableCollection(java.util.Collection&lt;? extends E&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Collections.UnmodifiableCollection boolean add(E) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Collections.UnmodifiableCollection boolean addAll(java.util.Collection&lt;? extends E&gt;) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Collections.UnmodifiableCollection boolean remove(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Collections.UnmodifiableCollection boolean removeAll(java.util.Collection&lt;?&gt;) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Collections.UnmodifiableCollection boolean retainAll(java.util.Collection&lt;?&gt;) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Collections.UnmodifiableCollection java.util.Iterator&lt;E&gt; iterator()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Collections.UnmodifiableList E set(int, E) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Collections.UnmodifiableList UnmodifiableList(java.util.List&lt;? extends E&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Collections.UnmodifiableList boolean addAll(int, java.util.Collection&lt;? extends E&gt;) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Collections.UnmodifiableList java.lang.Object readResolve()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -941,15 +1280,39 @@
<item name="java.util.Collections.UnmodifiableList java.util.ListIterator&lt;E&gt; listIterator(int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Collections.UnmodifiableList void add(int, E) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Collections.UnmodifiableList.1 void add(E) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Collections.UnmodifiableList.1 void set(E) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Collections.UnmodifiableMap UnmodifiableMap(java.util.Map&lt;? extends K,? extends V&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Collections.UnmodifiableMap V put(K, V) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Collections.UnmodifiableMap V put(K, V) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Collections.UnmodifiableMap V remove(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Collections.UnmodifiableMap void putAll(java.util.Map&lt;? extends K,? extends V&gt;) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Collections.UnmodifiableMap.UnmodifiableEntrySet T[] toArray(T[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.util.Collections.UnmodifiableMap.UnmodifiableEntrySet UnmodifiableEntrySet(java.util.Set&lt;? extends java.util.Map.Entry&lt;? extends K,? extends V&gt;&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Collections.UnmodifiableMap.UnmodifiableEntrySet boolean contains(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Collections.UnmodifiableMap.UnmodifiableEntrySet boolean contains(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -958,12 +1321,21 @@
<item name="java.util.Collections.UnmodifiableMap.UnmodifiableEntrySet boolean containsAll(java.util.Collection&lt;?&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Collections.UnmodifiableMap.UnmodifiableEntrySet boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Collections.UnmodifiableMap.UnmodifiableEntrySet java.util.Iterator&lt;java.util.Map.Entry&lt;K,V&gt;&gt; iterator()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.util.Collections.UnmodifiableMap.UnmodifiableEntrySet.1 java.util.Map.Entry&lt;K,V&gt; next()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Collections.UnmodifiableMap.UnmodifiableEntrySet.UnmodifiableEntry V setValue(V) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Collections.UnmodifiableMap.UnmodifiableEntrySet.UnmodifiableEntry boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Collections.UnmodifiableRandomAccessList UnmodifiableRandomAccessList(java.util.List&lt;? extends E&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -1009,6 +1381,9 @@
<item name="java.util.Date boolean before(java.util.Date) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Date boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Date boolean equals(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -1026,6 +1401,9 @@
<item name="java.util.Date void writeObject(java.io.ObjectOutputStream) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.GregorianCalendar boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.GregorianCalendar boolean equals(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -1052,6 +1430,9 @@
<item name="java.util.HashMap HashMap(java.util.Map&lt;? extends K,? extends V&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.HashMap T maskNull(T) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.HashMap T maskNull(T)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null&quot;"/>
@@ -1062,6 +1443,18 @@
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="java.util.HashMap V get(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.HashMap V put(K, V) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.HashMap boolean containsKey(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.HashMap boolean containsValue(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.HashMap boolean eq(java.lang.Object, java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;true&quot;"/>
@@ -1070,6 +1463,15 @@
<item name="java.util.HashMap int hash(java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.HashMap java.util.HashMap.Entry&lt;K,V&gt; getEntry(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.HashMap java.util.HashMap.Entry&lt;K,V&gt; removeEntryForKey(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.HashMap java.util.HashMap.Entry&lt;K,V&gt; removeMapping(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.HashMap java.util.HashMap.Entry&lt;K,V&gt; removeMapping(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
@@ -1090,6 +1492,9 @@
<item name="java.util.HashMap void putAllForCreate(java.util.Map&lt;? extends K,? extends V&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.HashMap void putForCreate(K, V) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.HashMap void readObject(java.io.ObjectInputStream) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -1120,6 +1525,9 @@
<item name="java.util.Hashtable boolean containsKey(java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Hashtable boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Hashtable int access$200(java.util.Hashtable) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -1162,6 +1570,9 @@
<item name="java.util.Hashtable.Entry V setValue(V) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Hashtable.Entry boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Hashtable.Entry boolean equals(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -1173,25 +1584,82 @@
<item name="java.util.Hashtable.Entry java.lang.String toString()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Hashtable.EntrySet EntrySet(java.util.Hashtable, java.util.Hashtable.1) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Hashtable.EntrySet boolean contains(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Hashtable.EntrySet boolean contains(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="java.util.Hashtable.EntrySet boolean remove(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Hashtable.EntrySet boolean remove(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="java.util.Hashtable.KeySet KeySet(java.util.Hashtable, java.util.Hashtable.1) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Hashtable.ValueCollection ValueCollection(java.util.Hashtable, java.util.Hashtable.1) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.IdentityHashMap IdentityHashMap(java.util.Map&lt;? extends K,? extends V&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.IdentityHashMap V get(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.IdentityHashMap V put(K, V) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.IdentityHashMap V remove(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.IdentityHashMap boolean access$1500(java.util.IdentityHashMap, java.lang.Object, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.IdentityHashMap boolean access$1500(java.util.IdentityHashMap, java.lang.Object, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.IdentityHashMap boolean access$1500(java.util.IdentityHashMap, java.lang.Object, java.lang.Object) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.IdentityHashMap boolean access$1600(java.util.IdentityHashMap, java.lang.Object, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.IdentityHashMap boolean access$1600(java.util.IdentityHashMap, java.lang.Object, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.IdentityHashMap boolean access$1600(java.util.IdentityHashMap, java.lang.Object, java.lang.Object) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.IdentityHashMap boolean containsKey(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.IdentityHashMap boolean containsMapping(java.lang.Object, java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.IdentityHashMap boolean containsMapping(java.lang.Object, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.IdentityHashMap boolean containsValue(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.IdentityHashMap boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.IdentityHashMap boolean removeMapping(java.lang.Object, java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.IdentityHashMap boolean removeMapping(java.lang.Object, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.IdentityHashMap int access$000(java.util.IdentityHashMap) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -1209,6 +1677,9 @@
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="java.util.IdentityHashMap java.lang.Object maskNull(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.IdentityHashMap java.lang.Object maskNull(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null&quot;"/>
@@ -1225,12 +1696,24 @@
<item name="java.util.IdentityHashMap void putAll(java.util.Map&lt;? extends K,? extends V&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.IdentityHashMap void putForCreate(K, V) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.IdentityHashMap void readObject(java.io.ObjectInputStream) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.util.IdentityHashMap void writeObject(java.io.ObjectOutputStream) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.IdentityHashMap.EntryIterator EntryIterator(java.util.IdentityHashMap, java.util.IdentityHashMap.1) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.IdentityHashMap.EntryIterator.Entry Entry(java.util.IdentityHashMap.EntryIterator, int, java.util.IdentityHashMap.1) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.IdentityHashMap.EntryIterator.Entry boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.IdentityHashMap.EntryIterator.Entry int access$800(java.util.IdentityHashMap.EntryIterator.Entry) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -1240,14 +1723,23 @@
<item name="java.util.IdentityHashMap.EntryIterator.Entry java.lang.String toString()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.IdentityHashMap.EntrySet EntrySet(java.util.IdentityHashMap, java.util.IdentityHashMap.1) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.IdentityHashMap.EntrySet T[] toArray(T[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.IdentityHashMap.EntrySet boolean contains(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.IdentityHashMap.EntrySet boolean contains(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="java.util.IdentityHashMap.EntrySet boolean remove(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.IdentityHashMap.EntrySet boolean remove(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -1256,9 +1748,27 @@
<item name="java.util.IdentityHashMap.EntrySet java.util.Iterator&lt;java.util.Map.Entry&lt;K,V&gt;&gt; iterator()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.IdentityHashMap.IdentityHashMapIterator IdentityHashMapIterator(java.util.IdentityHashMap, java.util.IdentityHashMap.1) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.IdentityHashMap.KeyIterator KeyIterator(java.util.IdentityHashMap, java.util.IdentityHashMap.1) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.IdentityHashMap.KeySet KeySet(java.util.IdentityHashMap, java.util.IdentityHashMap.1) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.IdentityHashMap.KeySet java.util.Iterator&lt;K&gt; iterator()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.IdentityHashMap.ValueIterator ValueIterator(java.util.IdentityHashMap, java.util.IdentityHashMap.1) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.IdentityHashMap.Values Values(java.util.IdentityHashMap, java.util.IdentityHashMap.1) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.IdentityHashMap.Values boolean remove(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.IdentityHashMap.Values java.util.Iterator&lt;V&gt; iterator()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -1280,12 +1790,21 @@
<item name="java.util.Locale Locale(java.lang.String, java.lang.String, java.lang.String) 2">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Locale boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Locale java.lang.String convertOldISOCodes(java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="java.util.Locale java.lang.String formatList(java.lang.String[], java.lang.String, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Locale java.lang.String formatList(java.lang.String[], java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.Locale java.lang.String formatList(java.lang.String[], java.lang.String, java.lang.String) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Locale java.lang.String formatList(java.lang.String[], java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,_,null-&gt;!null;_,null,_-&gt;!null&quot;"/>
@@ -1335,6 +1854,9 @@
<item name="java.util.Locale java.lang.String[] composeList(java.text.MessageFormat, java.lang.String[]) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.Locale java.lang.String[] getDisplayVariantArray(sun.util.resources.OpenListResourceBundle, java.util.Locale) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.Locale java.lang.String[] getISO2Table(java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -1422,11 +1944,23 @@
<item name="java.util.TreeMap TreeMap(java.util.SortedMap&lt;K,? extends V&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.TreeMap boolean access$500(java.lang.Object, java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.TreeMap boolean colorOf(java.util.TreeMap.Entry&lt;K,V&gt;) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.TreeMap boolean colorOf(java.util.TreeMap.Entry&lt;K,V&gt;)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;true&quot;"/>
</annotation>
</item>
+ <item name="java.util.TreeMap boolean containsValue(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.TreeMap boolean valEquals(java.lang.Object, java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.TreeMap boolean valueSearchNonNull(java.util.TreeMap.Entry, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -1475,6 +2009,9 @@
<item name="java.util.TreeMap java.util.TreeMap.Entry access$400(java.util.TreeMap, java.util.TreeMap.Entry) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.TreeMap java.util.TreeMap.Entry access$400(java.util.TreeMap, java.util.TreeMap.Entry) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.TreeMap java.util.TreeMap.Entry access$400(java.util.TreeMap, java.util.TreeMap.Entry)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,null-&gt;null&quot;"/>
@@ -1483,21 +2020,33 @@
<item name="java.util.TreeMap java.util.TreeMap.Entry access$800(java.util.TreeMap, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.TreeMap java.util.TreeMap.Entry&lt;K,V&gt; leftOf(java.util.TreeMap.Entry&lt;K,V&gt;) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.TreeMap java.util.TreeMap.Entry&lt;K,V&gt; leftOf(java.util.TreeMap.Entry&lt;K,V&gt;)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="java.util.TreeMap java.util.TreeMap.Entry&lt;K,V&gt; parentOf(java.util.TreeMap.Entry&lt;K,V&gt;) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.TreeMap java.util.TreeMap.Entry&lt;K,V&gt; parentOf(java.util.TreeMap.Entry&lt;K,V&gt;)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="java.util.TreeMap java.util.TreeMap.Entry&lt;K,V&gt; rightOf(java.util.TreeMap.Entry&lt;K,V&gt;) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.TreeMap java.util.TreeMap.Entry&lt;K,V&gt; rightOf(java.util.TreeMap.Entry&lt;K,V&gt;)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="java.util.TreeMap java.util.TreeMap.Entry&lt;K,V&gt; successor(java.util.TreeMap.Entry&lt;K,V&gt;) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.TreeMap java.util.TreeMap.Entry&lt;K,V&gt; successor(java.util.TreeMap.Entry&lt;K,V&gt;)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
@@ -1512,6 +2061,9 @@
<item name="java.util.TreeMap void deleteEntry(java.util.TreeMap.Entry&lt;K,V&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.TreeMap void fixAfterDeletion(java.util.TreeMap.Entry&lt;K,V&gt;) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.TreeMap void fixAfterInsertion(java.util.TreeMap.Entry&lt;K,V&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -1527,6 +2079,9 @@
<item name="java.util.TreeMap void rotateRight(java.util.TreeMap.Entry&lt;K,V&gt;) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.TreeMap void setColor(java.util.TreeMap.Entry&lt;K,V&gt;, boolean) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.TreeMap void writeObject(java.io.ObjectOutputStream) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/util/concurrent/atomic/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/util/concurrent/atomic/annotations.xml
index def395c4cf42..30e85d4f3ee8 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/util/concurrent/atomic/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/util/concurrent/atomic/annotations.xml
@@ -59,6 +59,12 @@
<item name="java.util.concurrent.atomic.AtomicMarkableReference V get(boolean[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.concurrent.atomic.AtomicMarkableReference boolean compareAndSet(V, V, boolean, boolean) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.concurrent.atomic.AtomicMarkableReference boolean weakCompareAndSet(V, V, boolean, boolean) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.concurrent.atomic.AtomicMarkableReference.ReferenceBooleanPair boolean access$100(java.util.concurrent.atomic.AtomicMarkableReference.ReferenceBooleanPair) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -86,9 +92,18 @@
<item name="java.util.concurrent.atomic.AtomicReferenceFieldUpdater.AtomicReferenceFieldUpdaterImpl AtomicReferenceFieldUpdaterImpl(java.lang.Class&lt;T&gt;, java.lang.Class&lt;V&gt;, java.lang.String) 2">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.concurrent.atomic.AtomicReferenceFieldUpdater.AtomicReferenceFieldUpdaterImpl void updateCheck(T, V) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.concurrent.atomic.AtomicStampedReference V get(int[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.concurrent.atomic.AtomicStampedReference boolean compareAndSet(V, V, int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="java.util.concurrent.atomic.AtomicStampedReference boolean weakCompareAndSet(V, V, int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.concurrent.atomic.AtomicStampedReference.ReferenceIntegerPair int access$100(java.util.concurrent.atomic.AtomicStampedReference.ReferenceIntegerPair) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/util/concurrent/locks/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/util/concurrent/locks/annotations.xml
index a5aef3c11bb8..08c07b4d957f 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/util/concurrent/locks/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/java/util/concurrent/locks/annotations.xml
@@ -2,6 +2,9 @@
<item name="java.util.concurrent.locks.AbstractQueuedSynchronizer boolean acquireQueued(java.util.concurrent.locks.AbstractQueuedSynchronizer.Node, int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.concurrent.locks.AbstractQueuedSynchronizer boolean findNodeFromTail(java.util.concurrent.locks.AbstractQueuedSynchronizer.Node) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.concurrent.locks.AbstractQueuedSynchronizer boolean hasWaiters(java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -35,6 +38,9 @@
<item name="java.util.concurrent.locks.AbstractQueuedSynchronizer java.util.concurrent.locks.AbstractQueuedSynchronizer.Node enq(java.util.concurrent.locks.AbstractQueuedSynchronizer.Node) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.concurrent.locks.AbstractQueuedSynchronizer void cancelAcquire(java.util.concurrent.locks.AbstractQueuedSynchronizer.Node) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.concurrent.locks.AbstractQueuedSynchronizer void setHead(java.util.concurrent.locks.AbstractQueuedSynchronizer.Node) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -50,6 +56,9 @@
<item name="java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject boolean awaitUntil(java.util.Date) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject boolean isOwnedBy(java.util.concurrent.locks.AbstractQueuedSynchronizer) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject java.util.concurrent.locks.AbstractQueuedSynchronizer.Node addConditionWaiter()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -59,6 +68,9 @@
<item name="java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject void doSignalAll(java.util.concurrent.locks.AbstractQueuedSynchronizer.Node) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="java.util.concurrent.locks.LockSupport void unpark(java.lang.Thread) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="java.util.concurrent.locks.ReentrantLock boolean hasWaiters(java.util.concurrent.locks.Condition) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/javax/swing/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/javax/swing/annotations.xml
index c0738eb8897d..910842a47153 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/javax/swing/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/javax/swing/annotations.xml
@@ -1,4 +1,10 @@
<root>
+ <item name="javax.swing.AbstractButton boolean isListener(java.lang.Class, java.awt.event.ActionListener) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="javax.swing.AbstractButton boolean isListener(java.lang.Class, java.awt.event.ActionListener) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.AbstractButton java.beans.PropertyChangeListener createActionPropertyChangeListener(javax.swing.Action)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -11,6 +17,24 @@
<item name="javax.swing.AbstractButton void access$100(javax.swing.AbstractButton) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="javax.swing.AbstractButton void configurePropertiesFromAction(javax.swing.Action, java.lang.String[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="javax.swing.AbstractButton void configurePropertiesFromAction(javax.swing.Action, java.lang.String[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="javax.swing.AbstractButton void init(java.lang.String, javax.swing.Icon) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="javax.swing.AbstractButton void init(java.lang.String, javax.swing.Icon) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="javax.swing.AbstractButton void setUIProperty(java.lang.String, java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="javax.swing.AbstractButton void updateDisplayedMnemonicIndex(java.lang.String, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.JButton java.lang.String getUIClassID()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -39,6 +63,9 @@
<item name="javax.swing.JComponent byte getWriteObjCounter(javax.swing.JComponent) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="javax.swing.JComponent java.awt.Dimension getSize(java.awt.Dimension) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.JComponent java.awt.Dimension getSize(java.awt.Dimension)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null;null-&gt;!null&quot;"/>
@@ -49,21 +76,36 @@
<val val="&quot;!null-&gt;!null;null-&gt;!null&quot;"/>
</annotation>
</item>
+ <item name="javax.swing.JComponent java.awt.Insets getInsets(java.awt.Insets) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="javax.swing.JComponent java.awt.Point getLocation(java.awt.Point) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.JComponent java.awt.Point getLocation(java.awt.Point)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null;null-&gt;!null&quot;"/>
</annotation>
</item>
+ <item name="javax.swing.JComponent java.awt.Point getPopupLocation(java.awt.event.MouseEvent) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.JComponent java.awt.Point getPopupLocation(java.awt.event.MouseEvent)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;null;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="javax.swing.JComponent java.awt.Point getToolTipLocation(java.awt.event.MouseEvent) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.JComponent java.awt.Point getToolTipLocation(java.awt.event.MouseEvent)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;null;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="javax.swing.JComponent java.awt.Rectangle getBounds(java.awt.Rectangle) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.JComponent java.awt.Rectangle getBounds(java.awt.Rectangle)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null;null-&gt;!null&quot;"/>
@@ -72,6 +114,9 @@
<item name="javax.swing.JComponent java.awt.Rectangle getVisibleRect()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="javax.swing.JComponent java.lang.String getToolTipText(java.awt.event.MouseEvent) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.JComponent java.lang.String getUIClassID()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -81,6 +126,9 @@
<item name="javax.swing.JComponent javax.swing.JToolTip createToolTip()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="javax.swing.JComponent void componentInputMapChanged(javax.swing.ComponentInputMap) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.JComponent void computeVisibleRect(java.awt.Component, java.awt.Rectangle) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -99,21 +147,33 @@
<item name="javax.swing.JComponent void paintWithOffscreenBuffer(javax.swing.JComponent, java.awt.Graphics, int, int, int, int, java.awt.Image) 6">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="javax.swing.JComponent void processComponentKeyEvent(java.awt.event.KeyEvent) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.JComponent void processKeyEvent(java.awt.event.KeyEvent) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="javax.swing.JComponent void readObject(java.io.ObjectInputStream) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="javax.swing.JComponent void registerNextFocusableComponent(java.awt.Component) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.JComponent void repaint(java.awt.Rectangle) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="javax.swing.JComponent void setUIProperty(java.lang.String, java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.JComponent void setWriteObjCounter(javax.swing.JComponent, byte) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="javax.swing.JComponent void writeObject(java.io.ObjectOutputStream) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="javax.swing.JComponent.AccessibleJComponent java.lang.String getBorderTitle(javax.swing.border.Border) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.JComponent.AccessibleJComponent java.lang.String getBorderTitle(javax.swing.border.Border)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
@@ -125,6 +185,21 @@
<item name="javax.swing.JComponent.AccessibleJComponent javax.swing.JComponent access$100(javax.swing.JComponent.AccessibleJComponent) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="javax.swing.JDialog JDialog(java.awt.Frame) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="javax.swing.JDialog JDialog(java.awt.Frame, boolean) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="javax.swing.JDialog JDialog(java.awt.Frame, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="javax.swing.JDialog JDialog(java.awt.Frame, java.lang.String, boolean) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="javax.swing.JDialog JDialog(java.awt.Frame, java.lang.String, boolean, java.awt.GraphicsConfiguration) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.JDialog java.lang.String paramString()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -161,6 +236,12 @@
<item name="javax.swing.JPanel void writeObject(java.io.ObjectOutputStream) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="javax.swing.JScrollPane JScrollPane(java.awt.Component) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="javax.swing.JScrollPane JScrollPane(java.awt.Component, int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.JScrollPane java.awt.Component getCorner(java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -188,6 +269,24 @@
<item name="javax.swing.JScrollPane void writeObject(java.io.ObjectOutputStream) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="javax.swing.JTable JTable(javax.swing.table.TableModel) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="javax.swing.JTable JTable(javax.swing.table.TableModel, javax.swing.table.TableColumnModel) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="javax.swing.JTable JTable(javax.swing.table.TableModel, javax.swing.table.TableColumnModel) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="javax.swing.JTable JTable(javax.swing.table.TableModel, javax.swing.table.TableColumnModel, javax.swing.ListSelectionModel) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="javax.swing.JTable JTable(javax.swing.table.TableModel, javax.swing.table.TableColumnModel, javax.swing.ListSelectionModel) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="javax.swing.JTable JTable(javax.swing.table.TableModel, javax.swing.table.TableColumnModel, javax.swing.ListSelectionModel) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.JTable boolean print(int, java.text.MessageFormat, java.text.MessageFormat, boolean, javax.print.attribute.PrintRequestAttributeSet)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,_,_,false,_-&gt;true&quot;"/>
@@ -199,9 +298,15 @@
<item name="javax.swing.JTable int getScrollableBlockIncrement(java.awt.Rectangle, int, int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="javax.swing.JTable int getScrollableUnitIncrement(java.awt.Rectangle, int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.JTable int rowAtPoint(java.awt.Point) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="javax.swing.JTable int viewIndexForColumn(javax.swing.table.TableColumn) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.JTable int[] getSelectedRows()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -226,6 +331,9 @@
<item name="javax.swing.JTable java.lang.String paramString()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="javax.swing.JTable javax.swing.JScrollPane createScrollPaneForTable(javax.swing.JTable) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.JTable javax.swing.JScrollPane createScrollPaneForTable(javax.swing.JTable)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -235,11 +343,17 @@
<item name="javax.swing.JTable javax.swing.table.JTableHeader createDefaultTableHeader()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="javax.swing.JTable javax.swing.table.TableCellEditor getDefaultEditor(java.lang.Class) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.JTable javax.swing.table.TableCellEditor getDefaultEditor(java.lang.Class)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="javax.swing.JTable javax.swing.table.TableCellRenderer getDefaultRenderer(java.lang.Class) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.JTable javax.swing.table.TableCellRenderer getDefaultRenderer(java.lang.Class)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
@@ -263,15 +377,39 @@
<item name="javax.swing.JTable void changeSelectionModel(javax.swing.ListSelectionModel, int, boolean, boolean, boolean) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="javax.swing.JTable void columnAdded(javax.swing.event.TableColumnModelEvent) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="javax.swing.JTable void columnMarginChanged(javax.swing.event.ChangeEvent) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="javax.swing.JTable void columnMoved(javax.swing.event.TableColumnModelEvent) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="javax.swing.JTable void columnRemoved(javax.swing.event.TableColumnModelEvent) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.JTable void columnSelectionChanged(javax.swing.event.ListSelectionEvent) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="javax.swing.JTable void editingCanceled(javax.swing.event.ChangeEvent) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="javax.swing.JTable void editingStopped(javax.swing.event.ChangeEvent) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.JTable void readObject(java.io.ObjectInputStream) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="javax.swing.JTable void setColumnModel(javax.swing.table.TableColumnModel) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="javax.swing.JTable void setDefaultEditor(java.lang.Class, javax.swing.table.TableCellEditor) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="javax.swing.JTable void setDefaultRenderer(java.lang.Class, javax.swing.table.TableCellRenderer) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.JTable void setGridColor(java.awt.Color) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -293,18 +431,36 @@
<item name="javax.swing.JTable void setSelectionModel(javax.swing.ListSelectionModel) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="javax.swing.JTable void setUIProperty(java.lang.String, java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="javax.swing.JTable void tableChanged(javax.swing.event.TableModelEvent) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.JTable void tableRowsDeleted(javax.swing.event.TableModelEvent) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="javax.swing.JTable void tableRowsInserted(javax.swing.event.TableModelEvent) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="javax.swing.JTable void updateSubComponentUI(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.JTable void valueChanged(javax.swing.event.ListSelectionEvent) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="javax.swing.JTable void writeObject(java.io.ObjectOutputStream) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="javax.swing.SwingUtilities boolean doesIconReferenceImage(javax.swing.Icon, java.awt.Image) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="javax.swing.SwingUtilities boolean doesIconReferenceImage(javax.swing.Icon, java.awt.Image) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="javax.swing.SwingUtilities boolean isDescendingFrom(java.awt.Component, java.awt.Component) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.SwingUtilities boolean isDescendingFrom(java.awt.Component, java.awt.Component)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;true&quot;"/>
@@ -331,11 +487,20 @@
<item name="javax.swing.SwingUtilities boolean isValidKeyEventForKeyBindings(java.awt.event.KeyEvent) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="javax.swing.SwingUtilities boolean notifyAction(javax.swing.Action, javax.swing.KeyStroke, java.awt.event.KeyEvent, java.lang.Object, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="javax.swing.SwingUtilities boolean notifyAction(javax.swing.Action, javax.swing.KeyStroke, java.awt.event.KeyEvent, java.lang.Object, int) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.SwingUtilities boolean notifyAction(javax.swing.Action, javax.swing.KeyStroke, java.awt.event.KeyEvent, java.lang.Object, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,_,null,_,_-&gt;false;null,_,_,_,_-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="javax.swing.SwingUtilities boolean processKeyBindings(java.awt.event.KeyEvent) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.SwingUtilities boolean processKeyBindings(java.awt.event.KeyEvent)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -344,20 +509,41 @@
<item name="javax.swing.SwingUtilities int computeStringWidth(java.awt.FontMetrics, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="javax.swing.SwingUtilities int findDisplayedMnemonicIndex(java.lang.String, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.SwingUtilities int getAccessibleChildrenCount(java.awt.Component) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="javax.swing.SwingUtilities int getAccessibleIndexInParent(java.awt.Component) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="javax.swing.SwingUtilities java.awt.Component findFocusOwner(java.awt.Component) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.SwingUtilities java.awt.Component getDeepestComponentAt(java.awt.Component, int, int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="javax.swing.SwingUtilities java.awt.Component getRoot(java.awt.Component) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="javax.swing.SwingUtilities java.awt.Container getAncestorNamed(java.lang.String, java.awt.Component) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="javax.swing.SwingUtilities java.awt.Container getAncestorNamed(java.lang.String, java.awt.Component) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.SwingUtilities java.awt.Container getAncestorNamed(java.lang.String, java.awt.Component)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,null-&gt;null;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="javax.swing.SwingUtilities java.awt.Container getAncestorOfClass(java.lang.Class, java.awt.Component) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="javax.swing.SwingUtilities java.awt.Container getAncestorOfClass(java.lang.Class, java.awt.Component) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.SwingUtilities java.awt.Container getAncestorOfClass(java.lang.Class, java.awt.Component)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,null-&gt;null;null,_-&gt;null&quot;"/>
@@ -379,6 +565,12 @@
<item name="javax.swing.SwingUtilities java.awt.Point convertScreenLocationToParent(java.awt.Container, int, int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="javax.swing.SwingUtilities java.awt.Rectangle calculateInnerArea(javax.swing.JComponent, java.awt.Rectangle) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="javax.swing.SwingUtilities java.awt.Rectangle calculateInnerArea(javax.swing.JComponent, java.awt.Rectangle) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.SwingUtilities java.awt.Rectangle calculateInnerArea(javax.swing.JComponent, java.awt.Rectangle)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;null&quot;"/>
@@ -412,6 +604,9 @@
<item name="javax.swing.SwingUtilities java.awt.Rectangle getLocalBounds(java.awt.Component)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="javax.swing.SwingUtilities java.awt.Rectangle[] computeDifference(java.awt.Rectangle, java.awt.Rectangle) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.SwingUtilities java.awt.Rectangle[] computeDifference(java.awt.Rectangle, java.awt.Rectangle)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -427,6 +622,9 @@
<item name="javax.swing.SwingUtilities java.awt.event.MouseEvent convertMouseEvent(java.awt.Component, java.awt.event.MouseEvent, java.awt.Component)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="javax.swing.SwingUtilities java.lang.String layoutCompoundLabel(java.awt.FontMetrics, java.lang.String, javax.swing.Icon, int, int, int, int, java.awt.Rectangle, java.awt.Rectangle, java.awt.Rectangle, int) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.SwingUtilities java.lang.String layoutCompoundLabel(java.awt.FontMetrics, java.lang.String, javax.swing.Icon, int, int, int, int, java.awt.Rectangle, java.awt.Rectangle, java.awt.Rectangle, int) 7">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -441,9 +639,15 @@
<val val="&quot;_,!null,_,_,_,_,_,_,_,_,_-&gt;!null&quot;"/>
</annotation>
</item>
+ <item name="javax.swing.SwingUtilities java.lang.String layoutCompoundLabel(javax.swing.JComponent, java.awt.FontMetrics, java.lang.String, javax.swing.Icon, int, int, int, int, java.awt.Rectangle, java.awt.Rectangle, java.awt.Rectangle, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.SwingUtilities java.lang.String layoutCompoundLabel(javax.swing.JComponent, java.awt.FontMetrics, java.lang.String, javax.swing.Icon, int, int, int, int, java.awt.Rectangle, java.awt.Rectangle, java.awt.Rectangle, int) 10">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="javax.swing.SwingUtilities java.lang.String layoutCompoundLabel(javax.swing.JComponent, java.awt.FontMetrics, java.lang.String, javax.swing.Icon, int, int, int, int, java.awt.Rectangle, java.awt.Rectangle, java.awt.Rectangle, int) 3">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.SwingUtilities java.lang.String layoutCompoundLabel(javax.swing.JComponent, java.awt.FontMetrics, java.lang.String, javax.swing.Icon, int, int, int, int, java.awt.Rectangle, java.awt.Rectangle, java.awt.Rectangle, int) 8">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -455,9 +659,15 @@
<val val="&quot;_,_,!null,_,_,_,_,_,_,_,_,_-&gt;!null&quot;"/>
</annotation>
</item>
+ <item name="javax.swing.SwingUtilities java.lang.String layoutCompoundLabelImpl(javax.swing.JComponent, java.awt.FontMetrics, java.lang.String, javax.swing.Icon, int, int, int, int, java.awt.Rectangle, java.awt.Rectangle, java.awt.Rectangle, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.SwingUtilities java.lang.String layoutCompoundLabelImpl(javax.swing.JComponent, java.awt.FontMetrics, java.lang.String, javax.swing.Icon, int, int, int, int, java.awt.Rectangle, java.awt.Rectangle, java.awt.Rectangle, int) 10">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="javax.swing.SwingUtilities java.lang.String layoutCompoundLabelImpl(javax.swing.JComponent, java.awt.FontMetrics, java.lang.String, javax.swing.Icon, int, int, int, int, java.awt.Rectangle, java.awt.Rectangle, java.awt.Rectangle, int) 3">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.SwingUtilities java.lang.String layoutCompoundLabelImpl(javax.swing.JComponent, java.awt.FontMetrics, java.lang.String, javax.swing.Icon, int, int, int, int, java.awt.Rectangle, java.awt.Rectangle, java.awt.Rectangle, int) 8">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -469,6 +679,9 @@
<val val="&quot;_,_,!null,_,_,_,_,_,_,_,_,_-&gt;!null&quot;"/>
</annotation>
</item>
+ <item name="javax.swing.SwingUtilities javax.accessibility.Accessible getAccessibleAt(java.awt.Component, java.awt.Point) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.SwingUtilities javax.accessibility.Accessible getAccessibleAt(java.awt.Component, java.awt.Point)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;null&quot;"/>
@@ -489,6 +702,9 @@
<item name="javax.swing.SwingUtilities javax.swing.InputMap getUIInputMap(javax.swing.JComponent, int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="javax.swing.SwingUtilities javax.swing.JRootPane getRootPane(java.awt.Component) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="javax.swing.SwingUtilities javax.swing.JRootPane getRootPane(java.awt.Component)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
@@ -524,4 +740,7 @@
<item name="javax.swing.SwingUtilities void updateComponentTreeUI(java.awt.Component) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="javax.swing.SwingUtilities void updateComponentTreeUI0(java.awt.Component) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
</root>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/collections/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/collections/annotations.xml
index 08e265e17fcf..89a90c53dae2 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/collections/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/collections/annotations.xml
@@ -5,6 +5,9 @@
<item name="org.apache.commons.collections.ExtendedProperties ExtendedProperties(java.lang.String, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.collections.ExtendedProperties ExtendedProperties(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.collections.ExtendedProperties boolean access$000(java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -17,6 +20,9 @@
<item name="org.apache.commons.collections.ExtendedProperties java.lang.String escape(java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.collections.ExtendedProperties java.lang.String interpolateHelper(java.lang.String, java.util.List) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.collections.ExtendedProperties java.lang.String interpolateHelper(java.lang.String, java.util.List)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;!null;null,_-&gt;null&quot;"/>
@@ -37,4 +43,16 @@
<item name="org.apache.commons.collections.ExtendedProperties void combine(org.apache.commons.collections.ExtendedProperties) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.collections.ExtendedProperties void save(java.io.OutputStream, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.collections.ExtendedProperties void save(java.io.OutputStream, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.collections.ExtendedProperties void setInclude(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.collections.ExtendedProperties.PropertiesTokenizer java.lang.String nextToken()">
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
</root>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/collections/iterators/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/collections/iterators/annotations.xml
new file mode 100644
index 000000000000..d4cfb7e5dfde
--- /dev/null
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/collections/iterators/annotations.xml
@@ -0,0 +1,11 @@
+<root>
+ <item name="org.apache.commons.collections.iterators.AbstractEmptyIterator java.lang.Object setValue(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.collections.iterators.AbstractEmptyIterator void add(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.collections.iterators.AbstractEmptyIterator void set(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+</root>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/collections/map/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/collections/map/annotations.xml
index 26b98c6bdf92..bd99ae8b862d 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/collections/map/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/collections/map/annotations.xml
@@ -2,6 +2,12 @@
<item name="org.apache.commons.collections.map.AbstractHashedMap AbstractHashedMap(java.util.Map) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.collections.map.AbstractHashedMap boolean containsValue(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.collections.map.AbstractHashedMap boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.collections.map.AbstractHashedMap boolean isEqualKey(java.lang.Object, java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;true&quot;"/>
@@ -18,6 +24,9 @@
<item name="org.apache.commons.collections.map.AbstractHashedMap int hash(java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.collections.map.AbstractHashedMap java.lang.Object convertKey(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.collections.map.AbstractHashedMap java.lang.Object convertKey(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null&quot;"/>
@@ -53,17 +62,26 @@
<item name="org.apache.commons.collections.map.AbstractHashedMap void removeEntry(org.apache.commons.collections.map.AbstractHashedMap.HashEntry, int, org.apache.commons.collections.map.AbstractHashedMap.HashEntry) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.collections.map.AbstractHashedMap void removeEntry(org.apache.commons.collections.map.AbstractHashedMap.HashEntry, int, org.apache.commons.collections.map.AbstractHashedMap.HashEntry) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.collections.map.AbstractHashedMap void reuseEntry(org.apache.commons.collections.map.AbstractHashedMap.HashEntry, int, int, java.lang.Object, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.collections.map.AbstractHashedMap void updateEntry(org.apache.commons.collections.map.AbstractHashedMap.HashEntry, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.collections.map.AbstractHashedMap.EntrySet boolean contains(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.collections.map.AbstractHashedMap.EntrySet boolean contains(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.collections.map.AbstractHashedMap.EntrySet boolean remove(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.collections.map.AbstractHashedMap.EntrySet boolean remove(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -72,6 +90,9 @@
<item name="org.apache.commons.collections.map.AbstractHashedMap.EntrySetIterator EntrySetIterator(org.apache.commons.collections.map.AbstractHashedMap) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.collections.map.AbstractHashedMap.HashEntry boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.collections.map.AbstractHashedMap.HashEntry java.lang.String toString()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -93,6 +114,9 @@
<item name="org.apache.commons.collections.map.AbstractLinkedMap AbstractLinkedMap(java.util.Map) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.collections.map.AbstractLinkedMap boolean containsValue(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.collections.map.AbstractLinkedMap org.apache.commons.collections.map.AbstractHashedMap.HashEntry createEntry(org.apache.commons.collections.map.AbstractHashedMap.HashEntry, int, java.lang.Object, java.lang.Object)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -108,6 +132,9 @@
<item name="org.apache.commons.collections.map.AbstractLinkedMap void removeEntry(org.apache.commons.collections.map.AbstractHashedMap.HashEntry, int, org.apache.commons.collections.map.AbstractHashedMap.HashEntry) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.collections.map.AbstractLinkedMap void removeEntry(org.apache.commons.collections.map.AbstractHashedMap.HashEntry, int, org.apache.commons.collections.map.AbstractHashedMap.HashEntry) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.collections.map.AbstractLinkedMap.EntrySetIterator EntrySetIterator(org.apache.commons.collections.map.AbstractLinkedMap) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -132,6 +159,9 @@
<item name="org.apache.commons.collections.map.LRUMap LRUMap(java.util.Map, boolean) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.collections.map.LRUMap boolean removeLRU(org.apache.commons.collections.map.AbstractLinkedMap.LinkEntry) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.collections.map.LRUMap boolean removeLRU(org.apache.commons.collections.map.AbstractLinkedMap.LinkEntry)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;true;null-&gt;true&quot;"/>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/annotations.xml
index e36a5e269c9a..7115dfb72473 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/annotations.xml
@@ -1,55 +1,169 @@
<root>
+ <item name="org.apache.commons.lang.ArrayUtils boolean contains(byte[], byte) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean contains(char[], char) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean contains(int[], int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean contains(java.lang.Object[], java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean contains(java.lang.Object[], java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean contains(long[], long) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean contains(short[], short) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean isEmpty(boolean[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils boolean isEmpty(boolean[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;true&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean isEmpty(byte[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils boolean isEmpty(byte[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;true&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean isEmpty(char[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils boolean isEmpty(char[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;true&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean isEmpty(double[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils boolean isEmpty(double[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;true&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean isEmpty(float[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils boolean isEmpty(float[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;true&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean isEmpty(int[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils boolean isEmpty(int[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;true&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean isEmpty(java.lang.Object[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils boolean isEmpty(java.lang.Object[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;true&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean isEmpty(long[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils boolean isEmpty(long[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;true&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean isEmpty(short[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils boolean isEmpty(short[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;true&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean isSameLength(boolean[], boolean[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean isSameLength(boolean[], boolean[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean isSameLength(byte[], byte[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean isSameLength(byte[], byte[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean isSameLength(char[], char[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean isSameLength(char[], char[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean isSameLength(double[], double[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean isSameLength(double[], double[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean isSameLength(float[], float[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean isSameLength(float[], float[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean isSameLength(int[], int[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean isSameLength(int[], int[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean isSameLength(java.lang.Object[], java.lang.Object[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean isSameLength(java.lang.Object[], java.lang.Object[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean isSameLength(long[], long[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean isSameLength(long[], long[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean isSameLength(short[], short[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean isSameLength(short[], short[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils boolean isSameType(java.lang.Object, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.ArrayUtils boolean isSameType(java.lang.Object, java.lang.Object) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean[] add(boolean[], boolean) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean[] addAll(boolean[], boolean[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean[] addAll(boolean[], boolean[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean[] clone(boolean[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils boolean[] clone(boolean[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
@@ -58,21 +172,42 @@
<item name="org.apache.commons.lang.ArrayUtils boolean[] remove(boolean[], int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean[] subarray(boolean[], int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils boolean[] subarray(boolean[], int, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean[] toPrimitive(java.lang.Boolean[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils boolean[] toPrimitive(java.lang.Boolean[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils boolean[] toPrimitive(java.lang.Boolean[], boolean) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils boolean[] toPrimitive(java.lang.Boolean[], boolean)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils byte[] add(byte[], byte) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils byte[] addAll(byte[], byte[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils byte[] addAll(byte[], byte[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils byte[] clone(byte[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils byte[] clone(byte[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
@@ -81,21 +216,42 @@
<item name="org.apache.commons.lang.ArrayUtils byte[] remove(byte[], int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils byte[] subarray(byte[], int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils byte[] subarray(byte[], int, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils byte[] toPrimitive(java.lang.Byte[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils byte[] toPrimitive(java.lang.Byte[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils byte[] toPrimitive(java.lang.Byte[], byte) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils byte[] toPrimitive(java.lang.Byte[], byte)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils char[] add(char[], char) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils char[] addAll(char[], char[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils char[] addAll(char[], char[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils char[] clone(char[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils char[] clone(char[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
@@ -104,21 +260,42 @@
<item name="org.apache.commons.lang.ArrayUtils char[] remove(char[], int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils char[] subarray(char[], int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils char[] subarray(char[], int, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils char[] toPrimitive(java.lang.Character[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils char[] toPrimitive(java.lang.Character[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils char[] toPrimitive(java.lang.Character[], char) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils char[] toPrimitive(java.lang.Character[], char)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils double[] add(double[], double) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils double[] addAll(double[], double[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils double[] addAll(double[], double[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils double[] clone(double[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils double[] clone(double[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
@@ -127,21 +304,42 @@
<item name="org.apache.commons.lang.ArrayUtils double[] remove(double[], int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils double[] subarray(double[], int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils double[] subarray(double[], int, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils double[] toPrimitive(java.lang.Double[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils double[] toPrimitive(java.lang.Double[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils double[] toPrimitive(java.lang.Double[], double) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils double[] toPrimitive(java.lang.Double[], double)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils float[] add(float[], float) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils float[] addAll(float[], float[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils float[] addAll(float[], float[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils float[] clone(float[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils float[] clone(float[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
@@ -150,21 +348,129 @@
<item name="org.apache.commons.lang.ArrayUtils float[] remove(float[], int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils float[] subarray(float[], int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils float[] subarray(float[], int, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils float[] toPrimitive(java.lang.Float[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils float[] toPrimitive(java.lang.Float[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils float[] toPrimitive(java.lang.Float[], float) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils float[] toPrimitive(java.lang.Float[], float)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils int getLength(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils int indexOf(byte[], byte) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils int indexOf(byte[], byte, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils int indexOf(char[], char) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils int indexOf(char[], char, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils int indexOf(int[], int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils int indexOf(int[], int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils int indexOf(java.lang.Object[], java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils int indexOf(java.lang.Object[], java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils int indexOf(java.lang.Object[], java.lang.Object, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils int indexOf(java.lang.Object[], java.lang.Object, int) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils int indexOf(long[], long) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils int indexOf(long[], long, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils int indexOf(short[], short) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils int indexOf(short[], short, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils int lastIndexOf(byte[], byte) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils int lastIndexOf(byte[], byte, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils int lastIndexOf(char[], char) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils int lastIndexOf(char[], char, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils int lastIndexOf(int[], int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils int lastIndexOf(int[], int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils int lastIndexOf(java.lang.Object[], java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils int lastIndexOf(java.lang.Object[], java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils int lastIndexOf(java.lang.Object[], java.lang.Object, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils int lastIndexOf(java.lang.Object[], java.lang.Object, int) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils int lastIndexOf(long[], long) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils int lastIndexOf(long[], long, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils int lastIndexOf(short[], short) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils int lastIndexOf(short[], short, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils int[] add(int[], int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils int[] addAll(int[], int[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils int[] addAll(int[], int[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils int[] clone(int[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils int[] clone(int[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
@@ -173,59 +479,104 @@
<item name="org.apache.commons.lang.ArrayUtils int[] remove(int[], int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils int[] subarray(int[], int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils int[] subarray(int[], int, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils int[] toPrimitive(java.lang.Integer[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils int[] toPrimitive(java.lang.Integer[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils int[] toPrimitive(java.lang.Integer[], int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils int[] toPrimitive(java.lang.Integer[], int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils java.lang.Boolean[] toObject(boolean[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils java.lang.Boolean[] toObject(boolean[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils java.lang.Byte[] toObject(byte[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils java.lang.Byte[] toObject(byte[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils java.lang.Character[] toObject(char[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils java.lang.Character[] toObject(char[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils java.lang.Double[] toObject(double[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils java.lang.Double[] toObject(double[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils java.lang.Float[] toObject(float[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils java.lang.Float[] toObject(float[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils java.lang.Integer[] toObject(int[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils java.lang.Integer[] toObject(int[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils java.lang.Long[] toObject(long[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils java.lang.Long[] toObject(long[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils java.lang.Object copyArrayGrow1(java.lang.Object, java.lang.Class) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils java.lang.Object remove(java.lang.Object, int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils java.lang.Object[] add(java.lang.Object[], java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils java.lang.Object[] addAll(java.lang.Object[], java.lang.Object[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils java.lang.Object[] addAll(java.lang.Object[], java.lang.Object[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils java.lang.Object[] clone(java.lang.Object[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils java.lang.Object[] clone(java.lang.Object[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
@@ -234,21 +585,51 @@
<item name="org.apache.commons.lang.ArrayUtils java.lang.Object[] remove(java.lang.Object[], int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils java.lang.Object[] removeElement(java.lang.Object[], java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils java.lang.Object[] subarray(java.lang.Object[], int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils java.lang.Object[] subarray(java.lang.Object[], int, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils java.lang.Short[] toObject(short[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils java.lang.Short[] toObject(short[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils java.lang.String toString(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils java.lang.String toString(java.lang.Object, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils java.util.Map toMap(java.lang.Object[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils java.util.Map toMap(java.lang.Object[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils long[] add(long[], long) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils long[] addAll(long[], long[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils long[] addAll(long[], long[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils long[] clone(long[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils long[] clone(long[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
@@ -257,21 +638,42 @@
<item name="org.apache.commons.lang.ArrayUtils long[] remove(long[], int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils long[] subarray(long[], int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils long[] subarray(long[], int, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils long[] toPrimitive(java.lang.Long[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils long[] toPrimitive(java.lang.Long[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils long[] toPrimitive(java.lang.Long[], long) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils long[] toPrimitive(java.lang.Long[], long)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils short[] add(short[], short) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils short[] addAll(short[], short[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils short[] addAll(short[], short[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils short[] clone(short[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils short[] clone(short[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
@@ -280,57 +682,177 @@
<item name="org.apache.commons.lang.ArrayUtils short[] remove(short[], int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils short[] subarray(short[], int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils short[] subarray(short[], int, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils short[] toPrimitive(java.lang.Short[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils short[] toPrimitive(java.lang.Short[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils short[] toPrimitive(java.lang.Short[], short) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ArrayUtils short[] toPrimitive(java.lang.Short[], short)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ArrayUtils void reverse(boolean[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils void reverse(byte[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils void reverse(char[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils void reverse(double[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils void reverse(float[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils void reverse(int[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils void reverse(java.lang.Object[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils void reverse(long[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ArrayUtils void reverse(short[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.BooleanUtils boolean isFalse(java.lang.Boolean) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.BooleanUtils boolean isFalse(java.lang.Boolean)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.BooleanUtils boolean isNotFalse(java.lang.Boolean) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.BooleanUtils boolean isNotTrue(java.lang.Boolean) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.BooleanUtils boolean isTrue(java.lang.Boolean) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.BooleanUtils boolean isTrue(java.lang.Boolean)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.BooleanUtils boolean toBoolean(java.lang.Boolean) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.BooleanUtils boolean toBoolean(java.lang.Boolean)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.BooleanUtils boolean toBoolean(java.lang.Integer, java.lang.Integer, java.lang.Integer) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.BooleanUtils boolean toBoolean(java.lang.Integer, java.lang.Integer, java.lang.Integer) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.BooleanUtils boolean toBoolean(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.BooleanUtils boolean toBoolean(java.lang.String, java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.BooleanUtils boolean toBoolean(java.lang.String, java.lang.String, java.lang.String) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.BooleanUtils boolean toBooleanDefaultIfNull(java.lang.Boolean, boolean) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.BooleanUtils boolean xor(boolean[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.BooleanUtils int toInteger(java.lang.Boolean, int, int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.BooleanUtils java.lang.Boolean negate(java.lang.Boolean) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.BooleanUtils java.lang.Boolean negate(java.lang.Boolean)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.BooleanUtils java.lang.Boolean toBooleanObject(java.lang.Integer) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.BooleanUtils java.lang.Boolean toBooleanObject(java.lang.Integer)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.BooleanUtils java.lang.Boolean toBooleanObject(java.lang.Integer, java.lang.Integer, java.lang.Integer, java.lang.Integer) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.BooleanUtils java.lang.Boolean toBooleanObject(java.lang.Integer, java.lang.Integer, java.lang.Integer, java.lang.Integer) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.BooleanUtils java.lang.Boolean toBooleanObject(java.lang.Integer, java.lang.Integer, java.lang.Integer, java.lang.Integer) 3">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.BooleanUtils java.lang.Boolean toBooleanObject(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.BooleanUtils java.lang.Boolean toBooleanObject(java.lang.String, java.lang.String, java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.BooleanUtils java.lang.Boolean toBooleanObject(java.lang.String, java.lang.String, java.lang.String, java.lang.String) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.BooleanUtils java.lang.Boolean toBooleanObject(java.lang.String, java.lang.String, java.lang.String, java.lang.String) 3">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.BooleanUtils java.lang.Boolean xor(java.lang.Boolean[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.BooleanUtils java.lang.Integer toIntegerObject(java.lang.Boolean) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.BooleanUtils java.lang.Integer toIntegerObject(java.lang.Boolean)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.BooleanUtils java.lang.Integer toIntegerObject(java.lang.Boolean, java.lang.Integer, java.lang.Integer, java.lang.Integer) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.BooleanUtils java.lang.String toString(java.lang.Boolean, java.lang.String, java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.BooleanUtils java.lang.String toStringOnOff(java.lang.Boolean) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.BooleanUtils java.lang.String toStringTrueFalse(java.lang.Boolean) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.BooleanUtils java.lang.String toStringYesNo(java.lang.Boolean) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.CharEncoding boolean isSupported(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.CharEncoding boolean isSupported(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -339,29 +861,56 @@
<item name="org.apache.commons.lang.CharRange boolean contains(org.apache.commons.lang.CharRange) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.CharRange boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.CharSet CharSet(java.lang.String[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.CharSet boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.CharSet org.apache.commons.lang.CharSet getInstance(java.lang.String[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.CharSet org.apache.commons.lang.CharSet getInstance(java.lang.String[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.CharSet void add(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.CharSetUtils int count(java.lang.String, java.lang.String[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.CharSetUtils java.lang.String delete(java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;!null;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.CharSetUtils java.lang.String delete(java.lang.String, java.lang.String[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.CharSetUtils java.lang.String delete(java.lang.String, java.lang.String[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;!null;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.CharSetUtils java.lang.String keep(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.CharSetUtils java.lang.String keep(java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;!null;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.CharSetUtils java.lang.String keep(java.lang.String, java.lang.String[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.CharSetUtils java.lang.String keep(java.lang.String, java.lang.String[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.CharSetUtils java.lang.String keep(java.lang.String, java.lang.String[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;!null;null,_-&gt;null&quot;"/>
@@ -370,6 +919,9 @@
<item name="org.apache.commons.lang.CharSetUtils java.lang.String modify(java.lang.String, java.lang.String[], boolean) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.CharSetUtils java.lang.String modify(java.lang.String, java.lang.String[], boolean) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.CharSetUtils java.lang.String modify(java.lang.String, java.lang.String[], boolean)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -378,6 +930,9 @@
<val val="&quot;!null,_-&gt;!null;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.CharSetUtils java.lang.String squeeze(java.lang.String, java.lang.String[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.CharSetUtils java.lang.String squeeze(java.lang.String, java.lang.String[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;!null;null,_-&gt;null&quot;"/>
@@ -388,6 +943,9 @@
<val val="&quot;!null,_,_-&gt;!null;null,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.CharSetUtils org.apache.commons.lang.CharSet evaluateSet(java.lang.String[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.CharSetUtils org.apache.commons.lang.CharSet evaluateSet(java.lang.String[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null;null-&gt;null&quot;"/>
@@ -396,17 +954,26 @@
<item name="org.apache.commons.lang.CharUtils char toChar(java.lang.Character) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.CharUtils char toChar(java.lang.Character, char) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.CharUtils char toChar(java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.CharUtils int toIntValue(java.lang.Character) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.CharUtils int toIntValue(java.lang.Character, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.CharUtils java.lang.Character toCharacterObject(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.CharUtils java.lang.String toString(java.lang.Character) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.CharUtils java.lang.String toString(java.lang.Character)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
@@ -415,16 +982,34 @@
<item name="org.apache.commons.lang.CharUtils java.lang.String unicodeEscaped(char)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.CharUtils java.lang.String unicodeEscaped(java.lang.Character) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.CharUtils java.lang.String unicodeEscaped(java.lang.Character)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ClassUtils boolean isAssignable(java.lang.Class, java.lang.Class) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ClassUtils boolean isAssignable(java.lang.Class, java.lang.Class) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ClassUtils boolean isAssignable(java.lang.Class, java.lang.Class)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ClassUtils boolean isAssignable(java.lang.Class[], java.lang.Class[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ClassUtils boolean isAssignable(java.lang.Class[], java.lang.Class[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ClassUtils boolean isInnerClass(java.lang.Class) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ClassUtils boolean isInnerClass(java.lang.Class)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -435,24 +1020,39 @@
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ClassUtils java.lang.Class[] primitivesToWrappers(java.lang.Class[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ClassUtils java.lang.Class[] primitivesToWrappers(java.lang.Class[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ClassUtils java.lang.Class[] toClass(java.lang.Object[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ClassUtils java.lang.Class[] toClass(java.lang.Object[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ClassUtils java.lang.Class[] wrappersToPrimitives(java.lang.Class[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ClassUtils java.lang.Class[] wrappersToPrimitives(java.lang.Class[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ClassUtils java.lang.String getPackageCanonicalName(java.lang.Class) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ClassUtils java.lang.String getPackageCanonicalName(java.lang.Class)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.ClassUtils java.lang.String getPackageCanonicalName(java.lang.Object, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ClassUtils java.lang.String getPackageCanonicalName(java.lang.Object, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;!null;_,!null-&gt;!null&quot;"/>
@@ -461,31 +1061,62 @@
<item name="org.apache.commons.lang.ClassUtils java.lang.String getPackageCanonicalName(java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.ClassUtils java.lang.String getPackageName(java.lang.Class) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ClassUtils java.lang.String getPackageName(java.lang.Class)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.ClassUtils java.lang.String getPackageName(java.lang.Object, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ClassUtils java.lang.String getPackageName(java.lang.Object, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;!null;_,!null-&gt;!null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ClassUtils java.lang.String getPackageName(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ClassUtils java.lang.String getPackageName(java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.ClassUtils java.lang.String getShortCanonicalName(java.lang.Class) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ClassUtils java.lang.String getShortCanonicalName(java.lang.Class)">
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
+ <item name="org.apache.commons.lang.ClassUtils java.lang.String getShortCanonicalName(java.lang.Object, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ClassUtils java.lang.String getShortCanonicalName(java.lang.Object, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;null-&gt;!null&quot;"/>
+ <val val="&quot;!null,_-&gt;!null;_,!null-&gt;!null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ClassUtils java.lang.String getShortCanonicalName(java.lang.String)">
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
+ <item name="org.apache.commons.lang.ClassUtils java.lang.String getShortClassName(java.lang.Class) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ClassUtils java.lang.String getShortClassName(java.lang.Class)">
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
+ <item name="org.apache.commons.lang.ClassUtils java.lang.String getShortClassName(java.lang.Object, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ClassUtils java.lang.String getShortClassName(java.lang.Object, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;null-&gt;!null&quot;"/>
+ <val val="&quot;!null,_-&gt;!null;_,!null-&gt;!null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ClassUtils java.lang.String getShortClassName(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ClassUtils java.lang.String getShortClassName(java.lang.String)">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;null-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.ClassUtils java.lang.String toCanonicalName(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
@@ -498,21 +1129,33 @@
<item name="org.apache.commons.lang.ClassUtils java.lang.reflect.Method getPublicMethod(java.lang.Class, java.lang.String, java.lang.Class[]) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.ClassUtils java.util.List convertClassNamesToClasses(java.util.List) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ClassUtils java.util.List convertClassNamesToClasses(java.util.List)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ClassUtils java.util.List convertClassesToClassNames(java.util.List) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ClassUtils java.util.List convertClassesToClassNames(java.util.List)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ClassUtils java.util.List getAllInterfaces(java.lang.Class) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ClassUtils java.util.List getAllInterfaces(java.lang.Class)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ClassUtils java.util.List getAllSuperclasses(java.lang.Class) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ClassUtils java.util.List getAllSuperclasses(java.lang.Class)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
@@ -551,11 +1194,41 @@
<item name="org.apache.commons.lang.Entities void unescape(java.io.Writer, java.lang.String) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.Entities.ArrayEntityMap int value(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.IllegalClassException IllegalClassException(java.lang.Class, java.lang.Class) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.IllegalClassException IllegalClassException(java.lang.Class, java.lang.Class) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.IllegalClassException IllegalClassException(java.lang.Class, java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.IllegalClassException IllegalClassException(java.lang.Class, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.IllegalClassException java.lang.String safeGetClassName(java.lang.Class) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.IllegalClassException java.lang.String safeGetClassName(java.lang.Class)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.IncompleteArgumentException IncompleteArgumentException(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.IncompleteArgumentException IncompleteArgumentException(java.lang.String, java.lang.String[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.IncompleteArgumentException IncompleteArgumentException(java.lang.String, java.lang.String[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.IncompleteArgumentException java.lang.String safeArrayToString(java.lang.Object[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.IncompleteArgumentException java.lang.String safeArrayToString(java.lang.Object[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
@@ -567,14 +1240,32 @@
<item name="org.apache.commons.lang.LocaleUtils java.util.List localeLookupList(java.util.Locale)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.LocaleUtils java.util.List localeLookupList(java.util.Locale, java.util.Locale) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.LocaleUtils java.util.List localeLookupList(java.util.Locale, java.util.Locale)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.LocaleUtils java.util.Locale toLocale(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.LocaleUtils java.util.Locale toLocale(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.NotImplementedException NotImplementedException(java.lang.Class) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.NotImplementedException NotImplementedException(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.NotImplementedException NotImplementedException(java.lang.String, java.lang.Throwable) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.NullArgumentException NullArgumentException(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.NumberRange NumberRange(java.lang.Number) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -584,16 +1275,28 @@
<item name="org.apache.commons.lang.NumberRange NumberRange(java.lang.Number, java.lang.Number) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.NumberRange boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.NumberRange boolean includesNumber(java.lang.Number) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.NumberRange boolean includesNumber(java.lang.Number)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.NumberRange boolean includesRange(org.apache.commons.lang.NumberRange) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.NumberRange boolean includesRange(org.apache.commons.lang.NumberRange)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.NumberRange boolean overlaps(org.apache.commons.lang.NumberRange) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.NumberRange boolean overlaps(org.apache.commons.lang.NumberRange)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -602,11 +1305,17 @@
<item name="org.apache.commons.lang.NumberRange java.lang.String toString()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.NumberUtils boolean isAllZeros(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.NumberUtils boolean isAllZeros(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;true&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.NumberUtils boolean isDigits(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.NumberUtils boolean isDigits(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -635,6 +1344,9 @@
<item name="org.apache.commons.lang.NumberUtils java.lang.Long createLong(java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.NumberUtils java.lang.Number createNumber(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.NumberUtils java.lang.Number createNumber(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
@@ -646,21 +1358,54 @@
<item name="org.apache.commons.lang.NumberUtils java.math.BigInteger createBigInteger(java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.ObjectUtils boolean equals(java.lang.Object, java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ObjectUtils boolean equals(java.lang.Object, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ObjectUtils int hashCode(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ObjectUtils java.lang.Object defaultIfNull(java.lang.Object, java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ObjectUtils java.lang.Object defaultIfNull(java.lang.Object, java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;!null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ObjectUtils java.lang.Object max(java.lang.Comparable, java.lang.Comparable) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ObjectUtils java.lang.Object min(java.lang.Comparable, java.lang.Comparable) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ObjectUtils java.lang.String identityToString(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ObjectUtils java.lang.String identityToString(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ObjectUtils java.lang.String toString(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ObjectUtils java.lang.String toString(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;!null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.ObjectUtils java.lang.String toString(java.lang.Object, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ObjectUtils java.lang.StringBuffer appendIdentityToString(java.lang.StringBuffer, java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.ObjectUtils java.lang.StringBuffer appendIdentityToString(java.lang.StringBuffer, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.ObjectUtils java.lang.StringBuffer appendIdentityToString(java.lang.StringBuffer, java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,!null-&gt;!null;_,null-&gt;null&quot;"/>
@@ -678,18 +1423,30 @@
<item name="org.apache.commons.lang.RandomStringUtils java.lang.String random(int, boolean, boolean)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.RandomStringUtils java.lang.String random(int, char[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.RandomStringUtils java.lang.String random(int, char[])">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.RandomStringUtils java.lang.String random(int, int, int, boolean, boolean)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.RandomStringUtils java.lang.String random(int, int, int, boolean, boolean, char[]) 5">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.RandomStringUtils java.lang.String random(int, int, int, boolean, boolean, char[])">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.RandomStringUtils java.lang.String random(int, int, int, boolean, boolean, char[], java.util.Random) 5">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.RandomStringUtils java.lang.String random(int, int, int, boolean, boolean, char[], java.util.Random)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.RandomStringUtils java.lang.String random(int, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.RandomStringUtils java.lang.String random(int, java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -714,41 +1471,77 @@
<item name="org.apache.commons.lang.SerializationUtils void serialize(java.io.Serializable, java.io.OutputStream) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.StringEscapeUtils java.lang.String escapeHtml(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringEscapeUtils java.lang.String escapeHtml(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringEscapeUtils java.lang.String escapeJava(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringEscapeUtils java.lang.String escapeJavaScript(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringEscapeUtils java.lang.String escapeJavaStyleString(java.lang.String, boolean) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringEscapeUtils java.lang.String escapeJavaStyleString(java.lang.String, boolean)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringEscapeUtils java.lang.String escapeSql(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringEscapeUtils java.lang.String escapeSql(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringEscapeUtils java.lang.String escapeXml(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringEscapeUtils java.lang.String escapeXml(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringEscapeUtils java.lang.String hex(char)">
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
+ <item name="org.apache.commons.lang.StringEscapeUtils java.lang.String unescapeCsv(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringEscapeUtils java.lang.String unescapeCsv(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringEscapeUtils java.lang.String unescapeHtml(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringEscapeUtils java.lang.String unescapeHtml(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringEscapeUtils java.lang.String unescapeJava(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringEscapeUtils java.lang.String unescapeJava(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringEscapeUtils java.lang.String unescapeJavaScript(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringEscapeUtils java.lang.String unescapeXml(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringEscapeUtils java.lang.String unescapeXml(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
@@ -757,136 +1550,358 @@
<item name="org.apache.commons.lang.StringEscapeUtils void escapeHtml(java.io.Writer, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.StringEscapeUtils void escapeHtml(java.io.Writer, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringEscapeUtils void escapeJava(java.io.Writer, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.StringEscapeUtils void escapeJava(java.io.Writer, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringEscapeUtils void escapeJavaScript(java.io.Writer, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.StringEscapeUtils void escapeJavaScript(java.io.Writer, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringEscapeUtils void escapeJavaStyleString(java.io.Writer, java.lang.String, boolean) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.StringEscapeUtils void escapeJavaStyleString(java.io.Writer, java.lang.String, boolean) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringEscapeUtils void escapeXml(java.io.Writer, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.StringEscapeUtils void escapeXml(java.io.Writer, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringEscapeUtils void unescapeCsv(java.io.Writer, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringEscapeUtils void unescapeHtml(java.io.Writer, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.StringEscapeUtils void unescapeHtml(java.io.Writer, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringEscapeUtils void unescapeJava(java.io.Writer, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.StringEscapeUtils void unescapeJava(java.io.Writer, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringEscapeUtils void unescapeJavaScript(java.io.Writer, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.StringEscapeUtils void unescapeJavaScript(java.io.Writer, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringEscapeUtils void unescapeXml(java.io.Writer, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.StringEscapeUtils void unescapeXml(java.io.Writer, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils boolean contains(java.lang.String, char)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils boolean contains(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils boolean contains(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils boolean contains(java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,null-&gt;false;null,_-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils boolean containsAny(java.lang.String, char[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils boolean containsAny(java.lang.String, char[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils boolean containsAny(java.lang.String, char[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,null-&gt;false;null,_-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils boolean containsAny(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils boolean containsAny(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils boolean containsAny(java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,null-&gt;false;null,_-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils boolean containsIgnoreCase(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils boolean containsIgnoreCase(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils boolean containsIgnoreCase(java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,null-&gt;false;null,_-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils boolean containsNone(java.lang.String, char[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils boolean containsNone(java.lang.String, char[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils boolean containsNone(java.lang.String, char[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,null-&gt;true;null,_-&gt;true&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils boolean containsNone(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils boolean containsNone(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils boolean containsNone(java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,null-&gt;true;null,_-&gt;true&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils boolean containsOnly(java.lang.String, char[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils boolean containsOnly(java.lang.String, char[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils boolean containsOnly(java.lang.String, char[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,null-&gt;false;null,_-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils boolean containsOnly(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils boolean containsOnly(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils boolean containsOnly(java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,null-&gt;false;null,_-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils boolean endsWith(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils boolean endsWith(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils boolean endsWith(java.lang.String, java.lang.String, boolean) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils boolean endsWith(java.lang.String, java.lang.String, boolean) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils boolean endsWithIgnoreCase(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils boolean endsWithIgnoreCase(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils boolean equals(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils boolean equals(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils boolean equalsIgnoreCase(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils boolean equalsIgnoreCase(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils boolean isAlpha(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils boolean isAlpha(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils boolean isAlphaSpace(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils boolean isAlphaSpace(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils boolean isAlphanumeric(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils boolean isAlphanumeric(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils boolean isAlphanumericSpace(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils boolean isAlphanumericSpace(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils boolean isAsciiPrintable(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils boolean isAsciiPrintable(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils boolean isBlank(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils boolean isBlank(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;true&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils boolean isEmpty(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils boolean isEmpty(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;true&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils boolean isNotBlank(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils boolean isNotEmpty(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils boolean isNumeric(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils boolean isNumeric(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils boolean isNumericSpace(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils boolean isNumericSpace(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils boolean isWhitespace(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils boolean isWhitespace(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils boolean startsWith(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils boolean startsWith(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils boolean startsWith(java.lang.String, java.lang.String, boolean) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils boolean startsWith(java.lang.String, java.lang.String, boolean) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils boolean startsWithIgnoreCase(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils boolean startsWithIgnoreCase(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils int getLevenshteinDistance(java.lang.String, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.StringUtils int getLevenshteinDistance(java.lang.String, java.lang.String) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.StringUtils int indexOf(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils int indexOf(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils int indexOf(java.lang.String, java.lang.String, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils int indexOf(java.lang.String, java.lang.String, int) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils int indexOfAny(java.lang.String, java.lang.String[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils int indexOfAny(java.lang.String, java.lang.String[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils int indexOfDifference(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils int indexOfDifference(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils int indexOfDifference(java.lang.String[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils int lastIndexOf(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils int lastIndexOf(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils int lastIndexOf(java.lang.String, java.lang.String, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils int lastIndexOf(java.lang.String, java.lang.String, int) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils int lastIndexOfAny(java.lang.String, java.lang.String[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils int lastIndexOfAny(java.lang.String, java.lang.String[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils int length(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils int ordinalIndexOf(java.lang.String, java.lang.String, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils int ordinalIndexOf(java.lang.String, java.lang.String, int) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String abbreviate(java.lang.String, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String abbreviate(java.lang.String, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;!null;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String abbreviate(java.lang.String, int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String abbreviate(java.lang.String, int, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_,_-&gt;!null;null,_,_-&gt;null&quot;"/>
@@ -927,6 +1942,9 @@
<val val="&quot;!null-&gt;!null;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String chomp(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String chomp(java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;!null;null,_-&gt;null&quot;"/>
@@ -948,6 +1966,9 @@
<val val="&quot;!null,_-&gt;!null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String chop(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String chop(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null;null-&gt;null&quot;"/>
@@ -959,26 +1980,39 @@
<item name="org.apache.commons.lang.StringUtils java.lang.String chopNewline(java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String clean(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String clean(java.lang.String)">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;null-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String concatenate(java.lang.Object[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
</item>
<item name="org.apache.commons.lang.StringUtils java.lang.String concatenate(java.lang.Object[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String defaultString(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String defaultString(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null;null-&gt;!null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String defaultString(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String defaultString(java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;!null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String deleteSpaces(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String deleteSpaces(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null;null-&gt;null&quot;"/>
@@ -989,11 +2023,17 @@
<val val="&quot;!null-&gt;!null;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String difference(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String difference(java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;!null;_,!null-&gt;!null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String escape(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String getChomp(java.lang.String, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -1005,16 +2045,34 @@
<val val="&quot;_,!null-&gt;!null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String getCommonPrefix(java.lang.String[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String getCommonPrefix(java.lang.String[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;!null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String getNestedString(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String getNestedString(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String getNestedString(java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,null-&gt;null;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String getNestedString(java.lang.String, java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String getNestedString(java.lang.String, java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String getNestedString(java.lang.String, java.lang.String, java.lang.String) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String getNestedString(java.lang.String, java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,_,null-&gt;null;_,null,_-&gt;null;null,_,_-&gt;null&quot;"/>
@@ -1029,81 +2087,144 @@
<item name="org.apache.commons.lang.StringUtils java.lang.String getPrechomp(java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String join(java.lang.Object[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String join(java.lang.Object[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String join(java.lang.Object[], char) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String join(java.lang.Object[], char)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;!null;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String join(java.lang.Object[], char, int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String join(java.lang.Object[], char, int, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_,_,_-&gt;!null;null,_,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String join(java.lang.Object[], java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String join(java.lang.Object[], java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String join(java.lang.Object[], java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;!null;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String join(java.lang.Object[], java.lang.String, int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String join(java.lang.Object[], java.lang.String, int, int) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String join(java.lang.Object[], java.lang.String, int, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_,_,_-&gt;!null;null,_,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String join(java.util.Collection, char) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String join(java.util.Collection, char)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String join(java.util.Collection, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String join(java.util.Collection, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String join(java.util.Collection, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String join(java.util.Iterator, char) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String join(java.util.Iterator, char)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String join(java.util.Iterator, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String join(java.util.Iterator, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String join(java.util.Iterator, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String left(java.lang.String, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String left(java.lang.String, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;!null;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String leftPad(java.lang.String, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String leftPad(java.lang.String, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String leftPad(java.lang.String, int, char) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String leftPad(java.lang.String, int, char)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String leftPad(java.lang.String, int, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String leftPad(java.lang.String, int, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String lowerCase(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String lowerCase(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;null-&gt;null&quot;"/>
+ <val val="&quot;!null-&gt;!null;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String mid(java.lang.String, int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String mid(java.lang.String, int, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_,_-&gt;!null;null,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String overlay(java.lang.String, java.lang.String, int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String overlay(java.lang.String, java.lang.String, int, int) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String overlay(java.lang.String, java.lang.String, int, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_,_,_-&gt;!null;null,_,_,_-&gt;null&quot;"/>
@@ -1162,116 +2283,200 @@
<val val="&quot;!null,_-&gt;!null;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String repeat(java.lang.String, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String repeat(java.lang.String, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;!null;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String replace(java.lang.String, java.lang.String, java.lang.String) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String replace(java.lang.String, java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_,_-&gt;!null;null,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String replace(java.lang.String, java.lang.String, java.lang.String, int) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String replace(java.lang.String, java.lang.String, java.lang.String, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_,_,_-&gt;!null;null,_,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String replaceChars(java.lang.String, char, char) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String replaceChars(java.lang.String, char, char)">
<annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;null,_,_-&gt;null&quot;"/>
+ <val val="&quot;!null,_,_-&gt;!null;null,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String replaceChars(java.lang.String, java.lang.String, java.lang.String) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String replaceChars(java.lang.String, java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_,_-&gt;!null;null,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String replaceEach(java.lang.String, java.lang.String[], java.lang.String[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String replaceEach(java.lang.String, java.lang.String[], java.lang.String[]) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String replaceEach(java.lang.String, java.lang.String[], java.lang.String[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String replaceEach(java.lang.String, java.lang.String[], java.lang.String[], boolean, int) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String replaceEach(java.lang.String, java.lang.String[], java.lang.String[], boolean, int) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String replaceEach(java.lang.String, java.lang.String[], java.lang.String[], boolean, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_,_,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String replaceEachRepeatedly(java.lang.String, java.lang.String[], java.lang.String[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String replaceEachRepeatedly(java.lang.String, java.lang.String[], java.lang.String[]) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String replaceEachRepeatedly(java.lang.String, java.lang.String[], java.lang.String[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String replaceOnce(java.lang.String, java.lang.String, java.lang.String) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String replaceOnce(java.lang.String, java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_,_-&gt;!null;null,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String reverse(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String reverse(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String reverseDelimited(java.lang.String, char) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String reverseDelimited(java.lang.String, char)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String reverseDelimitedString(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String reverseDelimitedString(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String reverseDelimitedString(java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String right(java.lang.String, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String right(java.lang.String, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;!null;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String rightPad(java.lang.String, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String rightPad(java.lang.String, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String rightPad(java.lang.String, int, char) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String rightPad(java.lang.String, int, char)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String rightPad(java.lang.String, int, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String rightPad(java.lang.String, int, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String strip(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String stripEnd(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String stripEnd(java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;!null;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String stripStart(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String stripStart(java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;!null;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String stripToEmpty(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String stripToEmpty(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;!null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String stripToNull(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String stripToNull(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String substring(java.lang.String, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String substring(java.lang.String, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;!null;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String substring(java.lang.String, int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String substring(java.lang.String, int, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_,_-&gt;!null;null,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String substringAfter(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String substringAfter(java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;!null&quot;"/>
@@ -1282,6 +2487,9 @@
<val val="&quot;!null,_-&gt;!null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String substringBefore(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String substringBefore(java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;!null&quot;"/>
@@ -1292,11 +2500,26 @@
<val val="&quot;!null,_-&gt;!null;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String substringBetween(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String substringBetween(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String substringBetween(java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,null-&gt;null;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String substringBetween(java.lang.String, java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String substringBetween(java.lang.String, java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String substringBetween(java.lang.String, java.lang.String, java.lang.String) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String substringBetween(java.lang.String, java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,_,null-&gt;null;_,null,_-&gt;null;null,_,_-&gt;null&quot;"/>
@@ -1307,15 +2530,22 @@
<val val="&quot;!null-&gt;!null;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String trim(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String trim(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;null-&gt;null&quot;"/>
+ <val val="&quot;!null-&gt;!null;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String trimToEmpty(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String trimToEmpty(java.lang.String)">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;null-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String trimToNull(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
</item>
<item name="org.apache.commons.lang.StringUtils java.lang.String trimToNull(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
@@ -1332,96 +2562,183 @@
<val val="&quot;!null-&gt;!null;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String upperCase(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String upperCase(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;null-&gt;null&quot;"/>
+ <val val="&quot;!null-&gt;!null;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String[] split(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String[] split(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String[] split(java.lang.String, char) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String[] split(java.lang.String, char)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String[] split(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String[] split(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String[] split(java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String[] split(java.lang.String, java.lang.String, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String[] split(java.lang.String, java.lang.String, int) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String[] split(java.lang.String, java.lang.String, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String[] splitByCharacterType(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String[] splitByCharacterType(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String[] splitByCharacterType(java.lang.String, boolean) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String[] splitByCharacterType(java.lang.String, boolean)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String[] splitByCharacterTypeCamelCase(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String[] splitByCharacterTypeCamelCase(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String[] splitByWholeSeparator(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String[] splitByWholeSeparator(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String[] splitByWholeSeparator(java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String[] splitByWholeSeparator(java.lang.String, java.lang.String, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String[] splitByWholeSeparator(java.lang.String, java.lang.String, int) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String[] splitByWholeSeparator(java.lang.String, java.lang.String, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String[] splitByWholeSeparatorPreserveAllTokens(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String[] splitByWholeSeparatorPreserveAllTokens(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String[] splitByWholeSeparatorPreserveAllTokens(java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String[] splitByWholeSeparatorPreserveAllTokens(java.lang.String, java.lang.String, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String[] splitByWholeSeparatorPreserveAllTokens(java.lang.String, java.lang.String, int) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String[] splitByWholeSeparatorPreserveAllTokens(java.lang.String, java.lang.String, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String[] splitByWholeSeparatorWorker(java.lang.String, java.lang.String, int, boolean) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String[] splitByWholeSeparatorWorker(java.lang.String, java.lang.String, int, boolean) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String[] splitByWholeSeparatorWorker(java.lang.String, java.lang.String, int, boolean)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String[] splitPreserveAllTokens(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String[] splitPreserveAllTokens(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String[] splitPreserveAllTokens(java.lang.String, char) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String[] splitPreserveAllTokens(java.lang.String, char)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String[] splitPreserveAllTokens(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String[] splitPreserveAllTokens(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String[] splitPreserveAllTokens(java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String[] splitPreserveAllTokens(java.lang.String, java.lang.String, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String[] splitPreserveAllTokens(java.lang.String, java.lang.String, int) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String[] splitPreserveAllTokens(java.lang.String, java.lang.String, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String[] splitWorker(java.lang.String, char, boolean) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String[] splitWorker(java.lang.String, char, boolean)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String[] splitWorker(java.lang.String, java.lang.String, int, boolean) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String[] splitWorker(java.lang.String, java.lang.String, int, boolean) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String[] splitWorker(java.lang.String, java.lang.String, int, boolean)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_,_,_-&gt;null&quot;"/>
@@ -1432,11 +2749,17 @@
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String[] stripAll(java.lang.String[], java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String[] stripAll(java.lang.String[], java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.StringUtils java.lang.String[] substringsBetween(java.lang.String, java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.StringUtils java.lang.String[] substringsBetween(java.lang.String, java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_,_-&gt;null&quot;"/>
@@ -1476,6 +2799,18 @@
<item name="org.apache.commons.lang.Validate void allElementsOfType(java.util.Collection, java.lang.Class, java.lang.String) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.Validate void isTrue(boolean, java.lang.String, double) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.Validate void isTrue(boolean, java.lang.String, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.Validate void isTrue(boolean, java.lang.String, java.lang.Object) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.Validate void isTrue(boolean, java.lang.String, long) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.Validate void noNullElements(java.lang.Object[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -1518,6 +2853,15 @@
<item name="org.apache.commons.lang.Validate void notNull(java.lang.Object, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.WordUtils boolean isDelimiter(char, char[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.WordUtils java.lang.String abbreviate(java.lang.String, int, int, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.WordUtils java.lang.String abbreviate(java.lang.String, int, int, java.lang.String) 3">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.WordUtils java.lang.String abbreviate(java.lang.String, int, int, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_,_,_-&gt;!null;null,_,_,_-&gt;null&quot;"/>
@@ -1528,6 +2872,9 @@
<val val="&quot;!null-&gt;!null;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.WordUtils java.lang.String capitalize(java.lang.String, char[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.WordUtils java.lang.String capitalize(java.lang.String, char[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;!null;null,_-&gt;null&quot;"/>
@@ -1538,6 +2885,9 @@
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.WordUtils java.lang.String capitalizeFully(java.lang.String, char[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.WordUtils java.lang.String capitalizeFully(java.lang.String, char[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;null&quot;"/>
@@ -1548,6 +2898,9 @@
<val val="&quot;!null-&gt;!null;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.WordUtils java.lang.String initials(java.lang.String, char[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.WordUtils java.lang.String initials(java.lang.String, char[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;!null;null,_-&gt;null&quot;"/>
@@ -1563,16 +2916,28 @@
<val val="&quot;!null-&gt;!null;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.WordUtils java.lang.String uncapitalize(java.lang.String, char[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.WordUtils java.lang.String uncapitalize(java.lang.String, char[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;!null;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.WordUtils java.lang.String wrap(java.lang.String, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.WordUtils java.lang.String wrap(java.lang.String, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;!null;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.WordUtils java.lang.String wrap(java.lang.String, int, java.lang.String, boolean) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.WordUtils java.lang.String wrap(java.lang.String, int, java.lang.String, boolean) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.WordUtils java.lang.String wrap(java.lang.String, int, java.lang.String, boolean)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_,_,_-&gt;!null;null,_,_,_-&gt;null&quot;"/>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/builder/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/builder/annotations.xml
index c46c851e0fa1..4cd0e1e34b32 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/builder/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/builder/annotations.xml
@@ -1,75 +1,126 @@
<root>
+ <item name="org.apache.commons.lang.builder.CompareToBuilder int reflectionCompare(java.lang.Object, java.lang.Object, boolean, java.lang.Class) 3">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.CompareToBuilder int reflectionCompare(java.lang.Object, java.lang.Object, boolean, java.lang.Class, java.lang.String[]) 3">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.CompareToBuilder int reflectionCompare(java.lang.Object, java.lang.Object, java.util.Collection) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(boolean, boolean)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(boolean[], boolean[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(boolean[], boolean[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(boolean[], boolean[])">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;_,null-&gt;!null;null,_-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(byte, byte)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(byte[], byte[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(byte[], byte[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(byte[], byte[])">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;_,null-&gt;!null;null,_-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(char, char)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(char[], char[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(char[], char[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(char[], char[])">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;_,null-&gt;!null;null,_-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(double, double)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(double[], double[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(double[], double[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(double[], double[])">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;_,null-&gt;!null;null,_-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(float, float)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(float[], float[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(float[], float[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(float[], float[])">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;_,null-&gt;!null;null,_-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(int, int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(int[], int[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(int[], int[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(int[], int[])">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;_,null-&gt;!null;null,_-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(java.lang.Object, java.lang.Object, java.util.Comparator) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(java.lang.Object, java.lang.Object, java.util.Comparator) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
</item>
<item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(java.lang.Object, java.lang.Object, java.util.Comparator)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(java.lang.Object[], java.lang.Object[], java.util.Comparator) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(java.lang.Object[], java.lang.Object[], java.util.Comparator) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(java.lang.Object[], java.lang.Object[], java.util.Comparator)">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;_,null,_-&gt;!null;null,_,_-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(long, long)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(long[], long[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(long[], long[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(long[], long[])">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;_,null-&gt;!null;null,_-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(short, short)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(short[], short[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(short[], short[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder append(short[], short[])">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;_,null-&gt;!null;null,_-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.builder.CompareToBuilder org.apache.commons.lang.builder.CompareToBuilder appendSuper(int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
@@ -77,71 +128,158 @@
<item name="org.apache.commons.lang.builder.CompareToBuilder void reflectionAppend(java.lang.Object, java.lang.Object, java.lang.Class, org.apache.commons.lang.builder.CompareToBuilder, boolean, java.lang.String[]) 2">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.EqualsBuilder boolean reflectionEquals(java.lang.Object, java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.EqualsBuilder boolean reflectionEquals(java.lang.Object, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.EqualsBuilder boolean reflectionEquals(java.lang.Object, java.lang.Object, boolean) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.EqualsBuilder boolean reflectionEquals(java.lang.Object, java.lang.Object, boolean) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.EqualsBuilder boolean reflectionEquals(java.lang.Object, java.lang.Object, boolean, java.lang.Class) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.EqualsBuilder boolean reflectionEquals(java.lang.Object, java.lang.Object, boolean, java.lang.Class) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.EqualsBuilder boolean reflectionEquals(java.lang.Object, java.lang.Object, boolean, java.lang.Class) 3">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.EqualsBuilder boolean reflectionEquals(java.lang.Object, java.lang.Object, boolean, java.lang.Class, java.lang.String[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.EqualsBuilder boolean reflectionEquals(java.lang.Object, java.lang.Object, boolean, java.lang.Class, java.lang.String[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.EqualsBuilder boolean reflectionEquals(java.lang.Object, java.lang.Object, boolean, java.lang.Class, java.lang.String[]) 3">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.EqualsBuilder boolean reflectionEquals(java.lang.Object, java.lang.Object, java.lang.String[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.EqualsBuilder boolean reflectionEquals(java.lang.Object, java.lang.Object, java.lang.String[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.EqualsBuilder boolean reflectionEquals(java.lang.Object, java.lang.Object, java.util.Collection) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.EqualsBuilder boolean reflectionEquals(java.lang.Object, java.lang.Object, java.util.Collection) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.EqualsBuilder boolean reflectionEquals(java.lang.Object, java.lang.Object, java.util.Collection) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(boolean, boolean)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(boolean[], boolean[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(boolean[], boolean[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(boolean[], boolean[])">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;_,null-&gt;!null;null,_-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(byte, byte)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(byte[], byte[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(byte[], byte[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(byte[], byte[])">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;_,null-&gt;!null;null,_-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(char, char)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(char[], char[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(char[], char[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(char[], char[])">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;_,null-&gt;!null;null,_-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(double[], double[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(double[], double[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
</item>
<item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(double[], double[])">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;_,null-&gt;!null;null,_-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(float[], float[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(float[], float[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
</item>
<item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(float[], float[])">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;_,null-&gt;!null;null,_-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(int, int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(int[], int[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(int[], int[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(int[], int[])">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;_,null-&gt;!null;null,_-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(java.lang.Object, java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(java.lang.Object, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
</item>
<item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(java.lang.Object, java.lang.Object)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(java.lang.Object[], java.lang.Object[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(java.lang.Object[], java.lang.Object[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(java.lang.Object[], java.lang.Object[])">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;_,null-&gt;!null;null,_-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(long, long)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(long[], long[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(long[], long[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(long[], long[])">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;_,null-&gt;!null;null,_-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(short, short)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(short[], short[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(short[], short[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder append(short[], short[])">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;_,null-&gt;!null;null,_-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.builder.EqualsBuilder org.apache.commons.lang.builder.EqualsBuilder appendSuper(boolean)">
<annotation name="org.jetbrains.annotations.NotNull"/>
@@ -158,9 +296,15 @@
<item name="org.apache.commons.lang.builder.HashCodeBuilder int reflectionHashCode(int, int, java.lang.Object, boolean, java.lang.Class) 2">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.HashCodeBuilder int reflectionHashCode(int, int, java.lang.Object, boolean, java.lang.Class) 4">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.HashCodeBuilder int reflectionHashCode(int, int, java.lang.Object, boolean, java.lang.Class, java.lang.String[]) 2">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.HashCodeBuilder int reflectionHashCode(int, int, java.lang.Object, boolean, java.lang.Class, java.lang.String[]) 4">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.HashCodeBuilder int reflectionHashCode(java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -173,77 +317,92 @@
<item name="org.apache.commons.lang.builder.HashCodeBuilder int reflectionHashCode(java.lang.Object, java.util.Collection) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.HashCodeBuilder int reflectionHashCode(java.lang.Object, java.util.Collection) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.HashCodeBuilder java.lang.Integer toIdentityHashCodeInteger(java.lang.Object)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.builder.HashCodeBuilder org.apache.commons.lang.builder.HashCodeBuilder append(boolean)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.HashCodeBuilder org.apache.commons.lang.builder.HashCodeBuilder append(boolean[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.HashCodeBuilder org.apache.commons.lang.builder.HashCodeBuilder append(boolean[])">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;null-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.builder.HashCodeBuilder org.apache.commons.lang.builder.HashCodeBuilder append(byte)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.HashCodeBuilder org.apache.commons.lang.builder.HashCodeBuilder append(byte[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.HashCodeBuilder org.apache.commons.lang.builder.HashCodeBuilder append(byte[])">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;null-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.builder.HashCodeBuilder org.apache.commons.lang.builder.HashCodeBuilder append(char)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.HashCodeBuilder org.apache.commons.lang.builder.HashCodeBuilder append(char[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.HashCodeBuilder org.apache.commons.lang.builder.HashCodeBuilder append(char[])">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;null-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.HashCodeBuilder org.apache.commons.lang.builder.HashCodeBuilder append(double[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
</item>
<item name="org.apache.commons.lang.builder.HashCodeBuilder org.apache.commons.lang.builder.HashCodeBuilder append(double[])">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;null-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.builder.HashCodeBuilder org.apache.commons.lang.builder.HashCodeBuilder append(float)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.HashCodeBuilder org.apache.commons.lang.builder.HashCodeBuilder append(float[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.HashCodeBuilder org.apache.commons.lang.builder.HashCodeBuilder append(float[])">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;null-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.builder.HashCodeBuilder org.apache.commons.lang.builder.HashCodeBuilder append(int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.HashCodeBuilder org.apache.commons.lang.builder.HashCodeBuilder append(int[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.HashCodeBuilder org.apache.commons.lang.builder.HashCodeBuilder append(int[])">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;null-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.HashCodeBuilder org.apache.commons.lang.builder.HashCodeBuilder append(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
</item>
<item name="org.apache.commons.lang.builder.HashCodeBuilder org.apache.commons.lang.builder.HashCodeBuilder append(java.lang.Object)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.HashCodeBuilder org.apache.commons.lang.builder.HashCodeBuilder append(java.lang.Object[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.HashCodeBuilder org.apache.commons.lang.builder.HashCodeBuilder append(java.lang.Object[])">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;null-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.builder.HashCodeBuilder org.apache.commons.lang.builder.HashCodeBuilder append(long)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.HashCodeBuilder org.apache.commons.lang.builder.HashCodeBuilder append(long[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.HashCodeBuilder org.apache.commons.lang.builder.HashCodeBuilder append(long[])">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;null-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.builder.HashCodeBuilder org.apache.commons.lang.builder.HashCodeBuilder append(short)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.HashCodeBuilder org.apache.commons.lang.builder.HashCodeBuilder append(short[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.HashCodeBuilder org.apache.commons.lang.builder.HashCodeBuilder append(short[])">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;null-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.builder.HashCodeBuilder org.apache.commons.lang.builder.HashCodeBuilder appendSuper(int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
@@ -251,15 +410,60 @@
<item name="org.apache.commons.lang.builder.HashCodeBuilder.1 java.lang.Object initialValue()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.ReflectionToStringBuilder ReflectionToStringBuilder(java.lang.Object, org.apache.commons.lang.builder.ToStringStyle) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ReflectionToStringBuilder ReflectionToStringBuilder(java.lang.Object, org.apache.commons.lang.builder.ToStringStyle, java.lang.StringBuffer) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ReflectionToStringBuilder ReflectionToStringBuilder(java.lang.Object, org.apache.commons.lang.builder.ToStringStyle, java.lang.StringBuffer) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ReflectionToStringBuilder ReflectionToStringBuilder(java.lang.Object, org.apache.commons.lang.builder.ToStringStyle, java.lang.StringBuffer, java.lang.Class, boolean) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ReflectionToStringBuilder ReflectionToStringBuilder(java.lang.Object, org.apache.commons.lang.builder.ToStringStyle, java.lang.StringBuffer, java.lang.Class, boolean) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ReflectionToStringBuilder ReflectionToStringBuilder(java.lang.Object, org.apache.commons.lang.builder.ToStringStyle, java.lang.StringBuffer, java.lang.Class, boolean, boolean) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ReflectionToStringBuilder ReflectionToStringBuilder(java.lang.Object, org.apache.commons.lang.builder.ToStringStyle, java.lang.StringBuffer, java.lang.Class, boolean, boolean) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.ReflectionToStringBuilder boolean accept(java.lang.reflect.Field) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.builder.ReflectionToStringBuilder java.lang.Object getValue(java.lang.reflect.Field) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.ReflectionToStringBuilder java.lang.String toString(java.lang.Object, org.apache.commons.lang.builder.ToStringStyle) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ReflectionToStringBuilder java.lang.String toString(java.lang.Object, org.apache.commons.lang.builder.ToStringStyle, boolean) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ReflectionToStringBuilder java.lang.String toString(java.lang.Object, org.apache.commons.lang.builder.ToStringStyle, boolean, boolean) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ReflectionToStringBuilder java.lang.String toString(java.lang.Object, org.apache.commons.lang.builder.ToStringStyle, boolean, boolean, java.lang.Class) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ReflectionToStringBuilder java.lang.String toString(java.lang.Object, org.apache.commons.lang.builder.ToStringStyle, boolean, java.lang.Class) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ReflectionToStringBuilder java.lang.String toStringExclude(java.lang.Object, java.util.Collection) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.ReflectionToStringBuilder java.lang.String[] toNoNullStringArray(java.lang.Object[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.ReflectionToStringBuilder java.lang.String[] toNoNullStringArray(java.util.Collection) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ReflectionToStringBuilder org.apache.commons.lang.builder.ReflectionToStringBuilder setExcludeFieldNames(java.lang.String[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.ReflectionToStringBuilder org.apache.commons.lang.builder.ReflectionToStringBuilder setExcludeFieldNames(java.lang.String[])">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -269,6 +473,60 @@
<item name="org.apache.commons.lang.builder.ReflectionToStringBuilder void appendFieldsIn(java.lang.Class) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.StandardToStringStyle void setArrayEnd(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.StandardToStringStyle void setArraySeparator(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.StandardToStringStyle void setArrayStart(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.StandardToStringStyle void setContentEnd(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.StandardToStringStyle void setContentStart(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.StandardToStringStyle void setFieldNameValueSeparator(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.StandardToStringStyle void setFieldSeparator(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.StandardToStringStyle void setNullText(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.StandardToStringStyle void setSizeEndText(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.StandardToStringStyle void setSizeStartText(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.StandardToStringStyle void setSummaryObjectEndText(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.StandardToStringStyle void setSummaryObjectStartText(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringBuilder ToStringBuilder(java.lang.Object, org.apache.commons.lang.builder.ToStringStyle) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringBuilder ToStringBuilder(java.lang.Object, org.apache.commons.lang.builder.ToStringStyle, java.lang.StringBuffer) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringBuilder ToStringBuilder(java.lang.Object, org.apache.commons.lang.builder.ToStringStyle, java.lang.StringBuffer) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringBuilder java.lang.String reflectionToString(java.lang.Object, org.apache.commons.lang.builder.ToStringStyle) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringBuilder java.lang.String reflectionToString(java.lang.Object, org.apache.commons.lang.builder.ToStringStyle, boolean) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringBuilder java.lang.String reflectionToString(java.lang.Object, org.apache.commons.lang.builder.ToStringStyle, boolean, java.lang.Class) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.ToStringBuilder java.lang.String toString()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -410,22 +668,68 @@
<item name="org.apache.commons.lang.builder.ToStringBuilder org.apache.commons.lang.builder.ToStringBuilder append(short[])">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.ToStringBuilder org.apache.commons.lang.builder.ToStringBuilder appendAsObjectToString(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.ToStringBuilder org.apache.commons.lang.builder.ToStringBuilder appendAsObjectToString(java.lang.Object)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.ToStringBuilder org.apache.commons.lang.builder.ToStringBuilder appendSuper(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.ToStringBuilder org.apache.commons.lang.builder.ToStringBuilder appendSuper(java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.ToStringBuilder org.apache.commons.lang.builder.ToStringBuilder appendToString(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.ToStringBuilder org.apache.commons.lang.builder.ToStringBuilder appendToString(java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.builder.ToStringBuilder void setDefaultStyle(org.apache.commons.lang.builder.ToStringStyle) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle boolean isFullDetail(java.lang.Boolean) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle java.lang.String getShortClassName(java.lang.Class) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.ToStringStyle java.lang.String getShortClassName(java.lang.Class)">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;null-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void append(java.lang.StringBuffer, java.lang.String, boolean[], java.lang.Boolean) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void append(java.lang.StringBuffer, java.lang.String, byte[], java.lang.Boolean) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void append(java.lang.StringBuffer, java.lang.String, char[], java.lang.Boolean) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void append(java.lang.StringBuffer, java.lang.String, double[], java.lang.Boolean) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void append(java.lang.StringBuffer, java.lang.String, float[], java.lang.Boolean) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void append(java.lang.StringBuffer, java.lang.String, int[], java.lang.Boolean) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void append(java.lang.StringBuffer, java.lang.String, java.lang.Object, java.lang.Boolean) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void append(java.lang.StringBuffer, java.lang.String, java.lang.Object[], java.lang.Boolean) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void append(java.lang.StringBuffer, java.lang.String, long[], java.lang.Boolean) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void append(java.lang.StringBuffer, java.lang.String, short[], java.lang.Boolean) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void appendClassName(java.lang.StringBuffer, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
</item>
<item name="org.apache.commons.lang.builder.ToStringStyle void appendContentEnd(java.lang.StringBuffer) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
@@ -433,9 +737,21 @@
<item name="org.apache.commons.lang.builder.ToStringStyle void appendContentStart(java.lang.StringBuffer) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void appendCyclicObject(java.lang.StringBuffer, java.lang.String, java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void appendCyclicObject(java.lang.StringBuffer, java.lang.String, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void appendCyclicObject(java.lang.StringBuffer, java.lang.String, java.lang.Object) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.ToStringStyle void appendDetail(java.lang.StringBuffer, java.lang.String, boolean) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void appendDetail(java.lang.StringBuffer, java.lang.String, boolean) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.ToStringStyle void appendDetail(java.lang.StringBuffer, java.lang.String, boolean[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -445,6 +761,9 @@
<item name="org.apache.commons.lang.builder.ToStringStyle void appendDetail(java.lang.StringBuffer, java.lang.String, byte) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void appendDetail(java.lang.StringBuffer, java.lang.String, byte) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.ToStringStyle void appendDetail(java.lang.StringBuffer, java.lang.String, byte[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -454,6 +773,9 @@
<item name="org.apache.commons.lang.builder.ToStringStyle void appendDetail(java.lang.StringBuffer, java.lang.String, char) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void appendDetail(java.lang.StringBuffer, java.lang.String, char) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.ToStringStyle void appendDetail(java.lang.StringBuffer, java.lang.String, char[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -463,6 +785,9 @@
<item name="org.apache.commons.lang.builder.ToStringStyle void appendDetail(java.lang.StringBuffer, java.lang.String, double) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void appendDetail(java.lang.StringBuffer, java.lang.String, double) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.ToStringStyle void appendDetail(java.lang.StringBuffer, java.lang.String, double[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -472,6 +797,9 @@
<item name="org.apache.commons.lang.builder.ToStringStyle void appendDetail(java.lang.StringBuffer, java.lang.String, float) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void appendDetail(java.lang.StringBuffer, java.lang.String, float) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.ToStringStyle void appendDetail(java.lang.StringBuffer, java.lang.String, float[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -481,6 +809,9 @@
<item name="org.apache.commons.lang.builder.ToStringStyle void appendDetail(java.lang.StringBuffer, java.lang.String, int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void appendDetail(java.lang.StringBuffer, java.lang.String, int) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.ToStringStyle void appendDetail(java.lang.StringBuffer, java.lang.String, int[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -490,6 +821,12 @@
<item name="org.apache.commons.lang.builder.ToStringStyle void appendDetail(java.lang.StringBuffer, java.lang.String, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void appendDetail(java.lang.StringBuffer, java.lang.String, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void appendDetail(java.lang.StringBuffer, java.lang.String, java.lang.Object) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.ToStringStyle void appendDetail(java.lang.StringBuffer, java.lang.String, java.lang.Object[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -499,12 +836,27 @@
<item name="org.apache.commons.lang.builder.ToStringStyle void appendDetail(java.lang.StringBuffer, java.lang.String, java.util.Collection) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void appendDetail(java.lang.StringBuffer, java.lang.String, java.util.Collection) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void appendDetail(java.lang.StringBuffer, java.lang.String, java.util.Collection) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.ToStringStyle void appendDetail(java.lang.StringBuffer, java.lang.String, java.util.Map) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void appendDetail(java.lang.StringBuffer, java.lang.String, java.util.Map) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void appendDetail(java.lang.StringBuffer, java.lang.String, java.util.Map) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.ToStringStyle void appendDetail(java.lang.StringBuffer, java.lang.String, long) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void appendDetail(java.lang.StringBuffer, java.lang.String, long) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.ToStringStyle void appendDetail(java.lang.StringBuffer, java.lang.String, long[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -514,18 +866,36 @@
<item name="org.apache.commons.lang.builder.ToStringStyle void appendDetail(java.lang.StringBuffer, java.lang.String, short) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void appendDetail(java.lang.StringBuffer, java.lang.String, short) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.ToStringStyle void appendDetail(java.lang.StringBuffer, java.lang.String, short[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.builder.ToStringStyle void appendDetail(java.lang.StringBuffer, java.lang.String, short[]) 2">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void appendFieldEnd(java.lang.StringBuffer, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.ToStringStyle void appendFieldSeparator(java.lang.StringBuffer) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void appendFieldStart(java.lang.StringBuffer, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void appendIdentityHashCode(java.lang.StringBuffer, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.ToStringStyle void appendNullText(java.lang.StringBuffer, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void appendNullText(java.lang.StringBuffer, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void appendStart(java.lang.StringBuffer, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.ToStringStyle void appendSummary(java.lang.StringBuffer, java.lang.String, boolean[]) 2">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -547,6 +917,9 @@
<item name="org.apache.commons.lang.builder.ToStringStyle void appendSummary(java.lang.StringBuffer, java.lang.String, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void appendSummary(java.lang.StringBuffer, java.lang.String, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.ToStringStyle void appendSummary(java.lang.StringBuffer, java.lang.String, java.lang.Object) 2">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -562,12 +935,57 @@
<item name="org.apache.commons.lang.builder.ToStringStyle void appendSummarySize(java.lang.StringBuffer, java.lang.String, int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void appendSummarySize(java.lang.StringBuffer, java.lang.String, int) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void appendToString(java.lang.StringBuffer, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.ToStringStyle void reflectionAppendArrayDetail(java.lang.StringBuffer, java.lang.String, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void register(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.ToStringStyle void removeLastFieldSeparator(java.lang.StringBuffer) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void setArrayEnd(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void setArraySeparator(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void setArrayStart(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void setContentEnd(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void setContentStart(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void setFieldNameValueSeparator(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void setFieldSeparator(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void setNullText(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void setSizeEndText(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void setSizeStartText(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void setSummaryObjectEndText(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.builder.ToStringStyle void setSummaryObjectStartText(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.builder.ToStringStyle.1 java.lang.Object initialValue()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/enum/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/enum/annotations.xml
index be5d5ca8d20e..05b15d3460ce 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/enum/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/enum/annotations.xml
@@ -2,6 +2,9 @@
<item name="org.apache.commons.lang.enum.Enum Enum(java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.enum.Enum boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.enum.Enum java.lang.String getNameInOtherClassLoader(java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/enums/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/enums/annotations.xml
index 0e7d219fd30a..3b827c118787 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/enums/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/enums/annotations.xml
@@ -2,6 +2,9 @@
<item name="org.apache.commons.lang.enums.Enum Enum(java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.enums.Enum boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.enums.Enum java.lang.String getNameInOtherClassLoader(java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/exception/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/exception/annotations.xml
index 2924cb9a5731..585584b958f2 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/exception/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/exception/annotations.xml
@@ -1,4 +1,10 @@
<root>
+ <item name="org.apache.commons.lang.exception.ExceptionUtils boolean isCauseMethodName(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.exception.ExceptionUtils boolean isNestedThrowable(java.lang.Throwable) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.exception.ExceptionUtils boolean isNestedThrowable(java.lang.Throwable)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -7,12 +13,54 @@
<item name="org.apache.commons.lang.exception.ExceptionUtils boolean setCause(java.lang.Throwable, java.lang.Throwable) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.exception.ExceptionUtils int getThrowableCount(java.lang.Throwable) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.exception.ExceptionUtils int indexOf(java.lang.Throwable, java.lang.Class, int, boolean) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.exception.ExceptionUtils int indexOf(java.lang.Throwable, java.lang.Class, int, boolean) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.exception.ExceptionUtils int indexOfThrowable(java.lang.Throwable, java.lang.Class) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.exception.ExceptionUtils int indexOfThrowable(java.lang.Throwable, java.lang.Class) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.exception.ExceptionUtils int indexOfThrowable(java.lang.Throwable, java.lang.Class, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.exception.ExceptionUtils int indexOfThrowable(java.lang.Throwable, java.lang.Class, int) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.exception.ExceptionUtils int indexOfType(java.lang.Throwable, java.lang.Class) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.exception.ExceptionUtils int indexOfType(java.lang.Throwable, java.lang.Class) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.exception.ExceptionUtils int indexOfType(java.lang.Throwable, java.lang.Class, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.exception.ExceptionUtils int indexOfType(java.lang.Throwable, java.lang.Class, int) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.exception.ExceptionUtils java.lang.String getFullStackTrace(java.lang.Throwable) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.exception.ExceptionUtils java.lang.String getFullStackTrace(java.lang.Throwable)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.exception.ExceptionUtils java.lang.String getMessage(java.lang.Throwable) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.exception.ExceptionUtils java.lang.String getMessage(java.lang.Throwable)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.exception.ExceptionUtils java.lang.String getRootCauseMessage(java.lang.Throwable) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.exception.ExceptionUtils java.lang.String getRootCauseMessage(java.lang.Throwable)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -22,30 +70,63 @@
<item name="org.apache.commons.lang.exception.ExceptionUtils java.lang.String getStackTrace(java.lang.Throwable)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.exception.ExceptionUtils java.lang.String[] getRootCauseStackTrace(java.lang.Throwable) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.exception.ExceptionUtils java.lang.String[] getStackFrames(java.lang.Throwable) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.exception.ExceptionUtils java.lang.String[] toArray(java.util.List) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.exception.ExceptionUtils java.lang.Throwable getCause(java.lang.Throwable) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.exception.ExceptionUtils java.lang.Throwable getCause(java.lang.Throwable)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.exception.ExceptionUtils java.lang.Throwable getCause(java.lang.Throwable, java.lang.String[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.exception.ExceptionUtils java.lang.Throwable getCause(java.lang.Throwable, java.lang.String[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.exception.ExceptionUtils java.lang.Throwable getCauseUsingWellKnownTypes(java.lang.Throwable) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.exception.ExceptionUtils java.lang.Throwable getCauseUsingWellKnownTypes(java.lang.Throwable)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.exception.ExceptionUtils java.lang.Throwable getRootCause(java.lang.Throwable) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.exception.ExceptionUtils java.lang.Throwable[] getThrowables(java.lang.Throwable) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.exception.ExceptionUtils java.util.ArrayList getCauseMethodNameList()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.exception.ExceptionUtils java.util.List getStackFrameList(java.lang.Throwable) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.exception.ExceptionUtils java.util.List getThrowableList(java.lang.Throwable) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.exception.ExceptionUtils void printRootCauseStackTrace(java.lang.Throwable) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.exception.ExceptionUtils void printRootCauseStackTrace(java.lang.Throwable, java.io.PrintStream) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.exception.ExceptionUtils void printRootCauseStackTrace(java.lang.Throwable, java.io.PrintWriter) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.exception.ExceptionUtils void removeCommonFrames(java.util.List, java.util.List) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -55,6 +136,9 @@
<item name="org.apache.commons.lang.exception.NestableDelegate NestableDelegate(org.apache.commons.lang.exception.Nestable) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.exception.NestableDelegate int indexOfThrowable(java.lang.Class, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.exception.NestableDelegate java.lang.String getMessage(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null&quot;"/>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/math/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/math/annotations.xml
index c799fc9bc0fd..567cb620681f 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/math/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/math/annotations.xml
@@ -8,16 +8,28 @@
<item name="org.apache.commons.lang.math.DoubleRange DoubleRange(java.lang.Number, java.lang.Number) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.math.DoubleRange boolean containsNumber(java.lang.Number) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.math.DoubleRange boolean containsNumber(java.lang.Number)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.math.DoubleRange boolean containsRange(org.apache.commons.lang.math.Range) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.math.DoubleRange boolean containsRange(org.apache.commons.lang.math.Range)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.math.DoubleRange boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.math.DoubleRange boolean overlapsRange(org.apache.commons.lang.math.Range) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.math.DoubleRange boolean overlapsRange(org.apache.commons.lang.math.Range)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -32,21 +44,36 @@
<item name="org.apache.commons.lang.math.FloatRange FloatRange(java.lang.Number, java.lang.Number) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.math.FloatRange boolean containsNumber(java.lang.Number) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.math.FloatRange boolean containsNumber(java.lang.Number)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.math.FloatRange boolean containsRange(org.apache.commons.lang.math.Range) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.math.FloatRange boolean containsRange(org.apache.commons.lang.math.Range)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.math.FloatRange boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.math.FloatRange boolean overlapsRange(org.apache.commons.lang.math.Range) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.math.FloatRange boolean overlapsRange(org.apache.commons.lang.math.Range)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.math.Fraction boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.math.Fraction org.apache.commons.lang.math.Fraction abs()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -116,21 +143,36 @@
<item name="org.apache.commons.lang.math.IntRange IntRange(java.lang.Number, java.lang.Number) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.math.IntRange boolean containsNumber(java.lang.Number) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.math.IntRange boolean containsNumber(java.lang.Number)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.math.IntRange boolean containsRange(org.apache.commons.lang.math.Range) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.math.IntRange boolean containsRange(org.apache.commons.lang.math.Range)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.math.IntRange boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.math.IntRange boolean overlapsRange(org.apache.commons.lang.math.Range) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.math.IntRange boolean overlapsRange(org.apache.commons.lang.math.Range)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.math.JVMRandom void nextBytes(byte[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.math.LongRange LongRange(java.lang.Number) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -140,16 +182,28 @@
<item name="org.apache.commons.lang.math.LongRange LongRange(java.lang.Number, java.lang.Number) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.math.LongRange boolean containsNumber(java.lang.Number) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.math.LongRange boolean containsNumber(java.lang.Number)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.math.LongRange boolean containsRange(org.apache.commons.lang.math.Range) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.math.LongRange boolean containsRange(org.apache.commons.lang.math.Range)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.math.LongRange boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.math.LongRange boolean overlapsRange(org.apache.commons.lang.math.Range) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.math.LongRange boolean overlapsRange(org.apache.commons.lang.math.Range)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -164,11 +218,20 @@
<item name="org.apache.commons.lang.math.NumberRange NumberRange(java.lang.Number, java.lang.Number) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.math.NumberRange boolean containsNumber(java.lang.Number) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.math.NumberRange boolean containsNumber(java.lang.Number)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.math.NumberRange boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.math.NumberUtils boolean isAllZeros(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.math.NumberUtils boolean isAllZeros(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;true&quot;"/>
@@ -196,48 +259,93 @@
<item name="org.apache.commons.lang.math.NumberUtils double min(double[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.math.NumberUtils double toDouble(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.math.NumberUtils double toDouble(java.lang.String, double) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.math.NumberUtils float max(float[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.math.NumberUtils float min(float[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.math.NumberUtils float toFloat(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.math.NumberUtils float toFloat(java.lang.String, float) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.math.NumberUtils int max(int[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.math.NumberUtils int min(int[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.math.NumberUtils int stringToInt(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.math.NumberUtils int stringToInt(java.lang.String, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.math.NumberUtils int toInt(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.math.NumberUtils int toInt(java.lang.String, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.math.NumberUtils java.lang.Double createDouble(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.math.NumberUtils java.lang.Double createDouble(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.math.NumberUtils java.lang.Float createFloat(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.math.NumberUtils java.lang.Float createFloat(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.math.NumberUtils java.lang.Integer createInteger(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.math.NumberUtils java.lang.Integer createInteger(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.math.NumberUtils java.lang.Long createLong(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.math.NumberUtils java.lang.Long createLong(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.math.NumberUtils java.lang.Number createNumber(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.math.NumberUtils java.lang.Number createNumber(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.math.NumberUtils java.math.BigDecimal createBigDecimal(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.math.NumberUtils java.math.BigDecimal createBigDecimal(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.math.NumberUtils java.math.BigInteger createBigInteger(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.math.NumberUtils java.math.BigInteger createBigInteger(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null;null-&gt;null&quot;"/>
@@ -249,6 +357,12 @@
<item name="org.apache.commons.lang.math.NumberUtils long min(long[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.math.NumberUtils long toLong(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.math.NumberUtils long toLong(java.lang.String, long) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.math.NumberUtils short max(short[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -273,31 +387,52 @@
<item name="org.apache.commons.lang.math.RandomUtils long nextLong(java.util.Random) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.math.Range boolean containsDouble(java.lang.Number) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.math.Range boolean containsDouble(java.lang.Number)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.math.Range boolean containsFloat(java.lang.Number) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.math.Range boolean containsFloat(java.lang.Number)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.math.Range boolean containsInteger(java.lang.Number) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.math.Range boolean containsInteger(java.lang.Number)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.math.Range boolean containsLong(java.lang.Number) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.math.Range boolean containsLong(java.lang.Number)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.math.Range boolean containsRange(org.apache.commons.lang.math.Range) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.math.Range boolean containsRange(org.apache.commons.lang.math.Range)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.math.Range boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.math.Range boolean overlapsRange(org.apache.commons.lang.math.Range) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.math.Range boolean overlapsRange(org.apache.commons.lang.math.Range)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/mutable/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/mutable/annotations.xml
index dd2d7d0d82ab..acf730ff9e41 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/mutable/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/mutable/annotations.xml
@@ -2,6 +2,9 @@
<item name="org.apache.commons.lang.mutable.MutableBoolean MutableBoolean(java.lang.Boolean) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.mutable.MutableBoolean boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.mutable.MutableBoolean boolean equals(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -19,6 +22,9 @@
<item name="org.apache.commons.lang.mutable.MutableByte MutableByte(java.lang.Number) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.mutable.MutableByte boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.mutable.MutableByte boolean equals(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -48,6 +54,9 @@
<item name="org.apache.commons.lang.mutable.MutableDouble MutableDouble(java.lang.Number) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.mutable.MutableDouble boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.mutable.MutableDouble boolean equals(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -74,6 +83,9 @@
<item name="org.apache.commons.lang.mutable.MutableFloat MutableFloat(java.lang.Number) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.mutable.MutableFloat boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.mutable.MutableFloat boolean equals(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -100,6 +112,9 @@
<item name="org.apache.commons.lang.mutable.MutableInt MutableInt(java.lang.Number) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.mutable.MutableInt boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.mutable.MutableInt boolean equals(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -129,6 +144,9 @@
<item name="org.apache.commons.lang.mutable.MutableLong MutableLong(java.lang.Number) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.mutable.MutableLong boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.mutable.MutableLong boolean equals(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -155,6 +173,9 @@
<item name="org.apache.commons.lang.mutable.MutableLong void subtract(java.lang.Number) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.mutable.MutableObject boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.mutable.MutableObject boolean equals(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -163,6 +184,9 @@
<item name="org.apache.commons.lang.mutable.MutableShort MutableShort(java.lang.Number) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.mutable.MutableShort boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.mutable.MutableShort boolean equals(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/text/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/text/annotations.xml
index d6d4e6ec1483..0e46f59ecbed 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/text/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/text/annotations.xml
@@ -1,4 +1,7 @@
<root>
+ <item name="org.apache.commons.lang.text.ExtendedMessageFormat boolean containsElements(java.util.Collection) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.ExtendedMessageFormat boolean containsElements(java.util.Collection)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -60,11 +63,32 @@
<item name="org.apache.commons.lang.text.ExtendedMessageFormat void seekNonWs(java.lang.String, java.text.ParsePosition) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.text.ExtendedMessageFormat void setFormat(int, java.text.Format) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.text.ExtendedMessageFormat void setFormatByArgumentIndex(int, java.text.Format) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.text.ExtendedMessageFormat void setFormats(java.text.Format[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.text.ExtendedMessageFormat void setFormatsByArgumentIndex(java.text.Format[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.text.StrBuilder StrBuilder(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.text.StrBuilder boolean endsWith(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrBuilder boolean endsWith(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.text.StrBuilder boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrBuilder boolean equals(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -80,16 +104,34 @@
<val val="&quot;null-&gt;true&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.text.StrBuilder boolean startsWith(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrBuilder boolean startsWith(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.text.StrBuilder char[] getChars(char[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrBuilder char[] getChars(char[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null;null-&gt;!null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.text.StrBuilder int indexOf(java.lang.String, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.text.StrBuilder int indexOf(org.apache.commons.lang.text.StrMatcher, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.text.StrBuilder int lastIndexOf(java.lang.String, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.text.StrBuilder int lastIndexOf(org.apache.commons.lang.text.StrMatcher, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrBuilder java.io.Reader asReader()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -120,60 +162,105 @@
<item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder append(char)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder append(char[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder append(char[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder append(char[], int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder append(char[], int, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_,_-&gt;!null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder append(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder append(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder append(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder append(java.lang.String, int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder append(java.lang.String, int, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_,_-&gt;!null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder append(java.lang.StringBuffer) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder append(java.lang.StringBuffer)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder append(java.lang.StringBuffer, int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder append(java.lang.StringBuffer, int, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_,_-&gt;!null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder append(org.apache.commons.lang.text.StrBuilder) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder append(org.apache.commons.lang.text.StrBuilder)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder append(org.apache.commons.lang.text.StrBuilder, int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder append(org.apache.commons.lang.text.StrBuilder, int, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_,_-&gt;!null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder appendAll(java.lang.Object[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder appendAll(java.lang.Object[])">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;null-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder appendAll(java.util.Collection) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
</item>
<item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder appendAll(java.util.Collection)">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;null-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder appendAll(java.util.Iterator) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
</item>
<item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder appendAll(java.util.Iterator)">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;null-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder appendFixedWidthPadLeft(java.lang.Object, int, char) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder appendFixedWidthPadLeft(java.lang.Object, int, char)">
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder appendFixedWidthPadRight(java.lang.Object, int, char) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder appendFixedWidthPadRight(java.lang.Object, int, char)">
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder appendPadding(int, char)">
+ <annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder appendSeparator(char)">
<annotation name="org.jetbrains.annotations.NotNull"/>
@@ -181,26 +268,44 @@
<item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder appendSeparator(char, int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder appendSeparator(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder appendSeparator(java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder appendSeparator(java.lang.String, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder appendSeparator(java.lang.String, int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder appendWithSeparators(java.lang.Object[], java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder appendWithSeparators(java.lang.Object[], java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder appendWithSeparators(java.lang.Object[], java.lang.String)">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;null,_-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder appendWithSeparators(java.util.Collection, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder appendWithSeparators(java.util.Collection, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
</item>
<item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder appendWithSeparators(java.util.Collection, java.lang.String)">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;null,_-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder appendWithSeparators(java.util.Iterator, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder appendWithSeparators(java.util.Iterator, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
</item>
<item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder appendWithSeparators(java.util.Iterator, java.lang.String)">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;null,_-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder clear()">
<annotation name="org.jetbrains.annotations.NotNull"/>
@@ -208,9 +313,18 @@
<item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder delete(int, int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder deleteAll(char)">
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder deleteAll(java.lang.String)">
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
<item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder deleteCharAt(int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder deleteFirst(char)">
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
<item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder deleteFirst(java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -223,16 +337,28 @@
<item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder insert(int, char)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder insert(int, char[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder insert(int, char[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,!null-&gt;!null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder insert(int, char[], int, int) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder insert(int, char[], int, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,!null,_,_-&gt;!null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder insert(int, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder insert(int, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder insert(int, java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -242,34 +368,57 @@
<item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder replace(int, int, java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder replace(org.apache.commons.lang.text.StrMatcher, java.lang.String, int, int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder replace(org.apache.commons.lang.text.StrMatcher, java.lang.String, int, int, int)">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;null,_,_,_,_-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder replaceAll(char, char)">
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder replaceAll(java.lang.String, java.lang.String)">
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder replaceFirst(char, char)">
+ <annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder replaceFirst(java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder replaceImpl(org.apache.commons.lang.text.StrMatcher, java.lang.String, int, int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder replaceImpl(org.apache.commons.lang.text.StrMatcher, java.lang.String, int, int, int)">
- <annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;null,_,_,_,_-&gt;!null&quot;"/>
- </annotation>
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder reverse()">
+ <annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder setCharAt(int, char)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder setLength(int)">
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
<item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder setNewLineText(java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder setNullText(java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrBuilder trim()">
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
<item name="org.apache.commons.lang.text.StrBuilder org.apache.commons.lang.text.StrTokenizer asTokenizer()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.text.StrBuilder.StrBuilderReader int read(char[], int, int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.text.StrBuilder.StrBuilderTokenizer java.util.List tokenize(char[], int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrLookup org.apache.commons.lang.text.StrLookup mapLookup(java.util.Map)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -279,6 +428,15 @@
<item name="org.apache.commons.lang.text.StrMatcher org.apache.commons.lang.text.StrMatcher charMatcher(char)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.text.StrMatcher org.apache.commons.lang.text.StrMatcher charSetMatcher(char[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.text.StrMatcher org.apache.commons.lang.text.StrMatcher charSetMatcher(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.text.StrMatcher org.apache.commons.lang.text.StrMatcher stringMatcher(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrMatcher.CharMatcher int isMatch(char[], int, int, int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -288,27 +446,42 @@
<item name="org.apache.commons.lang.text.StrMatcher.CharSetMatcher int isMatch(char[], int, int, int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.text.StrMatcher.NoMatcher int isMatch(char[], int, int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrMatcher.StringMatcher StringMatcher(java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.text.StrMatcher.TrimMatcher int isMatch(char[], int, int, int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.text.StrSubstitutor boolean replaceIn(java.lang.StringBuffer) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrSubstitutor boolean replaceIn(java.lang.StringBuffer)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.text.StrSubstitutor boolean replaceIn(java.lang.StringBuffer, int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrSubstitutor boolean replaceIn(java.lang.StringBuffer, int, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_,_-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.text.StrSubstitutor boolean replaceIn(org.apache.commons.lang.text.StrBuilder) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrSubstitutor boolean replaceIn(org.apache.commons.lang.text.StrBuilder)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.text.StrSubstitutor boolean replaceIn(org.apache.commons.lang.text.StrBuilder, int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrSubstitutor boolean replaceIn(org.apache.commons.lang.text.StrBuilder, int, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_,_-&gt;false&quot;"/>
@@ -320,51 +493,84 @@
<item name="org.apache.commons.lang.text.StrSubstitutor int substitute(org.apache.commons.lang.text.StrBuilder, int, int, java.util.List) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.text.StrSubstitutor int substitute(org.apache.commons.lang.text.StrBuilder, int, int, java.util.List) 3">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.text.StrSubstitutor java.lang.String replace(char[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrSubstitutor java.lang.String replace(char[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.text.StrSubstitutor java.lang.String replace(char[], int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrSubstitutor java.lang.String replace(char[], int, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.text.StrSubstitutor java.lang.String replace(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrSubstitutor java.lang.String replace(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.text.StrSubstitutor java.lang.String replace(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrSubstitutor java.lang.String replace(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.text.StrSubstitutor java.lang.String replace(java.lang.String, int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrSubstitutor java.lang.String replace(java.lang.String, int, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.text.StrSubstitutor java.lang.String replace(java.lang.StringBuffer) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrSubstitutor java.lang.String replace(java.lang.StringBuffer)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.text.StrSubstitutor java.lang.String replace(java.lang.StringBuffer, int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrSubstitutor java.lang.String replace(java.lang.StringBuffer, int, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.text.StrSubstitutor java.lang.String replace(org.apache.commons.lang.text.StrBuilder) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrSubstitutor java.lang.String replace(org.apache.commons.lang.text.StrBuilder)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.text.StrSubstitutor java.lang.String replace(org.apache.commons.lang.text.StrBuilder, int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrSubstitutor java.lang.String replace(org.apache.commons.lang.text.StrBuilder, int, int)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.text.StrSubstitutor java.lang.String resolveVariable(java.lang.String, org.apache.commons.lang.text.StrBuilder, int, int) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrSubstitutor org.apache.commons.lang.text.StrSubstitutor setVariablePrefix(java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -386,37 +592,82 @@
<item name="org.apache.commons.lang.text.StrSubstitutor void checkCyclicSubstitution(java.lang.String, java.util.List) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.text.StrTokenizer StrTokenizer(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.text.StrTokenizer StrTokenizer(java.lang.String, char) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.text.StrTokenizer StrTokenizer(java.lang.String, char, char) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.text.StrTokenizer StrTokenizer(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.text.StrTokenizer StrTokenizer(java.lang.String, org.apache.commons.lang.text.StrMatcher) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.text.StrTokenizer StrTokenizer(java.lang.String, org.apache.commons.lang.text.StrMatcher, org.apache.commons.lang.text.StrMatcher) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrTokenizer int readWithQuotes(char[], int, int, org.apache.commons.lang.text.StrBuilder, java.util.List, int, int) 3">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.text.StrTokenizer java.lang.String toString()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.text.StrTokenizer java.util.List tokenize(char[], int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrTokenizer org.apache.commons.lang.text.StrTokenizer reset()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.text.StrTokenizer org.apache.commons.lang.text.StrTokenizer reset(char[])">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.text.StrTokenizer org.apache.commons.lang.text.StrTokenizer reset(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrTokenizer org.apache.commons.lang.text.StrTokenizer reset(java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.text.StrTokenizer org.apache.commons.lang.text.StrTokenizer setDelimiterMatcher(org.apache.commons.lang.text.StrMatcher) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrTokenizer org.apache.commons.lang.text.StrTokenizer setDelimiterMatcher(org.apache.commons.lang.text.StrMatcher)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.text.StrTokenizer org.apache.commons.lang.text.StrTokenizer setDelimiterString(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrTokenizer org.apache.commons.lang.text.StrTokenizer setEmptyTokenAsNull(boolean)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.text.StrTokenizer org.apache.commons.lang.text.StrTokenizer setIgnoreEmptyTokens(boolean)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.text.StrTokenizer org.apache.commons.lang.text.StrTokenizer setIgnoredMatcher(org.apache.commons.lang.text.StrMatcher) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrTokenizer org.apache.commons.lang.text.StrTokenizer setIgnoredMatcher(org.apache.commons.lang.text.StrMatcher)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.text.StrTokenizer org.apache.commons.lang.text.StrTokenizer setQuoteMatcher(org.apache.commons.lang.text.StrMatcher) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrTokenizer org.apache.commons.lang.text.StrTokenizer setQuoteMatcher(org.apache.commons.lang.text.StrMatcher)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.text.StrTokenizer org.apache.commons.lang.text.StrTokenizer setTrimmerMatcher(org.apache.commons.lang.text.StrMatcher) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.text.StrTokenizer org.apache.commons.lang.text.StrTokenizer setTrimmerMatcher(org.apache.commons.lang.text.StrMatcher)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.text.StrTokenizer void add(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.text.StrTokenizer void set(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
</root>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/time/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/time/annotations.xml
index b392cffbce52..12183165228a 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/time/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/commons/lang/time/annotations.xml
@@ -5,48 +5,90 @@
<item name="org.apache.commons.lang.time.DateFormatUtils java.lang.String format(java.util.Calendar, java.lang.String, java.util.Locale) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.time.DateFormatUtils java.lang.String format(java.util.Calendar, java.lang.String, java.util.Locale) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.time.DateFormatUtils java.lang.String format(java.util.Calendar, java.lang.String, java.util.TimeZone) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.time.DateFormatUtils java.lang.String format(java.util.Calendar, java.lang.String, java.util.TimeZone) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.time.DateFormatUtils java.lang.String format(java.util.Calendar, java.lang.String, java.util.TimeZone, java.util.Locale) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.time.DateFormatUtils java.lang.String format(java.util.Calendar, java.lang.String, java.util.TimeZone, java.util.Locale) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.time.DateFormatUtils java.lang.String format(java.util.Calendar, java.lang.String, java.util.TimeZone, java.util.Locale) 3">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.time.DateFormatUtils java.lang.String format(java.util.Date, java.lang.String) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.time.DateFormatUtils java.lang.String format(java.util.Date, java.lang.String, java.util.Locale) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.time.DateFormatUtils java.lang.String format(java.util.Date, java.lang.String, java.util.Locale) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.time.DateFormatUtils java.lang.String format(java.util.Date, java.lang.String, java.util.TimeZone) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.time.DateFormatUtils java.lang.String format(java.util.Date, java.lang.String, java.util.TimeZone) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.time.DateFormatUtils java.lang.String format(java.util.Date, java.lang.String, java.util.TimeZone, java.util.Locale) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.time.DateFormatUtils java.lang.String format(java.util.Date, java.lang.String, java.util.TimeZone, java.util.Locale) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.time.DateFormatUtils java.lang.String format(java.util.Date, java.lang.String, java.util.TimeZone, java.util.Locale) 3">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.time.DateFormatUtils java.lang.String format(long, java.lang.String) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.time.DateFormatUtils java.lang.String format(long, java.lang.String, java.util.Locale) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.time.DateFormatUtils java.lang.String format(long, java.lang.String, java.util.Locale) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.time.DateFormatUtils java.lang.String format(long, java.lang.String, java.util.TimeZone) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.time.DateFormatUtils java.lang.String format(long, java.lang.String, java.util.TimeZone) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.time.DateFormatUtils java.lang.String format(long, java.lang.String, java.util.TimeZone, java.util.Locale) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.time.DateFormatUtils java.lang.String format(long, java.lang.String, java.util.TimeZone, java.util.Locale) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.time.DateFormatUtils java.lang.String format(long, java.lang.String, java.util.TimeZone, java.util.Locale) 3">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.time.DateFormatUtils java.lang.String formatUTC(java.util.Date, java.lang.String) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.time.DateFormatUtils java.lang.String formatUTC(java.util.Date, java.lang.String, java.util.Locale) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.time.DateFormatUtils java.lang.String formatUTC(java.util.Date, java.lang.String, java.util.Locale) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.time.DateFormatUtils java.lang.String formatUTC(long, java.lang.String) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.time.DateFormatUtils java.lang.String formatUTC(long, java.lang.String, java.util.Locale) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.time.DateFormatUtils java.lang.String formatUTC(long, java.lang.String, java.util.Locale) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.time.DateUtils boolean isSameDay(java.util.Calendar, java.util.Calendar) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -296,6 +338,9 @@
<item name="org.apache.commons.lang.time.DurationFormatUtils java.lang.String formatDurationISO(long)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.time.DurationFormatUtils java.lang.String formatDurationWords(long, boolean, boolean)">
+ <annotation name="org.jetbrains.annotations.NotNull"/>
+ </item>
<item name="org.apache.commons.lang.time.DurationFormatUtils java.lang.String formatPeriod(long, long, java.lang.String) 2">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -317,6 +362,12 @@
<item name="org.apache.commons.lang.time.DurationFormatUtils.Token boolean containsTokenWithValue(org.apache.commons.lang.time.DurationFormatUtils.Token[], java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.time.DurationFormatUtils.Token boolean containsTokenWithValue(org.apache.commons.lang.time.DurationFormatUtils.Token[], java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.time.DurationFormatUtils.Token boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.time.DurationFormatUtils.Token boolean equals(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -325,11 +376,23 @@
<item name="org.apache.commons.lang.time.FastDateFormat FastDateFormat(java.lang.String, java.util.TimeZone, java.util.Locale) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.time.FastDateFormat FastDateFormat(java.lang.String, java.util.TimeZone, java.util.Locale) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.time.FastDateFormat FastDateFormat(java.lang.String, java.util.TimeZone, java.util.Locale) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.time.FastDateFormat boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.time.FastDateFormat boolean equals(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.commons.lang.time.FastDateFormat java.lang.Object parseObject(java.lang.String, java.text.ParsePosition) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.time.FastDateFormat java.lang.Object parseObject(java.lang.String, java.text.ParsePosition) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -367,6 +430,9 @@
<item name="org.apache.commons.lang.time.FastDateFormat java.lang.StringBuffer format(java.lang.Object, java.lang.StringBuffer, java.text.FieldPosition) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.time.FastDateFormat java.lang.StringBuffer format(java.lang.Object, java.lang.StringBuffer, java.text.FieldPosition) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.time.FastDateFormat java.lang.StringBuffer format(java.util.Date, java.lang.StringBuffer) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -376,12 +442,24 @@
<item name="org.apache.commons.lang.time.FastDateFormat org.apache.commons.lang.time.FastDateFormat getInstance(java.lang.String, java.util.Locale) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.time.FastDateFormat org.apache.commons.lang.time.FastDateFormat getInstance(java.lang.String, java.util.Locale) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.time.FastDateFormat org.apache.commons.lang.time.FastDateFormat getInstance(java.lang.String, java.util.TimeZone) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.time.FastDateFormat org.apache.commons.lang.time.FastDateFormat getInstance(java.lang.String, java.util.TimeZone) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.time.FastDateFormat org.apache.commons.lang.time.FastDateFormat getInstance(java.lang.String, java.util.TimeZone, java.util.Locale) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.time.FastDateFormat org.apache.commons.lang.time.FastDateFormat getInstance(java.lang.String, java.util.TimeZone, java.util.Locale) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.commons.lang.time.FastDateFormat org.apache.commons.lang.time.FastDateFormat getInstance(java.lang.String, java.util.TimeZone, java.util.Locale) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.time.FastDateFormat org.apache.commons.lang.time.FastDateFormat.NumberRule selectNumberRule(int, int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -391,6 +469,9 @@
<item name="org.apache.commons.lang.time.FastDateFormat.CharacterLiteral void appendTo(java.lang.StringBuffer, java.util.Calendar) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.time.FastDateFormat.CharacterLiteral void appendTo(java.lang.StringBuffer, java.util.Calendar) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.time.FastDateFormat.PaddedNumberField void appendTo(java.lang.StringBuffer, int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -400,18 +481,27 @@
<item name="org.apache.commons.lang.time.FastDateFormat.PaddedNumberField void appendTo(java.lang.StringBuffer, java.util.Calendar) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.time.FastDateFormat.Pair boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.time.FastDateFormat.Pair java.lang.String toString()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.time.FastDateFormat.StringLiteral void appendTo(java.lang.StringBuffer, java.util.Calendar) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.time.FastDateFormat.StringLiteral void appendTo(java.lang.StringBuffer, java.util.Calendar) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.time.FastDateFormat.TextField void appendTo(java.lang.StringBuffer, java.util.Calendar) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.commons.lang.time.FastDateFormat.TextField void appendTo(java.lang.StringBuffer, java.util.Calendar) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.commons.lang.time.FastDateFormat.TimeZoneDisplayKey boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.commons.lang.time.FastDateFormat.TimeZoneNameRule void appendTo(java.lang.StringBuffer, java.util.Calendar) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/anakia/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/anakia/annotations.xml
index a2e1c91b68a7..81935a0dc483 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/anakia/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/anakia/annotations.xml
@@ -29,6 +29,9 @@
<item name="org.apache.velocity.anakia.AnakiaJDOMFactory org.jdom.Element element(java.lang.String, org.jdom.Namespace)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.anakia.AnakiaTask java.lang.String getRelativePath(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.anakia.AnakiaTask java.lang.String getRelativePath(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;!null&quot;"/>
@@ -70,6 +73,9 @@
<item name="org.apache.velocity.anakia.NodeList NodeList(org.jdom.Element) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.anakia.NodeList boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.anakia.NodeList boolean equals(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -81,6 +87,9 @@
<item name="org.apache.velocity.anakia.NodeList org.apache.velocity.anakia.NodeList selectNodes(java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.anakia.NodeList.AttributeXMLOutputter AttributeXMLOutputter(org.apache.velocity.anakia.NodeList.1) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.anakia.NodeList.AttributeXMLOutputter void output(org.jdom.Attribute, java.io.Writer) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/annotations.xml
new file mode 100644
index 000000000000..7ef87f095569
--- /dev/null
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/annotations.xml
@@ -0,0 +1,8 @@
+<root>
+ <item name="org.apache.velocity.VelocityContext VelocityContext(java.util.Map) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.VelocityContext VelocityContext(java.util.Map, org.apache.velocity.context.Context) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+</root>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/app/event/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/app/event/annotations.xml
index ad9def7fd362..d1987cbafc38 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/app/event/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/app/event/annotations.xml
@@ -1,14 +1,23 @@
<root>
+ <item name="org.apache.velocity.app.event.EventCartridge boolean addEventHandler(org.apache.velocity.app.event.EventHandler) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.app.event.EventCartridge boolean addEventHandler(org.apache.velocity.app.event.EventHandler)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.velocity.app.event.EventCartridge boolean attachToContext(org.apache.velocity.context.Context) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.app.event.EventCartridge boolean attachToContext(org.apache.velocity.context.Context)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.velocity.app.event.EventCartridge boolean removeEventHandler(org.apache.velocity.app.event.EventHandler) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.app.event.EventCartridge boolean removeEventHandler(org.apache.velocity.app.event.EventHandler)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -59,12 +68,24 @@
<item name="org.apache.velocity.app.event.EventHandlerUtil java.lang.String includeEvent(org.apache.velocity.runtime.RuntimeServices, org.apache.velocity.context.InternalContextAdapter, java.lang.String, java.lang.String, java.lang.String) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.app.event.EventHandlerUtil void callEventHandlers(java.util.Iterator, java.util.Iterator, org.apache.velocity.app.event.EventHandlerMethodExecutor) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.app.event.EventHandlerUtil void callEventHandlers(java.util.Iterator, java.util.Iterator, org.apache.velocity.app.event.EventHandlerMethodExecutor) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.app.event.EventHandlerUtil void initializeEventCartridge(org.apache.velocity.runtime.RuntimeServices, org.apache.velocity.app.event.EventCartridge) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.app.event.EventHandlerUtil void invalidSetMethod(org.apache.velocity.runtime.RuntimeServices, org.apache.velocity.context.InternalContextAdapter, java.lang.String, java.lang.String, org.apache.velocity.util.introspection.Info) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.velocity.app.event.EventHandlerUtil void invalidSetMethod(org.apache.velocity.runtime.RuntimeServices, org.apache.velocity.context.InternalContextAdapter, java.lang.String, java.lang.String, org.apache.velocity.util.introspection.Info) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.app.event.EventHandlerUtil void iterateOverEventHandlers(java.util.Iterator, org.apache.velocity.app.event.EventHandlerMethodExecutor) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.app.event.IncludeEventHandler.IncludeEventExecutor void execute(org.apache.velocity.app.event.EventHandler) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/app/event/implement/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/app/event/implement/annotations.xml
index 5591ed681847..643ea130fd54 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/app/event/implement/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/app/event/implement/annotations.xml
@@ -31,12 +31,21 @@
<item name="org.apache.velocity.app.event.implement.EscapeXmlReference java.lang.String getMatchAttribute()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.app.event.implement.IncludeNotFound java.lang.String includeEvent(java.lang.String, java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.app.event.implement.IncludeNotFound java.lang.String includeEvent(java.lang.String, java.lang.String, java.lang.String) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.app.event.implement.IncludeNotFound void setRuntimeServices(org.apache.velocity.runtime.RuntimeServices) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.velocity.app.event.implement.IncludeRelativePath java.lang.String includeEvent(java.lang.String, java.lang.String, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.app.event.implement.IncludeRelativePath java.lang.String includeEvent(java.lang.String, java.lang.String, java.lang.String) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.app.event.implement.IncludeRelativePath java.lang.String includeEvent(java.lang.String, java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_,_-&gt;!null&quot;"/>
@@ -48,6 +57,12 @@
<item name="org.apache.velocity.app.event.implement.InvalidReferenceInfo java.lang.String toString()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.app.event.implement.PrintExceptions java.lang.Object methodException(java.lang.Class, java.lang.String, java.lang.Exception) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.app.event.implement.PrintExceptions java.lang.Object methodException(java.lang.Class, java.lang.String, java.lang.Exception) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.app.event.implement.PrintExceptions java.lang.Object methodException(java.lang.Class, java.lang.String, java.lang.Exception) 2">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -57,6 +72,12 @@
<item name="org.apache.velocity.app.event.implement.PrintExceptions java.lang.String getStackTrace(java.lang.Throwable) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.app.event.implement.ReportInvalidReferences boolean invalidSetMethod(org.apache.velocity.context.Context, java.lang.String, java.lang.String, org.apache.velocity.util.introspection.Info) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.app.event.implement.ReportInvalidReferences boolean invalidSetMethod(org.apache.velocity.context.Context, java.lang.String, java.lang.String, org.apache.velocity.util.introspection.Info) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.app.event.implement.ReportInvalidReferences boolean invalidSetMethod(org.apache.velocity.context.Context, java.lang.String, java.lang.String, org.apache.velocity.util.introspection.Info) 3">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -65,6 +86,15 @@
<val val="&quot;!null,_,_,_-&gt;false;_,!null,_,_-&gt;false;_,_,!null,_-&gt;false;_,_,_,!null-&gt;false;_,_,_,null-&gt;false;_,_,null,_-&gt;false;_,null,_,_-&gt;false;null,_,_,_-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.velocity.app.event.implement.ReportInvalidReferences java.lang.Object invalidGetMethod(org.apache.velocity.context.Context, java.lang.String, java.lang.Object, java.lang.String, org.apache.velocity.util.introspection.Info) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.app.event.implement.ReportInvalidReferences java.lang.Object invalidGetMethod(org.apache.velocity.context.Context, java.lang.String, java.lang.Object, java.lang.String, org.apache.velocity.util.introspection.Info) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.app.event.implement.ReportInvalidReferences java.lang.Object invalidGetMethod(org.apache.velocity.context.Context, java.lang.String, java.lang.Object, java.lang.String, org.apache.velocity.util.introspection.Info) 3">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.app.event.implement.ReportInvalidReferences java.lang.Object invalidGetMethod(org.apache.velocity.context.Context, java.lang.String, java.lang.Object, java.lang.String, org.apache.velocity.util.introspection.Info) 4">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -73,6 +103,15 @@
<val val="&quot;!null,_,_,_,_-&gt;null;_,!null,_,_,_-&gt;null;_,_,!null,_,_-&gt;null;_,_,_,!null,_-&gt;null;_,_,_,_,!null-&gt;null;_,_,_,_,null-&gt;null;_,_,_,null,_-&gt;null;_,_,null,_,_-&gt;null;_,null,_,_,_-&gt;null;null,_,_,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.velocity.app.event.implement.ReportInvalidReferences java.lang.Object invalidMethod(org.apache.velocity.context.Context, java.lang.String, java.lang.Object, java.lang.String, org.apache.velocity.util.introspection.Info) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.app.event.implement.ReportInvalidReferences java.lang.Object invalidMethod(org.apache.velocity.context.Context, java.lang.String, java.lang.Object, java.lang.String, org.apache.velocity.util.introspection.Info) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.app.event.implement.ReportInvalidReferences java.lang.Object invalidMethod(org.apache.velocity.context.Context, java.lang.String, java.lang.Object, java.lang.String, org.apache.velocity.util.introspection.Info) 3">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.app.event.implement.ReportInvalidReferences java.lang.Object invalidMethod(org.apache.velocity.context.Context, java.lang.String, java.lang.Object, java.lang.String, org.apache.velocity.util.introspection.Info) 4">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/app/tools/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/app/tools/annotations.xml
index 855a668ec63b..0117ad6dfb45 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/app/tools/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/app/tools/annotations.xml
@@ -1,15 +1,30 @@
<root>
+ <item name="org.apache.velocity.app.tools.VelocityFormatter java.lang.Object isNull(java.lang.Object, java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.app.tools.VelocityFormatter java.lang.Object isNull(java.lang.Object, java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;!null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.velocity.app.tools.VelocityFormatter java.lang.String formatArray(java.lang.Object, java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.app.tools.VelocityFormatter java.lang.String formatArray(java.lang.Object, java.lang.String, java.lang.String) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.app.tools.VelocityFormatter java.lang.String formatArray(java.lang.Object, java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.velocity.app.tools.VelocityFormatter java.lang.String formatVector(java.util.List, java.lang.String, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.app.tools.VelocityFormatter java.lang.String formatVector(java.util.List, java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.app.tools.VelocityFormatter java.lang.String formatVector(java.util.List, java.lang.String, java.lang.String) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.app.tools.VelocityFormatter java.lang.String formatVector(java.util.List, java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/context/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/context/annotations.xml
index 2e739fb35c61..62279b8f44db 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/context/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/context/annotations.xml
@@ -1,19 +1,31 @@
<root>
+ <item name="org.apache.velocity.context.AbstractContext boolean containsKey(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.context.AbstractContext boolean containsKey(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.velocity.context.AbstractContext java.lang.Object get(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.context.AbstractContext java.lang.Object get(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.velocity.context.AbstractContext java.lang.Object put(java.lang.String, java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.context.AbstractContext java.lang.Object put(java.lang.String, java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.velocity.context.AbstractContext java.lang.Object remove(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.context.AbstractContext java.lang.Object remove(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;null&quot;"/>
@@ -31,6 +43,12 @@
<item name="org.apache.velocity.context.ProxyVMContext boolean isConstant(org.apache.velocity.runtime.parser.node.Node) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.context.ProxyVMContext void addVMProxyArg(org.apache.velocity.context.InternalContextAdapter, java.lang.String, java.lang.String, org.apache.velocity.runtime.Renderable) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.context.ProxyVMContext void addVMProxyArg(org.apache.velocity.context.InternalContextAdapter, java.lang.String, java.lang.String, org.apache.velocity.runtime.Renderable) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.context.ProxyVMContext void addVMProxyArg(org.apache.velocity.context.InternalContextAdapter, java.lang.String, java.lang.String, org.apache.velocity.runtime.parser.node.Node) 3">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/convert/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/convert/annotations.xml
index 8303b86a3cba..0f266c90651e 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/convert/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/convert/annotations.xml
@@ -2,6 +2,9 @@
<item name="org.apache.velocity.convert.WebMacro boolean writeTemplate(java.lang.String, java.lang.String, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.convert.WebMacro boolean writeTemplate(java.lang.String, java.lang.String, java.lang.String) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.convert.WebMacro boolean writeTemplate(java.lang.String, java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,null,_-&gt;false&quot;"/>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/exception/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/exception/annotations.xml
index d7d2ee1dcb64..d9611079bfb5 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/exception/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/exception/annotations.xml
@@ -11,7 +11,13 @@
<item name="org.apache.velocity.exception.ParseErrorException ParseErrorException(org.apache.velocity.exception.VelocityException, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.exception.ParseErrorException ParseErrorException(org.apache.velocity.exception.VelocityException, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.exception.ParseErrorException ParseErrorException(org.apache.velocity.runtime.parser.ParseException, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.exception.ParseErrorException ParseErrorException(org.apache.velocity.runtime.parser.ParseException, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
</root>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/io/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/io/annotations.xml
index 75ca57304d5b..f55b4257f29a 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/io/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/io/annotations.xml
@@ -2,7 +2,16 @@
<item name="org.apache.velocity.io.UnicodeInputStream org.apache.velocity.io.UnicodeInputStream.UnicodeBOM match(org.apache.velocity.io.UnicodeInputStream.UnicodeBOM, org.apache.velocity.io.UnicodeInputStream.UnicodeBOM) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.io.UnicodeInputStream void pushback(org.apache.velocity.io.UnicodeInputStream.UnicodeBOM) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.io.UnicodeInputStream.UnicodeBOM UnicodeBOM(java.lang.String, byte[], org.apache.velocity.io.UnicodeInputStream.1) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.io.VelocityWriter void write(char[]) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.io.VelocityWriter void write(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
</root>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/runtime/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/runtime/annotations.xml
index 457ea7d9dd4b..1dd01a70efdd 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/runtime/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/runtime/annotations.xml
@@ -31,6 +31,12 @@
<val val="&quot;!null,_,_,_-&gt;true;_,!null,_,_-&gt;true;_,_,!null,_-&gt;true;_,_,_,!null-&gt;true;_,_,_,null-&gt;true;_,_,null,_-&gt;true;_,null,_,_-&gt;true;null,_,_,_-&gt;true&quot;"/>
</annotation>
</item>
+ <item name="org.apache.velocity.runtime.RuntimeInstance org.apache.velocity.app.event.EventHandler initializeSpecificEventHandler(java.lang.String, java.lang.String, java.lang.Class) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.RuntimeInstance org.apache.velocity.app.event.EventHandler initializeSpecificEventHandler(java.lang.String, java.lang.String, java.lang.Class) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.RuntimeInstance org.apache.velocity.app.event.EventHandler initializeSpecificEventHandler(java.lang.String, java.lang.String, java.lang.Class)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,_,null-&gt;null;null,_,_-&gt;null&quot;"/>
@@ -81,6 +87,9 @@
<item name="org.apache.velocity.runtime.VelocimacroFactory boolean addVelocimacro(java.lang.String, org.apache.velocity.runtime.parser.node.Node, java.lang.String[], java.lang.String) 3">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.VelocimacroFactory.Twonk Twonk(org.apache.velocity.runtime.VelocimacroFactory.1) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.VelocimacroManager boolean addVM(java.lang.String, org.apache.velocity.runtime.parser.node.Node, java.lang.String[], java.lang.String, boolean) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -89,10 +98,22 @@
<val val="&quot;!null,_,_,_,_-&gt;true;_,!null,_,_,_-&gt;true;_,_,!null,_,_-&gt;true;_,_,_,!null,_-&gt;true;_,_,_,_,false-&gt;true;_,_,_,_,true-&gt;true;_,_,_,null,_-&gt;true;_,_,null,_,_-&gt;true;null,_,_,_,_-&gt;true&quot;"/>
</annotation>
</item>
+ <item name="org.apache.velocity.runtime.VelocimacroManager boolean usingNamespaces(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.VelocimacroManager org.apache.velocity.runtime.directive.VelocimacroProxy get(java.lang.String, java.lang.String, java.lang.String) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.VelocimacroManager.MacroEntry MacroEntry(java.lang.String, org.apache.velocity.runtime.parser.node.Node, java.lang.String[], java.lang.String, org.apache.velocity.runtime.RuntimeServices) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.velocity.runtime.VelocimacroManager.MacroEntry MacroEntry(java.lang.String, org.apache.velocity.runtime.parser.node.Node, java.lang.String[], java.lang.String, org.apache.velocity.runtime.RuntimeServices, org.apache.velocity.runtime.VelocimacroManager.1) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.VelocimacroManager.MacroEntry MacroEntry(java.lang.String, org.apache.velocity.runtime.parser.node.Node, java.lang.String[], java.lang.String, org.apache.velocity.runtime.RuntimeServices, org.apache.velocity.runtime.VelocimacroManager.1) 5">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.VelocimacroManager.MacroEntry org.apache.velocity.runtime.directive.VelocimacroProxy getProxy(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
</root>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/runtime/directive/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/runtime/directive/annotations.xml
index f6cd67632cb8..e9d35d5e61e8 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/runtime/directive/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/runtime/directive/annotations.xml
@@ -5,6 +5,9 @@
<item name="org.apache.velocity.runtime.directive.Block void init(org.apache.velocity.runtime.RuntimeServices, org.apache.velocity.context.InternalContextAdapter, org.apache.velocity.runtime.parser.node.Node) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.directive.Block void init(org.apache.velocity.runtime.RuntimeServices, org.apache.velocity.context.InternalContextAdapter, org.apache.velocity.runtime.parser.node.Node) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.directive.Block void init(org.apache.velocity.runtime.RuntimeServices, org.apache.velocity.context.InternalContextAdapter, org.apache.velocity.runtime.parser.node.Node) 2">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -14,6 +17,9 @@
<item name="org.apache.velocity.runtime.directive.BlockMacro void init(org.apache.velocity.runtime.RuntimeServices, org.apache.velocity.context.InternalContextAdapter, org.apache.velocity.runtime.parser.node.Node) 2">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.directive.Break boolean render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer, org.apache.velocity.runtime.parser.node.Node) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.directive.Break boolean render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer, org.apache.velocity.runtime.parser.node.Node) 2">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -25,12 +31,21 @@
<item name="org.apache.velocity.runtime.directive.Break java.lang.String getName()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.directive.Break void init(org.apache.velocity.runtime.RuntimeServices, org.apache.velocity.context.InternalContextAdapter, org.apache.velocity.runtime.parser.node.Node) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.directive.Break void init(org.apache.velocity.runtime.RuntimeServices, org.apache.velocity.context.InternalContextAdapter, org.apache.velocity.runtime.parser.node.Node) 2">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.velocity.runtime.directive.Define boolean render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer, org.apache.velocity.runtime.parser.node.Node) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.directive.Define boolean render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer, org.apache.velocity.runtime.parser.node.Node) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.directive.Define boolean render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer, org.apache.velocity.runtime.parser.node.Node) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.directive.Define boolean render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer, org.apache.velocity.runtime.parser.node.Node)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_,_-&gt;true;_,!null,_-&gt;true;_,_,!null-&gt;true;_,_,null-&gt;true;_,null,_-&gt;true&quot;"/>
@@ -42,12 +57,24 @@
<item name="org.apache.velocity.runtime.directive.Define void init(org.apache.velocity.runtime.RuntimeServices, org.apache.velocity.context.InternalContextAdapter, org.apache.velocity.runtime.parser.node.Node) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.directive.Define void init(org.apache.velocity.runtime.RuntimeServices, org.apache.velocity.context.InternalContextAdapter, org.apache.velocity.runtime.parser.node.Node) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.directive.Define void init(org.apache.velocity.runtime.RuntimeServices, org.apache.velocity.context.InternalContextAdapter, org.apache.velocity.runtime.parser.node.Node) 2">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.directive.Directive org.apache.velocity.runtime.directive.Scope makeScope(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.directive.Directive org.apache.velocity.runtime.directive.Scope makeScope(java.lang.Object)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.directive.Directive void init(org.apache.velocity.runtime.RuntimeServices, org.apache.velocity.context.InternalContextAdapter, org.apache.velocity.runtime.parser.node.Node) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.directive.Directive void init(org.apache.velocity.runtime.RuntimeServices, org.apache.velocity.context.InternalContextAdapter, org.apache.velocity.runtime.parser.node.Node) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.directive.Evaluate boolean render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer, org.apache.velocity.runtime.parser.node.Node) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -74,12 +101,36 @@
<item name="org.apache.velocity.runtime.directive.Foreach void clean(org.apache.velocity.context.InternalContextAdapter, java.lang.Object, java.lang.Object, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.directive.Foreach void clean(org.apache.velocity.context.InternalContextAdapter, java.lang.Object, java.lang.Object, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.directive.Foreach void clean(org.apache.velocity.context.InternalContextAdapter, java.lang.Object, java.lang.Object, java.lang.Object) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.directive.Foreach void clean(org.apache.velocity.context.InternalContextAdapter, java.lang.Object, java.lang.Object, java.lang.Object) 3">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.directive.Foreach void init(org.apache.velocity.runtime.RuntimeServices, org.apache.velocity.context.InternalContextAdapter, org.apache.velocity.runtime.parser.node.Node) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.directive.Foreach void init(org.apache.velocity.runtime.RuntimeServices, org.apache.velocity.context.InternalContextAdapter, org.apache.velocity.runtime.parser.node.Node) 2">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.velocity.runtime.directive.Foreach void put(org.apache.velocity.context.InternalContextAdapter, java.lang.String, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.directive.Foreach.NullHolderContext NullHolderContext(java.lang.String, org.apache.velocity.context.InternalContextAdapter) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.directive.Foreach.NullHolderContext NullHolderContext(java.lang.String, org.apache.velocity.context.InternalContextAdapter, org.apache.velocity.runtime.directive.Foreach.1) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.directive.Foreach.NullHolderContext NullHolderContext(java.lang.String, org.apache.velocity.context.InternalContextAdapter, org.apache.velocity.runtime.directive.Foreach.1) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.directive.ForeachScope ForeachScope(java.lang.Object, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.directive.Include boolean render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer, org.apache.velocity.runtime.parser.node.Node) 2">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -88,6 +139,9 @@
<val val="&quot;!null,_,_-&gt;true;_,!null,_-&gt;true;_,_,!null-&gt;true;_,null,_-&gt;true;null,_,_-&gt;true&quot;"/>
</annotation>
</item>
+ <item name="org.apache.velocity.runtime.directive.Include boolean renderOutput(org.apache.velocity.runtime.parser.node.Node, org.apache.velocity.context.InternalContextAdapter, java.io.Writer) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.directive.Include boolean renderOutput(org.apache.velocity.runtime.parser.node.Node, org.apache.velocity.context.InternalContextAdapter, java.io.Writer)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,null,_-&gt;false;null,_,_-&gt;false&quot;"/>
@@ -99,9 +153,15 @@
<item name="org.apache.velocity.runtime.directive.InputBase java.lang.String getInputEncoding(org.apache.velocity.context.InternalContextAdapter) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.directive.Literal boolean render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer, org.apache.velocity.runtime.parser.node.Node) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.directive.Literal boolean render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer, org.apache.velocity.runtime.parser.node.Node) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.directive.Literal boolean render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer, org.apache.velocity.runtime.parser.node.Node) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.directive.Literal boolean render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer, org.apache.velocity.runtime.parser.node.Node)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_,_-&gt;true;_,!null,_-&gt;true;_,_,!null-&gt;true;_,_,null-&gt;true;null,_,_-&gt;true&quot;"/>
@@ -110,9 +170,21 @@
<item name="org.apache.velocity.runtime.directive.Literal java.lang.String getName()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.directive.Literal void init(org.apache.velocity.runtime.RuntimeServices, org.apache.velocity.context.InternalContextAdapter, org.apache.velocity.runtime.parser.node.Node) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.directive.Literal void init(org.apache.velocity.runtime.RuntimeServices, org.apache.velocity.context.InternalContextAdapter, org.apache.velocity.runtime.parser.node.Node) 2">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.directive.Macro boolean render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer, org.apache.velocity.runtime.parser.node.Node) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.directive.Macro boolean render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer, org.apache.velocity.runtime.parser.node.Node) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.directive.Macro boolean render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer, org.apache.velocity.runtime.parser.node.Node) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.directive.Macro boolean render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer, org.apache.velocity.runtime.parser.node.Node)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_,_-&gt;true;_,!null,_-&gt;true;_,_,!null-&gt;true;_,_,null-&gt;true;_,null,_-&gt;true;null,_,_-&gt;true&quot;"/>
@@ -121,6 +193,9 @@
<item name="org.apache.velocity.runtime.directive.Macro java.lang.String getName()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.directive.Macro java.lang.StringBuffer macroToString(java.lang.StringBuffer, java.lang.String[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.directive.Macro java.lang.StringBuffer macroToString(java.lang.StringBuffer, java.lang.String[]) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -138,9 +213,15 @@
<item name="org.apache.velocity.runtime.directive.Macro void init(org.apache.velocity.runtime.RuntimeServices, org.apache.velocity.context.InternalContextAdapter, org.apache.velocity.runtime.parser.node.Node) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.directive.Macro void init(org.apache.velocity.runtime.RuntimeServices, org.apache.velocity.context.InternalContextAdapter, org.apache.velocity.runtime.parser.node.Node) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.directive.Macro void init(org.apache.velocity.runtime.RuntimeServices, org.apache.velocity.context.InternalContextAdapter, org.apache.velocity.runtime.parser.node.Node) 2">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.directive.MacroParseException MacroParseException(java.lang.String, java.lang.String, org.apache.velocity.runtime.parser.Token) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.directive.MacroParseException java.lang.String getMessage()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -171,15 +252,27 @@
<item name="org.apache.velocity.runtime.directive.RuntimeMacro void init(org.apache.velocity.runtime.RuntimeServices, org.apache.velocity.context.InternalContextAdapter, org.apache.velocity.runtime.parser.node.Node) 2">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.directive.Scope Scope(java.lang.Object, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.directive.Scope.Info Info(org.apache.velocity.runtime.directive.Scope, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.directive.Scope.Info java.lang.String toString()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.directive.Stop boolean render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer, org.apache.velocity.runtime.parser.node.Node) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.directive.Stop boolean render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer, org.apache.velocity.runtime.parser.node.Node) 2">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.velocity.runtime.directive.Stop java.lang.String getName()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.directive.Stop void init(org.apache.velocity.runtime.RuntimeServices, org.apache.velocity.context.InternalContextAdapter, org.apache.velocity.runtime.parser.node.Node) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.directive.Stop void init(org.apache.velocity.runtime.RuntimeServices, org.apache.velocity.context.InternalContextAdapter, org.apache.velocity.runtime.parser.node.Node) 2">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -194,6 +287,9 @@
<val val="&quot;!null,_,_,_-&gt;true;_,!null,_,_-&gt;true;_,_,!null,_-&gt;true;_,_,_,!null-&gt;true;_,_,_,null-&gt;true;_,null,_,_-&gt;true;null,_,_,_-&gt;true&quot;"/>
</annotation>
</item>
+ <item name="org.apache.velocity.runtime.directive.VelocimacroProxy java.lang.String buildErrorMsg(org.apache.velocity.runtime.parser.node.Node, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.directive.VelocimacroProxy java.lang.String buildErrorMsg(org.apache.velocity.runtime.parser.node.Node, int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/runtime/log/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/runtime/log/annotations.xml
index b49c0f73e389..f3dd5bc117e1 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/runtime/log/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/runtime/log/annotations.xml
@@ -8,9 +8,18 @@
<item name="org.apache.velocity.runtime.log.CommonsLogLogChute void init(org.apache.velocity.runtime.RuntimeServices) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.log.HoldingLogChute void init(org.apache.velocity.runtime.RuntimeServices) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.log.JdkLogChute void init(org.apache.velocity.runtime.RuntimeServices) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.log.JdkLogChute void log(int, java.lang.String, java.lang.Throwable) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.log.Log java.lang.String formatFileString(java.lang.String, int, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.log.Log java.lang.String formatFileString(java.lang.String, int, int)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -32,12 +41,30 @@
<item name="org.apache.velocity.runtime.log.Log java.lang.String formatFileString(org.apache.velocity.util.introspection.Info)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.log.Log void log(int, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.log.Log void log(int, java.lang.Object, java.lang.Throwable) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.log.Log void setLogChute(org.apache.velocity.runtime.log.LogChute) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.velocity.runtime.log.LogDisplayWrapper LogDisplayWrapper(org.apache.velocity.runtime.log.Log, java.lang.String, boolean) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.log.LogDisplayWrapper void log(boolean, int, java.lang.Object) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.log.LogDisplayWrapper void log(boolean, int, java.lang.Object, java.lang.Throwable) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.log.LogDisplayWrapper void log(int, java.lang.Object, java.lang.Throwable) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.log.LogManager boolean isProbablyProvidedLogChute(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.log.LogManager boolean isProbablyProvidedLogChute(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -52,15 +79,39 @@
<item name="org.apache.velocity.runtime.log.LogManager void updateLog(org.apache.velocity.runtime.log.Log, org.apache.velocity.runtime.RuntimeServices) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.log.NullLogChute void init(org.apache.velocity.runtime.RuntimeServices) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.log.NullLogChute void log(int, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.log.NullLogChute void log(int, java.lang.String, java.lang.Throwable) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.log.NullLogChute void log(int, java.lang.String, java.lang.Throwable) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.log.NullLogSystem void logVelocityMessage(int, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.log.RuntimeLoggerLog RuntimeLoggerLog(org.apache.velocity.runtime.RuntimeLogger) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.log.RuntimeLoggerLog void setLogChute(org.apache.velocity.runtime.log.LogChute) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.log.ServletLogChute int toLevel(java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.velocity.runtime.log.ServletLogChute void init(org.apache.velocity.runtime.RuntimeServices) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.log.ServletLogChute void log(int, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.log.ServletLogChute void log(int, java.lang.String, java.lang.Throwable) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.log.SystemLogChute int toLevel(java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -73,4 +124,10 @@
<item name="org.apache.velocity.runtime.log.SystemLogChute void write(java.io.PrintStream, java.lang.String, java.lang.String, java.lang.Throwable) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.log.SystemLogChute void write(java.io.PrintStream, java.lang.String, java.lang.String, java.lang.Throwable) 3">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.log.VelocityFormatter java.lang.String getTime(long, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
</root>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/runtime/parser/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/runtime/parser/annotations.xml
index 7d0bc8cdefa1..88ac417b986d 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/runtime/parser/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/runtime/parser/annotations.xml
@@ -1,4 +1,7 @@
<root>
+ <item name="org.apache.velocity.runtime.parser.JJTParserState void clearNodeScope(org.apache.velocity.runtime.parser.node.Node) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.parser.JJTParserState void closeNodeScope(org.apache.velocity.runtime.parser.node.Node, int) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -25,9 +28,18 @@
<item name="org.apache.velocity.runtime.parser.Parser org.apache.velocity.runtime.parser.ParseException generateParseException()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.parser.Parser.LookaheadSuccess LookaheadSuccess(org.apache.velocity.runtime.parser.Parser.1) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.parser.ParserTokenManager org.apache.velocity.runtime.parser.Token jjFillToken()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.parser.ParserTokenManager void SkipLexicalActions(org.apache.velocity.runtime.parser.Token) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.parser.ParserTokenManager.ParserState ParserState(org.apache.velocity.runtime.parser.ParserTokenManager.1) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.parser.TemplateParseException java.lang.String getMessage()">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/runtime/parser/node/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/runtime/parser/node/annotations.xml
index 5f78c94ea501..b6a2face76a9 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/runtime/parser/node/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/runtime/parser/node/annotations.xml
@@ -5,6 +5,15 @@
<item name="org.apache.velocity.runtime.parser.node.ASTAddNode java.lang.Number perform(java.lang.Number, java.lang.Number, org.apache.velocity.context.InternalContextAdapter) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.parser.node.ASTAddNode java.lang.Number perform(java.lang.Number, java.lang.Number, org.apache.velocity.context.InternalContextAdapter) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.parser.node.ASTAddNode java.lang.Object handleSpecial(java.lang.Object, java.lang.Object, org.apache.velocity.context.InternalContextAdapter) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.parser.node.ASTAddNode java.lang.Object handleSpecial(java.lang.Object, java.lang.Object, org.apache.velocity.context.InternalContextAdapter) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.parser.node.ASTAndNode java.lang.Object jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -19,6 +28,9 @@
<item name="org.apache.velocity.runtime.parser.node.ASTBlock java.lang.Object jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.parser.node.ASTComment boolean render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.parser.node.ASTComment boolean render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -27,6 +39,9 @@
<val val="&quot;!null,_-&gt;true;_,!null-&gt;true;null,_-&gt;true&quot;"/>
</annotation>
</item>
+ <item name="org.apache.velocity.runtime.parser.node.ASTComment java.lang.Object init(org.apache.velocity.context.InternalContextAdapter, java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.parser.node.ASTComment java.lang.Object init(org.apache.velocity.context.InternalContextAdapter, java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,!null-&gt;!null;_,null-&gt;null&quot;"/>
@@ -57,6 +72,9 @@
<item name="org.apache.velocity.runtime.parser.node.ASTElseIfStatement java.lang.Object jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.parser.node.ASTElseStatement boolean evaluate(org.apache.velocity.context.InternalContextAdapter) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.parser.node.ASTElseStatement boolean evaluate(org.apache.velocity.context.InternalContextAdapter)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;true;null-&gt;true&quot;"/>
@@ -65,6 +83,9 @@
<item name="org.apache.velocity.runtime.parser.node.ASTElseStatement java.lang.Object jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.parser.node.ASTEscape boolean render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.parser.node.ASTEscape boolean render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -73,6 +94,9 @@
<val val="&quot;!null,_-&gt;true;_,!null-&gt;true;null,_-&gt;true&quot;"/>
</annotation>
</item>
+ <item name="org.apache.velocity.runtime.parser.node.ASTEscape java.lang.Object init(org.apache.velocity.context.InternalContextAdapter, java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.parser.node.ASTEscape java.lang.Object init(org.apache.velocity.context.InternalContextAdapter, java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,!null-&gt;!null;_,null-&gt;null&quot;"/>
@@ -81,6 +105,9 @@
<item name="org.apache.velocity.runtime.parser.node.ASTEscape java.lang.Object jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.parser.node.ASTEscapedDirective boolean render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.parser.node.ASTEscapedDirective boolean render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -95,6 +122,9 @@
<item name="org.apache.velocity.runtime.parser.node.ASTExpression java.lang.Object jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.parser.node.ASTFalse boolean evaluate(org.apache.velocity.context.InternalContextAdapter) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.parser.node.ASTFalse boolean evaluate(org.apache.velocity.context.InternalContextAdapter)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;false;null-&gt;false&quot;"/>
@@ -103,6 +133,9 @@
<item name="org.apache.velocity.runtime.parser.node.ASTFalse java.lang.Object jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.parser.node.ASTFalse java.lang.Object value(org.apache.velocity.context.InternalContextAdapter) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.parser.node.ASTFloatingPointLiteral java.lang.Object init(org.apache.velocity.context.InternalContextAdapter, java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,!null-&gt;!null;_,null-&gt;null&quot;"/>
@@ -111,6 +144,9 @@
<item name="org.apache.velocity.runtime.parser.node.ASTFloatingPointLiteral java.lang.Object jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.parser.node.ASTFloatingPointLiteral java.lang.Object value(org.apache.velocity.context.InternalContextAdapter) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.parser.node.ASTGENode java.lang.Object jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -136,6 +172,12 @@
<item name="org.apache.velocity.runtime.parser.node.ASTIfStatement java.lang.Object jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.parser.node.ASTIfStatement void process(org.apache.velocity.context.InternalContextAdapter, org.apache.velocity.runtime.parser.node.ParserVisitor) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.parser.node.ASTIfStatement void process(org.apache.velocity.context.InternalContextAdapter, org.apache.velocity.runtime.parser.node.ParserVisitor) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.parser.node.ASTIncludeStatement java.lang.Object jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -160,6 +202,9 @@
<item name="org.apache.velocity.runtime.parser.node.ASTIntegerLiteral java.lang.Object jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.parser.node.ASTIntegerLiteral java.lang.Object value(org.apache.velocity.context.InternalContextAdapter) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.parser.node.ASTIntegerRange java.lang.Object jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -172,6 +217,15 @@
<item name="org.apache.velocity.runtime.parser.node.ASTMap java.lang.Object jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.parser.node.ASTMathNode java.lang.Object handleSpecial(java.lang.Object, java.lang.Object, org.apache.velocity.context.InternalContextAdapter) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.parser.node.ASTMathNode java.lang.Object handleSpecial(java.lang.Object, java.lang.Object, org.apache.velocity.context.InternalContextAdapter) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.parser.node.ASTMathNode java.lang.Object handleSpecial(java.lang.Object, java.lang.Object, org.apache.velocity.context.InternalContextAdapter) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.parser.node.ASTMathNode java.lang.Object handleSpecial(java.lang.Object, java.lang.Object, org.apache.velocity.context.InternalContextAdapter)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_,_-&gt;null;_,!null,_-&gt;null;_,_,!null-&gt;null;_,_,null-&gt;null;_,null,_-&gt;null;null,_,_-&gt;null&quot;"/>
@@ -205,6 +259,15 @@
<item name="org.apache.velocity.runtime.parser.node.ASTMethod java.lang.Object jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.parser.node.ASTMethod.MethodCacheKey MethodCacheKey(java.lang.String, java.lang.Class[]) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.parser.node.ASTMethod.MethodCacheKey MethodCacheKey(java.lang.String, java.lang.Class[]) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.parser.node.ASTMethod.MethodCacheKey boolean equals(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.parser.node.ASTMethod.MethodCacheKey boolean equals(java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -219,6 +282,9 @@
<item name="org.apache.velocity.runtime.parser.node.ASTMulNode java.lang.Number perform(java.lang.Number, java.lang.Number, org.apache.velocity.context.InternalContextAdapter) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.parser.node.ASTMulNode java.lang.Number perform(java.lang.Number, java.lang.Number, org.apache.velocity.context.InternalContextAdapter) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.parser.node.ASTNENode java.lang.Object jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -239,6 +305,9 @@
<val val="&quot;!null,_-&gt;true;_,!null-&gt;true;_,null-&gt;true;null,_-&gt;true&quot;"/>
</annotation>
</item>
+ <item name="org.apache.velocity.runtime.parser.node.ASTReference java.lang.Object execute(java.lang.Object, org.apache.velocity.context.InternalContextAdapter) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.parser.node.ASTReference java.lang.Object getVariableValue(org.apache.velocity.context.Context, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -256,11 +325,17 @@
<item name="org.apache.velocity.runtime.parser.node.ASTReference java.lang.String getNullString(org.apache.velocity.context.InternalContextAdapter) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.parser.node.ASTReference java.lang.String printClass(java.lang.Class) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.parser.node.ASTReference java.lang.String printClass(java.lang.Class)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;!null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.velocity.runtime.parser.node.ASTSetDirective boolean render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.parser.node.ASTSetDirective java.lang.Object init(org.apache.velocity.context.InternalContextAdapter, java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,!null-&gt;!null;_,null-&gt;null&quot;"/>
@@ -292,6 +367,12 @@
<item name="org.apache.velocity.runtime.parser.node.ASTSubtractNode java.lang.Number perform(java.lang.Number, java.lang.Number, org.apache.velocity.context.InternalContextAdapter) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.parser.node.ASTSubtractNode java.lang.Number perform(java.lang.Number, java.lang.Number, org.apache.velocity.context.InternalContextAdapter) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.parser.node.ASTText boolean render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.parser.node.ASTText boolean render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -300,6 +381,9 @@
<val val="&quot;!null,_-&gt;true;_,!null-&gt;true;null,_-&gt;true&quot;"/>
</annotation>
</item>
+ <item name="org.apache.velocity.runtime.parser.node.ASTText java.lang.Object init(org.apache.velocity.context.InternalContextAdapter, java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.parser.node.ASTText java.lang.Object init(org.apache.velocity.context.InternalContextAdapter, java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,!null-&gt;!null;_,null-&gt;null&quot;"/>
@@ -308,6 +392,9 @@
<item name="org.apache.velocity.runtime.parser.node.ASTText java.lang.Object jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.parser.node.ASTTextblock boolean render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.parser.node.ASTTextblock boolean render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -316,6 +403,9 @@
<val val="&quot;!null,_-&gt;true;_,!null-&gt;true;null,_-&gt;true&quot;"/>
</annotation>
</item>
+ <item name="org.apache.velocity.runtime.parser.node.ASTTextblock java.lang.Object init(org.apache.velocity.context.InternalContextAdapter, java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.parser.node.ASTTextblock java.lang.Object init(org.apache.velocity.context.InternalContextAdapter, java.lang.Object)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,!null-&gt;!null;_,null-&gt;null&quot;"/>
@@ -324,6 +414,9 @@
<item name="org.apache.velocity.runtime.parser.node.ASTTextblock java.lang.Object jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.parser.node.ASTTrue boolean evaluate(org.apache.velocity.context.InternalContextAdapter) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.parser.node.ASTTrue boolean evaluate(org.apache.velocity.context.InternalContextAdapter)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;true;null-&gt;true&quot;"/>
@@ -332,6 +425,9 @@
<item name="org.apache.velocity.runtime.parser.node.ASTTrue java.lang.Object jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.parser.node.ASTTrue java.lang.Object value(org.apache.velocity.context.InternalContextAdapter) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.parser.node.ASTVariable java.lang.Object jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -344,9 +440,18 @@
<item name="org.apache.velocity.runtime.parser.node.BooleanPropertyExecutor BooleanPropertyExecutor(org.apache.velocity.runtime.RuntimeLogger, org.apache.velocity.util.introspection.Introspector, java.lang.Class, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.parser.node.BooleanPropertyExecutor void discover(java.lang.Class, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.parser.node.GetExecutor GetExecutor(org.apache.velocity.runtime.RuntimeLogger, org.apache.velocity.util.introspection.Introspector, java.lang.Class, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.parser.node.GetExecutor GetExecutor(org.apache.velocity.runtime.RuntimeLogger, org.apache.velocity.util.introspection.Introspector, java.lang.Class, java.lang.String) 3">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.parser.node.GetExecutor GetExecutor(org.apache.velocity.runtime.log.Log, org.apache.velocity.util.introspection.Introspector, java.lang.Class, java.lang.String) 3">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.parser.node.MapGetExecutor java.lang.Object execute(java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -401,6 +506,9 @@
<item name="org.apache.velocity.runtime.parser.node.MathUtils java.lang.Number subtract(java.lang.Number, java.lang.Number) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.parser.node.MathUtils java.lang.Number wrapPrimitive(long, java.lang.Class) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.parser.node.MathUtils java.lang.Number wrapPrimitive(long, java.lang.Number, java.lang.Number) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -433,6 +541,12 @@
<item name="org.apache.velocity.runtime.parser.node.PropertyExecutor PropertyExecutor(org.apache.velocity.runtime.RuntimeLogger, org.apache.velocity.util.introspection.Introspector, java.lang.Class, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.parser.node.PropertyExecutor void discover(java.lang.Class, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.parser.node.SimpleNode boolean evaluate(org.apache.velocity.context.InternalContextAdapter) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.parser.node.SimpleNode boolean evaluate(org.apache.velocity.context.InternalContextAdapter)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;false;null-&gt;false&quot;"/>
@@ -448,6 +562,12 @@
<val val="&quot;_,!null-&gt;!null;_,null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.velocity.runtime.parser.node.SimpleNode java.lang.Object execute(java.lang.Object, org.apache.velocity.context.InternalContextAdapter) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.parser.node.SimpleNode java.lang.Object execute(java.lang.Object, org.apache.velocity.context.InternalContextAdapter) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.parser.node.SimpleNode java.lang.Object execute(java.lang.Object, org.apache.velocity.context.InternalContextAdapter)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_-&gt;null;_,!null-&gt;null;_,null-&gt;null;null,_-&gt;null&quot;"/>
@@ -461,14 +581,23 @@
<item name="org.apache.velocity.runtime.parser.node.SimpleNode java.lang.Object jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.parser.node.SimpleNode java.lang.Object value(org.apache.velocity.context.InternalContextAdapter) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.parser.node.SimpleNode java.lang.Object value(org.apache.velocity.context.InternalContextAdapter)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;null;null-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.velocity.runtime.parser.node.SimpleNode java.lang.String getLocation(org.apache.velocity.context.InternalContextAdapter) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.parser.node.SimpleNode java.lang.String getLocation(org.apache.velocity.context.InternalContextAdapter)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.parser.node.SimpleNode java.lang.String toString(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.parser.node.SimpleNode java.lang.String toString(java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/runtime/resource/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/runtime/resource/annotations.xml
index c85589b43d33..6d9f27bfe3ff 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/runtime/resource/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/runtime/resource/annotations.xml
@@ -1,4 +1,10 @@
<root>
+ <item name="org.apache.velocity.runtime.resource.ResourceFactory org.apache.velocity.runtime.resource.Resource getResource(java.lang.String, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.resource.ResourceManagerImpl org.apache.velocity.runtime.resource.Resource createResource(java.lang.String, int) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.resource.ResourceManagerImpl org.apache.velocity.runtime.resource.Resource refreshResource(org.apache.velocity.runtime.resource.Resource, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/runtime/resource/loader/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/runtime/resource/loader/annotations.xml
index 5fc5b3a6b8f0..ca5b1efb729c 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/runtime/resource/loader/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/runtime/resource/loader/annotations.xml
@@ -1,4 +1,7 @@
<root>
+ <item name="org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader boolean isSourceModified(org.apache.velocity.runtime.resource.Resource) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader boolean isSourceModified(org.apache.velocity.runtime.resource.Resource)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;false;null-&gt;false&quot;"/>
@@ -7,6 +10,12 @@
<item name="org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader java.io.InputStream getResourceStream(java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader long getLastModified(org.apache.velocity.runtime.resource.Resource) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader void init(org.apache.commons.collections.ExtendedProperties) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.resource.loader.DataSourceResourceLoader boolean isSourceModified(org.apache.velocity.runtime.resource.Resource) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -16,41 +25,71 @@
<item name="org.apache.velocity.runtime.resource.loader.DataSourceResourceLoader java.sql.PreparedStatement getStatement(java.sql.Connection, java.lang.String, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.resource.loader.DataSourceResourceLoader java.sql.PreparedStatement getStatement(java.sql.Connection, java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.resource.loader.DataSourceResourceLoader long getLastModified(org.apache.velocity.runtime.resource.Resource) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.velocity.runtime.resource.loader.DataSourceResourceLoader long readLastModified(org.apache.velocity.runtime.resource.Resource, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.resource.loader.DataSourceResourceLoader long readLastModified(org.apache.velocity.runtime.resource.Resource, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.resource.loader.DataSourceResourceLoader void closeDbConnection(java.sql.Connection) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.resource.loader.DataSourceResourceLoader void closeResultSet(java.sql.ResultSet) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.runtime.resource.loader.DataSourceResourceLoader void closeStatement(java.sql.PreparedStatement) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.resource.loader.DataSourceResourceLoader void init(org.apache.commons.collections.ExtendedProperties) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.velocity.runtime.resource.loader.FileResourceLoader boolean isSourceModified(org.apache.velocity.runtime.resource.Resource) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.resource.loader.FileResourceLoader boolean resourceExists(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.resource.loader.FileResourceLoader boolean resourceExists(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
</annotation>
</item>
+ <item name="org.apache.velocity.runtime.resource.loader.FileResourceLoader java.io.File getFile(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.resource.loader.FileResourceLoader java.io.File getFile(java.lang.String, java.lang.String) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.velocity.runtime.resource.loader.FileResourceLoader java.io.File getFile(java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.resource.loader.FileResourceLoader java.io.InputStream findTemplate(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.resource.loader.FileResourceLoader java.io.InputStream getResourceStream(java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.velocity.runtime.resource.loader.FileResourceLoader long getLastModified(org.apache.velocity.runtime.resource.Resource) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.resource.loader.FileResourceLoader void closeQuiet(java.io.InputStream) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.resource.loader.FileResourceLoader void init(org.apache.commons.collections.ExtendedProperties) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.velocity.runtime.resource.loader.JarHolder JarHolder(org.apache.velocity.runtime.RuntimeServices, java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.resource.loader.JarResourceLoader boolean isSourceModified(org.apache.velocity.runtime.resource.Resource) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.resource.loader.JarResourceLoader boolean isSourceModified(org.apache.velocity.runtime.resource.Resource)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;true;null-&gt;true&quot;"/>
@@ -59,6 +98,9 @@
<item name="org.apache.velocity.runtime.resource.loader.JarResourceLoader java.io.InputStream getResourceStream(java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.resource.loader.JarResourceLoader long getLastModified(org.apache.velocity.runtime.resource.Resource) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.resource.loader.JarResourceLoader void init(org.apache.commons.collections.ExtendedProperties) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -74,6 +116,9 @@
<item name="org.apache.velocity.runtime.resource.loader.StringResourceLoader boolean isSourceModified(org.apache.velocity.runtime.resource.Resource) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.resource.loader.StringResourceLoader boolean resourceExists(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.resource.loader.StringResourceLoader boolean resourceExists(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null-&gt;false&quot;"/>
@@ -85,6 +130,9 @@
<item name="org.apache.velocity.runtime.resource.loader.StringResourceLoader long getLastModified(org.apache.velocity.runtime.resource.Resource) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.runtime.resource.loader.StringResourceLoader org.apache.velocity.runtime.resource.util.StringResourceRepository createRepository(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.runtime.resource.loader.StringResourceLoader void init(org.apache.commons.collections.ExtendedProperties) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/servlet/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/servlet/annotations.xml
index a1d5f80fe4ca..8c2789a533bf 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/servlet/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/servlet/annotations.xml
@@ -1,13 +1,28 @@
<root>
+ <item name="org.apache.velocity.servlet.VelocityServlet java.lang.String chooseCharacterEncoding(javax.servlet.http.HttpServletRequest) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.servlet.VelocityServlet java.util.Properties loadConfiguration(javax.servlet.ServletConfig) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
<item name="org.apache.velocity.servlet.VelocityServlet java.util.Properties loadConfiguration(javax.servlet.ServletConfig)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.servlet.VelocityServlet org.apache.velocity.Template handleRequest(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, org.apache.velocity.context.Context) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.servlet.VelocityServlet org.apache.velocity.Template handleRequest(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, org.apache.velocity.context.Context) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.servlet.VelocityServlet org.apache.velocity.Template handleRequest(org.apache.velocity.context.Context) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.servlet.VelocityServlet org.apache.velocity.context.Context createContext(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.servlet.VelocityServlet void error(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Exception) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.servlet.VelocityServlet void error(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Exception) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -17,6 +32,15 @@
<item name="org.apache.velocity.servlet.VelocityServlet void mergeTemplate(org.apache.velocity.Template, org.apache.velocity.context.Context, javax.servlet.http.HttpServletResponse) 2">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.servlet.VelocityServlet void requestCleanup(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, org.apache.velocity.context.Context) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.servlet.VelocityServlet void requestCleanup(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, org.apache.velocity.context.Context) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.servlet.VelocityServlet void requestCleanup(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, org.apache.velocity.context.Context) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.servlet.VelocityServlet void setContentType(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/texen/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/texen/annotations.xml
index bea0f093ad72..8dbb538e058e 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/texen/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/texen/annotations.xml
@@ -1,10 +1,37 @@
<root>
+ <item name="org.apache.velocity.texen.Generator Generator(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.texen.Generator Generator(java.util.Properties) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.texen.Generator java.io.Writer getWriter(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.texen.Generator java.io.Writer getWriter(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.texen.Generator java.io.Writer getWriter(java.lang.String, java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.texen.Generator java.lang.String parse(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.Object) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.texen.Generator java.lang.String parse(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.Object) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.texen.Generator java.lang.String parse(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.Object) 3">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.texen.Generator java.lang.String parse(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.Object) 4">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.texen.Generator java.lang.String parse(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.Object) 5">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.texen.Generator org.apache.velocity.Template getTemplate(java.lang.String, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.texen.Generator void fillContextDefaults(org.apache.velocity.context.Context) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/texen/util/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/texen/util/annotations.xml
index 353ade77c7bc..20c60fde4b7b 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/texen/util/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/texen/util/annotations.xml
@@ -5,6 +5,9 @@
<item name="org.apache.velocity.texen.util.FileUtil java.io.File file(java.lang.String)">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.texen.util.FileUtil java.io.File file(java.lang.String, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.texen.util.FileUtil java.io.File file(java.lang.String, java.lang.String) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/util/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/util/annotations.xml
index e60004f3fd63..8b1334446ad3 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/util/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/util/annotations.xml
@@ -27,6 +27,9 @@
<val val="&quot;!null,_-&gt;!null;null,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.velocity.util.StringUtils java.lang.String chop(java.lang.String, int, java.lang.String) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.util.StringUtils java.lang.String chop(java.lang.String, int, java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null,_,_-&gt;!null;null,_,_-&gt;null&quot;"/>
@@ -65,9 +68,12 @@
<item name="org.apache.velocity.util.StringUtils java.lang.String normalizePath(java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.util.StringUtils java.lang.String nullTrim(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.util.StringUtils java.lang.String nullTrim(java.lang.String)">
<annotation name="org.jetbrains.annotations.Contract">
- <val val="&quot;null-&gt;null&quot;"/>
+ <val val="&quot;!null-&gt;!null;null-&gt;null&quot;"/>
</annotation>
</item>
<item name="org.apache.velocity.util.StringUtils java.lang.String removeAndHump(java.lang.String)">
@@ -101,6 +107,9 @@
<item name="org.apache.velocity.util.StringUtils java.lang.StringBuffer stringSubstitution(java.lang.String, java.util.Map) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.util.StringUtils java.util.List trimStrings(java.util.List) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.util.StringUtils java.util.List trimStrings(java.util.List)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;!null-&gt;!null;null-&gt;null&quot;"/>
diff --git a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/util/introspection/annotations.xml b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/util/introspection/annotations.xml
index 4518a467c463..4fd41ea336be 100644
--- a/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/util/introspection/annotations.xml
+++ b/java/java-tests/testData/codeInspection/bytecodeAnalysis/annotations/org/apache/velocity/util/introspection/annotations.xml
@@ -5,6 +5,9 @@
<item name="org.apache.velocity.util.introspection.ClassMap void populateMethodCacheWithInterface(org.apache.velocity.util.introspection.ClassMap.MethodCache, java.lang.Class) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.util.introspection.ClassMap.MethodCache MethodCache(org.apache.velocity.runtime.log.Log, org.apache.velocity.util.introspection.ClassMap.1) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.util.introspection.ClassMap.MethodCache java.lang.String makeMethodKey(java.lang.String, java.lang.Object[]) 1">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
@@ -90,11 +93,20 @@
<item name="org.apache.velocity.util.introspection.MethodMap void add(java.lang.reflect.Method) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.util.introspection.SecureIntrospectorImpl boolean checkObjectExecutePermission(java.lang.Class, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.util.introspection.SecureIntrospectorImpl java.lang.reflect.Method getMethod(java.lang.Class, java.lang.String, java.lang.Object[])">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;_,_,null-&gt;null;null,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.velocity.util.introspection.SecureUberspector java.util.Iterator getIterator(java.lang.Object, org.apache.velocity.util.introspection.Info) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.util.introspection.SecureUberspector java.util.Iterator getIterator(java.lang.Object, org.apache.velocity.util.introspection.Info) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.util.introspection.SecureUberspector java.util.Iterator getIterator(java.lang.Object, org.apache.velocity.util.introspection.Info)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_-&gt;null&quot;"/>
@@ -103,16 +115,37 @@
<item name="org.apache.velocity.util.introspection.UberspectImpl java.util.Iterator getIterator(java.lang.Object, org.apache.velocity.util.introspection.Info) 0">
<annotation name="org.jetbrains.annotations.NotNull"/>
</item>
+ <item name="org.apache.velocity.util.introspection.UberspectImpl java.util.Iterator getIterator(java.lang.Object, org.apache.velocity.util.introspection.Info) 1">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.util.introspection.UberspectImpl org.apache.velocity.util.introspection.VelMethod getMethod(java.lang.Object, java.lang.String, java.lang.Object[], org.apache.velocity.util.introspection.Info) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.util.introspection.UberspectImpl org.apache.velocity.util.introspection.VelMethod getMethod(java.lang.Object, java.lang.String, java.lang.Object[], org.apache.velocity.util.introspection.Info) 3">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.util.introspection.UberspectImpl org.apache.velocity.util.introspection.VelMethod getMethod(java.lang.Object, java.lang.String, java.lang.Object[], org.apache.velocity.util.introspection.Info)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.velocity.util.introspection.UberspectImpl org.apache.velocity.util.introspection.VelPropertyGet getPropertyGet(java.lang.Object, java.lang.String, org.apache.velocity.util.introspection.Info) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.util.introspection.UberspectImpl org.apache.velocity.util.introspection.VelPropertyGet getPropertyGet(java.lang.Object, java.lang.String, org.apache.velocity.util.introspection.Info) 2">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.util.introspection.UberspectImpl org.apache.velocity.util.introspection.VelPropertyGet getPropertyGet(java.lang.Object, java.lang.String, org.apache.velocity.util.introspection.Info)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_,_-&gt;null&quot;"/>
</annotation>
</item>
+ <item name="org.apache.velocity.util.introspection.UberspectImpl org.apache.velocity.util.introspection.VelPropertySet getPropertySet(java.lang.Object, java.lang.String, java.lang.Object, org.apache.velocity.util.introspection.Info) 0">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
+ <item name="org.apache.velocity.util.introspection.UberspectImpl org.apache.velocity.util.introspection.VelPropertySet getPropertySet(java.lang.Object, java.lang.String, java.lang.Object, org.apache.velocity.util.introspection.Info) 3">
+ <annotation name="org.jetbrains.annotations.Nullable"/>
+ </item>
<item name="org.apache.velocity.util.introspection.UberspectImpl org.apache.velocity.util.introspection.VelPropertySet getPropertySet(java.lang.Object, java.lang.String, java.lang.Object, org.apache.velocity.util.introspection.Info)">
<annotation name="org.jetbrains.annotations.Contract">
<val val="&quot;null,_,_,_-&gt;null&quot;"/>
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/GetterResultsNotSame.java b/java/java-tests/testData/inspection/dataFlow/fixture/GetterResultsNotSame.java
new file mode 100644
index 000000000000..1b60a7373900
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/GetterResultsNotSame.java
@@ -0,0 +1,26 @@
+class Main {
+
+ public static String getSameObject() {
+ return ""; // same object for any call
+ }
+
+ public static Main getNewObject() {
+ return new Main(); // different objects for different subsequent calls
+ }
+
+ public static void main(String[] args) {
+ Main m = new Main();
+
+ if (m.getSameObject() == m.getSameObject()) {
+ System.out.println("This will get printed");
+ }
+
+ if (m.getNewObject() == m.getNewObject()) {
+ System.out.println("This will not get printed");
+ }
+
+ if (Main.getNewObject() == Main.getNewObject()) {
+ System.out.println("This will not get printed");
+ }
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/SwitchOnNullable.java b/java/java-tests/testData/inspection/dataFlow/fixture/SwitchOnNullable.java
new file mode 100644
index 000000000000..c74852064bf4
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/SwitchOnNullable.java
@@ -0,0 +1,10 @@
+import org.jetbrains.annotations.Nullable;
+
+class BrokenAlignment {
+
+ void test(@Nullable String n) {
+ switch (<warning descr="Dereference of 'n' may produce 'java.lang.NullPointerException'">n</warning>) {
+
+ }
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/psi/repositoryUse/scr17094/classes/a/a/a/a/e/f/i.class b/java/java-tests/testData/psi/repositoryUse/deepPackages/classes/a/a/a/a/e/f/i.class
index 3b64eb80cda2..3b64eb80cda2 100644
--- a/java/java-tests/testData/psi/repositoryUse/scr17094/classes/a/a/a/a/e/f/i.class
+++ b/java/java-tests/testData/psi/repositoryUse/deepPackages/classes/a/a/a/a/e/f/i.class
Binary files differ
diff --git a/java/java-tests/testData/psi/repositoryUse/scr17094/classes2/com/intellij/internal/a/b/a/i.class b/java/java-tests/testData/psi/repositoryUse/deepPackages/classes2/com/intellij/internal/a/b/a/i.class
index 26bf433c204a..26bf433c204a 100644
--- a/java/java-tests/testData/psi/repositoryUse/scr17094/classes2/com/intellij/internal/a/b/a/i.class
+++ b/java/java-tests/testData/psi/repositoryUse/deepPackages/classes2/com/intellij/internal/a/b/a/i.class
Binary files differ
diff --git a/java/java-tests/testData/psi/repositoryUse/scr17094/classes1/com/intellij/util/d/bw.class b/java/java-tests/testData/psi/repositoryUse/scr17094/classes1/com/intellij/util/d/bw.class
deleted file mode 100644
index 46b8238fc620..000000000000
--- a/java/java-tests/testData/psi/repositoryUse/scr17094/classes1/com/intellij/util/d/bw.class
+++ /dev/null
Binary files differ
diff --git a/java/java-tests/testData/refactoring/inlineMethod/multifile/preserveStaticImportsIfOverloaded/after/Bar.java b/java/java-tests/testData/refactoring/inlineMethod/multifile/preserveStaticImportsIfOverloaded/after/Bar.java
new file mode 100644
index 000000000000..8ca1dc15c524
--- /dev/null
+++ b/java/java-tests/testData/refactoring/inlineMethod/multifile/preserveStaticImportsIfOverloaded/after/Bar.java
@@ -0,0 +1,6 @@
+import static Foo.foo;
+public class Bar {
+ void bar() {
+ foo(1);
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/inlineMethod/multifile/preserveStaticImportsIfOverloaded/after/Foo.java b/java/java-tests/testData/refactoring/inlineMethod/multifile/preserveStaticImportsIfOverloaded/after/Foo.java
new file mode 100644
index 000000000000..a72e7b529652
--- /dev/null
+++ b/java/java-tests/testData/refactoring/inlineMethod/multifile/preserveStaticImportsIfOverloaded/after/Foo.java
@@ -0,0 +1,3 @@
+public class Foo {
+ public static void foo(int i){}
+} \ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/inlineMethod/multifile/preserveStaticImportsIfOverloaded/before/Bar.java b/java/java-tests/testData/refactoring/inlineMethod/multifile/preserveStaticImportsIfOverloaded/before/Bar.java
new file mode 100644
index 000000000000..19bfccb3a7cf
--- /dev/null
+++ b/java/java-tests/testData/refactoring/inlineMethod/multifile/preserveStaticImportsIfOverloaded/before/Bar.java
@@ -0,0 +1,7 @@
+import static Foo.foo;
+public class Bar {
+ void bar() {
+ foo();
+ foo(1);
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/inlineMethod/multifile/preserveStaticImportsIfOverloaded/before/Foo.java b/java/java-tests/testData/refactoring/inlineMethod/multifile/preserveStaticImportsIfOverloaded/before/Foo.java
new file mode 100644
index 000000000000..9b8067c73350
--- /dev/null
+++ b/java/java-tests/testData/refactoring/inlineMethod/multifile/preserveStaticImportsIfOverloaded/before/Foo.java
@@ -0,0 +1,4 @@
+public class Foo {
+ public static void foo(){}
+ public static void foo(int i){}
+} \ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/inlineMethod/multifile/removeStaticImportsIfOverloadedUnused/after/Bar.java b/java/java-tests/testData/refactoring/inlineMethod/multifile/removeStaticImportsIfOverloadedUnused/after/Bar.java
new file mode 100644
index 000000000000..2f1dfde98c09
--- /dev/null
+++ b/java/java-tests/testData/refactoring/inlineMethod/multifile/removeStaticImportsIfOverloadedUnused/after/Bar.java
@@ -0,0 +1,4 @@
+public class Bar {
+ void bar() {
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/inlineMethod/multifile/removeStaticImportsIfOverloadedUnused/after/Foo.java b/java/java-tests/testData/refactoring/inlineMethod/multifile/removeStaticImportsIfOverloadedUnused/after/Foo.java
new file mode 100644
index 000000000000..a72e7b529652
--- /dev/null
+++ b/java/java-tests/testData/refactoring/inlineMethod/multifile/removeStaticImportsIfOverloadedUnused/after/Foo.java
@@ -0,0 +1,3 @@
+public class Foo {
+ public static void foo(int i){}
+} \ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/inlineMethod/multifile/removeStaticImportsIfOverloadedUnused/before/Bar.java b/java/java-tests/testData/refactoring/inlineMethod/multifile/removeStaticImportsIfOverloadedUnused/before/Bar.java
new file mode 100644
index 000000000000..0d111602e175
--- /dev/null
+++ b/java/java-tests/testData/refactoring/inlineMethod/multifile/removeStaticImportsIfOverloadedUnused/before/Bar.java
@@ -0,0 +1,6 @@
+import static Foo.foo;
+public class Bar {
+ void bar() {
+ foo();
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/inlineMethod/multifile/removeStaticImportsIfOverloadedUnused/before/Foo.java b/java/java-tests/testData/refactoring/inlineMethod/multifile/removeStaticImportsIfOverloadedUnused/before/Foo.java
new file mode 100644
index 000000000000..9b8067c73350
--- /dev/null
+++ b/java/java-tests/testData/refactoring/inlineMethod/multifile/removeStaticImportsIfOverloadedUnused/before/Foo.java
@@ -0,0 +1,4 @@
+public class Foo {
+ public static void foo(){}
+ public static void foo(int i){}
+} \ No newline at end of file
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/GenerateGetterSetterTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/GenerateGetterSetterTest.groovy
index 273ab150d8c5..4aabc1448492 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/GenerateGetterSetterTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/GenerateGetterSetterTest.groovy
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@ import com.intellij.openapi.command.WriteCommandAction
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
+import com.intellij.util.ui.UIUtil
import com.siyeh.ig.style.UnqualifiedFieldAccessInspection
import org.jetbrains.annotations.Nullable
/**
@@ -103,5 +104,6 @@ class Foo {
}
}.invoke(project, myFixture.editor, myFixture.file)
})
+ UIUtil.dispatchAllInvocationEvents()
}
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/JavaTypingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/JavaTypingTest.java
index 9ca3b6084a43..37aa8852136b 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/JavaTypingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/JavaTypingTest.java
@@ -74,6 +74,22 @@ public class JavaTypingTest extends LightPlatformCodeInsightFixtureTestCase {
myFixture.checkResultByFile(getTestName(true) + "_after.java");
}
+ public void testFixIfByBrace() {
+ doTest('{');
+ }
+
+ public void testFixIfByBraceNewObject() {
+ doTest('{');
+ }
+
+ public void testFixIfByBraceCompositeCondition() {
+ doTest('{');
+ }
+
+ public void testFixWhileByBrace() {
+ doTest('{');
+ }
+
private void doTest(char c) {
myFixture.configureByFile(getTestName(true) + "_before.java");
myFixture.type(c);
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy
index 7391f93a1ab2..1dd75011d3b8 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy
@@ -14,6 +14,7 @@
* limitations under the License.
*/
package com.intellij.codeInsight.completion
+
import com.intellij.codeInsight.CodeInsightSettings
import com.intellij.codeInsight.TargetElementUtil
import com.intellij.codeInsight.completion.impl.CompletionServiceImpl
@@ -24,10 +25,7 @@ import com.intellij.codeInsight.lookup.LookupManager
import com.intellij.codeInsight.lookup.PsiTypeLookupItem
import com.intellij.codeInsight.lookup.impl.LookupImpl
import com.intellij.codeInsight.template.*
-import com.intellij.codeInsight.template.impl.LiveTemplateDocumentationProvider
-import com.intellij.codeInsight.template.impl.TemplateImpl
-import com.intellij.codeInsight.template.impl.TemplateManagerImpl
-import com.intellij.codeInsight.template.impl.TemplateSettings
+import com.intellij.codeInsight.template.impl.*
import com.intellij.ide.DataManager
import com.intellij.ide.ui.UISettings
import com.intellij.openapi.Disposable
@@ -53,6 +51,7 @@ import com.intellij.openapi.util.Disposer
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiJavaFile
+import com.intellij.psi.PsiMethod
import com.intellij.psi.statistics.StatisticsManager
import com.intellij.psi.statistics.impl.StatisticsManagerImpl
import com.intellij.testFramework.EditorTestUtil
@@ -60,6 +59,7 @@ import com.intellij.util.containers.ContainerUtil
import org.jetbrains.annotations.NotNull
import java.awt.event.KeyEvent
+
/**
* @author peter
*/
@@ -974,8 +974,15 @@ class Foo {
return ((PsiJavaFile)myFixture.file).getClasses()[0];
}
});
- def foo = cls.methods[0]
- def goo = cls.methods[2]
+
+ PsiMethod[] methods = ApplicationManager.getApplication().runReadAction(new Computable<PsiMethod[]>() {
+ @Override
+ public PsiMethod[] compute() {
+ return cls.methods;
+ }
+ })
+ def foo = methods[0]
+ def goo = methods[2]
type('x')
assertContains 'x__foo', 'x__goo'
edt {
@@ -1292,7 +1299,7 @@ class Foo {{
type '.'
assert myFixture.lookupElementStrings == ['Util.bar', 'Util.CONSTANT', 'Util.foo']
- def p = LookupElementPresentation.renderElement(myFixture.lookupElements[1])
+ def p = ApplicationManager.application.runReadAction ({ LookupElementPresentation.renderElement(myFixture.lookupElements[1]) } as Computable)
assert p.itemText == 'Util.CONSTANT'
assert p.tailText == ' (foo)'
assert p.typeText == 'int'
@@ -1653,4 +1660,25 @@ class Foo {{
type 'toStr'
assert lookup
}
+
+ public void "test show popup with single live template if show_live_tempate_in_completion option is enabled"() {
+ def oldValue = LiveTemplateCompletionContributor.ourShowTemplatesInTests
+ try {
+ LiveTemplateCompletionContributor.ourShowTemplatesInTests = false
+ myFixture.configureByText "a.java", """
+class Foo {{
+ ita<caret>
+"""
+ type 'r'
+ assert lookup == null
+
+ LiveTemplateCompletionContributor.ourShowTemplatesInTests = true
+ type '\br'
+ assert lookup
+ assert myFixture.lookupElementStrings == ['itar']
+ }
+ finally {
+ LiveTemplateCompletionContributor.ourShowTemplatesInTests = oldValue
+ }
+ }
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/KeywordCompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/KeywordCompletionTest.java
index 6b9cff3f6149..59029a2fb05a 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/KeywordCompletionTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/KeywordCompletionTest.java
@@ -106,7 +106,9 @@ public class KeywordCompletionTest extends LightCompletionTestCase {
public void testReturnInTernary() throws Exception { doTest(1, "return"); }
public void testFinalAfterParameterAnno() throws Exception { doTest(2, "final", "float", "class"); }
public void testFinalAfterParameterAnno2() throws Exception { doTest(2, "final", "float", "class"); }
- public void testFinalAfterCase() throws Exception { doTest(3, "final", "float", "class"); }
+ public void testFinalAfterCase() { doTest(3, "final", "float", "class"); }
+ public void testFinalInCatch() { doTest(1, "final"); }
+ public void testFinalInIncompleteCatch() { doTest(1, "final"); }
public void testFinalInTryWithResources() throws Exception { doTest(1, "final", "float", "class"); }
public void testNoFinalAfterTryBody() throws Exception { doTest(1, "final", "finally"); }
public void testClassInMethod() throws Exception { doTest(2, "class", "char"); }
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.groovy
index 900555d21ab9..821e5f31fb91 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.groovy
@@ -638,7 +638,7 @@ interface TxANotAnno {}
}
public void testPreferThrownExceptionsInCatch() {
- checkPreferredItems 0, 'FileNotFoundException', 'File'
+ checkPreferredItems 0, 'final', 'FileNotFoundException', 'File'
}
public void testHonorFirstLetterCase() {
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java
index 5153f19fe94a..967de28820e8 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java
@@ -777,6 +777,11 @@ public class SmartTypeCompletionTest extends LightFixtureCompletionTestCase {
myFixture.assertPreferredCompletionItems(0, "i", "z", "zz", "i, z, zz");
}
+ public void testSuggestTypeParametersInTypeArgumentList() {
+ configureByTestName();
+ myFixture.assertPreferredCompletionItems(0, "T", "String");
+ }
+
public void testWrongAnonymous() throws Throwable {
configureByTestName();
select();
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java
index 688e83b5b198..09225b64bc1d 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java
@@ -372,6 +372,8 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testIDEA126633() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); }
public void testIDEA124363() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); }
public void testIDEA78402() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); }
+ public void testSuperCaptureSubstitutionWhenTypeParameterHasUpperBounds() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); }
+ public void testParameterBoundsWithCapturedWildcard() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); }
//jdk should propagate LL 1.4 but actually it provides LL 1.7?!
public void testCastObjectToIntJdk14() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_4, false); }
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/FindFunctionalInterfaceTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/FindFunctionalInterfaceTest.java
index a6a75b7c061c..2427748b22d4 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/FindFunctionalInterfaceTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/FindFunctionalInterfaceTest.java
@@ -16,6 +16,7 @@
package com.intellij.codeInsight.daemon.lambda;
import com.intellij.JavaTestUtil;
+import com.intellij.idea.Bombed;
import com.intellij.psi.*;
import com.intellij.psi.search.searches.FunctionalExpressionSearch;
import com.intellij.psi.search.searches.ReferencesSearch;
@@ -24,6 +25,7 @@ import com.intellij.testFramework.LightProjectDescriptor;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
import org.jetbrains.annotations.NotNull;
+import java.util.Calendar;
import java.util.Collection;
public class FindFunctionalInterfaceTest extends LightCodeInsightFixtureTestCase {
@@ -40,6 +42,7 @@ public class FindFunctionalInterfaceTest extends LightCodeInsightFixtureTestCase
assertEquals("() -> {}", next.getText());
}
+ @Bombed(day = 30, month = Calendar.SEPTEMBER)
public void testFieldFromAnonymousClassScope() throws Exception {
myFixture.configureByFile(getTestName(false) + ".java");
final PsiElement elementAtCaret = myFixture.getElementAtCaret();
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlighting8Test.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlighting8Test.java
index d23dfea6daf0..a66d999b283c 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlighting8Test.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlighting8Test.java
@@ -688,7 +688,7 @@ public class GenericsHighlighting8Test extends LightDaemonAnalyzerTestCase {
public void testIDEA110869() {
doTest();
}
- /*public void testIDEA110947() { doTest5(false); }*/
+ public void testIDEA110947() { doTest(false); }
public void testIDEA112122() {
doTest();
}
@@ -759,6 +759,10 @@ public class GenericsHighlighting8Test extends LightDaemonAnalyzerTestCase {
doTest();
}
+ public void testIDEA128333() throws Exception {
+ doTest();
+ }
+
public void testIDEA78402() { doTest(); }
private void doTest() {
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java
index c2ab020f09f3..7585d661b289 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java
@@ -47,16 +47,20 @@ public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase
doTest();
}
- @Bombed(day = 20, month = Calendar.AUGUST)
+ @Bombed(day = 30, month = Calendar.SEPTEMBER)
public void testInferenceFromSiblings() throws Exception {
doTest();
}
- @Bombed(day = 20, month = Calendar.AUGUST)
+ @Bombed(day = 30, month = Calendar.SEPTEMBER)
public void testChainedInferenceTypeParamsOrderIndependent() throws Exception {
doTest();
}
+ public void testCyclicParamsDependency() throws Exception {
+ doTest();
+ }
+
public void testInferenceForFirstArg() throws Exception {
doTest();
}
@@ -216,6 +220,21 @@ public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase
public void testIDEA127928() throws Exception {
doTest();
}
+ public void testIDEA128766() throws Exception {
+ doTest();
+ }
+
+ public void testSameMethodNestedChainedCallsNearFunctionInterfaces() throws Exception {
+ doTest();
+ }
+
+ public void testInfiniteTypes() throws Exception {
+ doTest();
+ }
+
+ public void testIDEA126163() throws Exception {
+ doTest();
+ }
private void doTest() throws Exception {
doTest(false);
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java
index 1411249b3dcc..1da75f51ba6f 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java
@@ -76,8 +76,9 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testIDEA122616() { doTest(); }
public void testIDEA122700() { doTest(); }
public void testIDEA122406() { doTest(); }
+ @Bombed(day = 30, month = Calendar.SEPTEMBER)
public void testNestedCallsInsideLambdaReturnExpression() { doTest(); }
- @Bombed(day = 20, month = Calendar.AUGUST)
+ @Bombed(day = 30, month = Calendar.SEPTEMBER)
public void testIDEA123731() { doTest(); }
public void testIDEA123869() { doTest(); }
public void testIDEA123848() { doTest(); }
@@ -98,7 +99,7 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest();
}
- @Bombed(day = 20, month = Calendar.AUGUST)
+ @Bombed(day = 30, month = Calendar.SEPTEMBER)
public void testIDEA124983() throws Exception {
doTest();
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java
index c48ef71d92d4..c981137d0253 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java
@@ -288,7 +288,7 @@ public class NewMethodRefHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest();
}
- @Bombed(day = 20, month = Calendar.AUGUST)
+ @Bombed(day = 30, month = Calendar.SEPTEMBER)
public void testIDEA127275_() throws Exception {
doTest();
}
@@ -305,6 +305,15 @@ public class NewMethodRefHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest();
}
+ @Bombed(day = 30, month = Calendar.SEPTEMBER)
+ public void testAdditionalConstraints3Level() throws Exception {
+ doTest();
+ }
+
+ public void testWildcardParametrization() throws Exception {
+ doTest();
+ }
+
private void doTest() {
doTest(false);
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/ContractInferenceFromSourceTest.groovy b/java/java-tests/testSrc/com/intellij/codeInspection/ContractInferenceFromSourceTest.groovy
index 89762efe5dd2..c3bb014d8342 100644
--- a/java/java-tests/testSrc/com/intellij/codeInspection/ContractInferenceFromSourceTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInspection/ContractInferenceFromSourceTest.groovy
@@ -27,7 +27,7 @@ class ContractInferenceFromSourceTest extends LightCodeInsightFixtureTestCase {
def c = inferContract("""
String smth(String s) {
if (s == null) return null;
- return s.substring(1);
+ return smth();
}
""")
assert c == 'null -> null'
@@ -310,6 +310,55 @@ class ContractInferenceFromSourceTest extends LightCodeInsightFixtureTestCase {
assert c == []
}
+ public void "test skip empty declarations"() {
+ def c = inferContracts("""
+ final Object foo(Object bar) {
+ Object o = 2;
+ if (bar == null) return null;
+ return new String("abc");
+ }
+ """)
+ assert c == ['null -> null', '!null -> !null']
+ }
+
+ public void "test go inside do-while"() {
+ def c = inferContracts("""
+ final Object foo(Object bar) {
+ do {
+ if (bar == null) return null;
+ bar = smth(bar);
+ } while (smthElse());
+ return new String("abc");
+ }
+ """)
+ assert c == ['null -> null']
+ }
+
+ public void "test go inside try"() {
+ def c = inferContracts("""
+ final Object foo(Object bar) {
+ try {
+ if (bar == null) return null;
+ bar = smth(bar);
+ } finally {}
+ return new String("abc");
+ }
+ """)
+ assert c == ['null -> null']
+ }
+
+ public void "test use invoked method notnull"() {
+ def c = inferContracts("""
+ final Object foo(Object bar) {
+ if (bar == null) return null;
+ return doo();
+ }
+
+ @org.jetbrains.annotations.NotNull Object doo() {}
+ """)
+ assert c == ['null -> null', '!null -> !null']
+ }
+
private String inferContract(String method) {
return assertOneElement(inferContracts(method))
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java
index 33eb32eb0ec6..a10d02d31fca 100644
--- a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java
@@ -109,6 +109,7 @@ public class DataFlowInspectionTest extends LightCodeInsightFixtureTestCase {
public void testAssigningClassLiteralToNullable() throws Throwable { doTest(); }
public void testSynchronizingOnNullable() throws Throwable { doTest(); }
+ public void testSwitchOnNullable() { doTest(); }
public void testReturningNullFromVoidMethod() throws Throwable { doTest(); }
public void testCatchRuntimeException() throws Throwable { doTest(); }
@@ -214,6 +215,7 @@ public class DataFlowInspectionTest extends LightCodeInsightFixtureTestCase {
public void testNoConfusionWithAnonymousConstantInitializer() { doTest(); }
public void testForeachOverWildcards() { doTest(); }
public void testFinalGetter() { doTest(); }
+ public void testGetterResultsNotSame() { doTest(); }
public void testByteBufferGetter() {
myFixture.addClass("package java.nio; public class MappedByteBuffer { public int getInt() {} }");
diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/UnusedLibraryInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/UnusedLibraryInspectionTest.java
index bb6195a94aa7..938a86da7587 100644
--- a/java/java-tests/testSrc/com/intellij/codeInspection/UnusedLibraryInspectionTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInspection/UnusedLibraryInspectionTest.java
@@ -25,6 +25,7 @@
package com.intellij.codeInspection;
import com.intellij.JavaTestUtil;
+import com.intellij.analysis.AnalysisScope;
import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;
import com.intellij.codeInspection.magicConstant.MagicConstantInspection;
import com.intellij.codeInspection.unusedLibraries.UnusedLibrariesInspection;
@@ -37,6 +38,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.testFramework.InspectionTestCase;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.testFramework.PsiTestUtil;
+import org.jetbrains.annotations.NotNull;
public class UnusedLibraryInspectionTest extends InspectionTestCase {
@Override
@@ -54,5 +56,11 @@ public class UnusedLibraryInspectionTest extends InspectionTestCase {
doTest("/" + getTestName(true), new UnusedLibrariesInspection());
}
+ @NotNull
+ @Override
+ protected AnalysisScope createAnalysisScope(VirtualFile sourceDir) {
+ return new AnalysisScope(getProject());
+ }
+
public void testSimple() throws Exception { doTest(); }
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisIntegrationTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisIntegrationTest.java
index 516b140cc0b1..ab6d92263162 100644
--- a/java/java-tests/testSrc/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisIntegrationTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisIntegrationTest.java
@@ -38,7 +38,7 @@ import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase;
import com.intellij.util.AsynchConsumer;
import org.jetbrains.annotations.Contract;
-import java.io.IOException;
+import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.List;
@@ -50,7 +50,7 @@ public class BytecodeAnalysisIntegrationTest extends JavaCodeInsightFixtureTestC
private InferredAnnotationsManager myInferredAnnotationsManager;
private ExternalAnnotationsManager myExternalAnnotationsManager;
-
+ private MessageDigest myMessageDigest;
private List<String> diffs = new ArrayList<String>();
@Override
@@ -62,6 +62,7 @@ public class BytecodeAnalysisIntegrationTest extends JavaCodeInsightFixtureTestC
myInferredAnnotationsManager = InferredAnnotationsManager.getInstance(myModule.getProject());
myExternalAnnotationsManager = ExternalAnnotationsManager.getInstance(myModule.getProject());
+ myMessageDigest = BytecodeAnalysisConverter.getMessageDigest();
}
private void setUpLibraries() {
@@ -127,13 +128,9 @@ public class BytecodeAnalysisIntegrationTest extends JavaCodeInsightFixtureTestC
}
private void checkMethodAnnotations(PsiMethod method) {
- try {
- if (ProjectBytecodeAnalysis.getKey(method) == -1) {
- return;
- }
- }
- catch (IOException e) {
- fail();
+
+ if (ProjectBytecodeAnalysis.getKey(method, myMessageDigest) == null) {
+ return;
}
// not null-result
@@ -149,12 +146,27 @@ public class BytecodeAnalysisIntegrationTest extends JavaCodeInsightFixtureTestC
for (PsiParameter parameter : method.getParameterList().getParameters()) {
String parameterKey = PsiFormatUtil.getExternalName(parameter, false, Integer.MAX_VALUE);
- String externalParameterAnnotation =
- myExternalAnnotationsManager.findExternalAnnotation(parameter, AnnotationUtil.NOT_NULL) == null ? "null" : "@NotNull";
- String inferredParameterAnnotation =
- myInferredAnnotationsManager.findInferredAnnotation(parameter, AnnotationUtil.NOT_NULL) == null ? "null" : "@NotNull";
- if (!externalParameterAnnotation.equals(inferredParameterAnnotation)) {
- diffs.add(parameterKey + ": " + externalParameterAnnotation + " != " + inferredParameterAnnotation);
+
+ {
+ // @NotNull
+ String externalNotNull =
+ myExternalAnnotationsManager.findExternalAnnotation(parameter, AnnotationUtil.NOT_NULL) == null ? "null" : "@NotNull";
+ String inferredNotNull =
+ myInferredAnnotationsManager.findInferredAnnotation(parameter, AnnotationUtil.NOT_NULL) == null ? "null" : "@NotNull";
+ if (!externalNotNull.equals(inferredNotNull)) {
+ diffs.add(parameterKey + ": " + externalNotNull + " != " + inferredNotNull);
+ }
+ }
+
+ {
+ // @Nullable
+ String externalNullable =
+ myExternalAnnotationsManager.findExternalAnnotation(parameter, AnnotationUtil.NULLABLE) == null ? "null" : "@Nullable";
+ String inferredNullable =
+ myInferredAnnotationsManager.findInferredAnnotation(parameter, AnnotationUtil.NULLABLE) == null ? "null" : "@Nullable";
+ if (!externalNullable.equals(inferredNullable)) {
+ diffs.add(parameterKey + ": " + externalNullable + " != " + inferredNullable);
+ }
}
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisTest.java
index 9d26fd804f68..2cbf3fbdfd6c 100644
--- a/java/java-tests/testSrc/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisTest.java
@@ -17,6 +17,7 @@ package com.intellij.codeInspection.bytecodeAnalysis;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInsight.InferredAnnotationsManager;
+import com.intellij.codeInspection.bytecodeAnalysis.asm.LeakingParameters;
import com.intellij.codeInspection.bytecodeAnalysis.data.*;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
@@ -37,6 +38,7 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
+import java.security.MessageDigest;
import java.util.HashMap;
/**
@@ -47,15 +49,15 @@ public class BytecodeAnalysisTest extends JavaCodeInsightFixtureTestCase {
private final String myClassesProjectRelativePath = "/classes/" + Test01.class.getPackage().getName().replace('.', '/');
private JavaPsiFacade myJavaPsiFacade;
private InferredAnnotationsManager myInferredAnnotationsManager;
- private BytecodeAnalysisConverter myBytecodeAnalysisConverter;
+ private MessageDigest myMessageDigest;
+
@Override
protected void setUp() throws Exception {
super.setUp();
myJavaPsiFacade = JavaPsiFacade.getInstance(myModule.getProject());
myInferredAnnotationsManager = InferredAnnotationsManager.getInstance(myModule.getProject());
- myBytecodeAnalysisConverter = BytecodeAnalysisConverter.getInstance();
-
+ myMessageDigest = MessageDigest.getInstance("MD5");
setUpDataClasses();
}
@@ -93,7 +95,7 @@ public class BytecodeAnalysisTest extends JavaCodeInsightFixtureTestCase {
public void visitEnd() {
super.visitEnd();
try {
- map.put(method, cfg.leakingParameters(classReader.getClassName(), node));
+ map.put(method, LeakingParameters.build(classReader.getClassName(), node, false).parameters);
}
catch (AnalyzerException ignore) {}
}
@@ -183,17 +185,21 @@ public class BytecodeAnalysisTest extends JavaCodeInsightFixtureTestCase {
private void checkCompoundId(Method method, PsiMethod psiMethod, boolean noKey) throws IOException {
Direction direction = new Out();
- long psiKey = myBytecodeAnalysisConverter.mkPsiKey(psiMethod, direction);
+ System.out.println();
+ System.out.println(method.internalClassName);
+ System.out.println(method.methodName);
+ System.out.println(method.methodDesc);
+
+
+ HKey psiKey = BytecodeAnalysisConverter.psiKey(psiMethod, direction, myMessageDigest);
if (noKey) {
- assertTrue(-1 == psiKey);
+ assertTrue(null == psiKey);
return;
}
else {
- assertFalse(-1 == psiKey);
+ assertFalse(null == psiKey);
}
-
- long asmKey = myBytecodeAnalysisConverter.mkAsmKey(new Key(method, direction, true));
-
+ HKey asmKey = BytecodeAnalysisConverter.asmKey(new Key(method, direction, true), myMessageDigest);
Assert.assertEquals(asmKey, psiKey);
}
diff --git a/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java b/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java
index e40e2c160822..cf876693e2f7 100644
--- a/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java
+++ b/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java
@@ -343,6 +343,28 @@ public class FindManagerTest extends DaemonAnalyzerTestCase {
assertSize(2, findUsages(findModel));
}
+ public void testNonRecursiveDirectory() throws Exception {
+ VirtualFile root = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(createTempDirectory());
+ addSourceContentToRoots(myModule, root);
+
+ VirtualFile foo = createChildDirectory(root, "foo");
+ VirtualFile bar = createChildDirectory(foo, "bar");
+ createFile(myModule, root, "A.txt", "goo doo");
+ createFile(myModule, foo, "A.txt", "goo doo");
+ createFile(myModule, bar, "A.txt", "doo goo");
+
+ FindModel findModel = FindManagerTestUtils.configureFindModel("done");
+ findModel.setProjectScope(false);
+ findModel.setDirectoryName(foo.getPath());
+ findModel.setStringToFind("doo");
+
+ findModel.setWithSubdirectories(true);
+ assertSize(2, findUsages(findModel));
+
+ findModel.setWithSubdirectories(false);
+ assertSize(1, findUsages(findModel));
+ }
+
public void testReplaceRegexp() {
FindModel findModel = new FindModel();
findModel.setStringToFind("bug_(?=here)");
diff --git a/java/java-tests/testSrc/com/intellij/navigation/ChooseByNameTest.groovy b/java/java-tests/testSrc/com/intellij/navigation/ChooseByNameTest.groovy
index 9a97a825964a..9c378a1e50cf 100644
--- a/java/java-tests/testSrc/com/intellij/navigation/ChooseByNameTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/navigation/ChooseByNameTest.groovy
@@ -229,8 +229,14 @@ class Intf {
edt {
sdkRun = ourRun.containingClass.interfaces[0].methods[0]
}
- assert getPopupElements(new GotoSymbolModel2(project), 'run ', true) == [sdkRun]
- assert getPopupElements(new GotoSymbolModel2(project), 'run ', false) == [ourRun]
+
+ def withLibs = getPopupElements(new GotoSymbolModel2(project), 'run ', true)
+ assert withLibs[0] == sdkRun
+ assert !(ourRun in withLibs)
+
+ def noLibs = getPopupElements(new GotoSymbolModel2(project), 'run ', false)
+ assert noLibs[0] == ourRun
+ assert !(sdkRun in noLibs)
}
private List<Object> getPopupElements(ChooseByNameModel model, String text, boolean checkboxState = false) {
diff --git a/java/java-tests/testSrc/com/intellij/project/LoadProjectTest.java b/java/java-tests/testSrc/com/intellij/project/LoadProjectTest.java
index b50e2d87c71f..69cc43416b5b 100644
--- a/java/java-tests/testSrc/com/intellij/project/LoadProjectTest.java
+++ b/java/java-tests/testSrc/com/intellij/project/LoadProjectTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,6 +28,7 @@ import com.intellij.openapi.project.impl.ProjectImpl;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.impl.source.PsiFileImpl;
import com.intellij.testFramework.LeakHunter;
@@ -61,6 +62,8 @@ public class LoadProjectTest extends PlatformTestCase {
assertNotNull(fileA);
fileA.navigate(true);
Editor editorA = FileEditorManager.getInstance(getProject()).openTextEditor(new OpenFileDescriptor(getProject(), a), true);
+ PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
+
assertNotNull(editorA);
CodeInsightTestFixtureImpl.instantiateAndRun(fileA, editorA, new int[0], false);
@@ -70,6 +73,8 @@ public class LoadProjectTest extends PlatformTestCase {
assertNotNull(fileB);
fileB.navigate(true);
Editor editorB = FileEditorManager.getInstance(getProject()).openTextEditor(new OpenFileDescriptor(getProject(), b), true);
+ PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
+
assertNotNull(editorB);
CodeInsightTestFixtureImpl.instantiateAndRun(fileB, editorB, new int[0], false);
diff --git a/java/java-tests/testSrc/com/intellij/psi/SCR17094Test.java b/java/java-tests/testSrc/com/intellij/psi/FindClassInDeepPackagesTest.java
index 501914bce501..5e5e010df2f7 100644
--- a/java/java-tests/testSrc/com/intellij/psi/SCR17094Test.java
+++ b/java/java-tests/testSrc/com/intellij/psi/FindClassInDeepPackagesTest.java
@@ -29,9 +29,13 @@ import java.io.File;
/**
* @author dsl
*/
-public class SCR17094Test extends PsiTestCase {
- protected void setUpClasses(final String s) throws Exception {
- final String testRoot = PathManagerEx.getTestDataPath() + "/psi/repositoryUse/scr17094";
+public class FindClassInDeepPackagesTest extends PsiTestCase {
+ @Override
+ protected void setUpJdk() {
+ }
+
+ private void setUpLibrary(final String s) throws Exception {
+ final String testRoot = PathManagerEx.getTestDataPath() + "/psi/repositoryUse/deepPackages";
VirtualFile classesRoot = WriteCommandAction.runWriteCommandAction(null, new Computable<VirtualFile>() {
@Override
public VirtualFile compute() {
@@ -44,20 +48,15 @@ public class SCR17094Test extends PsiTestCase {
ModuleRootModificationUtil.addModuleLibrary(myModule, classesRoot.getUrl());
}
- @Override
- protected void setUpJdk() {
-
- }
-
public void testSRC() throws Exception {
- setUpClasses("classes");
+ setUpLibrary("classes");
final JavaPsiFacade psiManager = getJavaFacade();
final PsiClass classA = psiManager.findClass("a.a.a.a.e.f.i", GlobalSearchScope.moduleWithLibrariesScope(myModule));
assertNotNull(classA);
}
public void test3() throws Exception {
- setUpClasses("classes2");
+ setUpLibrary("classes2");
final JavaPsiFacade psiManager = getJavaFacade();
final PsiClass classA = psiManager.findClass("com.intellij.internal.f.a.b.a.i", GlobalSearchScope.moduleWithLibrariesScope(myModule));
assertNotNull(classA);
diff --git a/java/java-tests/testSrc/com/intellij/psi/MiscPsiTest.java b/java/java-tests/testSrc/com/intellij/psi/MiscPsiTest.java
index 61414ab0b416..2ed8233e99fe 100644
--- a/java/java-tests/testSrc/com/intellij/psi/MiscPsiTest.java
+++ b/java/java-tests/testSrc/com/intellij/psi/MiscPsiTest.java
@@ -24,6 +24,7 @@ import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.impl.source.tree.LazyParseableElement;
+import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
import org.jetbrains.annotations.NotNull;
@@ -276,4 +277,24 @@ public class MiscPsiTest extends LightCodeInsightFixtureTestCase {
assertEquals("class A{}", psiClass.getText());
assertEquals(" class A{}", document.getText());
}
+
+ public void testASTBecomesInvalidOnExternalChange() {
+ final String text = "class A{}";
+ final PsiJavaFile file = (PsiJavaFile)myFixture.addFileToProject("a.java", text);
+ PsiElement leaf = file.findElementAt(5);
+
+ PlatformTestUtil.tryGcSoftlyReachableObjects();
+ assertNull(PsiDocumentManager.getInstance(getProject()).getCachedDocument(file));
+
+ new WriteCommandAction.Simple(getProject()) {
+ @Override
+ protected void run() throws Throwable {
+ VfsUtil.saveText(file.getVirtualFile(), text + " ");
+ }
+ }.execute();
+
+ assertTrue(file.isValid());
+ assertFalse(leaf.isValid());
+ assertNotSame(leaf, file.findElementAt(5));
+ }
}
diff --git a/java/java-tests/testSrc/com/intellij/psi/impl/cache/impl/SCR17650Test.java b/java/java-tests/testSrc/com/intellij/psi/impl/cache/impl/ClassFileUnderSourceRootTest.java
index 187d0c2ad80e..5311bd15dfec 100644
--- a/java/java-tests/testSrc/com/intellij/psi/impl/cache/impl/SCR17650Test.java
+++ b/java/java-tests/testSrc/com/intellij/psi/impl/cache/impl/ClassFileUnderSourceRootTest.java
@@ -3,7 +3,6 @@ package com.intellij.psi.impl.cache.impl;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ex.PathManagerEx;
import com.intellij.openapi.roots.ModuleRootModificationUtil;
-import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
@@ -17,20 +16,15 @@ import java.io.IOException;
/**
* @author max
*/
-public class SCR17650Test extends PsiTestCase {
+public class ClassFileUnderSourceRootTest extends PsiTestCase {
private static final String TEST_ROOT = PathManagerEx.getTestDataPath() + "/psi/repositoryUse/cls";
-
private VirtualFile myDir;
@Override
protected void setUp() throws Exception {
super.setUp();
- final File root = FileUtil.createTempFile(getName(), "");
- root.delete();
- root.mkdir();
- myFilesToDelete.add(root);
-
+ final File root = createTempDirectory();
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
@@ -55,11 +49,10 @@ public class SCR17650Test extends PsiTestCase {
private static VirtualFile getClassFile() {
VirtualFile vDir = LocalFileSystem.getInstance().findFileByPath(TEST_ROOT.replace(File.separatorChar, '/'));
- VirtualFile child = vDir.findChild("pack").findChild("MyClass.class");
- return child;
+ return vDir.findFileByRelativePath("pack/MyClass.class");
}
- public void test17650() throws Exception {
+ public void testFindClass() throws Exception {
assertEquals("p.A", myJavaFacade.findClass("p.A").getQualifiedName());
assertEquals("pack.MyClass", myJavaFacade.findClass("pack.MyClass").getQualifiedName());
}
diff --git a/java/java-tests/testSrc/com/intellij/psi/impl/cache/impl/SCR14423Test.java b/java/java-tests/testSrc/com/intellij/psi/impl/cache/impl/FindClassTest.java
index 2870108623b1..e88027409dc0 100644
--- a/java/java-tests/testSrc/com/intellij/psi/impl/cache/impl/SCR14423Test.java
+++ b/java/java-tests/testSrc/com/intellij/psi/impl/cache/impl/FindClassTest.java
@@ -18,11 +18,11 @@ package com.intellij.psi.impl.cache.impl;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.ModuleRootModificationUtil;
-import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
@@ -37,7 +37,7 @@ import java.io.IOException;
/**
* @author max
*/
-public class SCR14423Test extends PsiTestCase {
+public class FindClassTest extends PsiTestCase {
private VirtualFile myPrjDir1;
private VirtualFile mySrcDir1;
private VirtualFile myPackDir;
@@ -46,11 +46,7 @@ public class SCR14423Test extends PsiTestCase {
protected void setUp() throws Exception {
super.setUp();
- final File root = FileUtil.createTempFile(getName(), "");
- root.delete();
- root.mkdir();
- myFilesToDelete.add(root);
-
+ final File root = createTempDirectory();
WriteCommandAction.runWriteCommandAction(null, new Runnable() {
@Override
public void run() {
@@ -75,14 +71,12 @@ public class SCR14423Test extends PsiTestCase {
});
}
- public void testBug2() throws Exception {
+ public void testSimple() throws Exception {
PsiClass psiClass = myJavaFacade.findClass("p.A");
assertEquals("p.A", psiClass.getQualifiedName());
-
- testBug1();
}
- public void testBug1() {
+ public void testClassUnderExcludedFolder() {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
public void run() {
PsiTestUtil.addExcludedRoot(myModule, myPackDir);
@@ -101,7 +95,7 @@ public class SCR14423Test extends PsiTestCase {
});
}
- public void testBug3() {
+ public void testClassUnderIgnoredFolder() {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
public void run() {
PsiClass psiClass = myJavaFacade.findClass("p.A", GlobalSearchScope.allScope(myProject));
@@ -109,14 +103,15 @@ public class SCR14423Test extends PsiTestCase {
assertTrue(psiClass.isValid());
- PsiTestUtil.addExcludedRoot(myModule, myPackDir);
-
- assertFalse(psiClass.isValid());
-
- ModifiableRootModel rootModel = ModuleRootManager.getInstance(myModule).getModifiableModel();
- final ContentEntry content = rootModel.getContentEntries()[0];
- content.removeExcludeFolder(content.getExcludeFolders()[0]);
- rootModel.commit();
+ FileTypeManager fileTypeManager = FileTypeManager.getInstance();
+ String ignoredFilesList = fileTypeManager.getIgnoredFilesList();
+ fileTypeManager.setIgnoredFilesList(ignoredFilesList + ";p");
+ try {
+ assertFalse(psiClass.isValid());
+ }
+ finally {
+ fileTypeManager.setIgnoredFilesList(ignoredFilesList);
+ }
psiClass = myJavaFacade.findClass("p.A");
assertTrue(psiClass.isValid());
@@ -124,7 +119,7 @@ public class SCR14423Test extends PsiTestCase {
});
}
- public void testSyncrhonizationAfterChange() {
+ public void testSynchronizationAfterChange() {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
public void run() {
FileDocumentManager.getInstance().saveAllDocuments();
diff --git a/java/java-tests/testSrc/com/intellij/psi/impl/cache/impl/SCR20733Test.java b/java/java-tests/testSrc/com/intellij/psi/impl/cache/impl/SameSourceRootInTwoModulesTest.java
index 5fef7daea7d9..1a5d5faeca7c 100644
--- a/java/java-tests/testSrc/com/intellij/psi/impl/cache/impl/SCR20733Test.java
+++ b/java/java-tests/testSrc/com/intellij/psi/impl/cache/impl/SameSourceRootInTwoModulesTest.java
@@ -3,7 +3,6 @@ package com.intellij.psi.impl.cache.impl;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
-import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
@@ -18,7 +17,7 @@ import java.io.IOException;
/**
* @author max
*/
-public class SCR20733Test extends PsiTestCase {
+public class SameSourceRootInTwoModulesTest extends PsiTestCase {
private VirtualFile myPrjDir1;
private VirtualFile mySrcDir1;
private VirtualFile myPackDir;
@@ -27,11 +26,7 @@ public class SCR20733Test extends PsiTestCase {
protected void setUp() throws Exception {
super.setUp();
- final File root = FileUtil.createTempFile(getName(), "");
- root.delete();
- root.mkdir();
- myFilesToDelete.add(root);
-
+ final File root = createTempDirectory();
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
diff --git a/java/java-tests/testSrc/com/intellij/psi/impl/cache/impl/SCR19174Test.java b/java/java-tests/testSrc/com/intellij/psi/impl/cache/impl/SourceRootAddedAsLibraryRootTest.java
index c47bbf7184e8..36baf5de0d76 100644
--- a/java/java-tests/testSrc/com/intellij/psi/impl/cache/impl/SCR19174Test.java
+++ b/java/java-tests/testSrc/com/intellij/psi/impl/cache/impl/SourceRootAddedAsLibraryRootTest.java
@@ -2,7 +2,6 @@ package com.intellij.psi.impl.cache.impl;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.roots.ModuleRootModificationUtil;
-import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
@@ -16,7 +15,7 @@ import java.io.IOException;
/**
* @author max
*/
-public class SCR19174Test extends PsiTestCase {
+public class SourceRootAddedAsLibraryRootTest extends PsiTestCase {
private VirtualFile myDir;
private VirtualFile myVFile;
@@ -24,11 +23,7 @@ public class SCR19174Test extends PsiTestCase {
protected void setUp() throws Exception {
super.setUp();
- final File root = FileUtil.createTempFile(getName(), "");
- root.delete();
- root.mkdir();
- myFilesToDelete.add(root);
-
+ final File root = createTempDirectory();
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
@@ -37,12 +32,6 @@ public class SCR19174Test extends PsiTestCase {
myDir = rootVFile.createChildDirectory(null, "contentAndLibrary");
- /*
- myVFile = myDir.createChildData(null, "A.java");
- Writer writer1 = myVFile.getWriter(null);
- writer1.write("package p; public class A{ public void foo(); }");
- writer1.close();
- */
PsiTestUtil.addSourceRoot(myModule, myDir);
}
catch (IOException e) {
diff --git a/java/java-tests/testSrc/com/intellij/psi/impl/file/impl/PsiEventsTest.java b/java/java-tests/testSrc/com/intellij/psi/impl/file/impl/PsiEventsTest.java
index 2461a4601eba..a933d5bcacf6 100644
--- a/java/java-tests/testSrc/com/intellij/psi/impl/file/impl/PsiEventsTest.java
+++ b/java/java-tests/testSrc/com/intellij/psi/impl/file/impl/PsiEventsTest.java
@@ -43,13 +43,11 @@ public class PsiEventsTest extends PsiTestCase {
private VirtualFile myPrjDir1;
private VirtualFile myPrjDir2;
- private VirtualFile myPrjDir3;
private VirtualFile mySrcDir1;
private VirtualFile mySrcDir2;
private VirtualFile mySrcDir3;
- private VirtualFile mySrcDir4;
private VirtualFile myClsDir1;
- private VirtualFile myExcludedDir1;
+ private VirtualFile myIgnoredDir;
@Override
protected void setUp() throws Exception {
@@ -76,13 +74,12 @@ public class PsiEventsTest extends PsiTestCase {
myClsDir1 = myPrjDir1.createChildDirectory(null, "cls1");
- myExcludedDir1 = mySrcDir1.createChildDirectory(null, "excluded");
+ myIgnoredDir = mySrcDir1.createChildDirectory(null, "CVS");
PsiTestUtil.addContentRoot(myModule, myPrjDir1);
PsiTestUtil.addSourceRoot(myModule, mySrcDir1);
PsiTestUtil.addSourceRoot(myModule, mySrcDir2);
PsiTestUtil.addContentRoot(myModule, myPrjDir2);
- PsiTestUtil.addExcludedRoot(myModule, myExcludedDir1);
ModuleRootModificationUtil.addModuleLibrary(myModule, myClsDir1.getUrl());
PsiTestUtil.addSourceRoot(myModule, mySrcDir3);
} catch (IOException e) {
@@ -106,7 +103,7 @@ public class PsiEventsTest extends PsiTestCase {
String expected =
"beforeChildAddition\n" +
"childAdded\n";
- assertEquals(expected, string);
+ assertEquals(psiDir.getName(), expected, string);
}
public void testCreateDirectory() throws Exception {
@@ -121,7 +118,7 @@ public class PsiEventsTest extends PsiTestCase {
String expected =
"beforeChildAddition\n" +
"childAdded\n";
- assertEquals(expected, string);
+ assertEquals(psiDir.getName(), expected, string);
}
public void testDeleteFile() throws Exception {
@@ -139,7 +136,7 @@ public class PsiEventsTest extends PsiTestCase {
String expected =
"beforeChildRemoval\n" +
"childRemoved\n";
- assertEquals(expected, string);
+ assertEquals(psiFile.getName(), expected, string);
}
public void testDeleteDirectory() throws Exception {
@@ -157,10 +154,10 @@ public class PsiEventsTest extends PsiTestCase {
String expected =
"beforeChildRemoval\n" +
"childRemoved\n";
- assertEquals(expected, string);
+ assertEquals(psiDirectory.getName(), expected, string);
}
- public void testRenameFile1() throws Exception {
+ public void testRenameFile() throws Exception {
FileManager fileManager = myPsiManager.getFileManager();
VirtualFile file = myPrjDir1.createChildData(null, "a.txt");
PsiFile psiFile = fileManager.findFile(file);
@@ -174,10 +171,10 @@ public class PsiEventsTest extends PsiTestCase {
String expected =
"beforePropertyChange\n" +
"propertyChanged\n";
- assertEquals(expected, string);
+ assertEquals(psiFile.getName(), expected, string);
}
- public void testRenameFile2() throws Exception {
+ public void testRenameFileChangingExtension() throws Exception {
FileManager fileManager = myPsiManager.getFileManager();
VirtualFile file = myPrjDir1.createChildData(null, "a.txt");
PsiFile psiFile = fileManager.findFile(file);
@@ -191,10 +188,10 @@ public class PsiEventsTest extends PsiTestCase {
String expected =
"beforeChildReplacement\n" +
"childReplaced\n";
- assertEquals(expected, string);
+ assertEquals(psiFile.getName(), expected, string);
}
- public void testRenameFile3() throws Exception {
+ public void testRenameFileToIgnored() throws Exception {
FileManager fileManager = myPsiManager.getFileManager();
VirtualFile file = myPrjDir1.createChildData(null, "a.txt");
PsiFile psiFile = fileManager.findFile(file);
@@ -208,11 +205,11 @@ public class PsiEventsTest extends PsiTestCase {
String expected =
"beforeChildRemoval\n" +
"childRemoved\n";
- assertEquals(expected, string);
+ assertEquals(psiFile.getName(), expected, string);
assertNull(fileManager.findFile(file));
}
- public void testRenameFile4() throws Exception {
+ public void testRenameFileFromIgnored() throws Exception {
FileManager fileManager = myPsiManager.getFileManager();
VirtualFile file = myPrjDir1.createChildData(null, "CVS");
PsiDirectory psiDirectory = fileManager.findDirectory(file.getParent());
@@ -226,10 +223,10 @@ public class PsiEventsTest extends PsiTestCase {
String expected =
"beforeChildAddition\n" +
"childAdded\n";
- assertEquals(expected, string);
+ assertEquals(psiDirectory.getName(), expected, string);
}
- public void testRenameDirectory1() throws Exception {
+ public void testRenameDirectory() throws Exception {
FileManager fileManager = myPsiManager.getFileManager();
VirtualFile file = myPrjDir1.createChildDirectory(null, "dir1");
PsiDirectory psiDirectory = fileManager.findDirectory(file);
@@ -243,10 +240,10 @@ public class PsiEventsTest extends PsiTestCase {
String expected =
"beforePropertyChange\n" +
"propertyChanged\n";
- assertEquals(expected, string);
+ assertEquals(psiDirectory.getName(), expected, string);
}
- public void testRenameDirectory2() throws Exception {
+ public void testRenameDirectoryToIgnored() throws Exception {
FileManager fileManager = myPsiManager.getFileManager();
VirtualFile file = myPrjDir1.createChildDirectory(null, "dir1");
PsiDirectory psiDirectory = fileManager.findDirectory(file);
@@ -260,11 +257,11 @@ public class PsiEventsTest extends PsiTestCase {
String expected =
"beforeChildRemoval\n" +
"childRemoved\n";
- assertEquals(expected, string);
+ assertEquals(psiDirectory.getName(), expected, string);
assertNull(fileManager.findDirectory(file));
}
- public void testRenameDirectory3() throws Exception {
+ public void testRenameDirectoryFromIgnored() throws Exception {
FileManager fileManager = myPsiManager.getFileManager();
VirtualFile file = myPrjDir1.createChildDirectory(null, "CVS");
PsiDirectory psiDirectory = fileManager.findDirectory(file.getParent());
@@ -278,7 +275,7 @@ public class PsiEventsTest extends PsiTestCase {
String expected =
"beforeChildAddition\n" +
"childAdded\n";
- assertEquals(expected, string);
+ assertEquals(psiDirectory.getName(), expected, string);
}
public void testMakeFileReadOnly() throws Exception {
@@ -291,7 +288,6 @@ public class PsiEventsTest extends PsiTestCase {
ReadOnlyAttributeUtil.setReadOnlyAttribute(file, true);
- String string = listener.getEventsString();
final String expected =
"beforePropertyChange\n" +
"propertyChanged\n";
@@ -306,7 +302,7 @@ public class PsiEventsTest extends PsiTestCase {
ReadOnlyAttributeUtil.setReadOnlyAttribute(file, false);
}
- public void testMoveFile1() throws Exception {
+ public void testMoveFile() throws Exception {
FileManager fileManager = myPsiManager.getFileManager();
VirtualFile file = myPrjDir1.createChildData(null, "a.txt");
PsiFile psiFile = fileManager.findFile(file);
@@ -320,10 +316,10 @@ public class PsiEventsTest extends PsiTestCase {
String expected =
"beforeChildMovement\n" +
"childMoved\n";
- assertEquals(expected, string);
+ assertEquals(psiFile.getName(), expected, string);
}
- public void testMoveFile2() throws Exception {
+ public void testMoveFileToIgnoredDir() throws Exception {
FileManager fileManager = myPsiManager.getFileManager();
VirtualFile file = myPrjDir1.createChildData(null, "a.txt");
PsiFile psiFile = fileManager.findFile(file);
@@ -331,19 +327,18 @@ public class PsiEventsTest extends PsiTestCase {
EventsTestListener listener = new EventsTestListener();
myPsiManager.addPsiTreeChangeListener(listener,getTestRootDisposable());
- file.move(null, myExcludedDir1);
+ file.move(null, myIgnoredDir);
String string = listener.getEventsString();
String expected =
"beforeChildRemoval\n" +
"childRemoved\n";
- assertEquals(expected, string);
+ assertEquals(psiFile.getName(), expected, string);
assertNull(fileManager.findFile(file));
}
- public void testMoveFile3() throws Exception {
- FileManager fileManager = myPsiManager.getFileManager();
- VirtualFile file = myExcludedDir1.createChildData(null, "a.txt");
+ public void testMoveFileFromIgnoredDir() throws Exception {
+ VirtualFile file = myIgnoredDir.createChildData(null, "a.txt");
EventsTestListener listener = new EventsTestListener();
myPsiManager.addPsiTreeChangeListener(listener,getTestRootDisposable());
@@ -357,10 +352,9 @@ public class PsiEventsTest extends PsiTestCase {
assertEquals(expected, string);
}
- public void testMoveFile4() throws Exception {
- FileManager fileManager = myPsiManager.getFileManager();
- VirtualFile file = myExcludedDir1.createChildData(null, "a.txt");
- VirtualFile subdir = myExcludedDir1.createChildDirectory(null, "subdir");
+ public void testMoveFileInsideIgnoredDir() throws Exception {
+ VirtualFile file = myIgnoredDir.createChildData(null, "a.txt");
+ VirtualFile subdir = myIgnoredDir.createChildDirectory(null, "subdir");
EventsTestListener listener = new EventsTestListener();
myPsiManager.addPsiTreeChangeListener(listener,getTestRootDisposable());
@@ -372,7 +366,7 @@ public class PsiEventsTest extends PsiTestCase {
assertEquals(expected, string);
}
- public void testMoveDirectory1() throws Exception {
+ public void testMoveDirectory() throws Exception {
FileManager fileManager = myPsiManager.getFileManager();
VirtualFile file = myPrjDir1.createChildDirectory(null, "dir");
PsiDirectory psiDirectory = fileManager.findDirectory(file);
@@ -386,10 +380,10 @@ public class PsiEventsTest extends PsiTestCase {
String expected =
"beforeChildMovement\n" +
"childMoved\n";
- assertEquals(expected, string);
+ assertEquals(psiDirectory.getName(), expected, string);
}
- public void testMoveDirectory2() throws Exception {
+ public void testMoveDirectoryToIgnored() throws Exception {
FileManager fileManager = myPsiManager.getFileManager();
VirtualFile file = myPrjDir1.createChildDirectory(null, "dir");
PsiDirectory psiDirectory = fileManager.findDirectory(file);
@@ -397,19 +391,18 @@ public class PsiEventsTest extends PsiTestCase {
EventsTestListener listener = new EventsTestListener();
myPsiManager.addPsiTreeChangeListener(listener,getTestRootDisposable());
- file.move(null, myExcludedDir1);
+ file.move(null, myIgnoredDir);
String string = listener.getEventsString();
String expected =
"beforeChildRemoval\n" +
"childRemoved\n";
- assertEquals(expected, string);
+ assertEquals(psiDirectory.getName(), expected, string);
assertNull(fileManager.findDirectory(file));
}
- public void testMoveDirectory3() throws Exception {
- FileManager fileManager = myPsiManager.getFileManager();
- VirtualFile file = myExcludedDir1.createChildDirectory(null, "dir");
+ public void testMoveDirectoryFromIgnored() throws Exception {
+ VirtualFile file = myIgnoredDir.createChildDirectory(null, "dir");
EventsTestListener listener = new EventsTestListener();
myPsiManager.addPsiTreeChangeListener(listener,getTestRootDisposable());
@@ -423,10 +416,9 @@ public class PsiEventsTest extends PsiTestCase {
assertEquals(expected, string);
}
- public void testMoveDirectory4() throws Exception {
- FileManager fileManager = myPsiManager.getFileManager();
- VirtualFile file = myExcludedDir1.createChildDirectory(null, "dir");
- VirtualFile subdir = myExcludedDir1.createChildDirectory(null, "subdir");
+ public void testMoveDirectoryInsideIgnored() throws Exception {
+ VirtualFile file = myIgnoredDir.createChildDirectory(null, "dir");
+ VirtualFile subdir = myIgnoredDir.createChildDirectory(null, "subdir");
EventsTestListener listener = new EventsTestListener();
myPsiManager.addPsiTreeChangeListener(listener,getTestRootDisposable());
@@ -497,7 +489,6 @@ public class PsiEventsTest extends PsiTestCase {
}
public void testModifyFileTypes() throws Exception {
- FileManager fileManager = myPsiManager.getFileManager();
EventsTestListener listener = new EventsTestListener();
myPsiManager.addPsiTreeChangeListener(listener,getTestRootDisposable());
diff --git a/java/java-tests/testSrc/com/intellij/psi/impl/file/impl/TempFileSystemTest.java b/java/java-tests/testSrc/com/intellij/psi/impl/file/impl/TempFileSystemTest.java
new file mode 100644
index 000000000000..dbdd61bc340b
--- /dev/null
+++ b/java/java-tests/testSrc/com/intellij/psi/impl/file/impl/TempFileSystemTest.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.impl.file.impl;
+
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiManager;
+import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
+
+import java.io.IOException;
+
+public class TempFileSystemTest extends LightPlatformCodeInsightFixtureTestCase {
+ public void testMove() {
+ ProjectRootManager rootManager = ProjectRootManager.getInstance(getProject());
+ VirtualFile sourceRoot = rootManager.getContentSourceRoots()[0];
+ PsiManager psiManager = PsiManager.getInstance(getProject());
+ PsiDirectory psiSourceRoot = psiManager.findDirectory(sourceRoot);
+ PsiFile psiFile = psiSourceRoot.createFile("TestDocument.xml");
+ try {
+ psiFile.getVirtualFile().move(this, psiSourceRoot.createSubdirectory("com").getVirtualFile());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ assertTrue(psiFile.isValid());
+ psiFile.delete();
+ assertFalse(psiFile.isValid());
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineMethodMultifileTest.java b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineMethodMultifileTest.java
index 9d46f072f338..ded654d4a8d3 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineMethodMultifileTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineMethodMultifileTest.java
@@ -42,6 +42,9 @@ public class InlineMethodMultifileTest extends RefactoringTestCase {
public void testRemoveStaticImports() throws Exception {
doTest("Foo", "foo");
}
+ public void testPreserveStaticImportsIfOverloaded() throws Exception {
+ doTest("Foo", "foo");
+ }
private void doTest(String className, String methodName) throws Exception {
String rootBefore = getRoot() + "/before";
diff --git a/java/java-tests/testSrc/com/intellij/roots/libraries/LibraryTest.java b/java/java-tests/testSrc/com/intellij/roots/libraries/LibraryTest.java
index e78308b4ae92..1ee498cd5d2c 100644
--- a/java/java-tests/testSrc/com/intellij/roots/libraries/LibraryTest.java
+++ b/java/java-tests/testSrc/com/intellij/roots/libraries/LibraryTest.java
@@ -1,16 +1,24 @@
package com.intellij.roots.libraries;
import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.roots.OrderRootType;
-import com.intellij.openapi.roots.RootProvider;
+import com.intellij.openapi.application.Result;
+import com.intellij.openapi.application.WriteAction;
+import com.intellij.openapi.roots.*;
import com.intellij.openapi.roots.impl.libraries.LibraryEx;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
+import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.roots.ModuleRootManagerTestCase;
+import com.intellij.testFramework.PlatformTestUtil;
+import com.intellij.testFramework.PsiTestUtil;
+import com.intellij.util.CommonProcessors;
import org.jdom.Element;
-import org.jdom.output.XMLOutputter;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+import java.util.Collections;
/**
* @author dsl
@@ -40,11 +48,6 @@ public class LibraryTest extends ModuleRootManagerTestCase {
commit(model2);
assertFalse(listenerNotifiedOnChange[0]);
- final Element element = new Element("root");
- library.writeExternal(element);
- assertEquals("<root><library name=\"library\"><CLASSES><root url=\"file://x.jar\" /></CLASSES><JAVADOC /><SOURCES><root url=\"file://x-src.jar\" /></SOURCES></library></root>",
- new XMLOutputter().outputString(element));
-
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
@@ -53,6 +56,106 @@ public class LibraryTest extends ModuleRootManagerTestCase {
});
}
+ public void testLibrarySerialization() {
+ Library library = PsiTestUtil.addProjectLibrary(myModule, "junit", Collections.singletonList(getJDomJar()),
+ Collections.singletonList(getJDomSources()));
+ Element element = serialize(library);
+ String classesUrl = getJDomJar().getUrl();
+ String sourcesUrl = getJDomSources().getUrl();
+ PlatformTestUtil.assertElementEquals(
+ "<root><library name=\"junit\"><CLASSES><root url=\"" + classesUrl + "\" /></CLASSES>" +
+ "<JAVADOC /><SOURCES><root url=\"" + sourcesUrl + "\" /></SOURCES></library></root>",
+ element);
+ }
+
+ public void testResolveDependencyToAddedLibrary() {
+ final ModifiableRootModel model = ModuleRootManager.getInstance(myModule).getModifiableModel();
+ model.addInvalidLibrary("jdom", LibraryTablesRegistrar.PROJECT_LEVEL);
+ commit(model);
+ assertEmpty(getLibraries());
+
+ Library library = createLibrary("jdom", getJDomJar(), null);
+ assertSameElements(getLibraries(), library);
+ }
+
+ public void testResolveDependencyToRenamedLibrary() {
+ Library library = createLibrary("jdom2", getJDomJar(), null);
+
+ final ModifiableRootModel model = ModuleRootManager.getInstance(myModule).getModifiableModel();
+ model.addInvalidLibrary("jdom", LibraryTablesRegistrar.PROJECT_LEVEL);
+ commit(model);
+ assertEmpty(getLibraries());
+
+ Library.ModifiableModel libModel = library.getModifiableModel();
+ libModel.setName("jdom");
+ commit(libModel);
+ assertSameElements(getLibraries(), library);
+ }
+
+ private Collection<Library> getLibraries() {
+ CommonProcessors.CollectProcessor<Library> processor = new CommonProcessors.CollectProcessor<Library>();
+ ModuleRootManager.getInstance(myModule).orderEntries().forEachLibrary(processor);
+ return processor.getResults();
+ }
+
+ private static void commit(final ModifiableRootModel model) {
+ new WriteAction() {
+ protected void run(@NotNull final Result result) {
+ model.commit();
+ }
+ }.execute();
+ }
+
+ public void testNativePathSerialization() {
+ LibraryTable table = LibraryTablesRegistrar.getInstance().getLibraryTable(myProject);
+ Library library = table.createLibrary("native");
+ Library.ModifiableModel model = library.getModifiableModel();
+ model.addRoot("file://native-lib-root", NativeLibraryOrderRootType.getInstance());
+ commit(model);
+
+ Element element = serialize(library);
+ PlatformTestUtil.assertElementEquals(
+ "<root><library name=\"native\"><CLASSES /><JAVADOC />" +
+ "<NATIVE><root url=\"file://native-lib-root\" /></NATIVE>" +
+ "<SOURCES /></library></root>",
+ element);
+ }
+
+ public void testJarDirectoriesSerialization() {
+ LibraryTable table = LibraryTablesRegistrar.getInstance().getLibraryTable(myProject);
+ Library library = table.createLibrary("jarDirs");
+ Library.ModifiableModel model = library.getModifiableModel();
+ model.addJarDirectory("file://jar-dir", false, OrderRootType.CLASSES);
+ model.addJarDirectory("file://jar-dir-src", false, OrderRootType.SOURCES);
+ commit(model);
+
+ Element element = serialize(library);
+ PlatformTestUtil.assertElementEquals("<root>\n" +
+ " <library name=\"jarDirs\">\n" +
+ " <CLASSES>\n" +
+ " <root url=\"file://jar-dir\" />\n" +
+ " </CLASSES>\n" +
+ " <JAVADOC />\n" +
+ " <SOURCES>\n" +
+ " <root url=\"file://jar-dir-src\" />\n" +
+ " </SOURCES>\n" +
+ " <jarDirectory url=\"file://jar-dir\" recursive=\"false\" />\n" +
+ " <jarDirectory url=\"file://jar-dir-src\" recursive=\"false\" type=\"SOURCES\" />\n" +
+ " </library>\n" +
+ "</root>" , element);
+ }
+
+ private static Element serialize(Library library) {
+ try {
+ Element element = new Element("root");
+ library.writeExternal(element);
+ return element;
+ }
+ catch (WriteExternalException e) {
+ throw new AssertionError(e);
+ }
+ }
+
public void testAddRemoveExcludedRoot() {
VirtualFile jar = getJDomJar();
LibraryEx library = (LibraryEx)createLibrary("junit", jar, null);
diff --git a/java/jdkAnnotations/org/jdom/annotations.xml b/java/jdkAnnotations/org/jdom/annotations.xml
index 7cd091ac0512..d22b99b867ce 100644
--- a/java/jdkAnnotations/org/jdom/annotations.xml
+++ b/java/jdkAnnotations/org/jdom/annotations.xml
@@ -30,6 +30,9 @@
<item name='org.jdom.Attribute org.jdom.Attribute setValue(java.lang.String) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
+ <item name='org.jdom.Document org.jdom.Element getRootElement()'>
+ <annotation name='org.jetbrains.annotations.NotNull'/>
+ </item>
<item name="org.jdom.Element Element(java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NonNls" />
</item>
@@ -42,6 +45,9 @@
<item name="org.jdom.Element java.util.List getChildren(java.lang.String, org.jdom.Namespace)">
<annotation name="org.jetbrains.annotations.NotNull" />
</item>
+ <item name='org.jdom.Element java.util.List&lt;org.jdom.Content&gt; getContent()'>
+ <annotation name='org.jetbrains.annotations.NotNull'/>
+ </item>
<item name='org.jdom.Element org.jdom.Element setAttribute(java.lang.String, java.lang.String) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
diff --git a/java/openapi/src/com/intellij/lang/refactoring/JavaNamesValidator.java b/java/openapi/src/com/intellij/lang/refactoring/JavaNamesValidator.java
index f00fe56a0289..0d7dc480bb9e 100644
--- a/java/openapi/src/com/intellij/lang/refactoring/JavaNamesValidator.java
+++ b/java/openapi/src/com/intellij/lang/refactoring/JavaNamesValidator.java
@@ -17,6 +17,7 @@ package com.intellij.lang.refactoring;
import com.intellij.openapi.project.Project;
import com.intellij.psi.JavaPsiFacade;
+import com.intellij.psi.PsiNameHelper;
import org.jetbrains.annotations.NotNull;
/**
@@ -25,11 +26,11 @@ import org.jetbrains.annotations.NotNull;
public class JavaNamesValidator implements NamesValidator {
@Override
public boolean isKeyword(@NotNull String name, Project project) {
- return JavaPsiFacade.getInstance(project).getNameHelper().isKeyword(name);
+ return PsiNameHelper.getInstance(project).isKeyword(name);
}
@Override
public boolean isIdentifier(@NotNull String name, Project project) {
- return JavaPsiFacade.getInstance(project).getNameHelper().isIdentifier(name);
+ return PsiNameHelper.getInstance(project).isIdentifier(name);
}
}
diff --git a/java/openapi/src/com/intellij/openapi/roots/NativeLibraryOrderRootType.java b/java/openapi/src/com/intellij/openapi/roots/NativeLibraryOrderRootType.java
new file mode 100644
index 000000000000..58dbf0441ab3
--- /dev/null
+++ b/java/openapi/src/com/intellij/openapi/roots/NativeLibraryOrderRootType.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.roots;
+
+/**
+ * @author nik
+ */
+public class NativeLibraryOrderRootType extends PersistentOrderRootType {
+ public static OrderRootType getInstance() {
+ return getOrderRootType(NativeLibraryOrderRootType.class);
+ }
+
+ public NativeLibraryOrderRootType() {
+ super("NATIVE", null, null, null);
+ }
+
+ @Override
+ public boolean skipWriteIfEmpty() {
+ return true;
+ }
+}
diff --git a/java/openapi/src/com/intellij/util/xml/converters/AbstractMemberResolveConverter.java b/java/openapi/src/com/intellij/util/xml/converters/AbstractMemberResolveConverter.java
index 230fa140d0a3..80852bacf0aa 100644
--- a/java/openapi/src/com/intellij/util/xml/converters/AbstractMemberResolveConverter.java
+++ b/java/openapi/src/com/intellij/util/xml/converters/AbstractMemberResolveConverter.java
@@ -119,7 +119,7 @@ public abstract class AbstractMemberResolveConverter extends ResolvingConverter<
public LocalQuickFix[] getQuickFixes(final ConvertContext context) {
final String targetName = ((GenericValue)context.getInvocationElement()).getStringValue();
- if (!JavaPsiFacade.getInstance(context.getProject()).getNameHelper().isIdentifier(targetName)) return super.getQuickFixes(context);
+ if (!PsiNameHelper.getInstance(context.getProject()).isIdentifier(targetName)) return super.getQuickFixes(context);
final PsiClass targetClass = getTargetClass(context);
if (targetClass == null) return super.getQuickFixes(context);
final PropertyMemberType memberType = getMemberTypes(context)[0];
diff --git a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilder.java b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilder.java
index 62e256c14c8e..dbd2734b4b5a 100644
--- a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilder.java
+++ b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilder.java
@@ -171,4 +171,9 @@ public class CloudModuleBuilder extends JavaModuleBuilder {
}
return myFrameworkSupportModel;
}
+
+ @Override
+ protected boolean isAvailable() {
+ return CloudModuleBuilderContributionFactory.EP_NAME.getExtensions().length > 0;
+ }
}
diff --git a/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java b/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java
index 6ecec97f7fe7..631738835371 100644
--- a/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java
+++ b/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java
@@ -77,6 +77,8 @@ public abstract class CodeInsightTestCase extends PsiTestCase {
Editor editor = instance.openTextEditor(new OpenFileDescriptor(myProject, file, 0), false);
((EditorImpl)editor).setCaretActive();
+ PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
+
return editor;
}
diff --git a/java/testFramework/src/com/intellij/codeInsight/daemon/DaemonAnalyzerTestCase.java b/java/testFramework/src/com/intellij/codeInsight/daemon/DaemonAnalyzerTestCase.java
index b9e5ba977a5f..7160dc96787d 100644
--- a/java/testFramework/src/com/intellij/codeInsight/daemon/DaemonAnalyzerTestCase.java
+++ b/java/testFramework/src/com/intellij/codeInsight/daemon/DaemonAnalyzerTestCase.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -77,6 +77,7 @@ import com.intellij.testFramework.LightPlatformTestCase;
import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.ui.UIUtil;
import com.intellij.xml.XmlSchemaProvider;
import gnu.trove.THashMap;
import gnu.trove.TIntArrayList;
@@ -424,6 +425,7 @@ public abstract class DaemonAnalyzerTestCase extends CodeInsightTestCase {
assertNotNull(intentionActionName, intentionAction);
assertTrue(ShowIntentionActionsHandler.chooseActionAndInvoke(file, editor, intentionAction, intentionActionName));
+ UIUtil.dispatchAllInvocationEvents();
}
protected static IntentionAction findIntentionAction(@NotNull Collection<HighlightInfo> infos, @NotNull String intentionActionName, @NotNull Editor editor,
diff --git a/java/testFramework/src/com/intellij/codeInsight/daemon/quickFix/LightQuickFixTestCase.java b/java/testFramework/src/com/intellij/codeInsight/daemon/quickFix/LightQuickFixTestCase.java
index 9bf434c3e0f5..26a52c661cf6 100644
--- a/java/testFramework/src/com/intellij/codeInsight/daemon/quickFix/LightQuickFixTestCase.java
+++ b/java/testFramework/src/com/intellij/codeInsight/daemon/quickFix/LightQuickFixTestCase.java
@@ -185,6 +185,7 @@ public abstract class LightQuickFixTestCase extends LightDaemonAnalyzerTestCase
protected static void invoke(IntentionAction action) throws IncorrectOperationException {
ShowIntentionActionsHandler.chooseActionAndInvoke(getFile(), getEditor(), action, action.getText());
+ UIUtil.dispatchAllInvocationEvents();
}
protected IntentionAction findActionWithText(final String text) {
diff --git a/java/testFramework/src/com/intellij/debugger/DebuggerTestCase.java b/java/testFramework/src/com/intellij/debugger/DebuggerTestCase.java
index 2409104c7116..2ec9ae61e17b 100644
--- a/java/testFramework/src/com/intellij/debugger/DebuggerTestCase.java
+++ b/java/testFramework/src/com/intellij/debugger/DebuggerTestCase.java
@@ -51,6 +51,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiFile;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.ui.UIUtil;
import com.intellij.xdebugger.XDebugProcess;
@@ -328,15 +329,15 @@ public abstract class DebuggerTestCase extends ExecutionWithDebuggerToolsTestCas
}
protected void createBreakpoints(final String className) {
- final PsiClass psiClass = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass>() {
+ final PsiFile psiFile = ApplicationManager.getApplication().runReadAction(new Computable<PsiFile>() {
@Override
- public PsiClass compute() {
- return JavaPsiFacade.getInstance(myProject).findClass(className, GlobalSearchScope.allScope(myProject));
+ public PsiFile compute() {
+ PsiClass psiClass = JavaPsiFacade.getInstance(myProject).findClass(className, GlobalSearchScope.allScope(myProject));
+ return psiClass.getContainingFile();
}
});
- createBreakpoints(psiClass.getContainingFile());
-
+ createBreakpoints(psiFile);
}
protected EvaluationContextImpl createEvaluationContext(final SuspendContextImpl suspendContext) {
diff --git a/java/testFramework/src/com/intellij/testFramework/CompilerTester.java b/java/testFramework/src/com/intellij/testFramework/CompilerTester.java
index 00780b9b76ce..a3c05c6ec3fd 100644
--- a/java/testFramework/src/com/intellij/testFramework/CompilerTester.java
+++ b/java/testFramework/src/com/intellij/testFramework/CompilerTester.java
@@ -232,7 +232,7 @@ public class CompilerTester {
CompilerMessage[] messages = compileContext.getMessages(category);
for (CompilerMessage message : messages) {
final String text = message.getMessage();
- if (category != CompilerMessageCategory.INFORMATION || !(text.startsWith("Compilation completed successfully") || text.startsWith("Using javac"))) {
+ if (category != CompilerMessageCategory.INFORMATION || !(text.contains("Compilation completed successfully") || text.startsWith("Using javac"))) {
myMessages.add(message);
}
}
diff --git a/java/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ConvertFieldToAtomicIntention.java b/java/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ConvertFieldToAtomicIntention.java
index e983453a11c6..430f2182e516 100644
--- a/java/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ConvertFieldToAtomicIntention.java
+++ b/java/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ConvertFieldToAtomicIntention.java
@@ -19,6 +19,7 @@ import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.refactoring.typeMigration.TypeConversionDescriptor;
import com.intellij.refactoring.typeMigration.TypeMigrationReplacementUtil;
import com.intellij.refactoring.typeMigration.rules.AtomicConversionRule;
+import com.intellij.refactoring.util.RefactoringUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.Query;
import com.intellij.util.containers.ContainerUtil;
@@ -180,9 +181,14 @@ public class ConvertFieldToAtomicIntention extends PsiElementBaseIntentionAction
}
}
- final PsiExpression initializer = psiVariable.getInitializer();
+ PsiExpression initializer = psiVariable.getInitializer();
if (initializer != null) {
- final TypeConversionDescriptor directConversion = AtomicConversionRule.wrapWithNewExpression(toType, fromType, null, element);
+ if (initializer instanceof PsiArrayInitializerExpression) {
+ PsiExpression normalizedExpr =
+ RefactoringUtil.createNewExpressionFromArrayInitializer((PsiArrayInitializerExpression)initializer, psiVariable.getType());
+ initializer = (PsiExpression)initializer.replace(normalizedExpr);
+ }
+ final TypeConversionDescriptor directConversion = AtomicConversionRule.wrapWithNewExpression(toType, fromType, initializer, element);
if (directConversion != null) {
TypeMigrationReplacementUtil.replaceExpression(initializer, project, directConversion);
}
diff --git a/java/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ConvertFieldToThreadLocalIntention.java b/java/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ConvertFieldToThreadLocalIntention.java
index 38ff0ef466ae..8bdce8435be8 100644
--- a/java/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ConvertFieldToThreadLocalIntention.java
+++ b/java/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ConvertFieldToThreadLocalIntention.java
@@ -25,6 +25,7 @@ import com.intellij.refactoring.typeMigration.TypeMigrationLabeler;
import com.intellij.refactoring.typeMigration.TypeMigrationReplacementUtil;
import com.intellij.refactoring.typeMigration.TypeMigrationRules;
import com.intellij.refactoring.typeMigration.rules.ThreadLocalConversionRule;
+import com.intellij.refactoring.util.RefactoringUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.Query;
import com.intellij.util.containers.ContainerUtil;
@@ -116,8 +117,13 @@ public class ConvertFieldToThreadLocalIntention extends PsiElementBaseIntentionA
}
}
- final PsiExpression initializer = psiField.getInitializer();
+ PsiExpression initializer = psiField.getInitializer();
if (initializer != null) {
+ if (initializer instanceof PsiArrayInitializerExpression) {
+ PsiExpression normalizedExpr =
+ RefactoringUtil.createNewExpressionFromArrayInitializer((PsiArrayInitializerExpression)initializer, psiField.getType());
+ initializer = (PsiExpression)initializer.replace(normalizedExpr);
+ }
final TypeConversionDescriptor conversion = ThreadLocalConversionRule.wrapWithNewExpression(toType, fromType, initializer);
TypeMigrationReplacementUtil.replaceExpression(initializer, project, conversion);
CodeStyleManager.getInstance(project).reformat(psiField);
diff --git a/java/typeMigration/test/com/intellij/refactoring/TypeMigrationTest.java b/java/typeMigration/test/com/intellij/refactoring/TypeMigrationTest.java
index b3c36dca19f2..7cf1de7b16bc 100644
--- a/java/typeMigration/test/com/intellij/refactoring/TypeMigrationTest.java
+++ b/java/typeMigration/test/com/intellij/refactoring/TypeMigrationTest.java
@@ -28,6 +28,13 @@ public class TypeMigrationTest extends TypeMigrationTestBase {
myFactory = myJavaFacade.getElementFactory();
}
+ @Override
+ public void tearDown() throws Exception {
+ myFactory = null;
+
+ super.tearDown();
+ }
+
public void testT07() {
doTestFieldType("f",
PsiType.INT.createArrayType(),
diff --git a/java/typeMigration/testData/intentions/atomic/afterArrayInitializer.java b/java/typeMigration/testData/intentions/atomic/afterArrayInitializer.java
new file mode 100644
index 000000000000..f2b51fa36440
--- /dev/null
+++ b/java/typeMigration/testData/intentions/atomic/afterArrayInitializer.java
@@ -0,0 +1,6 @@
+import java.util.concurrent.atomic.AtomicReferenceArray;
+
+// "Convert to atomic" "true"
+class Test {
+ final AtomicReferenceArray<String> field= new AtomicReferenceArray<>(new String[]{});
+} \ No newline at end of file
diff --git a/java/typeMigration/testData/intentions/atomic/beforeArrayInitializer.java b/java/typeMigration/testData/intentions/atomic/beforeArrayInitializer.java
new file mode 100644
index 000000000000..6ef272b130e7
--- /dev/null
+++ b/java/typeMigration/testData/intentions/atomic/beforeArrayInitializer.java
@@ -0,0 +1,4 @@
+// "Convert to atomic" "true"
+class Test {
+ String[] <caret>field={};
+} \ No newline at end of file
diff --git a/java/typeMigration/testData/intentions/threadLocal/afterArrayInitializer.java b/java/typeMigration/testData/intentions/threadLocal/afterArrayInitializer.java
new file mode 100644
index 000000000000..59323f18e0e5
--- /dev/null
+++ b/java/typeMigration/testData/intentions/threadLocal/afterArrayInitializer.java
@@ -0,0 +1,9 @@
+// "Convert to ThreadLocal" "true"
+class Test {
+ final ThreadLocal<String[]> field = new ThreadLocal<String[]>() {
+ @Override
+ protected String[] initialValue() {
+ return new String[]{};
+ }
+ };
+} \ No newline at end of file
diff --git a/java/typeMigration/testData/intentions/threadLocal/beforeArrayInitializer.java b/java/typeMigration/testData/intentions/threadLocal/beforeArrayInitializer.java
new file mode 100644
index 000000000000..c2564a9cf266
--- /dev/null
+++ b/java/typeMigration/testData/intentions/threadLocal/beforeArrayInitializer.java
@@ -0,0 +1,4 @@
+// "Convert to ThreadLocal" "true"
+class Test {
+ String[] <caret>field={};
+} \ No newline at end of file
diff --git a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildMain.java b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildMain.java
index c6b34ab97bed..8634769222a0 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildMain.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildMain.java
@@ -74,7 +74,29 @@ public class BuildMain {
final File systemDir = new File(FileUtil.toCanonicalPath(args[SYSTEM_DIR_ARG]));
Utils.setSystemRoot(systemDir);
- ourEventLoopGroup = new NioEventLoopGroup(1, SharedThreadPool.getInstance());
+ // IDEA-123132, let's try again
+ for (int attempt = 0; attempt < 3; attempt++) {
+ try {
+ ourEventLoopGroup = new NioEventLoopGroup(1, SharedThreadPool.getInstance());
+ break;
+ }
+ catch (IllegalStateException e) {
+ if (attempt == 2) {
+ printErrorAndExit(host, port, e);
+ return;
+ }
+ else {
+ LOG.warn("Cannot create event loop, attempt #" + attempt, e);
+ try {
+ //noinspection BusyWait
+ Thread.sleep(10 * (attempt + 1));
+ }
+ catch (InterruptedException ignored) {
+ }
+ }
+ }
+ }
+
final Bootstrap bootstrap = new Bootstrap().group(ourEventLoopGroup).channel(NioSocketChannel.class).handler(new ChannelInitializer() {
@Override
protected void initChannel(Channel channel) throws Exception {
@@ -92,15 +114,17 @@ public class BuildMain {
future.channel().writeAndFlush(CmdlineProtoUtil.toMessage(sessionId, CmdlineProtoUtil.createParamRequest()));
}
else {
- @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
- final Throwable reason = future.cause();
- System.err.println("Error connecting to " + host + ":" + port + "; reason: " + (reason != null? reason.getMessage() : "unknown"));
- if (reason != null) {
- reason.printStackTrace(System.err);
- }
- System.err.println("Exiting.");
- System.exit(-1);
+ printErrorAndExit(host, port, future.cause());
+ }
+ }
+
+ private static void printErrorAndExit(String host, int port, Throwable reason) {
+ System.err.println("Error connecting to " + host + ":" + port + "; reason: " + (reason != null ? reason.getMessage() : "unknown"));
+ if (reason != null) {
+ reason.printStackTrace(System.err);
}
+ System.err.println("Exiting.");
+ System.exit(-1);
}
private static class MyMessageHandler extends SimpleChannelInboundHandler<CmdlineRemoteProto.Message> {
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/FSOperations.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/FSOperations.java
index 63e538022160..d52e1e6a0132 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/FSOperations.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/FSOperations.java
@@ -151,7 +151,7 @@ public class FSOperations {
}
}
- public static void processFilesToRecompile(CompileContext context, ModuleBuildTarget target, FileProcessor<JavaSourceRootDescriptor, ModuleBuildTarget> processor) throws IOException {
+ public static void processFilesToRecompile(CompileContext context, @NotNull ModuleBuildTarget target, FileProcessor<JavaSourceRootDescriptor, ModuleBuildTarget> processor) throws IOException {
context.getProjectDescriptor().fsState.processFilesToRecompile(context, target, processor);
}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/fs/BuildFSState.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/fs/BuildFSState.java
index e92c0d59a3b0..bb28c422044b 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/fs/BuildFSState.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/fs/BuildFSState.java
@@ -145,13 +145,17 @@ public class BuildFSState extends FSState {
setRoundDelta(CURRENT_ROUND_DELTA_KEY, context, new FilesDelta());
}
- public <R extends BuildRootDescriptor, T extends BuildTarget<R>> boolean processFilesToRecompile(CompileContext context, final T target, final FileProcessor<R, T> processor) throws IOException {
+ public <R extends BuildRootDescriptor, T extends BuildTarget<R>> boolean processFilesToRecompile(CompileContext context, final @NotNull T target, final FileProcessor<R, T> processor) throws IOException {
final Map<BuildRootDescriptor, Set<File>> data = getSourcesToRecompile(context, target);
final CompileScope scope = context.getScope();
synchronized (data) {
for (Map.Entry<BuildRootDescriptor, Set<File>> entry : data.entrySet()) {
//noinspection unchecked
R root = (R)entry.getKey();
+ if (!target.equals(root.getTarget())) {
+ // the data can contain roots from other targets (e.g. when compiling module cycles)
+ continue;
+ }
for (File file : entry.getValue()) {
if (!scope.isAffected(target, file)) {
continue;
diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/JpsNativeLibraryRootType.java b/jps/model-api/src/org/jetbrains/jps/model/java/JpsNativeLibraryRootType.java
new file mode 100644
index 000000000000..ae2e87b966f1
--- /dev/null
+++ b/jps/model-api/src/org/jetbrains/jps/model/java/JpsNativeLibraryRootType.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.jps.model.java;
+
+import org.jetbrains.jps.model.library.JpsOrderRootType;
+
+/**
+ * @author nik
+ */
+public class JpsNativeLibraryRootType extends JpsOrderRootType {
+ public static final JpsNativeLibraryRootType INSTANCE = new JpsNativeLibraryRootType();
+
+ private JpsNativeLibraryRootType() {
+ }
+}
diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/JpsJavaModelSerializerExtension.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/JpsJavaModelSerializerExtension.java
index 0dfead17644f..22188be46e2d 100644
--- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/JpsJavaModelSerializerExtension.java
+++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/JpsJavaModelSerializerExtension.java
@@ -126,7 +126,8 @@ public class JpsJavaModelSerializerExtension extends JpsModelSerializerExtension
@Override
public List<JpsLibraryRootTypeSerializer> getLibraryRootTypeSerializers() {
return Arrays.asList(new JpsLibraryRootTypeSerializer("JAVADOC", JpsOrderRootType.DOCUMENTATION, true),
- new JpsLibraryRootTypeSerializer("ANNOTATIONS", JpsAnnotationRootType.INSTANCE, false));
+ new JpsLibraryRootTypeSerializer("ANNOTATIONS", JpsAnnotationRootType.INSTANCE, false),
+ new JpsLibraryRootTypeSerializer("NATIVE", JpsNativeLibraryRootType.INSTANCE, false));
}
@NotNull
diff --git a/lib/netty-all-4.1.0.Beta1.jar b/lib/netty-all-4.1.0.Beta3.jar
index cbd8b2cb6d33..fd2f6ba0e6c5 100644
--- a/lib/netty-all-4.1.0.Beta1.jar
+++ b/lib/netty-all-4.1.0.Beta3.jar
Binary files differ
diff --git a/lib/required_for_dist.txt b/lib/required_for_dist.txt
index 6ea1f4d542ec..094e94784836 100644
--- a/lib/required_for_dist.txt
+++ b/lib/required_for_dist.txt
@@ -48,7 +48,7 @@ microba.jar
miglayout-swing.jar
nanoxml-2.2.3.jar
nekohtml-1.9.14.jar
-netty-all-4.1.0.Beta1.jar
+netty-all-4.1.0.Beta3.jar
oromatcher.jar
picocontainer.jar
protobuf-2.5.0.jar
diff --git a/lib/src/netty-all-4.1.0.Beta1-sources.jar b/lib/src/netty-all-4.1.0.Beta3-sources.jar
index 48e83c77330f..80f203cec58a 100644
--- a/lib/src/netty-all-4.1.0.Beta1-sources.jar
+++ b/lib/src/netty-all-4.1.0.Beta3-sources.jar
Binary files differ
diff --git a/platform/analysis-api/src/com/intellij/analysis/AnalysisScope.java b/platform/analysis-api/src/com/intellij/analysis/AnalysisScope.java
index 893a7f3d30da..f7c4ca1bf274 100644
--- a/platform/analysis-api/src/com/intellij/analysis/AnalysisScope.java
+++ b/platform/analysis-api/src/com/intellij/analysis/AnalysisScope.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -80,8 +80,8 @@ public class AnalysisScope {
private boolean mySearchInLibraries = false;
@Type protected int myType;
- private Set<VirtualFile> myVFiles;
- protected Set<VirtualFile> myFilesSet;
+ private final Set<VirtualFile> myVFiles; // initial files and directories the scope is configured on
+ protected Set<VirtualFile> myFilesSet; // set of files (not directories) this scope consists of. calculated in initFilesSet()
protected boolean myIncludeTestSource = true;
@@ -92,6 +92,7 @@ public class AnalysisScope {
myModule = null;
myScope = null;
myType = PROJECT;
+ myVFiles = null;
}
public AnalysisScope(@NotNull Module module) {
@@ -101,6 +102,7 @@ public class AnalysisScope {
myScope = null;
myModule = module;
myType = MODULE;
+ myVFiles = null;
}
public AnalysisScope(@NotNull Module[] modules) {
@@ -110,6 +112,7 @@ public class AnalysisScope {
myElement = null;
myScope = null;
myType = MODULES;
+ myVFiles = null;
}
public AnalysisScope(@NotNull PsiDirectory psiDirectory) {
@@ -119,6 +122,7 @@ public class AnalysisScope {
myScope = null;
myElement = psiDirectory;
myType = DIRECTORY;
+ myVFiles = null;
}
public AnalysisScope(@NotNull PsiFile psiFile) {
@@ -128,6 +132,7 @@ public class AnalysisScope {
myModules = null;
myScope = null;
myType = FILE;
+ myVFiles = null;
}
public AnalysisScope(@NotNull SearchScope scope, @NotNull Project project) {
@@ -138,6 +143,7 @@ public class AnalysisScope {
myScope = scope;
myType = CUSTOM;
mySearchInLibraries = scope instanceof GlobalSearchScope && ((GlobalSearchScope)scope).isSearchInLibraries();
+ myVFiles = null;
}
public AnalysisScope(@NotNull Project project, @NotNull Collection<VirtualFile> virtualFiles) {
@@ -212,10 +218,11 @@ public class AnalysisScope {
}
public boolean contains(@NotNull PsiElement psiElement) {
- return contains(psiElement.getContainingFile().getVirtualFile());
+ VirtualFile file = psiElement.getContainingFile().getVirtualFile();
+ return file != null && contains(file);
}
- public boolean contains(VirtualFile file) {
+ public boolean contains(@NotNull VirtualFile file) {
if (myFilesSet == null) {
if (myType == CUSTOM) {
// optimization
@@ -289,6 +296,7 @@ public class AnalysisScope {
@Override
public Boolean compute() {
if (!myIncludeTestSource && projectFileIndex.isInTestSourceContent(fileOrDir)) return false;
+ if (isInGeneratedSources(fileOrDir, myProject)) return false;
return ((GlobalSearchScope)myScope).contains(fileOrDir);
}
}).booleanValue();
@@ -424,7 +432,7 @@ public class AnalysisScope {
return indicator == null || !indicator.isCanceled();
}
- protected static boolean shouldHighlightFile(PsiFile file) {
+ protected static boolean shouldHighlightFile(@NotNull PsiFile file) {
return ProblemHighlightFilter.shouldProcessFileInBatch(file);
}
@@ -451,11 +459,14 @@ public class AnalysisScope {
final Project project = dir.getProject();
final PsiManager psiManager = PsiManager.getInstance(project);
final ProjectFileIndex index = ProjectRootManager.getInstance(project).getFileIndex();
+ //we should analyze generated source files only if the action is explicitly invoked for a directory located under generated roots
+ final boolean processGeneratedFiles = isInGeneratedSources(dir.getVirtualFile(), project);
VfsUtilCore.iterateChildrenRecursively(dir.getVirtualFile(), VirtualFileFilter.ALL, new ContentIterator() {
@Override
@SuppressWarnings({"SimplifiableIfStatement"})
public boolean processFile(@NotNull final VirtualFile fileOrDir) {
if (!myIncludeTestSource && index.isInTestSourceContent(fileOrDir)) return true;
+ if (!processGeneratedFiles && isInGeneratedSources(fileOrDir, project)) return true;
if (!fileOrDir.isDirectory()) {
return AnalysisScope.processFile(fileOrDir, visitor, psiManager, needReadAction);
}
@@ -481,6 +492,7 @@ public class AnalysisScope {
return myType;
}
+ @NotNull
public String getDisplayName() {
switch (myType) {
case CUSTOM:
@@ -515,12 +527,14 @@ public class AnalysisScope {
return "";
}
+ @NotNull
private static String getPresentableUrl(@NotNull final PsiFileSystemItem element) {
final VirtualFile virtualFile = element.getVirtualFile();
assert virtualFile != null : element;
return virtualFile.getPresentableUrl();
}
+ @NotNull
public String getShortenName(){
switch (myType) {
case CUSTOM:
@@ -589,9 +603,7 @@ public class AnalysisScope {
}
public void invalidate(){
- if (myType != VIRTUAL_FILES) {
- myFilesSet = null;
- } else {
+ if (myType == VIRTUAL_FILES) {
for (Iterator<VirtualFile> i = myVFiles.iterator(); i.hasNext();) {
final VirtualFile virtualFile = i.next();
if (virtualFile == null || !virtualFile.isValid()) {
@@ -599,6 +611,9 @@ public class AnalysisScope {
}
}
}
+ else {
+ myFilesSet = null;
+ }
}
public boolean containsSources(boolean isTest) {
diff --git a/platform/analysis-api/src/com/intellij/codeInsight/intention/IntentionManager.java b/platform/analysis-api/src/com/intellij/codeInsight/intention/IntentionManager.java
index aeb671df1e84..8aea24650b22 100644
--- a/platform/analysis-api/src/com/intellij/codeInsight/intention/IntentionManager.java
+++ b/platform/analysis-api/src/com/intellij/codeInsight/intention/IntentionManager.java
@@ -17,6 +17,7 @@ package com.intellij.codeInsight.intention;
import com.intellij.codeInsight.daemon.HighlightDisplayKey;
import com.intellij.codeInspection.LocalQuickFix;
+import com.intellij.codeInspection.ex.InspectionToolWrapper;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.project.Project;
@@ -24,6 +25,7 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.UserDataHolder;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.util.List;
@@ -126,6 +128,12 @@ public abstract class IntentionManager {
public abstract List<IntentionAction> getStandardIntentionOptions(@NotNull HighlightDisplayKey displayKey, @NotNull PsiElement context);
/**
+ * @return "Fix all '' inspections problems for a file" intention if toolWrapper is local inspection or simple global one
+ */
+ @Nullable
+ public abstract IntentionAction createFixAllIntention(InspectionToolWrapper toolWrapper, IntentionAction action);
+
+ /**
* Wraps given action in a LocalQuickFix object.
* @param action action to convert.
* @return quick fix instance.
diff --git a/platform/analysis-api/src/com/intellij/codeInspection/InspectionProfileEntry.java b/platform/analysis-api/src/com/intellij/codeInspection/InspectionProfileEntry.java
index 43d80faad886..450b4c2a4418 100644
--- a/platform/analysis-api/src/com/intellij/codeInspection/InspectionProfileEntry.java
+++ b/platform/analysis-api/src/com/intellij/codeInspection/InspectionProfileEntry.java
@@ -71,7 +71,7 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{
public boolean isSuppressedFor(@NotNull PsiElement element) {
Set<InspectionSuppressor> suppressors = getSuppressors(element);
for (InspectionSuppressor suppressor : suppressors) {
- if (suppressor != null && isSuppressed(suppressor, element)) {
+ if (isSuppressed(suppressor, element)) {
return true;
}
}
@@ -99,10 +99,8 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{
});
Set<InspectionSuppressor> suppressors = getSuppressors(element);
for (InspectionSuppressor suppressor : suppressors) {
- if (suppressor != null) {
- SuppressQuickFix[] actions = suppressor.getSuppressActions(element, getShortName());
- fixes.addAll(Arrays.asList(actions));
- }
+ SuppressQuickFix[] actions = suppressor.getSuppressActions(element, getShortName());
+ fixes.addAll(Arrays.asList(actions));
}
return fixes.toArray(new SuppressQuickFix[fixes.size()]);
}
@@ -121,16 +119,17 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{
public static Set<InspectionSuppressor> getSuppressors(@NotNull PsiElement element) {
FileViewProvider viewProvider = element.getContainingFile().getViewProvider();
+ final InspectionSuppressor elementLanguageSuppressor = LanguageInspectionSuppressors.INSTANCE.forLanguage(element.getLanguage());
if (viewProvider instanceof TemplateLanguageFileViewProvider) {
LinkedHashSet<InspectionSuppressor> suppressors = new LinkedHashSet<InspectionSuppressor>();
ContainerUtil.addIfNotNull(suppressors, LanguageInspectionSuppressors.INSTANCE.forLanguage(viewProvider.getBaseLanguage()));
for (Language language : viewProvider.getLanguages()) {
ContainerUtil.addIfNotNull(suppressors, LanguageInspectionSuppressors.INSTANCE.forLanguage(language));
}
- ContainerUtil.addIfNotNull(suppressors, LanguageInspectionSuppressors.INSTANCE.forLanguage(element.getLanguage()));
+ ContainerUtil.addIfNotNull(suppressors, elementLanguageSuppressor);
return suppressors;
}
- return Collections.singleton(LanguageInspectionSuppressors.INSTANCE.forLanguage(element.getLanguage()));
+ return elementLanguageSuppressor != null ? Collections.singleton(elementLanguageSuppressor) : Collections.<InspectionSuppressor>emptySet();
}
public void cleanup(Project project) {
diff --git a/platform/analysis-api/src/com/intellij/profile/ProfileChangeAdapter.java b/platform/analysis-api/src/com/intellij/profile/ProfileChangeAdapter.java
index 7e77e3de44ac..514c18766d40 100644
--- a/platform/analysis-api/src/com/intellij/profile/ProfileChangeAdapter.java
+++ b/platform/analysis-api/src/com/intellij/profile/ProfileChangeAdapter.java
@@ -23,7 +23,7 @@ import org.jetbrains.annotations.NotNull;
*/
public abstract class ProfileChangeAdapter {
public void profileChanged(Profile profile){}
- public void profileActivated(@NotNull Profile oldProfile, Profile profile){}
+ public void profileActivated(Profile oldProfile, Profile profile){}
public void profilesInitialized() {}
public void profilesShutdown(){}
}
diff --git a/platform/analysis-api/src/com/intellij/psi/search/scope/packageSet/FilePatternPackageSet.java b/platform/analysis-api/src/com/intellij/psi/search/scope/packageSet/FilePatternPackageSet.java
index 7f01ead5359f..4fed9ea06538 100644
--- a/platform/analysis-api/src/com/intellij/psi/search/scope/packageSet/FilePatternPackageSet.java
+++ b/platform/analysis-api/src/com/intellij/psi/search/scope/packageSet/FilePatternPackageSet.java
@@ -79,11 +79,14 @@ public class FilePatternPackageSet extends PatternBasedPackageSet {
matchesModule(myModuleGroupPattern, myModulePattern, file, fileIndex);
}
- private boolean fileMatcher(VirtualFile virtualFile, ProjectFileIndex fileIndex, VirtualFile projectBaseDir){
+ private boolean fileMatcher(@NotNull VirtualFile virtualFile, ProjectFileIndex fileIndex, VirtualFile projectBaseDir){
final String relativePath = getRelativePath(virtualFile, fileIndex, true, projectBaseDir);
if (relativePath == null) {
LOG.error("vFile: " + virtualFile + "; projectBaseDir: " + projectBaseDir + "; content File: "+fileIndex.getContentRootForFile(virtualFile));
}
+ if (StringUtil.isEmptyOrSpaces(relativePath) && !virtualFile.equals(projectBaseDir)) {
+ return false;
+ }
return myFilePattern.matcher(relativePath).matches();
}
diff --git a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java
index 483f3c5b2839..88f230f8f2d3 100644
--- a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java
+++ b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java
@@ -21,11 +21,9 @@ import com.intellij.codeInsight.daemon.HighlightDisplayKey;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInsight.intention.IntentionManager;
import com.intellij.codeInspection.*;
-import com.intellij.codeInspection.actions.CleanupInspectionIntention;
import com.intellij.codeInspection.ex.GlobalInspectionToolWrapper;
import com.intellij.codeInspection.ex.InspectionToolWrapper;
import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;
-import com.intellij.codeInspection.ex.QuickFixWrapper;
import com.intellij.lang.ASTNode;
import com.intellij.lang.annotation.Annotation;
import com.intellij.lang.annotation.HighlightSeverity;
@@ -114,8 +112,7 @@ public class HighlightInfo implements Segment {
String description = this.description;
if (toolTip == null || description == null || !toolTip.contains(DESCRIPTION_PLACEHOLDER)) return toolTip;
String decoded = StringUtil.replace(toolTip, DESCRIPTION_PLACEHOLDER, XmlStringUtil.escapeString(description));
- String niceTooltip = XmlStringUtil.wrapInHtml(decoded);
- return niceTooltip;
+ return XmlStringUtil.wrapInHtml(decoded);
}
private static String encodeTooltip(String toolTip, String description) {
@@ -177,10 +174,7 @@ public class HighlightInfo implements Segment {
return forcedTextAttributes;
}
- final EditorColorsScheme colorsScheme = getColorsScheme(editorColorsScheme);
- if (colorsScheme == null) {
- return null;
- }
+ EditorColorsScheme colorsScheme = getColorsScheme(editorColorsScheme);
if (forcedTextAttributesKey != null) {
return colorsScheme.getAttributes(forcedTextAttributesKey);
@@ -208,10 +202,7 @@ public class HighlightInfo implements Segment {
if (forcedTextAttributes != null && forcedTextAttributes.getErrorStripeColor() != null) {
return forcedTextAttributes.getErrorStripeColor();
}
- final EditorColorsScheme scheme = getColorsScheme(colorsScheme);
- if (scheme == null) {
- return null;
- }
+ EditorColorsScheme scheme = getColorsScheme(colorsScheme);
if (forcedTextAttributesKey != null) {
TextAttributes forcedTextAttributes = scheme.getAttributes(forcedTextAttributesKey);
if (forcedTextAttributes != null) {
@@ -244,7 +235,7 @@ public class HighlightInfo implements Segment {
}
- @Nullable
+ @NotNull
private static EditorColorsScheme getColorsScheme(@Nullable final EditorColorsScheme customScheme) {
if (customScheme != null) {
return customScheme;
@@ -325,6 +316,7 @@ public class HighlightInfo implements Segment {
return true;
}
+ @Override
public boolean equals(Object obj) {
if (obj == this) return true;
if (!(obj instanceof HighlightInfo)) return false;
@@ -340,7 +332,7 @@ public class HighlightInfo implements Segment {
Comparing.strEqual(info.getDescription(), getDescription());
}
- public boolean equalsByActualOffset(HighlightInfo info) {
+ public boolean equalsByActualOffset(@NotNull HighlightInfo info) {
if (info == this) return true;
return info.getSeverity() == getSeverity() &&
@@ -353,10 +345,12 @@ public class HighlightInfo implements Segment {
Comparing.strEqual(info.getDescription(), getDescription());
}
+ @Override
public int hashCode() {
return startOffset;
}
+ @Override
@NonNls
public String toString() {
return getDescription() != null ? getDescription() : "";
@@ -658,7 +652,7 @@ public class HighlightInfo implements Segment {
public static final String ANNOTATOR_INSPECTION_SHORT_NAME = "Annotator";
- private static void appendFixes(@Nullable TextRange fixedRange, @NotNull HighlightInfo info, List<Annotation.QuickFixInfo> fixes) {
+ private static void appendFixes(@Nullable TextRange fixedRange, @NotNull HighlightInfo info, @Nullable List<Annotation.QuickFixInfo> fixes) {
if (fixes != null) {
for (final Annotation.QuickFixInfo quickFixInfo : fixes) {
TextRange range = fixedRange != null ? fixedRange : quickFixInfo.textRange;
@@ -670,6 +664,7 @@ public class HighlightInfo implements Segment {
}
}
+ @NotNull
public static HighlightInfoType convertType(@NotNull Annotation annotation) {
ProblemHighlightType type = annotation.getHighlightType();
if (type == ProblemHighlightType.LIKE_UNUSED_SYMBOL) return HighlightInfoType.UNUSED_SYMBOL;
@@ -688,6 +683,7 @@ public class HighlightInfo implements Segment {
HighlightInfoType.INFORMATION;
}
+ @NotNull
public static ProblemHighlightType convertType(HighlightInfoType infoType) {
if (infoType == HighlightInfoType.ERROR || infoType == HighlightInfoType.WRONG_REF) return ProblemHighlightType.ERROR;
if (infoType == HighlightInfoType.WARNING) return ProblemHighlightType.GENERIC_ERROR_OR_WARNING;
@@ -695,6 +691,7 @@ public class HighlightInfo implements Segment {
return ProblemHighlightType.WEAK_WARNING;
}
+ @NotNull
public static ProblemHighlightType convertSeverityToProblemHighlight(HighlightSeverity severity) {
return severity == HighlightSeverity.ERROR ? ProblemHighlightType.ERROR :
severity == HighlightSeverity.WARNING ? ProblemHighlightType.GENERIC_ERROR_OR_WARNING :
@@ -763,7 +760,7 @@ public class HighlightInfo implements Segment {
return myAction;
}
- public boolean canCleanup(PsiElement element) {
+ public boolean canCleanup(@NotNull PsiElement element) {
if (myCanCleanup == null) {
InspectionProfile profile = InspectionProjectProfileManager.getInstance(element.getProject()).getInspectionProfile();
final HighlightDisplayKey key = myKey;
@@ -794,7 +791,8 @@ public class HighlightInfo implements Segment {
if (options != null || key == null) {
return options;
}
- List<IntentionAction> newOptions = IntentionManager.getInstance().getStandardIntentionOptions(key, element);
+ IntentionManager intentionManager = IntentionManager.getInstance();
+ List<IntentionAction> newOptions = intentionManager.getStandardIntentionOptions(key, element);
InspectionProfile profile = InspectionProjectProfileManager.getInstance(element.getProject()).getInspectionProfile();
InspectionToolWrapper toolWrapper = profile.getInspectionTool(key.toString(), element);
if (!(toolWrapper instanceof LocalInspectionToolWrapper)) {
@@ -807,29 +805,9 @@ public class HighlightInfo implements Segment {
myCanCleanup = toolWrapper.isCleanupTool();
- InspectionProfileEntry wrappedTool;
- if (toolWrapper instanceof LocalInspectionToolWrapper) {
- wrappedTool = ((LocalInspectionToolWrapper)toolWrapper).getTool();
- Class aClass = myAction.getClass();
- if (myAction instanceof QuickFixWrapper) {
- aClass = ((QuickFixWrapper)myAction).getFix().getClass();
- }
- newOptions.add(new CleanupInspectionIntention(toolWrapper, aClass));
- }
- else if (toolWrapper instanceof GlobalInspectionToolWrapper) {
- wrappedTool = ((GlobalInspectionToolWrapper)toolWrapper).getTool();
- if (wrappedTool instanceof GlobalSimpleInspectionTool && (myAction instanceof LocalQuickFix || myAction instanceof QuickFixWrapper)) {
- Class aClass = myAction.getClass();
- if (myAction instanceof QuickFixWrapper) {
- aClass = ((QuickFixWrapper)myAction).getFix().getClass();
- }
- newOptions.add(new CleanupInspectionIntention(toolWrapper, aClass));
- }
- }
- else {
- throw new AssertionError("unknown tool: " + toolWrapper+"; key: "+myKey);
- }
-
+ ContainerUtil.addIfNotNull(newOptions, intentionManager.createFixAllIntention(toolWrapper, myAction));
+ InspectionProfileEntry wrappedTool = toolWrapper instanceof LocalInspectionToolWrapper ? ((LocalInspectionToolWrapper)toolWrapper).getTool()
+ : ((GlobalInspectionToolWrapper)toolWrapper).getTool();
if (wrappedTool instanceof CustomSuppressableInspectionTool) {
final IntentionAction[] suppressActions = ((CustomSuppressableInspectionTool)wrappedTool).getSuppressActions(element);
if (suppressActions != null) {
@@ -868,6 +846,7 @@ public class HighlightInfo implements Segment {
return myDisplayName;
}
+ @Override
@NonNls
public String toString() {
String text = getAction().getText();
diff --git a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfoType.java b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfoType.java
index 90116ea84f5b..d1615b93bce6 100644
--- a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfoType.java
+++ b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfoType.java
@@ -131,6 +131,7 @@ public interface HighlightInfoType {
return myAttributesKey;
}
+ @Override
@SuppressWarnings({"HardCodedStringLiteral"})
public String toString() {
return "HighlightInfoTypeImpl[severity=" + mySeverity + ", key=" + myAttributesKey + "]";
@@ -141,6 +142,7 @@ public interface HighlightInfoType {
myAttributesKey.writeExternal(element);
}
+ @Override
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
@@ -153,6 +155,7 @@ public interface HighlightInfoType {
return true;
}
+ @Override
public int hashCode() {
int result = mySeverity.hashCode();
result = 29 * result + myAttributesKey.hashCode();
@@ -187,6 +190,7 @@ public interface HighlightInfoType {
return myAttributesKey;
}
+ @Override
@SuppressWarnings({"HardCodedStringLiteral"})
public String toString() {
return "HighlightInfoTypeSeverityByKey[severity=" + myToolKey + ", key=" + myAttributesKey + "]";
diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/InspectionEngine.java b/platform/analysis-impl/src/com/intellij/codeInspection/InspectionEngine.java
index ab9581f1d7d9..713b545c6247 100644
--- a/platform/analysis-impl/src/com/intellij/codeInspection/InspectionEngine.java
+++ b/platform/analysis-impl/src/com/intellij/codeInspection/InspectionEngine.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,16 +25,21 @@ import com.intellij.codeInspection.reference.RefEntity;
import com.intellij.codeInspection.reference.RefManagerImpl;
import com.intellij.codeInspection.reference.RefVisitor;
import com.intellij.concurrency.JobLauncher;
+import com.intellij.lang.Language;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.EmptyProgressIndicator;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.ProperTextRange;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.MultiMap;
+import com.intellij.util.containers.SmartHashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -78,29 +83,30 @@ public class InspectionEngine {
}
@NotNull
- public static List<ProblemDescriptor> inspect(@NotNull final List<LocalInspectionTool> tools,
+ public static List<ProblemDescriptor> inspect(@NotNull final List<LocalInspectionToolWrapper> toolWrappers,
@NotNull final PsiFile file,
@NotNull final InspectionManager iManager,
final boolean isOnTheFly,
boolean failFastOnAcquireReadAction,
@NotNull final ProgressIndicator indicator) {
- final Map<String, List<ProblemDescriptor>> problemDescriptors = inspectEx(tools, file, iManager, isOnTheFly, failFastOnAcquireReadAction, indicator);
+ final Map<String, List<ProblemDescriptor>> problemDescriptors = inspectEx(toolWrappers, file, iManager, isOnTheFly, failFastOnAcquireReadAction, indicator);
final List<ProblemDescriptor> result = new ArrayList<ProblemDescriptor>();
- for (List<ProblemDescriptor> group : problemDescriptors.values())
+ for (List<ProblemDescriptor> group : problemDescriptors.values()) {
result.addAll(group);
+ }
return result;
}
// public accessibility for Upsource
@NotNull
- public static Map<String, List<ProblemDescriptor>> inspectEx(@NotNull final List<LocalInspectionTool> tools,
+ public static Map<String, List<ProblemDescriptor>> inspectEx(@NotNull final List<LocalInspectionToolWrapper> toolWrappers,
@NotNull final PsiFile file,
@NotNull final InspectionManager iManager,
final boolean isOnTheFly,
boolean failFastOnAcquireReadAction,
@NotNull final ProgressIndicator indicator) {
- if (tools.isEmpty()) return Collections.emptyMap();
+ if (toolWrappers.isEmpty()) return Collections.emptyMap();
final Map<String, List<ProblemDescriptor>> resultDescriptors = new ConcurrentHashMap<String, List<ProblemDescriptor>>();
final List<PsiElement> elements = new ArrayList<PsiElement>();
@@ -109,32 +115,32 @@ public class InspectionEngine {
Divider.divideInsideAndOutside(file, range.getStartOffset(), range.getEndOffset(), range, elements, new ArrayList<ProperTextRange>(),
Collections.<PsiElement>emptyList(), Collections.<ProperTextRange>emptyList(), true, Condition.TRUE);
- boolean result = JobLauncher.getInstance().invokeConcurrentlyUnderProgress(
- tools, indicator, failFastOnAcquireReadAction,
- new Processor<LocalInspectionTool>() {
- @Override
- public boolean process(final LocalInspectionTool tool) {
- ProblemsHolder holder = new ProblemsHolder(iManager, file, isOnTheFly);
- createVisitorAndAcceptElements(tool, holder, isOnTheFly, session, elements, null);
-
- tool.inspectionFinished(session, holder);
-
- if (holder.hasResults()) {
- resultDescriptors.put(tool.getShortName(), ContainerUtil.filter(holder.getResults(), new Condition<ProblemDescriptor>() {
- @Override
- public boolean value(ProblemDescriptor descriptor) {
- PsiElement element = descriptor.getPsiElement();
- if (element != null) {
- return !SuppressionUtil.inspectionResultSuppressed(element, tool);
- }
- return true;
- }
- }));
- }
+ MultiMap<LocalInspectionToolWrapper, String> toolToLanguages = getToolsForElements(toolWrappers, DumbService.isDumb(file.getProject()), elements, Collections.<PsiElement>emptyList());
+ List<Map.Entry<LocalInspectionToolWrapper, Collection<String>>> entries = new ArrayList<Map.Entry<LocalInspectionToolWrapper, Collection<String>>>(toolToLanguages.entrySet());
+ Processor<Map.Entry<LocalInspectionToolWrapper, Collection<String>>> processor = new Processor<Map.Entry<LocalInspectionToolWrapper, Collection<String>>>() {
+ @Override
+ public boolean process(final Map.Entry<LocalInspectionToolWrapper, Collection<String>> entry) {
+ ProblemsHolder holder = new ProblemsHolder(iManager, file, isOnTheFly);
+ final LocalInspectionTool tool = entry.getKey().getTool();
+ Collection<String> languages = entry.getValue();
+ createVisitorAndAcceptElements(tool, holder, isOnTheFly, session, elements, languages);
- return true;
+ tool.inspectionFinished(session, holder);
+
+ if (holder.hasResults()) {
+ resultDescriptors.put(tool.getShortName(), ContainerUtil.filter(holder.getResults(), new Condition<ProblemDescriptor>() {
+ @Override
+ public boolean value(ProblemDescriptor descriptor) {
+ PsiElement element = descriptor.getPsiElement();
+ return element == null || !SuppressionUtil.inspectionResultSuppressed(element, tool);
+ }
+ }));
}
- });
+
+ return true;
+ }
+ };
+ JobLauncher.getInstance().invokeConcurrentlyUnderProgress(entries, indicator, failFastOnAcquireReadAction, processor);
return resultDescriptors;
}
@@ -149,8 +155,7 @@ public class InspectionEngine {
refManager.inspectionReadActionStarted();
try {
if (toolWrapper instanceof LocalInspectionToolWrapper) {
- LocalInspectionTool localTool = ((LocalInspectionToolWrapper)toolWrapper).getTool();
- return inspect(Collections.singletonList(localTool), file, inspectionManager, false, false, new EmptyProgressIndicator());
+ return inspect(Collections.singletonList((LocalInspectionToolWrapper)toolWrapper), file, inspectionManager, false, false, new EmptyProgressIndicator());
}
if (toolWrapper instanceof GlobalInspectionToolWrapper) {
final GlobalInspectionTool globalTool = ((GlobalInspectionToolWrapper)toolWrapper).getTool();
@@ -226,4 +231,74 @@ public class InspectionEngine {
}
}
}
+
+ @NotNull
+ public static <T extends InspectionToolWrapper> MultiMap<T, String> getToolsForElements(@NotNull List<T> toolWrappers,
+ boolean checkDumbAwareness,
+ @NotNull List<PsiElement> inside,
+ @NotNull List<PsiElement> outside) {
+ Set<Language> languages = new SmartHashSet<Language>();
+ Map<String, Language> langIds = new SmartHashMap<String, Language>();
+ Set<String> dialects = new SmartHashSet<String>();
+ calculateDialects(inside, languages, langIds, dialects);
+ calculateDialects(outside, languages, langIds, dialects);
+ MultiMap<T, String> toolToLanguages = new MultiMap<T, String>() {
+ @NotNull
+ @Override
+ protected Collection<String> createCollection() {
+ return new SmartHashSet<String>();
+ }
+
+ @NotNull
+ @Override
+ protected Collection<String> createEmptyCollection() {
+ return Collections.emptySet();
+ }
+ };
+ for (T wrapper : toolWrappers) {
+ ProgressManager.checkCanceled();
+ String language = wrapper.getLanguage();
+ if (language == null) {
+ InspectionProfileEntry tool = wrapper.getTool();
+ if (!checkDumbAwareness || tool instanceof DumbAware) {
+ toolToLanguages.put(wrapper, null);
+ }
+ continue;
+ }
+ Language lang = langIds.get(language);
+ if (lang != null) {
+ InspectionProfileEntry tool = wrapper.getTool();
+ if (!checkDumbAwareness || tool instanceof DumbAware) {
+ toolToLanguages.putValue(wrapper, language);
+ if (wrapper.applyToDialects()) {
+ for (Language dialect : lang.getDialects()) {
+ toolToLanguages.putValue(wrapper, dialect.getID());
+ }
+ }
+ }
+ }
+ else if (wrapper.applyToDialects() && dialects.contains(language)) {
+ InspectionProfileEntry tool = wrapper.getTool();
+ if (!checkDumbAwareness || tool instanceof DumbAware) {
+ toolToLanguages.putValue(wrapper, language);
+ }
+ }
+ }
+ return toolToLanguages;
+ }
+
+ private static void calculateDialects(@NotNull List<PsiElement> inside,
+ @NotNull Set<Language> languages,
+ @NotNull Map<String, Language> langIds,
+ @NotNull Set<String> dialects) {
+ for (PsiElement element : inside) {
+ Language language = element.getLanguage();
+ if (languages.add(language)) {
+ langIds.put(language.getID(), language);
+ for (Language dialect : language.getDialects()) {
+ dialects.add(dialect.getID());
+ }
+ }
+ }
+ }
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/SmartHashMap.java b/platform/analysis-impl/src/com/intellij/codeInspection/SmartHashMap.java
index 861df82d5d43..e66ae1ee379f 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/SmartHashMap.java
+++ b/platform/analysis-impl/src/com/intellij/codeInspection/SmartHashMap.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.intellij.codeInsight.daemon.impl;
+package com.intellij.codeInspection;
import com.intellij.openapi.util.Comparing;
import com.intellij.util.IncorrectOperationException;
diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextBase.java b/platform/analysis-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextBase.java
index 35f1e4c520ad..2c230254f188 100644
--- a/platform/analysis-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextBase.java
+++ b/platform/analysis-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextBase.java
@@ -21,6 +21,7 @@ import com.intellij.codeInspection.*;
import com.intellij.codeInspection.lang.GlobalInspectionContextExtension;
import com.intellij.codeInspection.lang.InspectionExtensionsFactory;
import com.intellij.codeInspection.reference.*;
+import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
@@ -35,10 +36,7 @@ import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.profile.Profile;
import com.intellij.profile.codeInspection.InspectionProfileManager;
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
-import com.intellij.psi.PsiDocumentManager;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.PsiManager;
+import com.intellij.psi.*;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.scope.packageSet.NamedScope;
import com.intellij.util.Function;
@@ -419,10 +417,35 @@ public class GlobalInspectionContextBase extends UserDataHolderBase implements G
globalContext.codeCleanup(project, scope, profile, null, runnable, false);
}
- public static void cleanupElements(Project project, Runnable runnable, PsiElement... scope) {
- GlobalInspectionContextBase globalContext = (GlobalInspectionContextBase)InspectionManager.getInstance(project).createNewGlobalContext(false);
- final InspectionProfile profile = InspectionProjectProfileManager.getInstance(project).getInspectionProfile();
- globalContext.codeCleanup(project, new AnalysisScope(new LocalSearchScope(scope), project), profile, null, runnable, true);
+ public static void cleanupElements(final Project project, final Runnable runnable, final PsiElement... scope) {
+ final List<SmartPsiElementPointer<PsiElement>> elements = new ArrayList<SmartPsiElementPointer<PsiElement>>();
+ final SmartPointerManager manager = SmartPointerManager.getInstance(project);
+ for (PsiElement element : scope) {
+ elements.add(manager.createSmartPsiElementPointer(element));
+ }
+
+ Runnable cleanupRunnable = new Runnable() {
+ public void run() {
+ final List<PsiElement> psiElements = new ArrayList<PsiElement>();
+ for (SmartPsiElementPointer<PsiElement> element : elements) {
+ PsiElement psiElement = element.getElement();
+ if (psiElement != null) {
+ psiElements.add(psiElement);
+ }
+ }
+ GlobalInspectionContextBase globalContext = (GlobalInspectionContextBase)InspectionManager.getInstance(project).createNewGlobalContext(false);
+ final InspectionProfile profile = InspectionProjectProfileManager.getInstance(project).getInspectionProfile();
+ AnalysisScope analysisScope = new AnalysisScope(new LocalSearchScope(psiElements.toArray(new PsiElement[psiElements.size()])), project);
+ globalContext.codeCleanup(project, analysisScope, profile, null, runnable, true);
+ }
+ };
+
+ Application application = ApplicationManager.getApplication();
+ if (application.isUnitTestMode() || !application.isWriteAccessAllowed()) {
+ cleanupRunnable.run();
+ } else {
+ application.invokeLater(cleanupRunnable);
+ }
}
public void close(boolean noSuspisiousCodeFound) {
diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java b/platform/analysis-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java
index f31e44e96e2c..f5ef75f8197b 100644
--- a/platform/analysis-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java
+++ b/platform/analysis-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java
@@ -102,10 +102,7 @@ public class RefManagerImpl extends RefManager {
}
if (scope != null) {
for (Module module : ModuleManager.getInstance(getProject()).getModules()) {
- //init all ref modules in scope
- if (scope.containsModule(module)) {
- getRefModule(module);
- }
+ getRefModule(module);
}
}
}
diff --git a/platform/analysis-impl/src/com/intellij/profile/codeInspection/InspectionProfileManager.java b/platform/analysis-impl/src/com/intellij/profile/codeInspection/InspectionProfileManager.java
index 7d0f203e94df..41f3c9b8e6b9 100644
--- a/platform/analysis-impl/src/com/intellij/profile/codeInspection/InspectionProfileManager.java
+++ b/platform/analysis-impl/src/com/intellij/profile/codeInspection/InspectionProfileManager.java
@@ -19,6 +19,7 @@ import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.components.NamedComponent;
import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.components.StoragePathMacros;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.profile.ApplicationProfileManager;
import com.intellij.profile.Profile;
@@ -41,7 +42,7 @@ import java.util.List;
*/
public abstract class InspectionProfileManager extends ApplicationProfileManager implements SeverityProvider, NamedComponent {
@NonNls protected static final String INSPECTION_DIR = "inspection";
- @NonNls protected static final String FILE_SPEC = "$ROOT_CONFIG$/" + INSPECTION_DIR;
+ @NonNls protected static final String FILE_SPEC = StoragePathMacros.ROOT_CONFIG + '/' + INSPECTION_DIR;
private final List<ProfileChangeAdapter> myProfileChangeAdapters = ContainerUtil.createLockFreeCopyOnWriteList();
diff --git a/platform/annotations/src/org/intellij/lang/annotations/Flow.java b/platform/annotations/src/org/intellij/lang/annotations/Flow.java
index c73fa57bf9f4..212103e904c9 100644
--- a/platform/annotations/src/org/intellij/lang/annotations/Flow.java
+++ b/platform/annotations/src/org/intellij/lang/annotations/Flow.java
@@ -19,14 +19,14 @@ import org.jetbrains.annotations.NonNls;
import java.lang.annotation.*;
-@Retention(RetentionPolicy.CLASS)
-@Target({ElementType.PARAMETER, ElementType.METHOD})
/**
* This annotation assists the 'Data flow to this' feature by describing data flow
* from the method parameter to the corresponding container (e.g. <code>ArrayList.add(item)</code>)
* or from the container to the method return value (e.g. <code>Set.toArray()</code>)
* or between method parameters (e.g. <code>System.arraycopy(array1, 0, array2, length)</code>)
*/
+@Retention(RetentionPolicy.CLASS)
+@Target({ElementType.PARAMETER, ElementType.METHOD})
public @interface Flow {
/**
* Denotes the source of the data flow.<br>
@@ -66,7 +66,7 @@ public @interface Flow {
/**
* true if the data source is container and we should track not the expression but its contents.<br>
* E.g. the java.util.ArrayList constructor takes the collection and stores its contents:<br>
- * {@code ArrayList(@Flow(sourceIsContainer=true, targetIsContainer=true) Collection<? extends E> collection)}<br>
+ * ArrayList(<tt><pre>{@code @Flow(sourceIsContainer=true, targetIsContainer=true) Collection<? extends E> collection }</pre></tt>) <br>
* By default it's false.
*/
boolean sourceIsContainer() default false;
diff --git a/platform/annotations/src/org/intellij/lang/annotations/MagicConstant.java b/platform/annotations/src/org/intellij/lang/annotations/MagicConstant.java
index 93f11fb116e5..c13cd9db3362 100644
--- a/platform/annotations/src/org/intellij/lang/annotations/MagicConstant.java
+++ b/platform/annotations/src/org/intellij/lang/annotations/MagicConstant.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -84,10 +84,11 @@ public @interface MagicConstant {
/**
* @return int values (typically named constants) which are allowed here.
* E.g.
- * <tt>
+ * <tt><pre>
+ * {@code
* void setConfirmOpenNewProject(@MagicConstant(intValues = {OPEN_PROJECT_ASK, OPEN_PROJECT_NEW_WINDOW, OPEN_PROJECT_SAME_WINDOW})
* int confirmOpenNewProject);
- * </tt>
+ * }</pre></tt>
*/
long[] intValues() default {};
@@ -100,13 +101,13 @@ public @interface MagicConstant {
* @return allowed int flags (i.e. values (typically named constants) which can be combined with bitwise or operator (|).
* Also 0 and -1 are considered allowed.
* E.g.
- * <tt>
- * @MagicConstant(flags = {HierarchyEvent.PARENT_CHANGED,HierarchyEvent.DISPLAYABILITY_CHANGED,HierarchyEvent.SHOWING_CHANGED})
+ * <tt><pre>
+ * {@code @MagicConstant(flags = {HierarchyEvent.PARENT_CHANGED,HierarchyEvent.DISPLAYABILITY_CHANGED,HierarchyEvent.SHOWING_CHANGED})
* int hFlags;
*
* hFlags = 3; // not allowed
* if (hFlags & (HierarchyEvent.PARENT_CHANGED | HierarchyEvent.SHOWING_CHANGED) != 0); // OK
- * </tt>
+ * }</pre></tt>
*/
long[] flags() default {};
@@ -114,27 +115,27 @@ public @interface MagicConstant {
* @return allowed values which are defined in the specified class public static final constants.
*
* E.g.
- * <tt>
- * @MagicConstant(valuesFromClass = Cursor.class)
+ * <tt><pre>
+ * {@code @MagicConstant(valuesFromClass = Cursor.class)
* int cursorType;
*
* cursorType = 11; // not allowed;
* cursorType = Cursor.E_RESIZE_CURSOR; // OK
- * </tt>
+ * }</pre></tt>
*/
Class valuesFromClass() default void.class;
-
/**
* @return allowed int flags which are defined in the specified class public static final constants.
*
* E.g.
- * <tt>@MagicConstant(flagsFromClass = java.awt.InputEvent.class)
+ * <tt><pre>
+ * {@code @MagicConstant(flagsFromClass = java.awt.InputEvent.class)
* int eventMask;
*
* eventMask = 10; // not allowed;
* eventMask = InputEvent.CTRL_MASK | InputEvent.ALT_MASK; // OK
- * </tt>
+ * }</pre></tt>
*/
Class flagsFromClass() default void.class;
}
diff --git a/platform/annotations/src/org/jetbrains/annotations/Contract.java b/platform/annotations/src/org/jetbrains/annotations/Contract.java
index 360bf5923d91..c1d08c483f74 100644
--- a/platform/annotations/src/org/jetbrains/annotations/Contract.java
+++ b/platform/annotations/src/org/jetbrains/annotations/Contract.java
@@ -54,7 +54,13 @@ public @interface Contract {
String value() default "";
/**
- * Specifies if this method is pure, i.e. has no visible side effects. This may be used for more precise data flow analysis, and
+ * Specifies that the annotated method has no visible side effects, in the following sense.
+ * If its return value is not used, removing its invocation won't
+ * affect program state and change the semantics. Such methods shouldn't throw exceptions by design, as exceptions affect semantics.<br><br>
+ *
+ * "Invisible" side effects (such as logging) that don't affect the "important" program semantics are allowed.<br><br>
+ *
+ * This annotation may be used for more precise data flow analysis, and
* to check that the method's return value is actually used in the call place.
*/
boolean pure() default false;
diff --git a/platform/core-api/src/com/intellij/lang/ASTNode.java b/platform/core-api/src/com/intellij/lang/ASTNode.java
index fe603470ad3a..0b8be360b6a1 100644
--- a/platform/core-api/src/com/intellij/lang/ASTNode.java
+++ b/platform/core-api/src/com/intellij/lang/ASTNode.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -291,6 +291,5 @@ public interface ASTNode extends UserDataHolder {
* @param clazz expected psi class
* @return the PSI element.
*/
- @Nullable
- <T extends PsiElement> T getPsi(Class<T> clazz);
+ <T extends PsiElement> T getPsi(@NotNull Class<T> clazz);
}
diff --git a/platform/core-api/src/com/intellij/openapi/options/SchemesManagerFactory.java b/platform/core-api/src/com/intellij/openapi/options/SchemesManagerFactory.java
index f1a090359b68..a0c0ee7dad62 100644
--- a/platform/core-api/src/com/intellij/openapi/options/SchemesManagerFactory.java
+++ b/platform/core-api/src/com/intellij/openapi/options/SchemesManagerFactory.java
@@ -19,14 +19,16 @@ import com.intellij.openapi.components.RoamingType;
import com.intellij.openapi.components.ServiceBean;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.extensions.ExtensionPointName;
+import org.jetbrains.annotations.NotNull;
public abstract class SchemesManagerFactory {
- public static ExtensionPointName<ServiceBean> SCHEME_OWNER = ExtensionPointName.create("com.intellij.schemeOwner");
+ public static final ExtensionPointName<ServiceBean> SCHEME_OWNER = ExtensionPointName.create("com.intellij.schemeOwner");
- public abstract <T extends Scheme, E extends ExternalizableScheme> SchemesManager<T,E> createSchemesManager(String fileSpec, SchemeProcessor<E> processor,
- RoamingType roamingType);
+ public abstract <T extends Scheme, E extends ExternalizableScheme> SchemesManager<T, E> createSchemesManager(@NotNull String fileSpec,
+ @NotNull SchemeProcessor<E> processor,
+ @NotNull RoamingType roamingType);
- public static SchemesManagerFactory getInstance(){
+ public static SchemesManagerFactory getInstance() {
return ServiceManager.getService(SchemesManagerFactory.class);
}
diff --git a/platform/core-api/src/com/intellij/openapi/progress/EmptyProgressIndicator.java b/platform/core-api/src/com/intellij/openapi/progress/EmptyProgressIndicator.java
index d5603b2a28ae..4225270ed4b4 100644
--- a/platform/core-api/src/com/intellij/openapi/progress/EmptyProgressIndicator.java
+++ b/platform/core-api/src/com/intellij/openapi/progress/EmptyProgressIndicator.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -42,6 +42,7 @@ public class EmptyProgressIndicator implements ProgressIndicator {
@Override
public void cancel() {
myIsCanceled = true;
+ ProgressIndicatorProvider.canceled();
}
@Override
diff --git a/platform/core-api/src/com/intellij/openapi/progress/ProgressIndicatorProvider.java b/platform/core-api/src/com/intellij/openapi/progress/ProgressIndicatorProvider.java
index afe440b8588f..89ff2fcd48a1 100644
--- a/platform/core-api/src/com/intellij/openapi/progress/ProgressIndicatorProvider.java
+++ b/platform/core-api/src/com/intellij/openapi/progress/ProgressIndicatorProvider.java
@@ -54,4 +54,8 @@ public abstract class ProgressIndicatorProvider {
ourInstance.doCheckCanceled();
}
}
+
+ public static void canceled() {
+ ourNeedToCheckCancel = true;
+ }
}
diff --git a/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java b/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java
index 4b4ace28cd37..3f0601ba951b 100644
--- a/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java
+++ b/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java
@@ -184,7 +184,7 @@ public abstract class ProgressManager extends ProgressIndicatorProvider {
throws ProcessCanceledException {
ProgressIndicator oldIndicator = null;
- boolean set = progress != null && progress != (oldIndicator = myThreadIndicator.get());
+ boolean set = progress != null && progress != (oldIndicator = getProgressIndicator());
if (set) {
myThreadIndicator.set(progress);
}
diff --git a/platform/core-api/src/com/intellij/openapi/util/ExecutionCallback.java b/platform/core-api/src/com/intellij/openapi/util/ExecutionCallback.java
index 40572e9f6a8e..5c72eb06def3 100644
--- a/platform/core-api/src/com/intellij/openapi/util/ExecutionCallback.java
+++ b/platform/core-api/src/com/intellij/openapi/util/ExecutionCallback.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,6 +34,7 @@ class ExecutionCallback {
ExecutionCallback(int executedCount) {
myCountToExecution = executedCount;
+ assert executedCount >= 1 : executedCount;
}
/**
diff --git a/platform/core-api/src/com/intellij/psi/util/PsiUtilCore.java b/platform/core-api/src/com/intellij/psi/util/PsiUtilCore.java
index 8977da50f0ec..a33cf43573e4 100644
--- a/platform/core-api/src/com/intellij/psi/util/PsiUtilCore.java
+++ b/platform/core-api/src/com/intellij/psi/util/PsiUtilCore.java
@@ -17,9 +17,11 @@ package com.intellij.psi.util;
import com.intellij.lang.ASTNode;
import com.intellij.lang.Language;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
@@ -516,4 +518,13 @@ public class PsiUtilCore {
}
return findLanguageFromElement(elt);
}
+
+ public static Project getProjectInReadAction(@NotNull final PsiElement element) {
+ return ApplicationManager.getApplication().runReadAction(new Computable<Project>() {
+ @Override
+ public Project compute() {
+ return element.getProject();
+ }
+ });
+ }
}
diff --git a/platform/core-api/src/com/intellij/usageView/UsageInfo.java b/platform/core-api/src/com/intellij/usageView/UsageInfo.java
index 2d3cecc3628b..e67958a21faf 100644
--- a/platform/core-api/src/com/intellij/usageView/UsageInfo.java
+++ b/platform/core-api/src/com/intellij/usageView/UsageInfo.java
@@ -246,6 +246,15 @@ public class UsageInfo {
return result;
}
+ @Override
+ public String toString() {
+ PsiReference reference = getReference();
+ if (reference == null) {
+ return super.toString();
+ }
+ return reference.getCanonicalText() + " (" + reference.getClass() + ")";
+ }
+
@Nullable
public PsiFile getFile() {
return mySmartPointer.getContainingFile();
diff --git a/platform/core-api/src/com/intellij/util/PlatformUtilsCore.java b/platform/core-api/src/com/intellij/util/PlatformUtilsCore.java
index 7e4ff81b69a1..0ea0b5a6eb60 100644
--- a/platform/core-api/src/com/intellij/util/PlatformUtilsCore.java
+++ b/platform/core-api/src/com/intellij/util/PlatformUtilsCore.java
@@ -22,7 +22,7 @@ public class PlatformUtilsCore {
public static final String IDEA_PREFIX = "idea";
public static final String COMMUNITY_PREFIX = "Idea";
public static final String APPCODE_PREFIX = "AppCode";
- public static final String CPP_PREFIX = "CppIde";
+ public static final String CLION_PREFIX = "CLion";
public static final String PYCHARM_PREFIX = "Python";
public static final String PYCHARM_PREFIX2 = "PyCharmCore";
public static final String RUBY_PREFIX = "Ruby";
@@ -59,8 +59,8 @@ public class PlatformUtilsCore {
return APPCODE_PREFIX.equals(getPlatformPrefix());
}
- public static boolean isCppIde() {
- return CPP_PREFIX.equals(getPlatformPrefix());
+ public static boolean isCLion() {
+ return CLION_PREFIX.equals(getPlatformPrefix());
}
public static boolean isPyCharm() {
diff --git a/platform/core-impl/src/com/intellij/core/CoreProjectEnvironment.java b/platform/core-impl/src/com/intellij/core/CoreProjectEnvironment.java
index 5889dbf48c63..2a89f73f9704 100644
--- a/platform/core-impl/src/com/intellij/core/CoreProjectEnvironment.java
+++ b/platform/core-impl/src/com/intellij/core/CoreProjectEnvironment.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -54,7 +54,7 @@ public class CoreProjectEnvironment {
protected final MockProject myProject;
protected final MessageBus myMessageBus;
- public CoreProjectEnvironment(Disposable parentDisposable, CoreApplicationEnvironment applicationEnvironment) {
+ public CoreProjectEnvironment(@NotNull Disposable parentDisposable, @NotNull CoreApplicationEnvironment applicationEnvironment) {
myParentDisposable = parentDisposable;
myEnvironment = applicationEnvironment;
myProject = createProject(myEnvironment.getApplication().getPicoContainer(), myParentDisposable);
@@ -87,10 +87,13 @@ public class CoreProjectEnvironment {
myProject.registerService(DumbService.class, new MockDumbService(myProject));
}
- protected MockProject createProject(PicoContainer parent, @NotNull Disposable parentDisposable) {
+ @SuppressWarnings("MethodMayBeStatic")
+ @NotNull
+ protected MockProject createProject(@NotNull PicoContainer parent, @NotNull Disposable parentDisposable) {
return new MockProject(parent, parentDisposable);
}
+ @NotNull
protected ProjectScopeBuilder createProjectScopeBuilder() {
return new CoreProjectScopeBuilder(myProject, myFileIndexFacade);
}
@@ -99,20 +102,23 @@ public class CoreProjectEnvironment {
}
+ @NotNull
protected FileIndexFacade createFileIndexFacade() {
return new MockFileIndexFacade(myProject);
}
- protected ResolveScopeManager createResolveScopeManager(PsiManager psiManager) {
- return new MockResolveScopeManager(myProject);
+ @SuppressWarnings("MethodMayBeStatic")
+ @NotNull
+ protected ResolveScopeManager createResolveScopeManager(@NotNull PsiManager psiManager) {
+ return new MockResolveScopeManager(psiManager.getProject());
}
- public <T> void registerProjectExtensionPoint(final ExtensionPointName<T> extensionPointName,
- final Class<? extends T> aClass) {
+ public <T> void registerProjectExtensionPoint(@NotNull ExtensionPointName<T> extensionPointName,
+ @NotNull Class<? extends T> aClass) {
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getArea(myProject), extensionPointName, aClass);
}
- public <T> void addProjectExtension(final ExtensionPointName<T> name, final T extension) {
+ public <T> void addProjectExtension(@NotNull ExtensionPointName<T> name, @NotNull final T extension) {
final ExtensionPoint<T> extensionPoint = Extensions.getArea(myProject).getExtensionPoint(name);
extensionPoint.registerExtension(extension);
Disposer.register(myParentDisposable, new Disposable() {
@@ -124,18 +130,21 @@ public class CoreProjectEnvironment {
}
- public <T> void registerProjectComponent(final Class<T> interfaceClass, final T implementation) {
+ public <T> void registerProjectComponent(@NotNull Class<T> interfaceClass, @NotNull T implementation) {
CoreApplicationEnvironment.registerComponentInstance(myProject.getPicoContainer(), interfaceClass, implementation);
}
+ @NotNull
public Disposable getParentDisposable() {
return myParentDisposable;
}
+ @NotNull
public CoreApplicationEnvironment getEnvironment() {
return myEnvironment;
}
+ @NotNull
public MockProject getProject() {
return myProject;
}
diff --git a/platform/core-impl/src/com/intellij/mock/MockApplicationEx.java b/platform/core-impl/src/com/intellij/mock/MockApplicationEx.java
index 7415e0d66fad..3a3ea6e8e0d7 100644
--- a/platform/core-impl/src/com/intellij/mock/MockApplicationEx.java
+++ b/platform/core-impl/src/com/intellij/mock/MockApplicationEx.java
@@ -20,7 +20,6 @@ import com.intellij.openapi.application.ex.ApplicationEx;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.InvalidDataException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -44,7 +43,7 @@ public class MockApplicationEx extends MockApplication implements ApplicationEx
}
@Override
- public void load(String path) throws IOException, InvalidDataException {
+ public void load(String path) throws IOException {
}
@Override
diff --git a/platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationEx.java b/platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationEx.java
index bf84725f7910..90506c071f35 100644
--- a/platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationEx.java
+++ b/platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationEx.java
@@ -38,7 +38,8 @@ public interface ApplicationEx extends Application {
* @throws IOException
* @throws InvalidDataException
*/
- void load(String optionsPath) throws IOException, InvalidDataException;
+ void load(@Nullable String optionsPath) throws IOException;
+
boolean isLoaded();
@NotNull
diff --git a/platform/core-impl/src/com/intellij/openapi/options/AbstractSchemesManager.java b/platform/core-impl/src/com/intellij/openapi/options/AbstractSchemesManager.java
index d1ed93f3a2be..ebb2896d2a8e 100644
--- a/platform/core-impl/src/com/intellij/openapi/options/AbstractSchemesManager.java
+++ b/platform/core-impl/src/com/intellij/openapi/options/AbstractSchemesManager.java
@@ -29,8 +29,7 @@ import java.util.*;
public abstract class AbstractSchemesManager<T extends Scheme, E extends ExternalizableScheme> implements SchemesManager<T,E> {
-
- private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.options.AbstractSchemesManager");
+ private static final Logger LOG = Logger.getInstance(AbstractSchemesManager.class);
protected final List<T> mySchemes = new ArrayList<T>();
private volatile T myCurrentScheme;
diff --git a/platform/core-impl/src/com/intellij/openapi/progress/util/AbstractProgressIndicatorBase.java b/platform/core-impl/src/com/intellij/openapi/progress/util/AbstractProgressIndicatorBase.java
index d548fd2412b2..132dd5b30ee4 100644
--- a/platform/core-impl/src/com/intellij/openapi/progress/util/AbstractProgressIndicatorBase.java
+++ b/platform/core-impl/src/com/intellij/openapi/progress/util/AbstractProgressIndicatorBase.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@ import com.intellij.openapi.application.impl.ModalityStateEx;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.ProgressIndicatorProvider;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.util.containers.ConcurrentHashSet;
import com.intellij.util.containers.DoubleArrayList;
@@ -89,6 +90,7 @@ public class AbstractProgressIndicatorBase extends UserDataHolderBase implements
@Override
public void cancel() {
myCanceled = true;
+ ProgressIndicatorProvider.canceled();
}
@Override
diff --git a/platform/core-impl/src/com/intellij/psi/SingleRootFileViewProvider.java b/platform/core-impl/src/com/intellij/psi/SingleRootFileViewProvider.java
index 9dbd8ee9ea07..bed56c25292d 100644
--- a/platform/core-impl/src/com/intellij/psi/SingleRootFileViewProvider.java
+++ b/platform/core-impl/src/com/intellij/psi/SingleRootFileViewProvider.java
@@ -383,7 +383,7 @@ public class SingleRootFileViewProvider extends UserDataHolderBase implements Fi
@Override
public PsiReference findReferenceAt(final int offset) {
- final PsiFileImpl psiFile = (PsiFileImpl)getPsi(getBaseLanguage());
+ final PsiFile psiFile = getPsi(getBaseLanguage());
return findReferenceAt(psiFile, offset);
}
diff --git a/platform/core-impl/src/com/intellij/psi/impl/PsiToDocumentSynchronizer.java b/platform/core-impl/src/com/intellij/psi/impl/PsiToDocumentSynchronizer.java
index 13c43571decb..60bae75fbe23 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/PsiToDocumentSynchronizer.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/PsiToDocumentSynchronizer.java
@@ -69,12 +69,14 @@ public class PsiToDocumentSynchronizer extends PsiTreeChangeAdapter {
void syncDocument(@NotNull Document document, @NotNull PsiTreeChangeEventImpl event);
}
- private void checkPsiModificationAllowed(@NotNull final PsiTreeChangeEvent event, boolean force) {
+ private void checkPsiModificationAllowed(@NotNull final PsiTreeChangeEvent event) {
if (!toProcessPsiEvent()) return;
final PsiFile psiFile = event.getFile();
if (psiFile == null || psiFile.getNode() == null) return;
- final Document document = myPsiDocumentManager.getCachedDocument(psiFile);
+ boolean forceDocument = !psiFile.getViewProvider().isPhysical();
+ final Document document = forceDocument ? myPsiDocumentManager.getDocument(psiFile)
+ : myPsiDocumentManager.getCachedDocument(psiFile);
if (document != null && myPsiDocumentManager.isUncommited(document)) {
throw new IllegalStateException("Attempt to modify PSI for non-committed Document!");
}
@@ -132,22 +134,22 @@ public class PsiToDocumentSynchronizer extends PsiTreeChangeAdapter {
@Override
public void beforeChildAddition(@NotNull PsiTreeChangeEvent event) {
- checkPsiModificationAllowed(event, false);
+ checkPsiModificationAllowed(event);
}
@Override
public void beforeChildRemoval(@NotNull PsiTreeChangeEvent event) {
- checkPsiModificationAllowed(event, false);
+ checkPsiModificationAllowed(event);
}
@Override
public void beforeChildReplacement(@NotNull PsiTreeChangeEvent event) {
- checkPsiModificationAllowed(event, false);
+ checkPsiModificationAllowed(event);
}
@Override
public void beforeChildrenChange(@NotNull PsiTreeChangeEvent event) {
- checkPsiModificationAllowed(event, false);
+ checkPsiModificationAllowed(event);
}
@Override
@@ -255,7 +257,7 @@ public class PsiToDocumentSynchronizer extends PsiTreeChangeAdapter {
final PsiTreeChangeEventImpl fakeEvent = new PsiTreeChangeEventImpl(changeScope.getManager());
fakeEvent.setParent(changeScope);
fakeEvent.setFile(changeScope.getContainingFile());
- checkPsiModificationAllowed(fakeEvent, true);
+ checkPsiModificationAllowed(fakeEvent);
doSync(fakeEvent, true, new DocSyncAction() {
@Override
public void syncDocument(@NotNull Document document, @NotNull PsiTreeChangeEventImpl event) {
diff --git a/platform/core-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java b/platform/core-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java
index 7b4e9ec210ac..6b2877d83351 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java
@@ -26,7 +26,6 @@ import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileTypes.ContentBasedFileSubstitutor;
import com.intellij.openapi.fileTypes.FileType;
-import com.intellij.openapi.fileTypes.FileTypeRegistry;
import com.intellij.openapi.fileTypes.LanguageFileType;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
@@ -71,13 +70,6 @@ public class FileManagerImpl implements FileManager {
private final FileDocumentManager myFileDocumentManager;
private final MessageBusConnection myConnection;
- @SuppressWarnings("UnusedDeclaration")
- private final LowMemoryWatcher myLowMemoryWatcher = LowMemoryWatcher.register(new Runnable() {
- @Override
- public void run() {
- processQueue();
- }
- });
public FileManagerImpl(PsiManagerImpl manager, FileDocumentManager fileDocumentManager, FileIndexFacade fileIndex) {
myManager = manager;
@@ -98,6 +90,12 @@ public class FileManagerImpl implements FileManager {
}
});
Disposer.register(manager.getProject(), this);
+ LowMemoryWatcher.register(new Runnable() {
+ @Override
+ public void run() {
+ processQueue();
+ }
+ }, this);
}
private static final VirtualFile NULL = new LightVirtualFile();
@@ -412,7 +410,7 @@ public class FileManagerImpl implements FileManager {
if (myFileIndex.isExcludedFile(vFile)) return null;
}
else {
- if (FileTypeRegistry.getInstance().isFileIgnored(vFile)) return null;
+ if (myFileIndex.isUnderIgnored(vFile)) return null;
}
VirtualFile parent = vFile.getParent();
@@ -538,7 +536,13 @@ public class FileManagerImpl implements FileManager {
if (document != null && !ignoreDocument){
fileDocumentManager.reloadFromDisk(document);
}
- else{
+ else {
+ FileViewProvider latestProvider = createFileViewProvider(vFile, false);
+ if (latestProvider.getPsi(latestProvider.getBaseLanguage()) instanceof PsiBinaryFile) {
+ forceReload(vFile);
+ return;
+ }
+
PsiTreeChangeEventImpl event = new PsiTreeChangeEventImpl(myManager);
event.setParent(file);
event.setFile(file);
diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java
index 1d96d820328a..dabb45cd7667 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java
@@ -74,7 +74,6 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF
protected PsiFile myOriginalFile = null;
private final FileViewProvider myViewProvider;
- private static final Key<Document> HARD_REFERENCE_TO_DOCUMENT = new Key<Document>("HARD_REFERENCE_TO_DOCUMENT");
private volatile Reference<StubTree> myStub;
protected final PsiManagerEx myManager;
private volatile Getter<FileElement> myTreeElementPointer; // SoftReference/WeakReference to ASTNode or a strong reference to a tree if the file is a DummyHolder
@@ -188,11 +187,7 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF
Document cachedDocument = FileDocumentManager.getInstance().getCachedDocument(getViewProvider().getVirtualFile());
- final Document document = viewProvider.isEventSystemEnabled() ? viewProvider.getDocument() : null;
FileElement treeElement = createFileElement(viewProvider.getContents());
- if (document != null) {
- treeElement.putUserData(HARD_REFERENCE_TO_DOCUMENT, document);
- }
treeElement.setPsi(this);
List<Pair<StubBasedPsiElementBase, CompositeElement>> bindings = calcStubAstBindings(treeElement, cachedDocument);
@@ -375,12 +370,22 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF
public void unloadContent() {
ApplicationManager.getApplication().assertWriteAccessAllowed();
- LOG.assertTrue(getTreeElement() != null);
clearCaches();
myViewProvider.beforeContentsSynchronized();
synchronized (PsiLock.LOCK) {
- myTreeElementPointer = null;
- clearStub("unloadContent");
+ FileElement treeElement = derefTreeElement();
+ DebugUtil.startPsiModification("unloadContent");
+ try {
+ if (treeElement != null) {
+ myTreeElementPointer = null;
+ treeElement.detachFromFile();
+ DebugUtil.onInvalidated(treeElement);
+ }
+ clearStub("unloadContent");
+ }
+ finally {
+ DebugUtil.finishPsiModification();
+ }
}
}
diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/tree/CompositeElement.java b/platform/core-impl/src/com/intellij/psi/impl/source/tree/CompositeElement.java
index f00c15220d57..c73d0bd485ce 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/source/tree/CompositeElement.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/source/tree/CompositeElement.java
@@ -771,8 +771,7 @@ public class CompositeElement extends TreeElement {
}
@Override
- @Nullable
- public <T extends PsiElement> T getPsi(Class<T> clazz) {
+ public <T extends PsiElement> T getPsi(@NotNull Class<T> clazz) {
return LeafElement.getPsi(clazz, getPsi(), LOG);
}
@@ -797,6 +796,10 @@ public class CompositeElement extends TreeElement {
myWrapper = psi;
}
+ protected void clearPsi() {
+ myWrapper = null;
+ }
+
public final void rawAddChildren(@NotNull TreeElement first) {
rawAddChildrenWithoutNotifications(first);
diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/tree/FileElement.java b/platform/core-impl/src/com/intellij/psi/impl/source/tree/FileElement.java
index f025de75b820..76d5c421094d 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/source/tree/FileElement.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/source/tree/FileElement.java
@@ -19,6 +19,7 @@ package com.intellij.psi.impl.source.tree;
import com.intellij.lang.ASTNode;
import com.intellij.lang.FileASTNode;
import com.intellij.openapi.util.Getter;
+import com.intellij.psi.PsiElement;
import com.intellij.psi.impl.PsiManagerEx;
import com.intellij.psi.impl.source.CharTableImpl;
import com.intellij.psi.impl.source.PsiFileImpl;
@@ -28,6 +29,17 @@ import org.jetbrains.annotations.NotNull;
public class FileElement extends LazyParseableElement implements FileASTNode, Getter<FileElement> {
private volatile CharTable myCharTable = new CharTableImpl();
+ private volatile boolean myDetached;
+
+ @Override
+ protected PsiElement createPsiNoLock() {
+ return myDetached ? null : super.createPsiNoLock();
+ }
+
+ public void detachFromFile() {
+ myDetached = true;
+ clearPsi();
+ }
@Override
@NotNull
diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/tree/LeafElement.java b/platform/core-impl/src/com/intellij/psi/impl/source/tree/LeafElement.java
index 929737177052..011cad8a8450 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/source/tree/LeafElement.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/source/tree/LeafElement.java
@@ -290,16 +290,14 @@ public abstract class LeafElement extends TreeElement {
}
@Override
- @Nullable
- public <T extends PsiElement> T getPsi(Class<T> clazz) {
+ public <T extends PsiElement> T getPsi(@NotNull Class<T> clazz) {
return getPsi(clazz, getPsi(), LOG);
}
- @Nullable
- static <T extends PsiElement> T getPsi(Class<T> clazz, PsiElement element, Logger log) {
+ static <T extends PsiElement> T getPsi(@NotNull Class<T> clazz, PsiElement element, Logger log) {
log.assertTrue(clazz.isInstance(element), "unexpected psi class. expected: " + clazz
+ " got: " + (element == null ? null : element.getClass()));
+ //noinspection unchecked
return (T)element;
}
-
}
diff --git a/platform/core-impl/src/com/intellij/util/DocumentUtil.java b/platform/core-impl/src/com/intellij/util/DocumentUtil.java
index e2c78be69a3e..df9d26c6e690 100644
--- a/platform/core-impl/src/com/intellij/util/DocumentUtil.java
+++ b/platform/core-impl/src/com/intellij/util/DocumentUtil.java
@@ -82,4 +82,8 @@ public final class DocumentUtil {
}
return startOffset;
}
+
+ public static boolean isValidOffset(int offset, @NotNull Document document) {
+ return offset >= 0 && offset <= document.getTextLength();
+ }
}
diff --git a/platform/dvcs-api/src/com/intellij/dvcs/push/OutgoingCommitsProvider.java b/platform/dvcs-api/src/com/intellij/dvcs/push/OutgoingCommitsProvider.java
index 4532146f9b4a..33053ffe4ecf 100644
--- a/platform/dvcs-api/src/com/intellij/dvcs/push/OutgoingCommitsProvider.java
+++ b/platform/dvcs-api/src/com/intellij/dvcs/push/OutgoingCommitsProvider.java
@@ -21,15 +21,20 @@ import org.jetbrains.annotations.NotNull;
/**
* Provider for outgoing commits
*/
-public abstract class OutgoingCommitsProvider {
+public abstract class OutgoingCommitsProvider<Repo extends Repository, Source extends PushSource, Target extends PushTarget> {
/**
- * Collect outgoing commits or errors for selected repo for specified {@link PushSpec} and store to {@link OutgoingResult}
+ * Collect either outgoing commits or errors for the given repository and {@link PushSpec}.
*
- * @param initial true for first commits loading, which identify that all inside actions should be silent
- * and do not ask user about smth, a.e authorization request
+ * @param initial true for the first attempt to load commits, which happens when the push dialog just appears on the screen.
+ * If later the user modifies the push target, commits are reloaded, and {@code initial} is false.
+ * <br/>
+ * Implementations should make sure that if {@code initial} is true, no user interaction is allowed
+ * (to avoid suddenly throwing dialogs into user's face).
+ * E.g. if authentication is needed to collect outgoing changes, then the method should silently show the corresponding
+ * request in the error field of the OutgoingResult.
*/
@NotNull
- public abstract OutgoingResult getOutgoingCommits(@NotNull Repository repository,
- @NotNull PushSpec pushSpec, boolean initial);
+ public abstract OutgoingResult getOutgoingCommits(@NotNull Repo repository, @NotNull PushSpec<Source, Target> pushSpec, boolean initial);
+
}
diff --git a/platform/dvcs-api/src/com/intellij/dvcs/push/PushSpec.java b/platform/dvcs-api/src/com/intellij/dvcs/push/PushSpec.java
index 81ff874979bd..e205009a4c0d 100644
--- a/platform/dvcs-api/src/com/intellij/dvcs/push/PushSpec.java
+++ b/platform/dvcs-api/src/com/intellij/dvcs/push/PushSpec.java
@@ -16,28 +16,32 @@
package com.intellij.dvcs.push;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/**
- * Specified a push from-to settings for one repository
+ * For a single repository, specifies what is pushed and where.
*/
-public class PushSpec {
+public class PushSpec<S extends PushSource, T extends PushTarget> {
- @NotNull private PushSource mySource;
- @Nullable private PushTarget myTarget;
+ @NotNull private S mySource;
+ @NotNull private T myTarget;
- public PushSpec(@NotNull PushSource source, @Nullable PushTarget target) {
+ public PushSpec(@NotNull S source, @NotNull T target) {
mySource = source;
myTarget = target;
}
@NotNull
- public PushSource getSource() {
+ public S getSource() {
return mySource;
}
- @Nullable
- public PushTarget getTarget() {
+ @NotNull
+ public T getTarget() {
return myTarget;
}
+
+ @Override
+ public String toString() {
+ return mySource + "->" + myTarget;
+ }
}
diff --git a/platform/dvcs-api/src/com/intellij/dvcs/push/PushSupport.java b/platform/dvcs-api/src/com/intellij/dvcs/push/PushSupport.java
index d6af8eec1088..fbf6f148c3b1 100644
--- a/platform/dvcs-api/src/com/intellij/dvcs/push/PushSupport.java
+++ b/platform/dvcs-api/src/com/intellij/dvcs/push/PushSupport.java
@@ -19,55 +19,56 @@ import com.intellij.dvcs.repo.Repository;
import com.intellij.dvcs.repo.RepositoryManager;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.vcs.AbstractVcs;
+import com.intellij.ui.SimpleColoredText;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.Collection;
+import java.util.List;
/**
* Base class to provide vcs-specific info
*/
-public abstract class PushSupport<Repo extends Repository> {
+public abstract class PushSupport<Repo extends Repository, Source extends PushSource, Target extends PushTarget> {
- public static final ExtensionPointName<PushSupport<? extends Repository>> PUSH_SUPPORT_EP =
+ public static final ExtensionPointName<PushSupport<? extends Repository, ? extends PushSource, ? extends PushTarget>> PUSH_SUPPORT_EP =
ExtensionPointName.create("com.intellij.pushSupport");
@NotNull
public abstract AbstractVcs getVcs();
@NotNull
- public abstract Pusher getPusher();
+ public abstract Pusher<Repo, Source, Target> getPusher();
@NotNull
- public abstract OutgoingCommitsProvider getOutgoingCommitsProvider();
+ public abstract OutgoingCommitsProvider<Repo, Source, Target> getOutgoingCommitsProvider();
/**
* @return Default push destination
*/
@Nullable
- public abstract PushTarget getDefaultTarget(@NotNull Repo repository);
+ public abstract Target getDefaultTarget(@NotNull Repo repository);
/**
- * @return All remembered remote destinations used for completion
+ * @return All remote destinations which will be proposed to user in the target field completion.
+ * They will be shown in the same order as they appear in the returned list.
*/
@NotNull
- public abstract Collection<String> getTargetNames(@NotNull Repo repository);
+ public abstract List<String> getTargetNames(@NotNull Repo repository);
/**
* @return current source(branch) for repository
*/
@NotNull
- public abstract PushSource getSource(@NotNull Repo repository);
+ public abstract Source getSource(@NotNull Repo repository);
/**
- * Parse user input string, and create the valid target for push,
- * or return <code><b>null</b></code> if the target name is not valid.
+ * Parse user input string, and create the VALID target for push
*
* @see #validateSpec(Repository, PushSpec)
*/
- @Nullable
- public abstract PushTarget createTarget(@NotNull Repo repository, @NotNull String targetName);
+ @NotNull
+ public abstract Target createTarget(@NotNull Repo repository, @NotNull String targetName);
/**
* @return RepositoryManager for vcs
@@ -84,5 +85,7 @@ public abstract class PushSupport<Repo extends Repository> {
* @return null if target is valid for selected repository
*/
@Nullable
- public abstract VcsError validate(@NotNull Repository repository, @Nullable String targetToValidate);
+ public abstract VcsError validate(@NotNull Repo repository, @Nullable String targetToValidate);
+
+ public abstract SimpleColoredText renderTarget(@Nullable Target target);
}
diff --git a/platform/dvcs-api/src/com/intellij/dvcs/push/PushTarget.java b/platform/dvcs-api/src/com/intellij/dvcs/push/PushTarget.java
index 87c7244bd77c..d7ed69d0875c 100644
--- a/platform/dvcs-api/src/com/intellij/dvcs/push/PushTarget.java
+++ b/platform/dvcs-api/src/com/intellij/dvcs/push/PushTarget.java
@@ -24,5 +24,6 @@ import org.jetbrains.annotations.NotNull;
public interface PushTarget {
@NotNull
+ //todo rename - > getName or smth
String getPresentation();
}
diff --git a/platform/dvcs-api/src/com/intellij/dvcs/push/Pusher.java b/platform/dvcs-api/src/com/intellij/dvcs/push/Pusher.java
index 6d5fc1611030..306122537660 100644
--- a/platform/dvcs-api/src/com/intellij/dvcs/push/Pusher.java
+++ b/platform/dvcs-api/src/com/intellij/dvcs/push/Pusher.java
@@ -24,16 +24,19 @@ import java.util.Map;
/**
* Base class to execute push command.
*/
-public abstract class Pusher {
+public abstract class Pusher<Repo extends Repository, Source extends PushSource, Target extends PushTarget> {
+
/**
- * Perform push command for all repositories belonged to one vcs.
+ * Perform push for all given repositories.
*
- * @param pushSpecs specify push from and to params
- * @param vcsPushOptionValue specify additional options to push, null if not supported
- * @param force if true then execute force push
+ * @param pushSpecs push specs for each repository telling what to push and where.
+ * @param additionalOption some additional push option(s), which are received from
+ * {@link PushSupport#getVcsPushOptionsPanel() the additional panel} if the plugin has one.
+ * @param force if true then force push should be performed.
*/
- public abstract void push(@NotNull Map<Repository, PushSpec> pushSpecs,
- @Nullable VcsPushOptionValue vcsPushOptionValue,
+ public abstract void push(@NotNull Map<Repo, PushSpec<Source, Target>> pushSpecs,
+ @Nullable VcsPushOptionValue additionalOption,
boolean force);
+
}
diff --git a/platform/dvcs-api/src/com/intellij/dvcs/push/VcsError.java b/platform/dvcs-api/src/com/intellij/dvcs/push/VcsError.java
index de2c640d12b1..b76095629ccd 100644
--- a/platform/dvcs-api/src/com/intellij/dvcs/push/VcsError.java
+++ b/platform/dvcs-api/src/com/intellij/dvcs/push/VcsError.java
@@ -40,4 +40,8 @@ public class VcsError {
myErrorHandleListener.handleError(loader);
}
}
+
+ public static VcsError createEmptyTargetError(@NotNull String name) {
+ return new VcsError("Please, specify remote push path for repository " + name + ".");
+ }
}
diff --git a/platform/dvcs-impl/dvcs-impl.iml b/platform/dvcs-impl/dvcs-impl.iml
index 43dd32b785b4..f47efef84148 100644
--- a/platform/dvcs-impl/dvcs-impl.iml
+++ b/platform/dvcs-impl/dvcs-impl.iml
@@ -4,13 +4,11 @@
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/testFramework" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/resources" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="core-api" />
- <orderEntry type="module" module-name="testFramework" scope="TEST" />
<orderEntry type="module" module-name="vcs-impl" />
<orderEntry type="library" name="Guava" level="project" />
<orderEntry type="module" module-name="core-impl" />
diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/PushController.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/PushController.java
index 2a409e12c854..45f5c68e1d0a 100644
--- a/platform/dvcs-impl/src/com/intellij/dvcs/push/PushController.java
+++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/PushController.java
@@ -29,8 +29,11 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ValidationInfo;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.AbstractVcs;
import com.intellij.ui.CheckedTreeNode;
+import com.intellij.ui.SimpleColoredText;
+import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.hash.HashMap;
@@ -38,7 +41,6 @@ import com.intellij.vcs.log.VcsFullCommitDetails;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@@ -48,15 +50,15 @@ import java.util.concurrent.atomic.AtomicReference;
public class PushController implements Disposable {
@NotNull private final Project myProject;
- @NotNull private final List<PushSupport<? extends Repository>> myPushSupports;
+ @NotNull private final List<PushSupport<? extends Repository, ? extends PushSource, ? extends PushTarget>> myPushSupports;
@NotNull private final PushLog myPushLog;
@NotNull private final VcsPushDialog myDialog;
private boolean mySingleRepoProject;
private static final int DEFAULT_CHILDREN_PRESENTATION_NUMBER = 20;
private final Map<PushSupport, MyPushOptionValueModel> myAdditionalValuesMap;
- private final Map<RepositoryNode, MyRepoModel> myView2Model = new HashMap<RepositoryNode, MyRepoModel>();
-
+ private final Map<RepositoryNode, MyRepoModel> myView2Model = new TreeMap<RepositoryNode, MyRepoModel>();
+ //todo need to sort repositories in ui tree using natural order
public PushController(@NotNull Project project,
@NotNull VcsPushDialog dialog,
@@ -72,6 +74,20 @@ public class PushController implements Disposable {
myDialog.updateButtons();
startLoadingCommits();
Disposer.register(dialog.getDisposable(), this);
+ selectFirstChecked();
+ }
+
+ private void selectFirstChecked() {
+ Map.Entry<RepositoryNode, MyRepoModel> selected =
+ ContainerUtil.find(myView2Model.entrySet(), new Condition<Map.Entry<RepositoryNode, MyRepoModel>>() {
+ @Override
+ public boolean value(Map.Entry<RepositoryNode, MyRepoModel> entry) {
+ return entry.getValue().isSelected();
+ }
+ });
+ if (selected != null) {
+ myPushLog.selectNode(selected.getKey());
+ }
}
@Nullable
@@ -80,16 +96,8 @@ public class PushController implements Disposable {
for (Map.Entry<RepositoryNode, MyRepoModel> entry : myView2Model.entrySet()) {
MyRepoModel model = entry.getValue();
if (model.isSelected()) {
- //has one or more selected roots
+ if (model.hasError()) return new ValidationInfo(model.getError().getText());
validInfo = null;
- RepositoryNode node = entry.getKey();
- PushTarget target = model.getSpec().getTarget();
- //todo add validation for model -> hasErrors, too
- if (target == null) {
- JComponent editingComponent = myPushLog.startEditNode(node);
- return new ValidationInfo("Invalid remote for repository " + DvcsUtil.getShortRepositoryName(model.getRepository()),
- editingComponent);
- }
}
}
return validInfo;
@@ -123,36 +131,44 @@ public class PushController implements Disposable {
private boolean createTreeModel(@NotNull CheckedTreeNode rootNode, @NotNull List<? extends Repository> preselectedRepositories) {
if (myPushSupports.isEmpty()) return true;
int repoCount = 0;
- for (PushSupport<? extends Repository> support : myPushSupports) {
+ for (PushSupport<? extends Repository, ? extends PushSource, ? extends PushTarget> support : myPushSupports) {
repoCount += createNodesForVcs(support, rootNode, preselectedRepositories);
}
return repoCount == 1;
}
- private <T extends Repository> int createNodesForVcs(@NotNull PushSupport<T> pushSupport,
- @NotNull CheckedTreeNode rootNode,
- @NotNull List<? extends Repository> preselectedRepositories) {
- RepositoryManager<T> repositoryManager = pushSupport.getRepositoryManager();
- List<T> repositories = repositoryManager.getRepositories();
- for (T repository : repositories) {
+ private <R extends Repository, S extends PushSource, T extends PushTarget> int createNodesForVcs(
+ @NotNull PushSupport<R, S, T> pushSupport,
+ @NotNull CheckedTreeNode rootNode,
+ @NotNull List<? extends Repository> preselectedRepositories) {
+ RepositoryManager<R> repositoryManager = pushSupport.getRepositoryManager();
+ List<R> repositories = repositoryManager.getRepositories();
+ for (R repository : repositories) {
createRepoNode(pushSupport, repository, rootNode, preselectedRepositories.contains(repository), repositories.size() == 1);
}
return repositories.size();
}
- private <T extends Repository> void createRepoNode(@NotNull final PushSupport<T> support,
- @NotNull final T repository,
- @NotNull CheckedTreeNode rootNode,
- boolean isSelected,
- boolean isSingleRepositoryProject) {
- PushTarget target = support.getDefaultTarget(repository);
- final MyRepoModel model = new MyRepoModel(repository, support, isSelected, new PushSpec(support.getSource(repository), target),
- DEFAULT_CHILDREN_PRESENTATION_NUMBER);
- RepositoryWithBranchPanel repoPanel = new RepositoryWithBranchPanel(myProject, DvcsUtil.getShortRepositoryName(repository),
+ private <R extends Repository, S extends PushSource, T extends PushTarget> void createRepoNode(@NotNull final PushSupport<R, S, T> support,
+ @NotNull final R repository,
+ @NotNull CheckedTreeNode rootNode,
+ boolean isSelected,
+ boolean isSingleRepositoryProject) {
+ T target = support.getDefaultTarget(repository);
+ String repoName = DvcsUtil.getShortRepositoryName(repository);
+ final MyRepoModel<R, S, T> model = new MyRepoModel<R, S, T>(repository, support, isSingleRepositoryProject || isSelected,
+ support.getSource(repository), target,
+ DEFAULT_CHILDREN_PRESENTATION_NUMBER);
+ if (target == null) {
+ model.setError(VcsError.createEmptyTargetError(repoName));
+ }
+ RepositoryWithBranchPanel repoPanel = new RepositoryWithBranchPanel(myProject, repoName,
support.getSource(repository).getPresentation(),
target == null ? "" : target.getPresentation(),
support.getTargetNames(repository));
- final RepositoryNode repoNode = isSingleRepositoryProject ? new SingleRepositoryNode(repoPanel) : new RepositoryNode(repoPanel);
+ final RepositoryNode repoNode = isSingleRepositoryProject
+ ? new SingleRepositoryNode(repoPanel, support.renderTarget(target))
+ : new RepositoryNode(repoPanel, support.renderTarget(target));
myView2Model.put(repoNode, model);
repoNode.setChecked(model.isSelected());
repoPanel.addRepoNodeListener(new RepositoryNodeListener() {
@@ -160,19 +176,25 @@ public class PushController implements Disposable {
public void onTargetChanged(String newValue) {
VcsError validationError = support.validate(model.getRepository(), newValue);
if (validationError == null) {
- myView2Model.get(repoNode).setSpec(new PushSpec(model.getSpec().getSource(), support.createTarget(repository, newValue)));
+ T newTarget = support.createTarget(repository, newValue);
+ repoNode.setTargetPresentation(support.renderTarget(newTarget));
+ model.setTarget(newTarget);
+ model.clearErrors();
loadCommits(model, repoNode, false);
}
else {
- //todo may be should store validation errors in model and get errors during dialog validation
- myView2Model.get(repoNode).setSpec(new PushSpec(model.getSpec().getSource(), null));
+ repoNode.setTargetPresentation(StringUtil.isEmptyOrSpaces(newValue)
+ ? support.renderTarget(null)
+ : new SimpleColoredText(newValue, SimpleTextAttributes.ERROR_ATTRIBUTES));
+ model.setError(validationError); // todo may be should accept and store errors collection, now store one major target error
+ model.setTarget(null);
}
myDialog.updateButtons();
}
@Override
public void onSelectionChanged(boolean isSelected) {
- myView2Model.get(repoNode).setSelected(isSelected);
+ model.setSelected(isSelected);
repoNode.setChecked(isSelected);
myDialog.updateButtons();
}
@@ -180,13 +202,15 @@ public class PushController implements Disposable {
rootNode.add(repoNode);
}
- private void loadCommits(@NotNull final MyRepoModel model,
- @NotNull final RepositoryNode node,
- final boolean initial) {
+ private <R extends Repository, S extends PushSource, T extends PushTarget> void loadCommits(@NotNull final MyRepoModel<R, S, T> model,
+ @NotNull final RepositoryNode node,
+ final boolean initial) {
node.stopLoading();
+ final T target = model.getTarget();
+ if (target == null) return; //todo should be removed when commit loader executor will be modified
myPushLog.startLoading(node);
final ProgressIndicator indicator = node.startLoading();
- final PushSupport support = model.getSupport();
+ final PushSupport<R, S, T> support = model.getSupport();
final AtomicReference<OutgoingResult> result = new AtomicReference<OutgoingResult>();
Task.Backgroundable task = new Task.Backgroundable(myProject, "Loading Commits", true) {
@@ -229,7 +253,7 @@ public class PushController implements Disposable {
@Override
public void run(@NotNull ProgressIndicator indicator) {
OutgoingResult outgoing = support.getOutgoingCommitsProvider()
- .getOutgoingCommits(model.getRepository(), model.getSpec(), initial);
+ .getOutgoingCommits(model.getRepository(), new PushSpec<S, T>(model.getSource(), model.getTarget()), initial);
result.compareAndSet(null, outgoing);
}
};
@@ -237,8 +261,7 @@ public class PushController implements Disposable {
ProgressManagerImpl.runProcessWithProgressAsynchronously(task, indicator, null, ModalityState.any());
}
-
- public PushLog getPushPanelInfo() {
+ public PushLog getPushPanelLog() {
return myPushLog;
}
@@ -247,22 +270,32 @@ public class PushController implements Disposable {
@Override
public void run(@NotNull ProgressIndicator indicator) {
for (PushSupport support : myPushSupports) {
- MyPushOptionValueModel additionalOptionsModel = myAdditionalValuesMap.get(support);
- support.getPusher()
- .push(collectPushInfoForVcs(support), additionalOptionsModel == null ? null : additionalOptionsModel.getCurrentValue(), force);
+ doPush(support, force);
}
}
};
task.queue();
}
+ private <R extends Repository, S extends PushSource, T extends PushTarget> void doPush(@NotNull PushSupport<R, S, T> support,
+ boolean force) {
+ MyPushOptionValueModel additionalOptionsModel = myAdditionalValuesMap.get(support);
+ VcsPushOptionValue options = additionalOptionsModel == null ? null : additionalOptionsModel.getCurrentValue();
+ Pusher<R, S, T> pusher = support.getPusher();
+ pusher.push(collectPushSpecsForVcs(support), options, force);
+ }
+
@NotNull
- private Map<Repository, PushSpec> collectPushInfoForVcs(@NotNull final PushSupport pushSupport) {
- Map<Repository, PushSpec> pushSpecs = new HashMap<Repository, PushSpec>();
+ private <R extends Repository, S extends PushSource, T extends PushTarget> Map<R, PushSpec<S, T>> collectPushSpecsForVcs(@NotNull PushSupport<R, S, T> pushSupport) {
+ Map<R, PushSpec<S, T>> pushSpecs = ContainerUtil.newHashMap();
Collection<MyRepoModel> repositoriesInformation = getSelectedRepoNode();
for (MyRepoModel repoModel : repositoriesInformation) {
if (pushSupport.equals(repoModel.getSupport())) {
- pushSpecs.put(repoModel.getRepository(), repoModel.getSpec());
+ //todo improve generics: unchecked casts
+ T target = (T)repoModel.getTarget();
+ if (target != null) {
+ pushSpecs.put((R)repoModel.getRepository(), new PushSpec<S, T>((S)repoModel.getSource(), target));
+ }
}
}
return pushSpecs;
@@ -356,38 +389,53 @@ public class PushController implements Disposable {
});
}
- private static class MyRepoModel {
- @NotNull final Repository myRepository;
- @NotNull private PushSupport mySupport;
+ private static class MyRepoModel<Repo extends Repository, S extends PushSource, T extends PushTarget> {
+ @NotNull final Repo myRepository;
+ @NotNull private PushSupport<Repo, S, T> mySupport;
+ @NotNull private final S mySource;
+ @Nullable private T myTarget;
+ @Nullable VcsError myTargetError;
- @NotNull PushSpec mySpec;
int myNumberOfShownCommits;
-
List<? extends VcsFullCommitDetails> myLoadedCommits;
boolean myIsSelected;
- public MyRepoModel(@NotNull Repository repository,
- @NotNull PushSupport supportForRepo,
- boolean isSelected,
- @NotNull PushSpec spec,
+ public MyRepoModel(@NotNull Repo repository,
+ @NotNull PushSupport<Repo, S, T> supportForRepo,
+ boolean isSelected, @NotNull S source, @Nullable T target,
int num) {
myRepository = repository;
mySupport = supportForRepo;
myIsSelected = isSelected;
- mySpec = spec;
+ mySource = source;
+ myTarget = target;
myNumberOfShownCommits = num;
}
@NotNull
- public Repository getRepository() {
+ public Repo getRepository() {
return myRepository;
}
@NotNull
- public PushSupport getSupport() {
+ public PushSupport<Repo, S, T> getSupport() {
return mySupport;
}
+ @NotNull
+ public S getSource() {
+ return mySource;
+ }
+
+ @Nullable
+ public T getTarget() {
+ return myTarget;
+ }
+
+ public void setTarget(@Nullable T target) {
+ myTarget = target;
+ }
+
public boolean isSelected() {
return myIsSelected;
}
@@ -396,13 +444,21 @@ public class PushController implements Disposable {
return myRepository.getVcs();
}
- @NotNull
- public PushSpec getSpec() {
- return mySpec;
+ @Nullable
+ public VcsError getError() {
+ return myTargetError;
+ }
+
+ public void setError(@Nullable VcsError error) {
+ myTargetError = error;
+ }
+
+ public void clearErrors() {
+ myTargetError = null;
}
- public void setSpec(@NotNull PushSpec spec) {
- mySpec = spec;
+ public boolean hasError() {
+ return myTargetError != null;
}
public void setSelected(boolean isSelected) {
diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/EditableTreeNode.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/EditableTreeNode.java
index 5d0d20cdc4c0..b5747de91bf7 100644
--- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/EditableTreeNode.java
+++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/EditableTreeNode.java
@@ -20,7 +20,9 @@ import org.jetbrains.annotations.NotNull;
public interface EditableTreeNode extends CustomRenderedTreeNode {
- void fireOnChange(@NotNull String value);
+ void fireOnChange();
+
+ void fireOnCancel();
void fireOnSelectionChange(boolean isSelected);
diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/PushLog.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/PushLog.java
index b07bf9243f8a..0b4bcb0fbef0 100644
--- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/PushLog.java
+++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/PushLog.java
@@ -31,7 +31,6 @@ import com.intellij.util.ArrayUtil;
import com.intellij.util.ui.tree.TreeUtil;
import com.intellij.vcs.log.VcsFullCommitDetails;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.CellEditorListener;
@@ -56,6 +55,7 @@ public class PushLog extends JPanel implements TypeSafeDataProvider {
private final ChangesBrowser myChangesBrowser;
private final CheckboxTree myTree;
private final MyTreeCellRenderer myTreeCellRenderer;
+ //private final AtomicBoolean myIgnoreStopEditing = new AtomicBoolean(false);
public PushLog(Project project, CheckedTreeNode root) {
DefaultTreeModel treeModel = new DefaultTreeModel(root);
@@ -96,14 +96,17 @@ public class PushLog extends JPanel implements TypeSafeDataProvider {
treeCellEditor.addCellEditorListener(new CellEditorListener() {
@Override
public void editingStopped(ChangeEvent e) {
+ DefaultMutableTreeNode node = (DefaultMutableTreeNode)myTree.getLastSelectedPathComponent();
+ if (node != null && node instanceof EditableTreeNode) {
+ ((EditableTreeNode)node).fireOnChange();
+ }
}
@Override
public void editingCanceled(ChangeEvent e) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode)myTree.getLastSelectedPathComponent();
if (node != null && node instanceof EditableTreeNode) {
- //todo restore from appropriate editor
- ((EditableTreeNode)node).fireOnChange(((EditableTreeNode)node).getValue());
+ ((EditableTreeNode)node).fireOnCancel();
}
}
});
@@ -119,10 +122,13 @@ public class PushLog extends JPanel implements TypeSafeDataProvider {
TreePath[] nodes = myTree.getSelectionPaths();
if (nodes != null) {
ArrayList<Change> changes = new ArrayList<Change>();
- for (TreePath node : nodes) {
- Object nodeInfo = ((DefaultMutableTreeNode)node.getLastPathComponent()).getUserObject();
- if (nodeInfo instanceof VcsFullCommitDetails) {
- changes.addAll(((VcsFullCommitDetails)nodeInfo).getChanges());
+ for (TreePath path : nodes) {
+ if (path.getLastPathComponent() instanceof VcsFullCommitDetailsNode) {
+ VcsFullCommitDetailsNode commitDetailsNode = (VcsFullCommitDetailsNode)path.getLastPathComponent();
+ changes.addAll(commitDetailsNode.getUserObject().getChanges());
+ }
+ else if (path.getLastPathComponent() instanceof RepositoryNode) {
+ changes.addAll(collectAllChanges((RepositoryNode)path.getLastPathComponent()));
}
}
myChangesBrowser.getViewer().setEmptyText("No differences");
@@ -151,10 +157,29 @@ public class PushLog extends JPanel implements TypeSafeDataProvider {
add(splitter);
}
+ @NotNull
+ private static Collection<? extends Change> collectAllChanges(@NotNull RepositoryNode rootNode) {
+ ArrayList<Change> changes = new ArrayList<Change>();
+ if (rootNode.getChildCount() <= 0) return changes;
+ for (DefaultMutableTreeNode childNode = (DefaultMutableTreeNode)rootNode.getFirstChild();
+ childNode != null;
+ childNode = (DefaultMutableTreeNode)rootNode.getChildAfter(childNode)) {
+ if (childNode instanceof VcsFullCommitDetailsNode) {
+ changes.addAll(((VcsFullCommitDetailsNode)childNode).getUserObject().getChanges());
+ }
+ }
+ return changes;
+ }
+
private void setDefaultEmptyText() {
myChangesBrowser.getViewer().setEmptyText("No commits selected");
}
+ public void selectNode(@NotNull DefaultMutableTreeNode node) {
+ TreePath selectionPath = new TreePath(node.getPath());
+ myTree.addSelectionPath(selectionPath);
+ }
+
// Make changes available for diff action
@Override
public void calcData(DataKey key, DataSink sink) {
@@ -173,7 +198,7 @@ public class PushLog extends JPanel implements TypeSafeDataProvider {
@Override
protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, int condition, boolean pressed) {
if (e.getKeyCode() == KeyEvent.VK_ENTER && myTree.isEditing()) {
- myTree.cancelEditing();
+ myTree.stopEditing();
return true;
}
return super.processKeyBinding(ks, e, condition, pressed);
@@ -185,6 +210,10 @@ public class PushLog extends JPanel implements TypeSafeDataProvider {
setChildren(parentNode, Collections.singleton(loading));
}
+ public JComponent getPreferredFocusedComponent() {
+ return myTree;
+ }
+
private class MyTreeCellEditor extends DefaultCellEditor {
public MyTreeCellEditor(JTextField field) {
@@ -265,6 +294,7 @@ public class PushLog extends JPanel implements TypeSafeDataProvider {
final DefaultTreeModel model = ((DefaultTreeModel)myTree.getModel());
model.nodeStructureChanged(parentNode);
TreePath path = TreeUtil.getPathFromRoot(parentNode);
+ //myIgnoreStopEditing.set(true);
if (shouldExpand) {
myTree.expandPath(path);
}
@@ -274,16 +304,15 @@ public class PushLog extends JPanel implements TypeSafeDataProvider {
}
finally {
TREE_CONSTRUCTION_LOCK.writeLock().unlock();
+ //myIgnoreStopEditing.set(false);
}
}
- @Nullable
- public JComponent startEditNode(@NotNull TreeNode node) {
+ public void startEditNode(@NotNull TreeNode node) {
TreePath path = TreeUtil.getPathFromRoot(node);
if (!myTree.isEditing()) {
+ myTree.setSelectionPath(path);
myTree.startEditingAtPath(path);
}
- return (JComponent)myTree.getCellEditor()
- .getTreeCellEditorComponent(myTree, node, false, false, false, myTree.getRowForPath(path));
}
}
diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryNode.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryNode.java
index 24a26ece96d9..05e752c4be85 100644
--- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryNode.java
+++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryNode.java
@@ -17,26 +17,27 @@ package com.intellij.dvcs.push.ui;
import com.intellij.openapi.progress.EmptyProgressIndicator;
import com.intellij.openapi.progress.ProgressIndicator;
-import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.ui.CheckedTreeNode;
-import com.intellij.ui.ColoredTreeCellRenderer;
-import com.intellij.ui.EditorTextField;
-import com.intellij.ui.SimpleTextAttributes;
+import com.intellij.ui.*;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
+import java.util.ArrayList;
-public class RepositoryNode extends CheckedTreeNode implements EditableTreeNode {
- protected final static String ENTER_REMOTE = "Enter Remote";
+public class RepositoryNode extends CheckedTreeNode implements EditableTreeNode, Comparable<RepositoryNode> {
@NotNull private final RepositoryWithBranchPanel myRepositoryPanel;
-
+ @NotNull protected SimpleColoredText myTargetPresentation;
private ProgressIndicator myCurrentIndicator;
- public RepositoryNode(@NotNull RepositoryWithBranchPanel repositoryPanel) {
+ public RepositoryNode(@NotNull RepositoryWithBranchPanel repositoryPanel, @NotNull SimpleColoredText targetPresentation) {
super(repositoryPanel);
myRepositoryPanel = repositoryPanel;
+ myTargetPresentation = targetPresentation;
+ }
+
+ public void setTargetPresentation(@NotNull SimpleColoredText targetPresentation) {
+ myTargetPresentation = targetPresentation;
}
public boolean isCheckboxVisible() {
@@ -51,30 +52,38 @@ public class RepositoryNode extends CheckedTreeNode implements EditableTreeNode
renderer.append(myRepositoryPanel.getSourceName(), SimpleTextAttributes.REGULAR_ATTRIBUTES);
renderer.append(myRepositoryPanel.getArrow(), SimpleTextAttributes.REGULAR_ATTRIBUTES);
EditorTextField textField = myRepositoryPanel.getRemoteTextFiled();
- renderTargetName(renderer, textField, myRepositoryPanel.getRemoteTargetName());
+ renderTargetName(renderer, textField);
Insets insets = BorderFactory.createEmptyBorder().getBorderInsets(textField);
renderer.setBorder(new EmptyBorder(insets));
}
- protected void renderTargetName(@NotNull ColoredTreeCellRenderer renderer, @NotNull EditorTextField textField,
- @NotNull String targetName) {
- if (StringUtil.isEmptyOrSpaces(targetName)) {
- renderer.append(ENTER_REMOTE, SimpleTextAttributes.GRAY_ITALIC_ATTRIBUTES, textField);
- }
- else {
- renderer.append(targetName, SimpleTextAttributes.SYNTHETIC_ATTRIBUTES, textField);
+ protected void renderTargetName(@NotNull ColoredTreeCellRenderer renderer, @NotNull EditorTextField textField) {
+ ArrayList<String> strings = myTargetPresentation.getTexts();
+ ArrayList<SimpleTextAttributes> attributes = myTargetPresentation.getAttributes();
+ for (int i = 0; i < strings.size(); i++) {
+ renderer.append(strings.get(i), attributes.get(i), textField);
}
}
@Override
+ public Object getUserObject() {
+ return myRepositoryPanel;
+ }
+
+ @Override
@NotNull
public String getValue() {
return myRepositoryPanel.getRemoteTargetName();
}
@Override
- public void fireOnChange(@NotNull String value) {
- myRepositoryPanel.fireOnChange(value);
+ public void fireOnChange() {
+ myRepositoryPanel.fireOnChange();
+ }
+
+ @Override
+ public void fireOnCancel() {
+ myRepositoryPanel.fireOnCancel();
}
@Override
@@ -94,4 +103,10 @@ public class RepositoryNode extends CheckedTreeNode implements EditableTreeNode
public ProgressIndicator startLoading() {
return myCurrentIndicator = new EmptyProgressIndicator();
}
+
+ public int compareTo(@NotNull RepositoryNode repositoryNode) {
+ String name = myRepositoryPanel.getRepositoryName();
+ RepositoryWithBranchPanel panel = (RepositoryWithBranchPanel)repositoryNode.getUserObject();
+ return name.compareTo(panel.getRepositoryName());
+ }
}
diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryWithBranchPanel.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryWithBranchPanel.java
index c1afcdd52839..cd93d0653c36 100644
--- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryWithBranchPanel.java
+++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryWithBranchPanel.java
@@ -36,7 +36,6 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
-import java.util.Collection;
import java.util.List;
public class RepositoryWithBranchPanel extends NonOpaquePanel implements TreeCellRenderer {
@@ -48,12 +47,14 @@ public class RepositoryWithBranchPanel extends NonOpaquePanel implements TreeCel
private final JLabel myRepositoryLabel;
private final ColoredTreeCellRenderer myTextRenderer;
@NotNull private final List<RepositoryNodeListener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
+ private String myOldDestination;
public RepositoryWithBranchPanel(Project project, @NotNull String repoName,
- @NotNull String sourceName, String targetName, @NotNull Collection<String> targetVariants) {
+ @NotNull String sourceName, String targetName, @NotNull final List<String> targetVariants) {
super();
setLayout(new BorderLayout());
myRepositoryCheckbox = new JBCheckBox();
+ myRepositoryCheckbox.setFocusable(false);
myRepositoryCheckbox.setOpaque(false);
myRepositoryCheckbox.addActionListener(new ActionListener() {
@Override
@@ -64,8 +65,14 @@ public class RepositoryWithBranchPanel extends NonOpaquePanel implements TreeCel
myRepositoryLabel = new JLabel(repoName);
myLocalBranch = new JBLabel(sourceName);
myArrowLabel = new JLabel(" -> ");
+ myOldDestination = targetName;
TextFieldWithAutoCompletionListProvider<String> provider =
- new TextFieldWithAutoCompletion.StringsCompletionProvider(targetVariants, null);
+ new TextFieldWithAutoCompletion.StringsCompletionProvider(targetVariants, null) {
+ @Override
+ public int compare(String item1, String item2) {
+ return Integer.valueOf(ContainerUtil.indexOf(targetVariants, item1)).compareTo(ContainerUtil.indexOf(targetVariants, item2));
+ }
+ };
myDestBranchTextField = new TextFieldWithAutoCompletion<String>(project, provider, true, targetName) {
@Override
@@ -77,15 +84,17 @@ public class RepositoryWithBranchPanel extends NonOpaquePanel implements TreeCel
protected void updateBorder(@NotNull final EditorEx editor) {
}
};
- myDestBranchTextField.setBorder(UIUtil.getTableFocusCellHighlightBorder());//getTextFieldBorder());
+ myDestBranchTextField.setBorder(UIUtil.getTableFocusCellHighlightBorder());
myDestBranchTextField.setOneLineMode(true);
myDestBranchTextField.setOpaque(true);
- myDestBranchTextField.addFocusListener(new FocusAdapter() {
+ FocusAdapter focusListener = new FocusAdapter() {
@Override
public void focusGained(FocusEvent e) {
myDestBranchTextField.selectAll();
}
- });
+ };
+ myDestBranchTextField.addFocusListener(focusListener);
+ addFocusListener(focusListener);
myTextRenderer = new ColoredTreeCellRenderer() {
public void customizeCellRenderer(@NotNull JTree tree,
@@ -169,9 +178,10 @@ public class RepositoryWithBranchPanel extends NonOpaquePanel implements TreeCel
myListeners.add(listener);
}
- public void fireOnChange(@NotNull String newValue) {
+ public void fireOnChange() {
+ myOldDestination = myDestBranchTextField.getText();
for (RepositoryNodeListener listener : myListeners) {
- listener.onTargetChanged(newValue);
+ listener.onTargetChanged(myOldDestination);
}
}
@@ -180,6 +190,10 @@ public class RepositoryWithBranchPanel extends NonOpaquePanel implements TreeCel
listener.onSelectionChanged(isSelected);
}
}
+
+ public void fireOnCancel() {
+ myDestBranchTextField.setText(myOldDestination);
+ }
}
diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/SingleRepositoryNode.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/SingleRepositoryNode.java
index c566dd6f2867..81fb2bd1a9d0 100644
--- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/SingleRepositoryNode.java
+++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/SingleRepositoryNode.java
@@ -17,6 +17,7 @@ package com.intellij.dvcs.push.ui;
import com.intellij.ui.ColoredTreeCellRenderer;
import com.intellij.ui.EditorTextField;
+import com.intellij.ui.SimpleColoredText;
import com.intellij.ui.SimpleTextAttributes;
import org.jetbrains.annotations.NotNull;
@@ -28,8 +29,8 @@ public class SingleRepositoryNode extends RepositoryNode {
@NotNull private final RepositoryWithBranchPanel myRepositoryPanel;
- public SingleRepositoryNode(@NotNull RepositoryWithBranchPanel repositoryPanel) {
- super(repositoryPanel);
+ public SingleRepositoryNode(@NotNull RepositoryWithBranchPanel repositoryPanel, @NotNull SimpleColoredText customTargetPresentation) {
+ super(repositoryPanel, customTargetPresentation);
myRepositoryPanel = repositoryPanel;
}
@@ -43,10 +44,8 @@ public class SingleRepositoryNode extends RepositoryNode {
renderer.append(myRepositoryPanel.getSourceName(), SimpleTextAttributes.REGULAR_ATTRIBUTES);
renderer.append(myRepositoryPanel.getArrow(), SimpleTextAttributes.REGULAR_ATTRIBUTES);
EditorTextField textField = myRepositoryPanel.getRemoteTextFiled();
- String targetName = myRepositoryPanel.getRemoteTargetName();
- renderTargetName(renderer, textField, targetName);
+ renderTargetName(renderer, textField);
Insets insets = BorderFactory.createEmptyBorder().getBorderInsets(textField);
renderer.setBorder(new EmptyBorder(insets));
}
-
}
diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsFullCommitDetailsNode.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsFullCommitDetailsNode.java
index 0df7af05d496..51e8aaf3e9db 100644
--- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsFullCommitDetailsNode.java
+++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsFullCommitDetailsNode.java
@@ -17,6 +17,7 @@ package com.intellij.dvcs.push.ui;
import com.intellij.dvcs.DvcsUtil;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.changes.issueLinks.IssueLinkHtmlRenderer;
import com.intellij.ui.ColoredTreeCellRenderer;
import com.intellij.ui.SimpleTextAttributes;
@@ -30,16 +31,21 @@ public class VcsFullCommitDetailsNode extends DefaultMutableTreeNode implements
@NotNull private final Project myProject;
private final VcsFullCommitDetails myCommit;
- public VcsFullCommitDetailsNode(@NotNull Project project, VcsFullCommitDetails commit) {
+ public VcsFullCommitDetailsNode(@NotNull Project project, @NotNull VcsFullCommitDetails commit) {
super(commit, false);
myProject = project;
myCommit = commit;
}
@Override
+ public VcsFullCommitDetails getUserObject() {
+ return myCommit;
+ }
+
+ @Override
public void render(@NotNull ColoredTreeCellRenderer renderer) {
- renderer
- .append(myCommit.getSubject(), new SimpleTextAttributes(SimpleTextAttributes.STYLE_SMALLER, renderer.getForeground()));
+ String subject = StringUtil.shortenTextWithEllipsis(myCommit.getSubject(), 80, 0);
+ renderer.append(subject, new SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN, renderer.getForeground()));
}
public String getTooltip() {
diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsPushDialog.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsPushDialog.java
index b441952f7a43..22f1e74abbbd 100644
--- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsPushDialog.java
+++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsPushDialog.java
@@ -15,11 +15,13 @@
*/
package com.intellij.dvcs.push.ui;
+import com.intellij.CommonBundle;
import com.intellij.dvcs.push.PushController;
import com.intellij.dvcs.push.VcsPushOptionsPanel;
import com.intellij.dvcs.repo.Repository;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.OptionAction;
import com.intellij.openapi.ui.ValidationInfo;
import net.miginfocom.swing.MigLayout;
@@ -32,8 +34,11 @@ import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.List;
+import static com.intellij.openapi.ui.Messages.OK;
+
public class VcsPushDialog extends DialogWrapper {
+ @NotNull private final Project myProject;
private final PushLog myListPanel;
private final PushController myController;
private final Action[] myExecutorActions = {new DvcsPushAction("&Force Push", true)};
@@ -43,8 +48,9 @@ public class VcsPushDialog extends DialogWrapper {
public VcsPushDialog(@NotNull Project project, @NotNull List<? extends Repository> selectedRepositories) {
super(project);
+ myProject = project;
myController = new PushController(project, this, selectedRepositories);
- myListPanel = myController.getPushPanelInfo();
+ myListPanel = myController.getPushPanelLog();
myAdditionalOptionsFromVcsPanel = new JPanel(new MigLayout("ins 0 0, flowx"));
init();
setOKButtonText("Push");
@@ -82,6 +88,12 @@ public class VcsPushDialog extends DialogWrapper {
return actions.toArray(new Action[actions.size()]);
}
+ @Nullable
+ @Override
+ public JComponent getPreferredFocusedComponent() {
+ return myListPanel.getPreferredFocusedComponent();
+ }
+
@NotNull
@Override
protected Action getOKAction() {
@@ -127,6 +139,12 @@ public class VcsPushDialog extends DialogWrapper {
@Override
public void actionPerformed(ActionEvent e) {
+ if (myForce) {
+ int answer = Messages.showOkCancelDialog(myProject, getConfirmationMessage(),
+ "Force Push",
+ "&Force Push", CommonBundle.getCancelButtonText(), Messages.getWarningIcon());
+ if (answer != OK) return;
+ }
myController.push(myForce);
close(OK_EXIT_CODE);
}
@@ -141,4 +159,9 @@ public class VcsPushDialog extends DialogWrapper {
myOptions = actions;
}
}
+
+ @NotNull
+ private static String getConfirmationMessage() {
+ return "You're going to force push. It will overwrite commits at the remote. Are you sure you want to proceed?";
+ }
}
diff --git a/platform/dvcs-impl/testFramework/com/intellij/dvcs/test/MockProject.java b/platform/dvcs-impl/testFramework/com/intellij/dvcs/test/MockProject.java
deleted file mode 100644
index a8dc262d7be1..000000000000
--- a/platform/dvcs-impl/testFramework/com/intellij/dvcs/test/MockProject.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright 2000-2013 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.dvcs.test;
-
-import com.intellij.openapi.components.BaseComponent;
-import com.intellij.openapi.extensions.ExtensionPointName;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Condition;
-import com.intellij.openapi.util.Key;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.messages.MessageBus;
-import org.jetbrains.annotations.NotNull;
-import org.picocontainer.PicoContainer;
-
-/**
- *
- * @author Kirill Likhodedov
- */
-public class MockProject implements Project {
-
- private final String myProjectDir;
-
- public MockProject(String projectDir) {
- myProjectDir = projectDir;
- }
-
- @NotNull
- @Override
- public String getName() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public VirtualFile getBaseDir() {
- return new MockVirtualFile(myProjectDir);
- }
-
- @Override
- public String getBasePath() {
- return myProjectDir;
- }
-
- @Override
- public VirtualFile getProjectFile() {
- throw new UnsupportedOperationException();
- }
-
- @NotNull
- @Override
- public String getProjectFilePath() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public String getPresentableUrl() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public VirtualFile getWorkspaceFile() {
- throw new UnsupportedOperationException();
- }
-
- @NotNull
- @Override
- public String getLocationHash() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void save() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean isOpen() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean isInitialized() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean isDefault() {
- return false;
- }
-
- @Override
- public BaseComponent getComponent(@NotNull String name) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public <T> T getComponent(@NotNull Class<T> interfaceClass) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public <T> T getComponent(@NotNull Class<T> interfaceClass, T defaultImplementationIfAbsent) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean hasComponent(@NotNull Class interfaceClass) {
- throw new UnsupportedOperationException();
- }
-
- @NotNull
- @Override
- public <T> T[] getComponents(@NotNull Class<T> baseClass) {
- throw new UnsupportedOperationException();
- }
-
- @NotNull
- @Override
- public PicoContainer getPicoContainer() {
- throw new UnsupportedOperationException();
- }
-
- @NotNull
- @Override
- public MessageBus getMessageBus() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean isDisposed() {
- return false;
- }
-
- @NotNull
- @Override
- public <T> T[] getExtensions(@NotNull ExtensionPointName<T> extensionPointName) {
- throw new UnsupportedOperationException();
- }
-
- @NotNull
- @Override
- public Condition getDisposed() {
- return Condition.FALSE;
- }
-
- @Override
- public void dispose() {
- }
-
- @Override
- public <T> T getUserData(@NotNull Key<T> key) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public <T> void putUserData(@NotNull Key<T> key, T value) {
- throw new UnsupportedOperationException();
- }
-}
diff --git a/platform/dvcs-impl/testFramework/com/intellij/dvcs/test/MockProjectRootManager.java b/platform/dvcs-impl/testFramework/com/intellij/dvcs/test/MockProjectRootManager.java
deleted file mode 100644
index d89b92878f54..000000000000
--- a/platform/dvcs-impl/testFramework/com/intellij/dvcs/test/MockProjectRootManager.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright 2000-2014 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.dvcs.test;
-
-import com.intellij.openapi.module.Module;
-import com.intellij.openapi.projectRoots.Sdk;
-import com.intellij.openapi.roots.OrderEnumerator;
-import com.intellij.openapi.roots.ProjectFileIndex;
-import com.intellij.openapi.roots.ProjectRootManager;
-import com.intellij.openapi.vfs.VirtualFile;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
-
-/**
- *
- * @author Kirill Likhodedov
- */
-public class MockProjectRootManager extends ProjectRootManager {
- private final List<VirtualFile> myContentRoots = new ArrayList<VirtualFile>();
-
- @NotNull
- @Override
- public VirtualFile[] getContentRoots() {
- VirtualFile[] roots = new VirtualFile[myContentRoots.size()];
- for (int i = 0; i < myContentRoots.size(); i++) {
- roots[i] = myContentRoots.get(i);
- }
- return roots;
- }
-
- @NotNull
- @Override
- public ProjectFileIndex getFileIndex() {
- throw new UnsupportedOperationException();
- }
-
- @NotNull
- @Override
- public OrderEnumerator orderEntries() {
- throw new UnsupportedOperationException();
- }
-
- @NotNull
- @Override
- public OrderEnumerator orderEntries(@NotNull Collection<? extends Module> modules) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public VirtualFile[] getContentRootsFromAllModules() {
- throw new UnsupportedOperationException();
- }
-
- @NotNull
- @Override
- public List<String> getContentRootUrls() {
- throw new UnsupportedOperationException();
- }
-
- @NotNull
- @Override
- public VirtualFile[] getContentSourceRoots() {
- throw new UnsupportedOperationException();
- }
-
- @NotNull
- @Override
- public List<VirtualFile> getModuleSourceRoots(@NotNull Set<? extends JpsModuleSourceRootType<?>> rootTypes) {
- throw new UnsupportedOperationException("'getContentSourceRoots' not implemented in " + getClass().getName());
- }
-
- @Override
- public Sdk getProjectSdk() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public String getProjectSdkName() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void setProjectSdk(Sdk sdk) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void setProjectSdkName(String name) {
- throw new UnsupportedOperationException();
- }
-}
diff --git a/platform/editor-ui-api/src/com/intellij/ide/ui/UISettings.java b/platform/editor-ui-api/src/com/intellij/ide/ui/UISettings.java
index aff6216c3dba..9f5f5d5720da 100644
--- a/platform/editor-ui-api/src/com/intellij/ide/ui/UISettings.java
+++ b/platform/editor-ui-api/src/com/intellij/ide/ui/UISettings.java
@@ -64,7 +64,8 @@ public class UISettings extends SimpleModificationTracker implements PersistentS
*/
public static UISettings getShadowInstance() {
Application application = ApplicationManager.getApplication();
- return application != null ? getInstance() : new UISettings();
+ UISettings settings = application == null ? null : application.getComponent(UISettings.class);
+ return settings == null ? new UISettings() : settings;
}
@Property(filter = FontFilter.class) public String FONT_FACE;
diff --git a/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/ActionManager.java b/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/ActionManager.java
index 5577664bf9f7..ee850c3fe060 100644
--- a/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/ActionManager.java
+++ b/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/ActionManager.java
@@ -20,6 +20,7 @@ import com.intellij.openapi.actionSystem.ex.AnActionListener;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ApplicationComponent;
import com.intellij.openapi.extensions.PluginId;
+import com.intellij.openapi.project.ProjectType;
import com.intellij.openapi.util.ActionCallback;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -80,7 +81,7 @@ public abstract class ActionManager implements ApplicationComponent {
* @param actionId Id of the registered action
*
* @return Action associated with the specified actionId, <code>null</code> if
- * there is no actions associated with the speicified actionId
+ * there is no actions associated with the specified actionId
*
* @exception java.lang.IllegalArgumentException if <code>actionId</code> is <code>null</code>
*
@@ -89,6 +90,20 @@ public abstract class ActionManager implements ApplicationComponent {
public abstract AnAction getAction(@NonNls @NotNull String actionId);
/**
+ * Returns action associated with the specified actionId.
+ *
+ * @param actionId Id of the registered action
+ *
+ * @return Action associated with the specified actionId, <code>null</code> if
+ * there is no actions associated with the specified actionId
+ *
+ * @exception java.lang.IllegalArgumentException if <code>actionId</code> is <code>null</code>
+ *
+ * @see com.intellij.openapi.actionSystem.IdeActions
+ */
+ public abstract AnAction getAction(@NonNls @NotNull String actionId, @Nullable ProjectType projectType);
+
+ /**
* Returns actionId associated with the specified action.
*
* @return id associated with the specified action, <code>null</code> if action
diff --git a/platform/editor-ui-api/src/com/intellij/openapi/editor/Caret.java b/platform/editor-ui-api/src/com/intellij/openapi/editor/Caret.java
index ba0743b4cfb0..fc824844be6e 100644
--- a/platform/editor-ui-api/src/com/intellij/openapi/editor/Caret.java
+++ b/platform/editor-ui-api/src/com/intellij/openapi/editor/Caret.java
@@ -198,6 +198,8 @@ public interface Caret extends UserDataHolderEx, Disposable {
/**
* Selects the specified range of text.
+ * <p>
+ * System selection will be updated, if such feature is supported by current editor.
*
* @param startOffset the start offset of the text range to select.
* @param endOffset the end offset of the text range to select.
@@ -205,11 +207,22 @@ public interface Caret extends UserDataHolderEx, Disposable {
void setSelection(int startOffset, int endOffset);
/**
+ * Selects the specified range of text.
+ *
+ * @param startOffset the start offset of the text range to select.
+ * @param endOffset the end offset of the text range to select.
+ * @param updateSystemSelection whether system selection should be updated (might not have any effect if current editor doesn't support such a feature)
+ */
+ void setSelection(int startOffset, int endOffset, boolean updateSystemSelection);
+
+ /**
* Selects target range providing information about visual boundary of selection end.
* <p/>
* That is the case for soft wraps-aware processing where the whole soft wraps virtual space is matched to the same offset.
* <p/>
* Also, in column mode this method allows to create selection spanning virtual space after the line end.
+ * <p>
+ * System selection will be updated, if such feature is supported by current editor.
*
* @param startOffset start selection offset
* @param endPosition end visual position of the text range to select (<code>null</code> argument means that
@@ -224,6 +237,8 @@ public interface Caret extends UserDataHolderEx, Disposable {
* That is the case for soft wraps-aware processing where the whole soft wraps virtual space is matched to the same offset.
* <p/>
* Also, in column mode this method allows to create selection spanning virtual space after the line end.
+ * <p>
+ * System selection will be updated, if such feature is supported by current editor.
*
* @param startPosition start visual position of the text range to select (<code>null</code> argument means that
* no specific visual position should be used)
@@ -235,6 +250,23 @@ public interface Caret extends UserDataHolderEx, Disposable {
void setSelection(@Nullable VisualPosition startPosition, int startOffset, @Nullable VisualPosition endPosition, int endOffset);
/**
+ * Selects target range based on its visual boundaries.
+ * <p/>
+ * That is the case for soft wraps-aware processing where the whole soft wraps virtual space is matched to the same offset.
+ * <p/>
+ * Also, in column mode this method allows to create selection spanning virtual space after the line end.
+ *
+ * @param startPosition start visual position of the text range to select (<code>null</code> argument means that
+ * no specific visual position should be used)
+ * @param endPosition end visual position of the text range to select (<code>null</code> argument means that
+ * no specific visual position should be used)
+ * @param startOffset start selection offset
+ * @param endOffset end selection offset
+ * @param updateSystemSelection whether system selection should be updated (might not have any effect if current editor doesn't support such a feature)
+ */
+ void setSelection(@Nullable VisualPosition startPosition, int startOffset, @Nullable VisualPosition endPosition, int endOffset, boolean updateSystemSelection);
+
+ /**
* Removes the selection in the editor.
*/
void removeSelection();
diff --git a/platform/editor-ui-api/src/com/intellij/openapi/editor/CaretModel.java b/platform/editor-ui-api/src/com/intellij/openapi/editor/CaretModel.java
index df247d5be401..a5053923fa31 100644
--- a/platform/editor-ui-api/src/com/intellij/openapi/editor/CaretModel.java
+++ b/platform/editor-ui-api/src/com/intellij/openapi/editor/CaretModel.java
@@ -222,6 +222,8 @@ public interface CaretModel {
* selection boundaries will mean that corresponding caret's position and/or selection won't be changed.
* <p>
* If multiple carets are not supported, the behaviour is unspecified.
+ * <p>
+ * System selection will be updated, if such feature is supported by current editor.
*
* @see #supportsMultipleCarets()
* @see #getCaretsAndSelections()
@@ -229,6 +231,20 @@ public interface CaretModel {
void setCaretsAndSelections(@NotNull List<CaretState> caretStates);
/**
+ * Sets the number of carets, their positions and selection ranges according to the provided data. Null values for caret position or
+ * selection boundaries will mean that corresponding caret's position and/or selection won't be changed.
+ * <p>
+ * If multiple carets are not supported, the behaviour is unspecified.
+ * <p>
+ * System selection will be updated, if such feature is supported by current editor
+ * and corresponding invocation parameter is set to <code>true</code>.
+ *
+ * @see #supportsMultipleCarets()
+ * @see #getCaretsAndSelections()
+ */
+ void setCaretsAndSelections(@NotNull List<CaretState> caretStates, boolean updateSystemSelection);
+
+ /**
* Returns the current positions of all carets and their selections. The order of entries in the returned list does not necessarily
* correspond to the order of {@link #getAllCarets()} method results. Passing the result of this method to
* {@link #setCaretsAndSelections(java.util.List)} will restore the state of carets, including the internal caret order, in particular,
diff --git a/platform/editor-ui-api/src/com/intellij/openapi/editor/colors/FontPreferences.java b/platform/editor-ui-api/src/com/intellij/openapi/editor/colors/FontPreferences.java
index 557d41435878..5d2038d171ea 100644
--- a/platform/editor-ui-api/src/com/intellij/openapi/editor/colors/FontPreferences.java
+++ b/platform/editor-ui-api/src/com/intellij/openapi/editor/colors/FontPreferences.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -226,4 +226,9 @@ public class FontPreferences {
}
return null;
}
+
+ @Override
+ public String toString() {
+ return "Effective font families: " + myEffectiveFontFamilies;
+ }
}
diff --git a/platform/editor-ui-api/src/com/intellij/openapi/editor/event/EditorFactoryListener.java b/platform/editor-ui-api/src/com/intellij/openapi/editor/event/EditorFactoryListener.java
index b8bd41980b7c..1d8ddcc2930b 100644
--- a/platform/editor-ui-api/src/com/intellij/openapi/editor/event/EditorFactoryListener.java
+++ b/platform/editor-ui-api/src/com/intellij/openapi/editor/event/EditorFactoryListener.java
@@ -23,7 +23,13 @@ import java.util.EventListener;
* @see {@link com.intellij.openapi.editor.EditorFactory#addEditorFactoryListener(com.intellij.openapi.editor.event.EditorFactoryListener, com.intellij.openapi.Disposable)}
*/
public interface EditorFactoryListener extends EventListener {
+ /**
+ * Called after {@link com.intellij.openapi.editor.Editor} instance has been created.
+ */
void editorCreated(@NotNull EditorFactoryEvent event);
+ /**
+ * Called before {@link com.intellij.openapi.editor.Editor} instance will be released.
+ */
void editorReleased(@NotNull EditorFactoryEvent event);
}
diff --git a/platform/extensions/src/com/intellij/openapi/extensions/Extensions.java b/platform/extensions/src/com/intellij/openapi/extensions/Extensions.java
index 1c0152514e33..bf61094015f0 100644
--- a/platform/extensions/src/com/intellij/openapi/extensions/Extensions.java
+++ b/platform/extensions/src/com/intellij/openapi/extensions/Extensions.java
@@ -28,15 +28,16 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class Extensions {
- private static LogProvider ourLogger = new SimpleLogProvider();
-
public static final ExtensionPointName<AreaListener> AREA_LISTENER_EXTENSION_POINT = new ExtensionPointName<AreaListener>("com.intellij.arealistener");
-
+ private static LogProvider ourLogger = new SimpleLogProvider();
private static Map<AreaInstance,ExtensionsAreaImpl> ourAreaInstance2area = new THashMap<AreaInstance, ExtensionsAreaImpl>();
private static Map<String,AreaClassConfiguration> ourAreaClass2Configuration = new THashMap<String, AreaClassConfiguration>();
@NotNull private static ExtensionsAreaImpl ourRootArea = createRootArea();
+ private Extensions() {
+ }
+
@NotNull
private static ExtensionsAreaImpl createRootArea() {
ExtensionsAreaImpl rootArea = new ExtensionsAreaImpl(null, null, null, ourLogger);
@@ -44,9 +45,6 @@ public class Extensions {
return rootArea;
}
- private Extensions() {
- }
-
public static void setSynchronized() {
assert ourAreaInstance2area.isEmpty();
assert ourAreaClass2Configuration.isEmpty();
@@ -101,6 +99,7 @@ public class Extensions {
@NotNull
@SuppressWarnings({"unchecked"})
public static <T> T[] getExtensions(@NotNull ExtensionPointName<T> extensionPointName, AreaInstance areaInstance) {
+ // keep it until 1.7 JDK
return Extensions.<T>getExtensions(extensionPointName.getName(), areaInstance);
}
diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/RemoteExternalSystemCommunicationManager.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/RemoteExternalSystemCommunicationManager.java
index 2cc4b2eb5cca..e17d2443da61 100644
--- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/RemoteExternalSystemCommunicationManager.java
+++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/RemoteExternalSystemCommunicationManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,9 +30,9 @@ import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.process.ProcessTerminatedListener;
import com.intellij.execution.rmi.RemoteProcessSupport;
import com.intellij.execution.runners.ProgramRunner;
-import com.intellij.ide.actions.OpenProjectFileChooserDescriptor;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.components.impl.stores.StorageUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.externalSystem.ExternalSystemManager;
@@ -136,7 +136,7 @@ public class RemoteExternalSystemCommunicationManager implements ExternalSystemC
ContainerUtil.addIfNotNull(PathUtil.getJarPathForClass(Alarm.class), classPath);
ContainerUtil.addIfNotNull(PathUtil.getJarPathForClass(DependencyScope.class), classPath);
ContainerUtil.addIfNotNull(PathUtil.getJarPathForClass(ExtensionPointName.class), classPath);
- ContainerUtil.addIfNotNull(PathUtil.getJarPathForClass(OpenProjectFileChooserDescriptor.class), classPath);
+ ContainerUtil.addIfNotNull(PathUtil.getJarPathForClass(StorageUtil.class), classPath);
ContainerUtil.addIfNotNull(PathUtil.getJarPathForClass(ExternalSystemTaskNotificationListener.class), classPath);
// External system module jars
diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskRunner.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskRunner.java
index d45be42bbbd9..4fc22b2e517b 100644
--- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskRunner.java
+++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskRunner.java
@@ -25,7 +25,6 @@ import com.intellij.execution.runners.GenericProgramRunner;
import com.intellij.execution.runners.RunContentBuilder;
import com.intellij.execution.ui.RunContentDescriptor;
import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
-import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -48,11 +47,8 @@ public class ExternalSystemTaskRunner extends GenericProgramRunner {
@Nullable
@Override
- protected RunContentDescriptor doExecute(@NotNull Project project,
- @NotNull RunProfileState state,
- RunContentDescriptor contentToReuse,
- @NotNull ExecutionEnvironment env) throws ExecutionException {
+ protected RunContentDescriptor doExecute(@NotNull RunProfileState state, @NotNull ExecutionEnvironment env) throws ExecutionException {
ExecutionResult executionResult = state.execute(env.getExecutor(), this);
- return executionResult == null ? null : new RunContentBuilder(executionResult, env).showRunContent(contentToReuse);
+ return executionResult == null ? null : new RunContentBuilder(executionResult, env).showRunContent(env.getContentToReuse());
}
}
diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/AbstractExternalSystemToolWindowFactory.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/AbstractExternalSystemToolWindowFactory.java
index 1e08045faeea..a5bf2827ef26 100644
--- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/AbstractExternalSystemToolWindowFactory.java
+++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/AbstractExternalSystemToolWindowFactory.java
@@ -28,6 +28,8 @@ import com.intellij.ui.content.ContentManager;
import com.intellij.ui.content.impl.ContentImpl;
import org.jetbrains.annotations.NotNull;
+import java.util.Locale;
+
/**
* @author Denis Zhdanov
* @since 5/13/13 4:15 PM
@@ -39,9 +41,8 @@ public abstract class AbstractExternalSystemToolWindowFactory implements ToolWin
protected AbstractExternalSystemToolWindowFactory(@NotNull ProjectSystemId id) {
myExternalSystemId = id;
- myNotificationGroup = NotificationGroup.toolWindowGroup("notification.group.id." + id.toString().toLowerCase(),
- myExternalSystemId.getReadableName(),
- true);
+ myNotificationGroup = NotificationGroup.toolWindowGroup("notification.group.id." + id.toString().toLowerCase(Locale.ENGLISH),
+ myExternalSystemId.getReadableName());
}
@Override
diff --git a/platform/icons/src/actions/GroupByClass.png b/platform/icons/src/actions/GroupByClass.png
index dddca942c295..8370b26019d1 100644
--- a/platform/icons/src/actions/GroupByClass.png
+++ b/platform/icons/src/actions/GroupByClass.png
Binary files differ
diff --git a/platform/icons/src/actions/GroupByFile.png b/platform/icons/src/actions/GroupByFile.png
index b79988d3f0ed..56a2d76c9e0f 100644
--- a/platform/icons/src/actions/GroupByFile.png
+++ b/platform/icons/src/actions/GroupByFile.png
Binary files differ
diff --git a/platform/icons/src/general/projectConfigurable.png b/platform/icons/src/general/projectConfigurable.png
index d04d56ca4983..450c1863c231 100644
--- a/platform/icons/src/general/projectConfigurable.png
+++ b/platform/icons/src/general/projectConfigurable.png
Binary files differ
diff --git a/platform/icons/src/general/projectConfigurable@2x.png b/platform/icons/src/general/projectConfigurable@2x.png
index 3550d5fbf390..a6a92d5e6a66 100644
--- a/platform/icons/src/general/projectConfigurable@2x.png
+++ b/platform/icons/src/general/projectConfigurable@2x.png
Binary files differ
diff --git a/platform/icons/src/gutter/extAnnotation.png b/platform/icons/src/gutter/extAnnotation.png
index 83bfdd350f5c..456eb7171faa 100644
--- a/platform/icons/src/gutter/extAnnotation.png
+++ b/platform/icons/src/gutter/extAnnotation.png
Binary files differ
diff --git a/platform/icons/src/nodes/nativeLibrariesFolder.png b/platform/icons/src/nodes/nativeLibrariesFolder.png
new file mode 100644
index 000000000000..b70cec57b9e2
--- /dev/null
+++ b/platform/icons/src/nodes/nativeLibrariesFolder.png
Binary files differ
diff --git a/platform/icons/src/nodes/nativeLibrariesFolder@2x.png b/platform/icons/src/nodes/nativeLibrariesFolder@2x.png
new file mode 100644
index 000000000000..532896bb9b4d
--- /dev/null
+++ b/platform/icons/src/nodes/nativeLibrariesFolder@2x.png
Binary files differ
diff --git a/platform/icons/src/nodes/nativeLibrariesFolder@2x_dark.png b/platform/icons/src/nodes/nativeLibrariesFolder@2x_dark.png
new file mode 100644
index 000000000000..ac966a7a35bb
--- /dev/null
+++ b/platform/icons/src/nodes/nativeLibrariesFolder@2x_dark.png
Binary files differ
diff --git a/platform/icons/src/nodes/nativeLibrariesFolder_dark.png b/platform/icons/src/nodes/nativeLibrariesFolder_dark.png
new file mode 100644
index 000000000000..fd74984620bc
--- /dev/null
+++ b/platform/icons/src/nodes/nativeLibrariesFolder_dark.png
Binary files differ
diff --git a/platform/indexing-api/src/com/intellij/psi/search/searches/ReferencesSearch.java b/platform/indexing-api/src/com/intellij/psi/search/searches/ReferencesSearch.java
index aafb85d529bc..1820de4b2336 100644
--- a/platform/indexing-api/src/com/intellij/psi/search/searches/ReferencesSearch.java
+++ b/platform/indexing-api/src/com/intellij/psi/search/searches/ReferencesSearch.java
@@ -19,6 +19,7 @@ import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.search.*;
+import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.*;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
@@ -88,7 +89,7 @@ public class ReferencesSearch extends ExtensibleQueryFactory<PsiReference, Refer
@NotNull
public static Query<PsiReference> search(@NotNull PsiElement element) {
- return search(element, GlobalSearchScope.allScope(element.getProject()), false);
+ return search(element, GlobalSearchScope.allScope(PsiUtilCore.getProjectInReadAction(element)), false);
}
@NotNull
@@ -112,7 +113,7 @@ public class ReferencesSearch extends ExtensibleQueryFactory<PsiReference, Refer
final PsiElement element = parameters.getElementToSearch();
- return uniqueResults(new MergeQuery<PsiReference>(result, new SearchRequestQuery(element.getProject(), requests)));
+ return uniqueResults(new MergeQuery<PsiReference>(result, new SearchRequestQuery(PsiUtilCore.getProjectInReadAction(element), requests)));
}
@NotNull
diff --git a/platform/lang-api/src/com/intellij/execution/RunProfileStarter.java b/platform/lang-api/src/com/intellij/execution/RunProfileStarter.java
index 163031f956f9..00c87576ecfd 100644
--- a/platform/lang-api/src/com/intellij/execution/RunProfileStarter.java
+++ b/platform/lang-api/src/com/intellij/execution/RunProfileStarter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,8 +28,19 @@ import org.jetbrains.annotations.Nullable;
* @author nik
*/
public abstract class RunProfileStarter {
+ @SuppressWarnings("UnusedParameters")
+ @Deprecated
@Nullable
- public abstract RunContentDescriptor execute(@NotNull Project project, @NotNull Executor executor, @NotNull RunProfileState state,
- @Nullable RunContentDescriptor contentToReuse, @NotNull ExecutionEnvironment environment) throws ExecutionException;
+ /**
+ * @deprecated to remove in IDEA 15
+ */
+ public RunContentDescriptor execute(@NotNull Project project, @NotNull Executor executor, @NotNull RunProfileState state,
+ @Nullable RunContentDescriptor contentToReuse, @NotNull ExecutionEnvironment environment) throws ExecutionException {
+ return execute(state, environment);
+ }
+ @Nullable
+ public RunContentDescriptor execute(@NotNull RunProfileState state, @NotNull ExecutionEnvironment environment) throws ExecutionException {
+ throw new AbstractMethodError();
+ }
}
diff --git a/platform/lang-api/src/com/intellij/execution/configuration/RunConfigurationExtensionsManager.java b/platform/lang-api/src/com/intellij/execution/configuration/RunConfigurationExtensionsManager.java
index c52f6c9da729..b42cd249ca8e 100644
--- a/platform/lang-api/src/com/intellij/execution/configuration/RunConfigurationExtensionsManager.java
+++ b/platform/lang-api/src/com/intellij/execution/configuration/RunConfigurationExtensionsManager.java
@@ -16,6 +16,7 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.StringInterner;
+import com.intellij.util.containers.WeakStringInterner;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -33,7 +34,7 @@ public class RunConfigurationExtensionsManager<U extends RunConfigurationBase, T
private static final String EXT_ID_ATTR = "ID";
private static final String EXTENSION_ROOT_ATTR = "EXTENSION";
protected final ExtensionPointName<T> myExtensionPointName;
- private final StringInterner myInterner = new StringInterner();
+ private final StringInterner myInterner = new WeakStringInterner();
public RunConfigurationExtensionsManager(ExtensionPointName<T> extensionPointName) {
myExtensionPointName = extensionPointName;
diff --git a/platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationsSettings.java b/platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationsSettings.java
index 732976cf73a7..259fd4e7484c 100644
--- a/platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationsSettings.java
+++ b/platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationsSettings.java
@@ -17,11 +17,12 @@ package com.intellij.execution.configurations;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.options.UnnamedConfigurable;
+import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
public interface RunConfigurationsSettings {
ExtensionPointName<RunConfigurationsSettings> EXTENSION_POINT = ExtensionPointName.create("com.intellij.runConfigurationsSettings");
@NotNull
- UnnamedConfigurable createConfigurable();
+ UnnamedConfigurable createConfigurable(@NotNull Project project);
} \ No newline at end of file
diff --git a/platform/lang-api/src/com/intellij/execution/configurations/SimpleProgramParameters.java b/platform/lang-api/src/com/intellij/execution/configurations/SimpleProgramParameters.java
index 15bd92cfcf8c..b157d6ba7852 100644
--- a/platform/lang-api/src/com/intellij/execution/configurations/SimpleProgramParameters.java
+++ b/platform/lang-api/src/com/intellij/execution/configurations/SimpleProgramParameters.java
@@ -16,7 +16,7 @@
package com.intellij.execution.configurations;
-import com.intellij.execution.configuration.EnvironmentVariablesComponent;
+import com.intellij.util.EnvironmentUtil;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
@@ -70,7 +70,7 @@ public class SimpleProgramParameters {
public void setupEnvs(Map<String, String> envs, boolean passDefault) {
if (!envs.isEmpty()) {
final HashMap<String, String> map = new HashMap<String, String>(envs);
- EnvironmentVariablesComponent.inlineParentOccurrences(map);
+ EnvironmentUtil.inlineParentOccurrences(map);
setEnv(map);
setPassParentEnvs(passDefault);
}
diff --git a/platform/lang-api/src/com/intellij/execution/runners/AsyncGenericProgramRunner.java b/platform/lang-api/src/com/intellij/execution/runners/AsyncGenericProgramRunner.java
index aeaaf58eda65..ce7145adeaf9 100644
--- a/platform/lang-api/src/com/intellij/execution/runners/AsyncGenericProgramRunner.java
+++ b/platform/lang-api/src/com/intellij/execution/runners/AsyncGenericProgramRunner.java
@@ -17,16 +17,12 @@ package com.intellij.execution.runners;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.ExecutionManager;
-import com.intellij.execution.Executor;
import com.intellij.execution.RunProfileStarter;
import com.intellij.execution.configurations.RunProfileState;
import com.intellij.execution.configurations.RunnerSettings;
import com.intellij.execution.ui.RunContentDescriptor;
-import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.AsyncResult;
import com.intellij.util.Consumer;
-import com.intellij.util.NullableConsumer;
-import com.intellij.util.ObjectUtils;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -38,30 +34,19 @@ public abstract class AsyncGenericProgramRunner<Settings extends RunnerSettings>
@Override
protected final void execute(@NotNull final ExecutionEnvironment environment,
@Nullable final Callback callback,
- @NotNull final Project project,
@NotNull final RunProfileState state) throws ExecutionException {
- prepare(project, environment, state).doWhenDone(new Consumer<RunProfileStarter>() {
+ prepare(environment, state).doWhenDone(new Consumer<RunProfileStarter>() {
@Override
public void consume(@Nullable final RunProfileStarter result) {
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
- if (!project.isDisposed()) {
- startRunProfile(project, environment, state, callback, result);
+ if (!environment.getProject().isDisposed()) {
+ startRunProfile(environment, state, callback, result);
}
}
});
}
- }).doWhenRejected(new NullableConsumer<String>() {
- @Override
- public void consume(@Nullable String errorMessage) {
- if (project.isDisposed()) {
- return;
- }
-
- ExecutionUtil.handleExecutionError(project, environment.getExecutor().getToolWindowId(), environment.getRunProfile(),
- new ExecutionException(ObjectUtils.chooseNotNull(errorMessage, "Internal error")));
- }
});
}
@@ -69,29 +54,23 @@ public abstract class AsyncGenericProgramRunner<Settings extends RunnerSettings>
* Makes all the needed preparations for the further execution. Although this method is called in EDT,
* these preparations can be performed in a background thread.
*
- * @param project Project instance
+ * You must call {@link ExecutionUtil#handleExecutionError} in case of error
+ *
* @param environment ExecutionEnvironment instance
* @param state RunProfileState instance
* @return RunProfileStarter async result
*/
@NotNull
- protected abstract AsyncResult<RunProfileStarter> prepare(@NotNull Project project,
- @NotNull ExecutionEnvironment environment,
- @NotNull RunProfileState state) throws ExecutionException;
+ protected abstract AsyncResult<RunProfileStarter> prepare(@NotNull ExecutionEnvironment environment, @NotNull RunProfileState state) throws ExecutionException;
- private static void startRunProfile(@NotNull Project project,
- @NotNull ExecutionEnvironment environment,
+ private static void startRunProfile(@NotNull ExecutionEnvironment environment,
@NotNull RunProfileState state,
@Nullable final Callback callback,
@Nullable final RunProfileStarter starter) {
- ExecutionManager.getInstance(project).startRunProfile(new RunProfileStarter() {
+ ExecutionManager.getInstance(environment.getProject()).startRunProfile(new RunProfileStarter() {
@Override
- public RunContentDescriptor execute(@NotNull Project project,
- @NotNull Executor executor,
- @NotNull RunProfileState state,
- @Nullable RunContentDescriptor contentToReuse,
- @NotNull ExecutionEnvironment environment) throws ExecutionException {
- return postProcess(environment, starter == null ? null : starter.execute(project, executor, state, contentToReuse, environment), callback);
+ public RunContentDescriptor execute(@NotNull RunProfileState state, @NotNull ExecutionEnvironment environment) throws ExecutionException {
+ return postProcess(environment, starter == null ? null : starter.execute(state, environment), callback);
}
}, state, environment);
}
diff --git a/platform/lang-api/src/com/intellij/execution/runners/BaseProgramRunner.java b/platform/lang-api/src/com/intellij/execution/runners/BaseProgramRunner.java
index 29c9e5be0767..a2028185089b 100644
--- a/platform/lang-api/src/com/intellij/execution/runners/BaseProgramRunner.java
+++ b/platform/lang-api/src/com/intellij/execution/runners/BaseProgramRunner.java
@@ -23,7 +23,6 @@ import com.intellij.execution.RunManager;
import com.intellij.execution.configurations.*;
import com.intellij.execution.ui.RunContentDescriptor;
import com.intellij.openapi.options.SettingsEditor;
-import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -61,14 +60,12 @@ abstract class BaseProgramRunner<Settings extends RunnerSettings> implements Pro
return;
}
- Project project = environment.getProject();
- RunManager.getInstance(project).refreshUsagesList(environment.getRunProfile());
- execute(environment, callback, project, state);
+ RunManager.getInstance(environment.getProject()).refreshUsagesList(environment.getRunProfile());
+ execute(environment, callback, state);
}
protected abstract void execute(@NotNull ExecutionEnvironment environment,
@Nullable Callback callback,
- @NotNull Project project,
@NotNull RunProfileState state) throws ExecutionException;
@Nullable
diff --git a/platform/lang-api/src/com/intellij/execution/runners/ExecutionUtil.java b/platform/lang-api/src/com/intellij/execution/runners/ExecutionUtil.java
index 0d15a272498c..b6c300c3f7e2 100644
--- a/platform/lang-api/src/com/intellij/execution/runners/ExecutionUtil.java
+++ b/platform/lang-api/src/com/intellij/execution/runners/ExecutionUtil.java
@@ -31,6 +31,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
+import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.ui.content.Content;
import com.intellij.util.ObjectUtils;
@@ -65,18 +66,19 @@ public class ExecutionUtil {
@NotNull final String toolWindowId,
@NotNull String taskName,
@NotNull ExecutionException e) {
- if (e instanceof RunCanceledByUserException) return;
+ if (e instanceof RunCanceledByUserException) {
+ return;
+ }
LOG.debug(e);
String description = e.getMessage();
- HyperlinkListener listener = null;
-
if (description == null) {
LOG.warn("Execution error without description", e);
description = "Unknown error";
}
+ HyperlinkListener listener = null;
if ((description.contains("87") || description.contains("111") || description.contains("206")) &&
e instanceof ProcessNotCreatedException &&
!PropertiesComponent.getInstance(project).isTrueValue("dynamic.classpath")) {
@@ -110,7 +112,14 @@ public class ExecutionUtil {
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
- ToolWindowManager.getInstance(project).notifyByBalloon(toolWindowId, MessageType.ERROR, fullMessage, null, finalListener);
+ ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(project);
+ if (toolWindowManager.canShowNotification(toolWindowId)) {
+ //noinspection SSBasedInspection
+ toolWindowManager.notifyByBalloon(toolWindowId, MessageType.ERROR, fullMessage, null, finalListener);
+ }
+ else {
+ Messages.showErrorDialog(project, fullMessage, "");
+ }
NotificationListener notificationListener = ObjectUtils.tryCast(finalListener, NotificationListener.class);
ourNotificationGroup.createNotification(title, finalDescription, NotificationType.ERROR, notificationListener).notify(project);
}
diff --git a/platform/lang-api/src/com/intellij/execution/runners/GenericProgramRunner.java b/platform/lang-api/src/com/intellij/execution/runners/GenericProgramRunner.java
index adbd04e822e6..3c59227eb85a 100644
--- a/platform/lang-api/src/com/intellij/execution/runners/GenericProgramRunner.java
+++ b/platform/lang-api/src/com/intellij/execution/runners/GenericProgramRunner.java
@@ -18,7 +18,6 @@ package com.intellij.execution.runners;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.ExecutionManager;
-import com.intellij.execution.Executor;
import com.intellij.execution.RunProfileStarter;
import com.intellij.execution.configurations.RunProfileState;
import com.intellij.execution.configurations.RunnerSettings;
@@ -36,24 +35,30 @@ public abstract class GenericProgramRunner<Settings extends RunnerSettings> exte
public static final String CONTENT_TO_REUSE = CONTENT_TO_REUSE_DATA_KEY.getName();
@Override
- protected void execute(@NotNull ExecutionEnvironment environment, @Nullable final Callback callback, @NotNull Project project, @NotNull RunProfileState state)
+ protected void execute(@NotNull ExecutionEnvironment environment, @Nullable final Callback callback, @NotNull RunProfileState state)
throws ExecutionException {
- ExecutionManager.getInstance(project).startRunProfile(new RunProfileStarter() {
+ ExecutionManager.getInstance(environment.getProject()).startRunProfile(new RunProfileStarter() {
@Override
- public RunContentDescriptor execute(@NotNull Project project,
- @NotNull Executor executor,
- @NotNull RunProfileState state,
- @Nullable RunContentDescriptor contentToReuse,
- @NotNull ExecutionEnvironment environment) throws ExecutionException {
- return postProcess(environment, doExecute(project, state, contentToReuse, environment), callback);
+ public RunContentDescriptor execute(@NotNull RunProfileState state, @NotNull ExecutionEnvironment environment) throws ExecutionException {
+ return postProcess(environment, doExecute(state, environment), callback);
}
}, state, environment);
}
@Nullable
- protected abstract RunContentDescriptor doExecute(@NotNull Project project,
- @NotNull RunProfileState state,
- @Nullable RunContentDescriptor contentToReuse,
- @NotNull ExecutionEnvironment environment) throws ExecutionException;
+ protected RunContentDescriptor doExecute(@NotNull RunProfileState state, @NotNull ExecutionEnvironment environment) throws ExecutionException {
+ return doExecute(environment.getProject(), state, environment.getContentToReuse(), environment);
+ }
+ @Deprecated
+ @Nullable
+ /**
+ * @deprecated to remove in IDEA 16
+ */
+ protected RunContentDescriptor doExecute(@NotNull Project project,
+ @NotNull RunProfileState state,
+ @Nullable RunContentDescriptor contentToReuse,
+ @NotNull ExecutionEnvironment environment) throws ExecutionException {
+ throw new AbstractMethodError();
+ }
}
diff --git a/platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java b/platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java
index d72a0640c595..fddb2b2f50b7 100644
--- a/platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java
+++ b/platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java
@@ -32,6 +32,7 @@ import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.ThrowableComputable;
import com.intellij.openapi.util.io.FileUtil;
@@ -39,6 +40,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.EventDispatcher;
+import com.intellij.util.containers.ContainerUtil;
import org.jdom.JDOMException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -70,7 +72,17 @@ public abstract class ModuleBuilder extends AbstractModuleBuilder {
for (ModuleBuilderFactory factory : EP_NAME.getExtensions()) {
result.add(factory.createBuilder());
}
- return result;
+ return ContainerUtil.filter(result, new Condition<ModuleBuilder>() {
+
+ @Override
+ public boolean value(ModuleBuilder moduleBuilder) {
+ return moduleBuilder.isAvailable();
+ }
+ });
+ }
+
+ protected boolean isAvailable() {
+ return true;
}
@Nullable
diff --git a/platform/lang-api/src/com/intellij/lang/documentation/AbstractDocumentationProvider.java b/platform/lang-api/src/com/intellij/lang/documentation/AbstractDocumentationProvider.java
index f57190e5725e..9a80bf72ed6d 100644
--- a/platform/lang-api/src/com/intellij/lang/documentation/AbstractDocumentationProvider.java
+++ b/platform/lang-api/src/com/intellij/lang/documentation/AbstractDocumentationProvider.java
@@ -15,15 +15,6 @@
*/
package com.intellij.lang.documentation;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.PsiManager;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.List;
-
/**
* @author Dmitry Avdeev
*/
diff --git a/platform/lang-api/src/com/intellij/lang/documentation/CompositeDocumentationProvider.java b/platform/lang-api/src/com/intellij/lang/documentation/CompositeDocumentationProvider.java
index 17bc66f8ada2..14a7c4b99a94 100644
--- a/platform/lang-api/src/com/intellij/lang/documentation/CompositeDocumentationProvider.java
+++ b/platform/lang-api/src/com/intellij/lang/documentation/CompositeDocumentationProvider.java
@@ -22,13 +22,11 @@ import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
+import java.util.*;
public class CompositeDocumentationProvider extends DocumentationProviderEx implements ExternalDocumentationProvider, ExternalDocumentationHandler {
@@ -53,14 +51,21 @@ public class CompositeDocumentationProvider extends DocumentationProviderEx impl
myProviders = providers;
}
+ @NotNull
+ public List<DocumentationProvider> getAllProviders() {
+ return ContainerUtil.concat(getProviders(), Arrays.asList(Extensions.getExtensions(EP_NAME)));
+ }
+
+ @NotNull
public List<DocumentationProvider> getProviders() {
return myProviders;
}
@Override
public boolean handleExternal(PsiElement element, PsiElement originalElement) {
- for (DocumentationProvider provider : myProviders) {
- if (provider instanceof ExternalDocumentationHandler && ((ExternalDocumentationHandler)provider).handleExternal(element, originalElement)) {
+ for (DocumentationProvider provider : getAllProviders()) {
+ if (provider instanceof ExternalDocumentationHandler &&
+ ((ExternalDocumentationHandler)provider).handleExternal(element, originalElement)) {
return true;
}
}
@@ -70,8 +75,9 @@ public class CompositeDocumentationProvider extends DocumentationProviderEx impl
@Override
public boolean handleExternalLink(PsiManager psiManager, String link, PsiElement context) {
- for (DocumentationProvider provider : myProviders) {
- if (provider instanceof ExternalDocumentationHandler && ((ExternalDocumentationHandler)provider).handleExternalLink(psiManager, link, context)) {
+ for (DocumentationProvider provider : getAllProviders()) {
+ if (provider instanceof ExternalDocumentationHandler &&
+ ((ExternalDocumentationHandler)provider).handleExternalLink(psiManager, link, context)) {
return true;
}
}
@@ -81,7 +87,7 @@ public class CompositeDocumentationProvider extends DocumentationProviderEx impl
@Override
public boolean canFetchDocumentationLink(String link) {
- for (DocumentationProvider provider : myProviders) {
+ for (DocumentationProvider provider : getAllProviders()) {
if (provider instanceof ExternalDocumentationHandler && ((ExternalDocumentationHandler)provider).canFetchDocumentationLink(link)) {
return true;
}
@@ -93,7 +99,7 @@ public class CompositeDocumentationProvider extends DocumentationProviderEx impl
@NotNull
@Override
public String fetchExternalDocumentation(@NotNull String link, @Nullable PsiElement element) {
- for (DocumentationProvider provider : myProviders) {
+ for (DocumentationProvider provider : getAllProviders()) {
if (provider instanceof ExternalDocumentationHandler && ((ExternalDocumentationHandler)provider).canFetchDocumentationLink(link)) {
return ((ExternalDocumentationHandler)provider).fetchExternalDocumentation(link, element);
}
@@ -104,12 +110,8 @@ public class CompositeDocumentationProvider extends DocumentationProviderEx impl
@Override
public String getQuickNavigateInfo(PsiElement element, PsiElement originalElement) {
- for ( DocumentationProvider provider : myProviders ) {
+ for (DocumentationProvider provider : getAllProviders()) {
String result = provider.getQuickNavigateInfo(element, originalElement);
- if ( result != null ) return result;
- }
- for (DocumentationProvider provider : Extensions.getExtensions(EP_NAME)) {
- final String result = provider.getQuickNavigateInfo(element, originalElement);
if (result != null) return result;
}
return null;
@@ -117,14 +119,8 @@ public class CompositeDocumentationProvider extends DocumentationProviderEx impl
@Override
public List<String> getUrlFor(PsiElement element, PsiElement originalElement) {
- for ( DocumentationProvider provider : myProviders ) {
- List<String> result = provider.getUrlFor(element,originalElement);
- if ( result != null ) {
- return result;
- }
- }
- for (DocumentationProvider provider : Extensions.getExtensions(EP_NAME)) {
- final List<String> result = provider.getUrlFor(element, originalElement);
+ for (DocumentationProvider provider : getAllProviders()) {
+ List<String> result = provider.getUrlFor(element, originalElement);
if (result != null) {
return result;
}
@@ -134,14 +130,8 @@ public class CompositeDocumentationProvider extends DocumentationProviderEx impl
@Override
public String generateDoc(PsiElement element, PsiElement originalElement) {
- for ( DocumentationProvider provider : myProviders ) {
- String result = provider.generateDoc(element,originalElement);
- if ( result != null ) {
- return result;
- }
- }
- for (DocumentationProvider provider : Extensions.getExtensions(EP_NAME)) {
- final String result = provider.generateDoc(element, originalElement);
+ for (DocumentationProvider provider : getAllProviders()) {
+ String result = provider.generateDoc(element, originalElement);
if (result != null) {
return result;
}
@@ -151,14 +141,8 @@ public class CompositeDocumentationProvider extends DocumentationProviderEx impl
@Override
public PsiElement getDocumentationElementForLookupItem(PsiManager psiManager, Object object, PsiElement element) {
- for ( DocumentationProvider provider : myProviders ) {
- PsiElement result = provider.getDocumentationElementForLookupItem(psiManager,object,element);
- if ( result != null ) {
- return result;
- }
- }
- for (DocumentationProvider provider : Extensions.getExtensions(EP_NAME)) {
- final PsiElement result = provider.getDocumentationElementForLookupItem(psiManager, object, element);
+ for (DocumentationProvider provider : getAllProviders()) {
+ PsiElement result = provider.getDocumentationElementForLookupItem(psiManager, object, element);
if (result != null) {
return result;
}
@@ -168,12 +152,8 @@ public class CompositeDocumentationProvider extends DocumentationProviderEx impl
@Override
public PsiElement getDocumentationElementForLink(PsiManager psiManager, String link, PsiElement context) {
- for ( DocumentationProvider provider : myProviders ) {
- PsiElement result = provider.getDocumentationElementForLink(psiManager,link,context);
- if ( result != null ) return result;
- }
- for (DocumentationProvider provider : Extensions.getExtensions(EP_NAME)) {
- final PsiElement result = provider.getDocumentationElementForLink(psiManager, link, context);
+ for (DocumentationProvider provider : getAllProviders()) {
+ PsiElement result = provider.getDocumentationElementForLink(psiManager, link, context);
if (result != null) return result;
}
return null;
@@ -182,7 +162,7 @@ public class CompositeDocumentationProvider extends DocumentationProviderEx impl
@Nullable
public CodeDocumentationProvider getFirstCodeDocumentationProvider() {
- for (DocumentationProvider provider : myProviders) {
+ for (DocumentationProvider provider : getAllProviders()) {
if (provider instanceof CodeDocumentationProvider) {
return (CodeDocumentationProvider)provider;
}
@@ -192,7 +172,7 @@ public class CompositeDocumentationProvider extends DocumentationProviderEx impl
@Override
public String fetchExternalDocumentation(Project project, PsiElement element, List<String> docUrls) {
- for (DocumentationProvider provider : myProviders) {
+ for (DocumentationProvider provider : getAllProviders()) {
if (provider instanceof ExternalDocumentationProvider) {
final String doc = ((ExternalDocumentationProvider)provider).fetchExternalDocumentation(project, element, docUrls);
if (doc != null) {
@@ -205,9 +185,9 @@ public class CompositeDocumentationProvider extends DocumentationProviderEx impl
@Override
public boolean hasDocumentationFor(PsiElement element, PsiElement originalElement) {
- for (DocumentationProvider provider : myProviders) {
+ for (DocumentationProvider provider : getAllProviders()) {
if (provider instanceof ExternalDocumentationProvider) {
- if (((ExternalDocumentationProvider) provider).hasDocumentationFor(element, originalElement)) return true;
+ if (((ExternalDocumentationProvider)provider).hasDocumentationFor(element, originalElement)) return true;
}
else {
if (hasUrlsFor(provider, element, originalElement)) return true;
@@ -218,7 +198,7 @@ public class CompositeDocumentationProvider extends DocumentationProviderEx impl
@Override
public boolean canPromptToConfigureDocumentation(PsiElement element) {
- for (DocumentationProvider provider : myProviders) {
+ for (DocumentationProvider provider : getAllProviders()) {
if (provider instanceof ExternalDocumentationProvider &&
((ExternalDocumentationProvider)provider).canPromptToConfigureDocumentation(element)) {
return true;
@@ -229,7 +209,7 @@ public class CompositeDocumentationProvider extends DocumentationProviderEx impl
@Override
public void promptToConfigureDocumentation(PsiElement element) {
- for (DocumentationProvider provider : myProviders) {
+ for (DocumentationProvider provider : getAllProviders()) {
if (provider instanceof ExternalDocumentationProvider &&
((ExternalDocumentationProvider)provider).canPromptToConfigureDocumentation(element)) {
((ExternalDocumentationProvider)provider).promptToConfigureDocumentation(element);
@@ -249,7 +229,7 @@ public class CompositeDocumentationProvider extends DocumentationProviderEx impl
public PsiElement getCustomDocumentationElement(@NotNull Editor editor,
@NotNull PsiFile file,
@Nullable PsiElement contextElement) {
- for (DocumentationProvider provider : myProviders) {
+ for (DocumentationProvider provider : getAllProviders()) {
if (provider instanceof DocumentationProviderEx) {
PsiElement element = ((DocumentationProviderEx)provider).getCustomDocumentationElement(editor, file, contextElement);
if (element != null) {
@@ -262,6 +242,6 @@ public class CompositeDocumentationProvider extends DocumentationProviderEx impl
@Override
public String toString() {
- return myProviders.toString();
+ return getProviders().toString();
}
}
diff --git a/platform/lang-api/src/com/intellij/lang/documentation/DocumentationProviderEx.java b/platform/lang-api/src/com/intellij/lang/documentation/DocumentationProviderEx.java
index 5ae5af91bac0..8b9143a0d995 100644
--- a/platform/lang-api/src/com/intellij/lang/documentation/DocumentationProviderEx.java
+++ b/platform/lang-api/src/com/intellij/lang/documentation/DocumentationProviderEx.java
@@ -22,6 +22,7 @@ import com.intellij.psi.PsiManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.awt.*;
import java.util.List;
/**
@@ -57,4 +58,9 @@ public class DocumentationProviderEx implements DocumentationProvider {
public PsiElement getCustomDocumentationElement(@NotNull final Editor editor, @NotNull final PsiFile file, @Nullable PsiElement contextElement) {
return null;
}
+
+ @Nullable
+ public Image getLocalImageForElement(@NotNull PsiElement element, @NotNull String imageSpec) {
+ return null;
+ }
}
diff --git a/platform/lang-api/src/com/intellij/lexer/CompositeLexer.java b/platform/lang-api/src/com/intellij/lexer/CompositeLexer.java
index d728aff0e823..af456e0074ac 100644
--- a/platform/lang-api/src/com/intellij/lexer/CompositeLexer.java
+++ b/platform/lang-api/src/com/intellij/lexer/CompositeLexer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,16 @@ package com.intellij.lexer;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
+/**
+ * Naive implementation of lexer that able to combine element types of two other lexers.
+ *
+ * The implementation doesn't give any guarantees about valid points of 'incremental relexing',
+ * because it returns start/end-offsets not for token that was used but for the shortest one.
+ *
+ * Also it reduces state size to 16 bits for nested lexer.
+ *
+ * @deprecated use {@link com.intellij.psi.templateLanguages.TemplateBlackAndWhiteLexer} or {@link com.intellij.lexer.LayeredLexer} instead
+ */
public abstract class CompositeLexer extends LexerBase {
private final Lexer myLexer1;
private final Lexer myLexer2;
diff --git a/platform/lang-api/src/com/intellij/openapi/roots/ui/OrderRootTypeUIFactory.java b/platform/lang-api/src/com/intellij/openapi/roots/ui/OrderRootTypeUIFactory.java
index 021c055dd70f..c9a0053619ce 100644
--- a/platform/lang-api/src/com/intellij/openapi/roots/ui/OrderRootTypeUIFactory.java
+++ b/platform/lang-api/src/com/intellij/openapi/roots/ui/OrderRootTypeUIFactory.java
@@ -23,6 +23,7 @@ import com.intellij.openapi.projectRoots.ui.SdkPathEditor;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.util.KeyedExtensionFactory;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -41,6 +42,7 @@ public interface OrderRootTypeUIFactory {
}
};
+ @Nullable
SdkPathEditor createPathEditor(Sdk sdk);
Icon getIcon();
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/LegacyCodeStyleSettingsManager.java b/platform/lang-api/src/com/intellij/psi/codeStyle/LegacyCodeStyleSettingsManager.java
index c6d4c738c1fd..fdc9a662df1d 100644
--- a/platform/lang-api/src/com/intellij/psi/codeStyle/LegacyCodeStyleSettingsManager.java
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/LegacyCodeStyleSettingsManager.java
@@ -31,7 +31,6 @@ import org.jdom.Element;
}
)
public class LegacyCodeStyleSettingsManager implements PersistentStateComponent<Element> {
-
private Element myState;
@Override
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ArrangementSectionRule.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ArrangementSectionRule.java
index 9e9e9c0caa0f..2f7249f9d22d 100644
--- a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ArrangementSectionRule.java
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ArrangementSectionRule.java
@@ -53,7 +53,7 @@ public class ArrangementSectionRule implements Cloneable {
}
public static ArrangementSectionRule create(@Nullable String start, @Nullable String end, @NotNull StdArrangementMatchRule... rules) {
- return create(start, end, ContainerUtil.newArrayList(rules));
+ return create(start, end, rules.length == 0 ? ContainerUtil.<StdArrangementMatchRule>emptyList() : ContainerUtil.newArrayList(rules));
}
public static ArrangementSectionRule create(@Nullable String start, @Nullable String end, @NotNull List<StdArrangementMatchRule> rules) {
@@ -68,14 +68,10 @@ public class ArrangementSectionRule implements Cloneable {
return new ArrangementSectionRule(start, end, matchRules);
}
- @Nullable
- private static StdArrangementMatchRule createSectionRule(@Nullable String comment, @NotNull ArrangementSettingsToken token) {
- if (StringUtil.isEmpty(comment)) {
- return null;
- }
- final ArrangementAtomMatchCondition type = new ArrangementAtomMatchCondition(token);
+ @NotNull
+ private static StdArrangementMatchRule createSectionRule(@NotNull String comment, @NotNull ArrangementSettingsToken token) {
final ArrangementAtomMatchCondition text = new ArrangementAtomMatchCondition(StdArrangementTokens.Regexp.TEXT, comment);
- final ArrangementMatchCondition condition = ArrangementUtil.combine(type, text);
+ final ArrangementMatchCondition condition = ArrangementUtil.combine(new ArrangementAtomMatchCondition(token), text);
return new StdArrangementMatchRule(new StdArrangementEntryMatcher(condition));
}
diff --git a/platform/lang-api/src/com/intellij/psi/util/PsiUtilBase.java b/platform/lang-api/src/com/intellij/psi/util/PsiUtilBase.java
index 13f84cb1dc4f..4565832c310b 100644
--- a/platform/lang-api/src/com/intellij/psi/util/PsiUtilBase.java
+++ b/platform/lang-api/src/com/intellij/psi/util/PsiUtilBase.java
@@ -46,7 +46,7 @@ public class PsiUtilBase extends PsiUtilCore implements PsiEditorUtil {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.util.PsiUtilBase");
public static final Comparator<Language> LANGUAGE_COMPARATOR = new Comparator<Language>() {
@Override
- public int compare(Language o1, Language o2) {
+ public int compare(@NotNull Language o1, @NotNull Language o2) {
return o1.getID().compareTo(o2.getID());
}
};
diff --git a/platform/lang-impl/src/com/intellij/application/options/CodeStyleSchemesConfigurable.java b/platform/lang-impl/src/com/intellij/application/options/CodeStyleSchemesConfigurable.java
index b07c7a62bc47..760d17e67d24 100644
--- a/platform/lang-impl/src/com/intellij/application/options/CodeStyleSchemesConfigurable.java
+++ b/platform/lang-impl/src/com/intellij/application/options/CodeStyleSchemesConfigurable.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -56,7 +56,7 @@ public class CodeStyleSchemesConfigurable extends SearchableConfigurable.Parent.
public JComponent createComponent() {
myModel = ensureModel();
- if (Registry.is("ide.file.settings.order.new")) {
+ if (Registry.is("ide.new.settings.dialog")) {
return myPanels == null || myPanels.isEmpty() ? null : myPanels.get(0).createComponent();
}
return myRootSchemesPanel.getPanel();
@@ -236,7 +236,7 @@ public class CodeStyleSchemesConfigurable extends SearchableConfigurable.Parent.
}
}
- if (Registry.is("ide.file.settings.order.new")) {
+ if (Registry.is("ide.new.settings.dialog")) {
int size = myPanels.size();
Configurable[] result = new Configurable[size > 0 ? size - 1 : 0];
for (int i = 0; i < result.length; i++) {
@@ -346,34 +346,31 @@ public class CodeStyleSchemesConfigurable extends SearchableConfigurable.Parent.
String displayName = myProvider.getConfigurableDisplayName();
if (displayName != null) return displayName;
- return ensurePanel().getDisplayName(); // fallback for 8.0 API compatibility
+ return myPanel != null ? myPanel.getDisplayName() : null; // fallback for 8.0 API compatibility
}
@Override
public String getHelpTopic() {
- return ensurePanel().getHelpTopic();
- }
-
- private CodeStyleMainPanel ensurePanel() {
- if (myPanel == null) {
- myPanel = new CodeStyleMainPanel(ensureModel(), myLangSelector, myFactory);
- }
- return myPanel;
+ return myPanel != null ? myPanel.getHelpTopic() : null;
}
@Override
public JComponent createComponent() {
- return ensurePanel();
+ myPanel = new CodeStyleMainPanel(ensureModel(), myLangSelector, myFactory);
+ return myPanel;
}
@Override
public boolean isModified() {
- boolean someSchemeModified = ensurePanel().isModified();
- if (someSchemeModified) {
- myApplyCompleted = false;
- myRevertCompleted = false;
+ if (myPanel != null) {
+ boolean someSchemeModified = myPanel.isModified();
+ if (someSchemeModified) {
+ myApplyCompleted = false;
+ myRevertCompleted = false;
+ }
+ return someSchemeModified;
}
- return someSchemeModified;
+ return false;
}
@Override
@@ -428,20 +425,25 @@ public class CodeStyleSchemesConfigurable extends SearchableConfigurable.Parent.
}
public boolean isPanelModified(CodeStyleScheme scheme) {
- return ensurePanel().isModified(scheme);
+ return myPanel != null && myPanel.isModified(scheme);
}
public boolean isPanelModified() {
- return ensurePanel().isModified();
+ return myPanel != null && myPanel.isModified();
}
public void applyPanel() throws ConfigurationException {
- ensurePanel().apply();
+ if (myPanel != null) {
+ myPanel.apply();
+ }
}
@Override
public Set<String> processListOptions() {
- return ensurePanel().processListOptions();
+ if (myPanel == null) {
+ myPanel = new CodeStyleMainPanel(ensureModel(), myLangSelector, myFactory);
+ }
+ return myPanel.processListOptions();
}
}
}
diff --git a/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.form b/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.form
index 586f9b48779e..3ce71602fe06 100644
--- a/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.form
+++ b/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.form
@@ -259,7 +259,7 @@
<component id="25b75" class="javax.swing.JTextField" binding="myClipboardContentLimitTextField">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="4" anchor="8" fill="0" indent="0" use-parent-layout="false">
- <preferred-size width="35" height="-1"/>
+ <preferred-size width="50" height="-1"/>
</grid>
</constraints>
<properties>
@@ -285,7 +285,7 @@
<component id="695ab" class="javax.swing.JTextField" binding="myRecentFilesLimitField">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false">
- <preferred-size width="35" height="-1"/>
+ <preferred-size width="50" height="-1"/>
</grid>
</constraints>
<properties>
@@ -295,7 +295,7 @@
<component id="8f324" class="javax.swing.JTextField" binding="myCommandsHistoryLimitField">
<constraints>
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false">
- <preferred-size width="35" height="-1"/>
+ <preferred-size width="50" height="-1"/>
</grid>
</constraints>
<properties>
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/actions/FormatChangedTextUtil.java b/platform/lang-impl/src/com/intellij/codeInsight/actions/FormatChangedTextUtil.java
index 0bc36c17325d..3b51cc9ad976 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/actions/FormatChangedTextUtil.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/actions/FormatChangedTextUtil.java
@@ -20,6 +20,7 @@ import com.intellij.openapi.application.Result;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.EditorFactory;
+import com.intellij.openapi.editor.impl.EditorFactoryImpl;
import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.module.ModifiableModuleModel;
import com.intellij.openapi.module.Module;
@@ -281,7 +282,7 @@ public class FormatChangedTextUtil {
@NotNull
private static List<TextRange> calculateChangedTextRanges(@NotNull Project project, @NotNull PsiFile file, @NotNull String contentFromVcs) {
- Document documentFromVcs = EditorFactory.getInstance().createDocument(contentFromVcs);
+ Document documentFromVcs = ((EditorFactoryImpl)EditorFactory.getInstance()).createDocument(contentFromVcs, true, false);
Document document = PsiDocumentManager.getInstance(project).getDocument(file);
if (document == null) {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/actions/OptimizeImportsProcessor.java b/platform/lang-impl/src/com/intellij/codeInsight/actions/OptimizeImportsProcessor.java
index ed254aec1e8b..6cdb063c0434 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/actions/OptimizeImportsProcessor.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/actions/OptimizeImportsProcessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -82,8 +82,9 @@ public class OptimizeImportsProcessor extends AbstractLayoutCodeProcessor {
public void run() {
CodeStyleManagerImpl.setSequentialProcessingAllowed(false);
try {
- for (Runnable runnable : runnables)
+ for (Runnable runnable : runnables) {
runnable.run();
+ }
}
finally {
CodeStyleManagerImpl.setSequentialProcessingAllowed(true);
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java
index fcb080dcd277..3bdd05f58a40 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java
@@ -316,7 +316,6 @@ public class CodeCompletionHandlerBase {
final LookupElement[] allItems = data.get();
if (allItems != null && !indicator.isRunning() && !indicator.isCanceled()) { // the completion is really finished, now we may auto-insert or show lookup
completionFinished(initContext.getStartOffset(), initContext.getSelectionEndOffset(), indicator, allItems, hasModifiers);
- checkNotSync(indicator, allItems);
return;
}
}
@@ -424,18 +423,18 @@ public class CodeCompletionHandlerBase {
LOG.assertTrue(!indicator.isRunning(), "running");
LOG.assertTrue(!indicator.isCanceled(), "canceled");
- indicator.getLookup().refreshUi(true, false);
- final AutoCompletionDecision decision = shouldAutoComplete(indicator, items);
- if (decision == AutoCompletionDecision.SHOW_LOOKUP) {
- CompletionServiceImpl.setCompletionPhase(new CompletionPhase.ItemsCalculated(indicator));
- indicator.getLookup().setCalculating(false);
- indicator.showLookup();
- }
- else if (decision instanceof AutoCompletionDecision.InsertItem) {
- final Runnable restorePrefix = rememberDocumentState(indicator.getEditor());
+ try {
+ indicator.getLookup().refreshUi(true, false);
+ final AutoCompletionDecision decision = shouldAutoComplete(indicator, items);
+ if (decision == AutoCompletionDecision.SHOW_LOOKUP) {
+ CompletionServiceImpl.setCompletionPhase(new CompletionPhase.ItemsCalculated(indicator));
+ indicator.getLookup().setCalculating(false);
+ indicator.showLookup();
+ }
+ else if (decision instanceof AutoCompletionDecision.InsertItem) {
+ final Runnable restorePrefix = rememberDocumentState(indicator.getEditor());
- final LookupElement item = ((AutoCompletionDecision.InsertItem)decision).getElement();
- try {
+ final LookupElement item = ((AutoCompletionDecision.InsertItem)decision).getElement();
CommandProcessor.getInstance().executeCommand(indicator.getProject(), new Runnable() {
@Override
public void run() {
@@ -443,22 +442,22 @@ public class CodeCompletionHandlerBase {
indicator.getLookup().finishLookup(Lookup.AUTO_INSERT_SELECT_CHAR, item);
}
}, "Autocompletion", null);
- }
- catch (Throwable e) {
- CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion);
- LOG.error(e);
- return;
- }
- // the insert handler may have started a live template with completion
- if (CompletionService.getCompletionService().getCurrentCompletion() == null &&
- // ...or scheduled another autopopup
- !CompletionServiceImpl.isPhase(CompletionPhase.CommittingDocuments.class)) {
- CompletionServiceImpl.setCompletionPhase(hasModifiers? new CompletionPhase.InsertedSingleItem(indicator, restorePrefix) : CompletionPhase.NoCompletion);
+ // the insert handler may have started a live template with completion
+ if (CompletionService.getCompletionService().getCurrentCompletion() == null &&
+ // ...or scheduled another autopopup
+ !CompletionServiceImpl.isPhase(CompletionPhase.CommittingDocuments.class)) {
+ CompletionServiceImpl.setCompletionPhase(hasModifiers? new CompletionPhase.InsertedSingleItem(indicator, restorePrefix) : CompletionPhase.NoCompletion);
+ }
+ } else if (decision == AutoCompletionDecision.CLOSE_LOOKUP) {
+ LookupManager.getInstance(indicator.getProject()).hideActiveLookup();
}
- checkNotSync(indicator, items);
- } else if (decision == AutoCompletionDecision.CLOSE_LOOKUP) {
- LookupManager.getInstance(indicator.getProject()).hideActiveLookup();
+ }
+ catch (Throwable e) {
+ CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion);
+ LOG.error(e);
+ }
+ finally {
checkNotSync(indicator, items);
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java
index e25f050c8d7b..8ca94d80463c 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java
@@ -193,9 +193,10 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
if (!CodeInsightSettings.getInstance().SELECT_AUTOPOPUP_SUGGESTIONS_BY_CHARS) {
myLookup.setFocusDegree(LookupImpl.FocusDegree.SEMI_FOCUSED);
if (FeatureUsageTracker.getInstance().isToBeAdvertisedInLookup(CodeCompletionFeatures.EDITING_COMPLETION_FINISH_BY_CONTROL_DOT, getProject())) {
- addAdvertisement("Press " +
- CompletionContributor.getActionShortcut(IdeActions.ACTION_CHOOSE_LOOKUP_ITEM_DOT) +
- " to choose the selected (or first) suggestion and insert a dot afterwards", null);
+ String dotShortcut = CompletionContributor.getActionShortcut(IdeActions.ACTION_CHOOSE_LOOKUP_ITEM_DOT);
+ if (StringUtil.isNotEmpty(dotShortcut)) {
+ addAdvertisement("Press " + dotShortcut + " to choose the selected (or first) suggestion and insert a dot afterwards", null);
+ }
}
} else {
myLookup.setFocusDegree(LookupImpl.FocusDegree.FOCUSED);
@@ -204,9 +205,11 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
if (!myEditor.isOneLineMode() &&
FeatureUsageTracker.getInstance()
.isToBeAdvertisedInLookup(CodeCompletionFeatures.EDITING_COMPLETION_CONTROL_ARROWS, getProject())) {
- addAdvertisement(CompletionContributor.getActionShortcut(IdeActions.ACTION_LOOKUP_DOWN) + " and " +
- CompletionContributor.getActionShortcut(IdeActions.ACTION_LOOKUP_UP) +
- " will move caret down and up in the editor", null);
+ String downShortcut = CompletionContributor.getActionShortcut(IdeActions.ACTION_LOOKUP_DOWN);
+ String upShortcut = CompletionContributor.getActionShortcut(IdeActions.ACTION_LOOKUP_UP);
+ if (StringUtil.isNotEmpty(downShortcut) && StringUtil.isNotEmpty(upShortcut)) {
+ addAdvertisement(downShortcut + " and " + upShortcut + " will move caret down and up in the editor", null);
+ }
}
} else if (DumbService.isDumb(getProject())) {
addAdvertisement("The results might be incomplete while indexing is in progress", MessageType.WARNING.getPopupBackground());
@@ -759,6 +762,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
data.set(calculateItems(initContext, weigher));
}
catch (ProcessCanceledException ignore) {
+ cancel(); // some contributor may just throw PCE; if indicator is not canceled everything will hang
}
catch (Throwable t) {
cancel();
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java
index d8fd3ab40508..4ac5e686c5bc 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java
@@ -709,11 +709,20 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzerEx implements JDOM
return new Runnable() {
@Override
public void run() {
- if (myDisposed || !myProject.isInitialized()) return;
- if (PowerSaveMode.isEnabled()) return;
- Editor activeEditor = FileEditorManager.getInstance(myProject).getSelectedTextEditor();
+ ApplicationManager.getApplication().assertIsDispatchThread();
+ if (myDisposed || !myProject.isInitialized() || PowerSaveMode.isEnabled()) {
+ return;
+ }
+ if (HeavyProcessLatch.INSTANCE.isRunning()) {
+ if (myAlarm.isEmpty()) {
+ myAlarm.addRequest(myUpdateRunnable, mySettings.AUTOREPARSE_DELAY);
+ }
+ return;
+ }
+ Editor activeEditor = FileEditorManager.getInstance(myProject).getSelectedTextEditor();
final PsiDocumentManagerImpl documentManager = (PsiDocumentManagerImpl)PsiDocumentManager.getInstance(myProject);
+
Runnable runnable = new Runnable() {
@Override
public void run() {
@@ -728,7 +737,6 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzerEx implements JDOM
final Collection<FileEditor> activeEditors = getSelectedEditors();
if (activeEditors.isEmpty()) return;
- ApplicationManager.getApplication().assertIsDispatchThread();
if (ApplicationManager.getApplication().isWriteAccessAllowed()) {
// makes no sense to start from within write action, will cancel anyway
// we'll restart when write action finish
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java
index c8d5ec4b8ddb..760029d689db 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java
@@ -507,7 +507,7 @@ public class DaemonListeners implements Disposable {
}
@Override
- public void profileActivated(@NotNull Profile oldProfile, Profile profile) {
+ public void profileActivated(Profile oldProfile, Profile profile) {
stopDaemonAndRestartAllFiles();
}
@@ -530,6 +530,7 @@ public class DaemonListeners implements Disposable {
StatusBarEx statusBar = (StatusBarEx)WindowManager.getInstance().getStatusBar(myProject);
myTogglePopupHintsPanel = new TogglePopupHintsPanel(myProject);
statusBar.addWidget(myTogglePopupHintsPanel, myProject);
+ updateStatusBar();
stopDaemonAndRestartAllFiles();
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/EditorTracker.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/EditorTracker.java
index cfa7c029d8fc..c88ac636243a 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/EditorTracker.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/EditorTracker.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -209,7 +209,7 @@ public class EditorTracker extends AbstractProjectComponent {
return filtered;
}
- private void setActiveEditors(@NotNull List<Editor> editors) {
+ void setActiveEditors(@NotNull List<Editor> editors) {
myActiveEditors = editors;
if (LOG.isDebugEnabled()) {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/IdentifierHighlighterPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/IdentifierHighlighterPass.java
index 2c44451ef260..72b0a4471e9c 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/IdentifierHighlighterPass.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/IdentifierHighlighterPass.java
@@ -34,6 +34,7 @@ import com.intellij.openapi.editor.markup.MarkupModel;
import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Couple;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
@@ -115,33 +116,50 @@ public class IdentifierHighlighterPass extends TextEditorHighlightingPass {
}
}
- private void highlightTargetUsages(@NotNull PsiElement target) {
+ /**
+ * Returns read and write usages of psi element inside single file
+ *
+ * @param target target psi element
+ * @param psiFile psi file for element
+ * @return a pair where first element is read usages and second is write usages
+ */
+ public static Couple<Collection<TextRange>> getHighlightUsages(@NotNull PsiElement target, PsiFile psiFile) {
+ Collection<TextRange> readRanges = new ArrayList<TextRange>();
+ Collection<TextRange> writeRanges = new ArrayList<TextRange>();
final ReadWriteAccessDetector detector = ReadWriteAccessDetector.findDetector(target);
final FindUsagesManager findUsagesManager = ((FindManagerImpl)FindManager.getInstance(target.getProject())).getFindUsagesManager();
final FindUsagesHandler findUsagesHandler = findUsagesManager.getFindUsagesHandler(target, true);
- final LocalSearchScope scope = new LocalSearchScope(myFile);
+ final LocalSearchScope scope = new LocalSearchScope(psiFile);
Collection<PsiReference> refs = findUsagesHandler != null
? findUsagesHandler.findReferencesToHighlight(target, scope)
: ReferencesSearch.search(target, scope).findAll();
for (PsiReference psiReference : refs) {
final List<TextRange> textRanges = HighlightUsagesHandler.getRangesToHighlight(psiReference);
if (detector == null || detector.getReferenceAccess(target, psiReference) == ReadWriteAccessDetector.Access.Read) {
- myReadAccessRanges.addAll(textRanges);
+ readRanges.addAll(textRanges);
}
else {
- myWriteAccessRanges.addAll(textRanges);
+ writeRanges.addAll(textRanges);
}
}
- final TextRange declRange = HighlightUsagesHandler.getNameIdentifierRange(myFile, target);
+ final TextRange declRange = HighlightUsagesHandler.getNameIdentifierRange(psiFile, target);
if (declRange != null) {
if (detector != null && detector.isDeclarationWriteAccess(target)) {
- myWriteAccessRanges.add(declRange);
+ writeRanges.add(declRange);
}
else {
- myReadAccessRanges.add(declRange);
+ readRanges.add(declRange);
}
}
+
+ return Couple.of(readRanges, writeRanges);
+ }
+
+ private void highlightTargetUsages(@NotNull PsiElement target) {
+ final Couple<Collection<TextRange>> usages = getHighlightUsages(target, myFile);
+ myReadAccessRanges.addAll(usages.first);
+ myWriteAccessRanges.addAll(usages.second);
}
@Override
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java
index 207b66be6112..0761379652ac 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java
@@ -223,7 +223,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
Divider.divideInsideAndOutside(myFile, myStartOffset, myEndOffset, myPriorityRange, inside, new ArrayList<ProperTextRange>(), outside, new ArrayList<ProperTextRange>(),
true, FILE_FILTER);
- MultiMap<LocalInspectionToolWrapper, String> toolToLanguages = getToolsForElements(toolWrappers, checkDumbAwareness, inside, outside);
+ MultiMap<LocalInspectionToolWrapper, String> toolToLanguages = InspectionEngine.getToolsForElements(toolWrappers, checkDumbAwareness, inside, outside);
setProgressLimit(toolToLanguages.size() * 2L);
final LocalInspectionToolSession session = new LocalInspectionToolSession(myFile, myStartOffset, myEndOffset);
@@ -240,76 +240,6 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
}
@NotNull
- private static MultiMap<LocalInspectionToolWrapper, String> getToolsForElements(@NotNull List<LocalInspectionToolWrapper> toolWrappers,
- boolean checkDumbAwareness,
- @NotNull List<PsiElement> inside,
- @NotNull List<PsiElement> outside) {
- Set<Language> languages = new SmartHashSet<Language>();
- Map<String, Language> langIds = new SmartHashMap<String, Language>();
- Set<String> dialects = new SmartHashSet<String>();
- calculateDialects(inside, languages, langIds, dialects);
- calculateDialects(outside, languages, langIds, dialects);
- MultiMap<LocalInspectionToolWrapper, String> toolToLanguages = new MultiMap<LocalInspectionToolWrapper, String>() {
- @NotNull
- @Override
- protected Collection<String> createCollection() {
- return new SmartHashSet<String>();
- }
-
- @NotNull
- @Override
- protected Collection<String> createEmptyCollection() {
- return Collections.emptySet();
- }
- };
- for (LocalInspectionToolWrapper wrapper : toolWrappers) {
- ProgressManager.checkCanceled();
- String language = wrapper.getLanguage();
- if (language == null) {
- LocalInspectionTool tool = wrapper.getTool();
- if (!checkDumbAwareness || tool instanceof DumbAware) {
- toolToLanguages.put(wrapper, null);
- }
- continue;
- }
- Language lang = langIds.get(language);
- if (lang != null) {
- LocalInspectionTool tool = wrapper.getTool();
- if (!checkDumbAwareness || tool instanceof DumbAware) {
- toolToLanguages.putValue(wrapper, language);
- if (wrapper.applyToDialects()) {
- for (Language dialect : lang.getDialects()) {
- toolToLanguages.putValue(wrapper, dialect.getID());
- }
- }
- }
- }
- else if (wrapper.applyToDialects() && dialects.contains(language)) {
- LocalInspectionTool tool = wrapper.getTool();
- if (!checkDumbAwareness || tool instanceof DumbAware) {
- toolToLanguages.putValue(wrapper, language);
- }
- }
- }
- return toolToLanguages;
- }
-
- private static void calculateDialects(@NotNull List<PsiElement> inside,
- @NotNull Set<Language> languages,
- @NotNull Map<String, Language> langIds,
- @NotNull Set<String> dialects) {
- for (PsiElement element : inside) {
- Language language = element.getLanguage();
- if (languages.add(language)) {
- langIds.put(language.getID(), language);
- for (Language dialect : language.getDialects()) {
- dialects.add(dialect.getID());
- }
- }
- }
- }
-
- @NotNull
private List<InspectionContext> visitPriorityElementsAndInit(@NotNull MultiMap<LocalInspectionToolWrapper, String> toolToLanguages,
@NotNull final InspectionManagerEx iManager,
final boolean isOnTheFly,
@@ -412,17 +342,16 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
});
}
if (injected.isEmpty()) return;
- if (!JobLauncher.getInstance().invokeConcurrentlyUnderProgress(new ArrayList<PsiFile>(injected), indicator,
- myFailFastOnAcquireReadAction,
- new Processor<PsiFile>() {
- @Override
- public boolean process(final PsiFile injectedPsi) {
- doInspectInjectedPsi(injectedPsi, onTheFly, indicator, iManager,
- inVisibleRange,
- wrappers, checkDumbAwareness);
- return true;
- }
- })) throw new ProcessCanceledException();
+ Processor<PsiFile> processor = new Processor<PsiFile>() {
+ @Override
+ public boolean process(final PsiFile injectedPsi) {
+ doInspectInjectedPsi(injectedPsi, onTheFly, indicator, iManager, inVisibleRange, wrappers, checkDumbAwareness);
+ return true;
+ }
+ };
+ if (!JobLauncher.getInstance().invokeConcurrentlyUnderProgress(new ArrayList<PsiFile>(injected), indicator, myFailFastOnAcquireReadAction, processor)) {
+ throw new ProcessCanceledException();
+ }
}
@Nullable
@@ -740,7 +669,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
return;
}
MultiMap<LocalInspectionToolWrapper, String> toolToLanguages =
- getToolsForElements(wrappers, checkDumbAwareness, elements, Collections.<PsiElement>emptyList());
+ InspectionEngine.getToolsForElements(wrappers, checkDumbAwareness, elements, Collections.<PsiElement>emptyList());
for (final Map.Entry<LocalInspectionToolWrapper, Collection<String>> pair : toolToLanguages.entrySet()) {
indicator.checkCanceled();
final LocalInspectionToolWrapper wrapper = pair.getKey();
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PsiElementListNavigator.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PsiElementListNavigator.java
index 1f47f5c5c69a..57f65283fd2f 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PsiElementListNavigator.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PsiElementListNavigator.java
@@ -33,6 +33,7 @@ import com.intellij.ui.CollectionListModel;
import com.intellij.ui.JBListWithHintProvider;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.popup.AbstractPopup;
+import com.intellij.ui.popup.HintUpdateSupply;
import com.intellij.usages.UsageView;
import com.intellij.util.Consumer;
import com.intellij.util.Processor;
@@ -147,8 +148,7 @@ public class PsiElementListNavigator {
setCancelCallback(new Computable<Boolean>() {
@Override
public Boolean compute() {
- list.hideHint();
-
+ HintUpdateSupply.hideHint(list);
return true;
}
});
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TrafficLightRenderer.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TrafficLightRenderer.java
index 9c4404a21d58..c67af24d8cdc 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TrafficLightRenderer.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TrafficLightRenderer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -42,7 +42,6 @@ import com.intellij.psi.FileViewProvider;
import com.intellij.psi.PsiFile;
import com.intellij.ui.LayeredIcon;
import com.intellij.util.ArrayUtil;
-import com.intellij.util.ui.EmptyIcon;
import com.intellij.util.ui.UIUtil;
import gnu.trove.TIntArrayList;
import org.jetbrains.annotations.NonNls;
@@ -57,9 +56,7 @@ import java.util.List;
import java.util.Set;
public class TrafficLightRenderer implements ErrorStripeRenderer, Disposable {
- private static final Icon IN_PROGRESS_ICON = AllIcons.General.ErrorsInProgress;
private static final Icon NO_ANALYSIS_ICON = AllIcons.General.NoAnalysis;
- private static final Icon NO_ICON = new EmptyIcon(IN_PROGRESS_ICON.getIconWidth(), IN_PROGRESS_ICON.getIconHeight());
private static final Icon STARING_EYE_ICON = AllIcons.General.InspectionInProgress;
private final Project myProject;
@@ -162,6 +159,7 @@ public class TrafficLightRenderer implements ErrorStripeRenderer, Disposable {
public boolean enabled = true;
public int rootsNumber;
+ @Override
public String toString() {
@NonNls String s = "DS: finished=" + errorAnalyzingFinished;
s += "; pass statuses: " + passStati.size() + "; ";
@@ -175,7 +173,7 @@ public class TrafficLightRenderer implements ErrorStripeRenderer, Disposable {
@Nullable
protected DaemonCodeAnalyzerStatus getDaemonCodeAnalyzerStatus(boolean fillErrorsCount, SeverityRegistrar severityRegistrar) {
- if (myFile == null || myProject.isDisposed() || !myDaemonCodeAnalyzer.isHighlightingAvailable(myFile)) return null;
+ if (myFile == null || myProject != null && myProject.isDisposed() || !myDaemonCodeAnalyzer.isHighlightingAvailable(myFile)) return null;
List<String> noInspectionRoots = new ArrayList<String>();
List<String> noHighlightingRoots = new ArrayList<String>();
@@ -243,10 +241,7 @@ public class TrafficLightRenderer implements ErrorStripeRenderer, Disposable {
}
private Icon getIcon(DaemonCodeAnalyzerStatus status) {
- if (status == null) {
- return NO_ICON;
- }
- if (status.noHighlightingRoots != null && status.noHighlightingRoots.length == status.rootsNumber) {
+ if (status == null || status.noHighlightingRoots != null && status.noHighlightingRoots.length == status.rootsNumber) {
return NO_ANALYSIS_ICON;
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TrafficProgressPanel.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TrafficProgressPanel.java
index 19a958a8bd71..74cfdd9f434e 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TrafficProgressPanel.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TrafficProgressPanel.java
@@ -137,31 +137,33 @@ public class TrafficProgressPanel extends JPanel {
}
}
- private void rebuildPassesPanel(@NotNull TrafficLightRenderer.DaemonCodeAnalyzerStatus status) {
+ private void rebuildPassesPanel(@Nullable TrafficLightRenderer.DaemonCodeAnalyzerStatus status) {
myPassStatuses.removeAll();
myPassStatuses.setLayout(new GridBagLayout());
passes.clear();
GridBagConstraints c = new GridBagConstraints();
c.gridy = 0;
c.fill = GridBagConstraints.HORIZONTAL;
- for (ProgressableTextEditorHighlightingPass pass : status.passStati) {
- JLabel label = new JLabel(pass.getPresentableName() + ": ");
- label.setHorizontalTextPosition(SwingConstants.RIGHT);
+ if (status != null) {
+ for (ProgressableTextEditorHighlightingPass pass : status.passStati) {
+ JLabel label = new JLabel(pass.getPresentableName() + ": ");
+ label.setHorizontalTextPosition(SwingConstants.RIGHT);
- JProgressBar progressBar = new JProgressBar(0, MAX);
- progressBar.putClientProperty("JComponent.sizeVariant", "mini");
- JLabel percLabel = new JLabel();
- passes.put(pass, Pair.create(progressBar, percLabel));
- myProgressToText.put(progressBar, percLabel);
- c.gridx = 0;
- myPassStatuses.add(label, c);
- c.gridx = 1;
- myPassStatuses.add(progressBar, c);
- c.gridx = 2;
- c.weightx = 1;
- myPassStatuses.add(percLabel, c);
+ JProgressBar progressBar = new JProgressBar(0, MAX);
+ progressBar.putClientProperty("JComponent.sizeVariant", "mini");
+ JLabel percLabel = new JLabel();
+ passes.put(pass, Pair.create(progressBar, percLabel));
+ myProgressToText.put(progressBar, percLabel);
+ c.gridx = 0;
+ myPassStatuses.add(label, c);
+ c.gridx = 1;
+ myPassStatuses.add(progressBar, c);
+ c.gridx = 2;
+ c.weightx = 1;
+ myPassStatuses.add(percLabel, c);
- c.gridy++;
+ c.gridy++;
+ }
}
myHintHint.initStyle(myPassStatuses, true);
@@ -169,7 +171,6 @@ public class TrafficProgressPanel extends JPanel {
}
public void updatePanel(@Nullable TrafficLightRenderer.DaemonCodeAnalyzerStatus status, boolean isFake) {
- if (status == null) return;
boolean isDumb = DumbService.isDumb(myTrafficLightRenderer.getProject());
dumbLabel.setVisible(isDumb);
try {
@@ -178,6 +179,12 @@ public class TrafficProgressPanel extends JPanel {
myPassStatuses.setVisible(false);
statistics.setText("");
}
+ else if (status == null || status.noHighlightingRoots != null && status.noHighlightingRoots.length == status.rootsNumber) {
+ statusLabel.setText(DaemonBundle.message("analysis.hasnot.been.run"));
+ myPassStatuses.setVisible(true);
+ setPassesEnabled(false, Boolean.FALSE);
+ statistics.setText("");
+ }
else if (status.errorAnalyzingFinished) {
if (isDumb) {
statusLabel.setText("Shallow analysis completed");
@@ -194,12 +201,6 @@ public class TrafficProgressPanel extends JPanel {
setPassesEnabled(false, Boolean.FALSE);
statistics.setText("");
}
- else if (status.noHighlightingRoots != null && status.noHighlightingRoots.length == status.rootsNumber) {
- statusLabel.setText(DaemonBundle.message("analysis.hasnot.been.run"));
- myPassStatuses.setVisible(true);
- setPassesEnabled(false, Boolean.FALSE);
- statistics.setText("");
- }
else {
statusLabel.setText(DaemonBundle.message("performing.code.analysis"));
myPassStatuses.setVisible(true);
@@ -207,42 +208,45 @@ public class TrafficProgressPanel extends JPanel {
}
- if (!status.passStati.equals(new ArrayList<ProgressableTextEditorHighlightingPass>(passes.keySet()))) {
+ if (status == null ||
+ !status.passStati.equals(new ArrayList<ProgressableTextEditorHighlightingPass>(passes.keySet()))) {
// passes set has changed
rebuildPassesPanel(status);
}
- for (ProgressableTextEditorHighlightingPass pass : status.passStati) {
- double progress = pass.getProgress();
- Pair<JProgressBar, JLabel> pair = passes.get(pass);
- JProgressBar progressBar = pair.first;
- int percent = (int)Math.round(progress * MAX);
- progressBar.setValue(percent);
- JLabel percentage = pair.second;
- percentage.setText(percent + "%");
- }
+ if (status != null) {
+ for (ProgressableTextEditorHighlightingPass pass : status.passStati) {
+ double progress = pass.getProgress();
+ Pair<JProgressBar, JLabel> pair = passes.get(pass);
+ JProgressBar progressBar = pair.first;
+ int percent = (int)Math.round(progress * MAX);
+ progressBar.setValue(percent);
+ JLabel percentage = pair.second;
+ percentage.setText(percent + "%");
+ }
- int currentSeverityErrors = 0;
- @Language("HTML")
- String text = "";
- for (int i = status.errorCount.length - 1; i >= 0; i--) {
- if (status.errorCount[i] > 0) {
- final HighlightSeverity severity = SeverityRegistrar.getSeverityRegistrar(myTrafficLightRenderer.getProject()).getSeverityByIndex(i);
- String name =
- status.errorCount[i] > 1 ? StringUtil.pluralize(severity.getName().toLowerCase()) : severity.getName().toLowerCase();
+ int currentSeverityErrors = 0;
+ @Language("HTML")
+ String text = "";
+ for (int i = status.errorCount.length - 1; i >= 0; i--) {
+ if (status.errorCount[i] > 0) {
+ final HighlightSeverity severity = SeverityRegistrar.getSeverityRegistrar(myTrafficLightRenderer.getProject()).getSeverityByIndex(i);
+ String name =
+ status.errorCount[i] > 1 ? StringUtil.pluralize(severity.getName().toLowerCase()) : severity.getName().toLowerCase();
+ text += status.errorAnalyzingFinished
+ ? DaemonBundle.message("errors.found", status.errorCount[i], name)
+ : DaemonBundle.message("errors.found.so.far", status.errorCount[i], name);
+ text += "<br>";
+ currentSeverityErrors += status.errorCount[i];
+ }
+ }
+ if (currentSeverityErrors == 0) {
text += status.errorAnalyzingFinished
- ? DaemonBundle.message("errors.found", status.errorCount[i], name)
- : DaemonBundle.message("errors.found.so.far", status.errorCount[i], name);
- text += "<br>";
- currentSeverityErrors += status.errorCount[i];
+ ? DaemonBundle.message("no.errors.or.warnings.found")
+ : DaemonBundle.message("no.errors.or.warnings.found.so.far") + "<br>";
}
+ statistics.setText(XmlStringUtil.wrapInHtml(text));
}
- if (currentSeverityErrors == 0) {
- text += status.errorAnalyzingFinished
- ? DaemonBundle.message("no.errors.or.warnings.found")
- : DaemonBundle.message("no.errors.or.warnings.found.so.far") + "<br>";
- }
- statistics.setText(XmlStringUtil.wrapInHtml(text));
}
finally {
if (isFake) {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/WholeFileLocalInspectionsPassFactory.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/WholeFileLocalInspectionsPassFactory.java
index 40a798c6af48..a1d95d51d7b4 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/WholeFileLocalInspectionsPassFactory.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/WholeFileLocalInspectionsPassFactory.java
@@ -76,7 +76,7 @@ public class WholeFileLocalInspectionsPassFactory extends AbstractProjectCompone
}
@Override
- public void profileActivated(@NotNull Profile oldProfile, Profile profile) {
+ public void profileActivated(Profile oldProfile, Profile profile) {
myFileTools.clear();
}
};
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DockablePopupManager.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DockablePopupManager.java
index 83f17299987b..e0d17d3c164b 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DockablePopupManager.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DockablePopupManager.java
@@ -23,7 +23,7 @@ import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.AsyncResult;
+import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowAnchor;
import com.intellij.openapi.wm.ToolWindowType;
@@ -34,6 +34,7 @@ import com.intellij.psi.PsiFile;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.ui.content.*;
+import com.intellij.util.Consumer;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.update.Activatable;
import com.intellij.util.ui.update.UiNotifyConnector;
@@ -136,30 +137,33 @@ public abstract class DockablePopupManager<T extends JComponent & Disposable> {
protected AnAction[] createActions() {
- return new AnAction[]{
- new ToggleAction(getAutoUpdateTitle(), getAutoUpdateDescription(),
- AllIcons.General.AutoscrollFromSource) {
- @Override
- public boolean isSelected(AnActionEvent e) {
- return myAutoUpdateDocumentation;
- }
-
- @Override
- public void setSelected(AnActionEvent e, boolean state) {
- PropertiesComponent.getInstance().setValue(getAutoUpdateEnabledProperty(), String.valueOf(state));
- myAutoUpdateDocumentation = state;
- restartAutoUpdate(state);
- }
- },
- new AnAction("Restore Popup", getRestorePopupDescription(), AllIcons.Actions.Cancel) {
- @Override
- public void actionPerformed(AnActionEvent e) {
- restorePopupBehavior();
- }
- }};
+ ToggleAction toggleAutoUpdateAction = new ToggleAction(getAutoUpdateTitle(), getAutoUpdateDescription(),
+ AllIcons.General.AutoscrollFromSource) {
+ @Override
+ public boolean isSelected(AnActionEvent e) {
+ return myAutoUpdateDocumentation;
+ }
+
+ @Override
+ public void setSelected(AnActionEvent e, boolean state) {
+ PropertiesComponent.getInstance().setValue(getAutoUpdateEnabledProperty(), String.valueOf(state));
+ myAutoUpdateDocumentation = state;
+ restartAutoUpdate(state);
+ }
+ };
+ return new AnAction[]{toggleAutoUpdateAction, createRestorePopupAction()};
+ }
+
+ @NotNull
+ protected AnAction createRestorePopupAction() {
+ return new AnAction("Restore Popup", getRestorePopupDescription(), AllIcons.Actions.Cancel) {
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ restorePopupBehavior();
+ }
+ };
}
-
protected void restartAutoUpdate(final boolean state) {
if (state && myToolWindow != null) {
if (myAutoUpdateRequest == null) {
@@ -189,12 +193,16 @@ public abstract class DockablePopupManager<T extends JComponent & Disposable> {
public void updateComponent() {
if (myProject.isDisposed()) return;
- AsyncResult<DataContext> asyncResult = DataManager.getInstance().getDataContextFromFocus();
- DataContext dataContext = asyncResult.getResult();
- if (dataContext == null) {
- return;
- }
+ DataManager.getInstance().getDataContextFromFocus().doWhenDone(new Consumer<DataContext>() {
+ @Override
+ public void consume(@NotNull DataContext dataContext) {
+ if (!myProject.isOpen()) return;
+ updateComponentInner(dataContext);
+ }
+ });
+ }
+ private void updateComponentInner(@NotNull DataContext dataContext) {
if (CommonDataKeys.PROJECT.getData(dataContext) != myProject) {
return;
}
@@ -228,13 +236,10 @@ public abstract class DockablePopupManager<T extends JComponent & Disposable> {
protected void restorePopupBehavior() {
if (myToolWindow != null) {
PropertiesComponent.getInstance().setValue(getShowInToolWindowProperty(), Boolean.FALSE.toString());
-
- final Content[] contents = myToolWindow.getContentManager().getContents();
- for (final Content content : contents) {
- myToolWindow.getContentManager().removeContent(content, true);
- }
-
- ToolWindowManagerEx.getInstanceEx(myProject).unregisterToolWindow(getToolwindowId());
+ ToolWindowManagerEx toolWindowManagerEx = ToolWindowManagerEx.getInstanceEx(myProject);
+ toolWindowManagerEx.hideToolWindow(getToolwindowId(), false);
+ toolWindowManagerEx.unregisterToolWindow(getToolwindowId());
+ Disposer.dispose(myToolWindow.getContentManager());
myToolWindow = null;
restartAutoUpdate(false);
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java
index cf9b5ad22798..50f69088033b 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java
@@ -32,6 +32,7 @@ import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.impl.ActionButton;
import com.intellij.openapi.application.ApplicationBundle;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
@@ -47,6 +48,7 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.SmartPointerManager;
import com.intellij.psi.SmartPsiElementPointer;
import com.intellij.ui.IdeBorderFactory;
+import com.intellij.ui.JBColor;
import com.intellij.ui.SideBorder;
import com.intellij.ui.components.JBLayeredPane;
import com.intellij.ui.components.JBScrollPane;
@@ -66,10 +68,9 @@ import javax.swing.event.HyperlinkListener;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.*;
-import java.util.Collections;
+import java.net.URL;
+import java.util.*;
import java.util.List;
-import java.util.Map;
-import java.util.Stack;
public class DocumentationComponent extends JPanel implements Disposable, DataProvider {
@@ -92,7 +93,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
private final Stack<Context> myBackStack = new Stack<Context>();
private final Stack<Context> myForwardStack = new Stack<Context>();
private final ActionToolbar myToolBar;
- private boolean myIsEmpty;
+ private volatile boolean myIsEmpty;
private boolean myIsShown;
private final JLabel myElementLabel;
private Style myFontSizeStyle;
@@ -101,6 +102,13 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
private final MyShowSettingsButton myShowSettingsButton;
private boolean myIgnoreFontSizeSliderChange;
private String myEffectiveExternalUrl;
+ private final MyDictionary<String, Image> myImageProvider = new MyDictionary<String, Image>() {
+ @Override
+ public Image get(Object key) {
+ PsiElement element = getElement();
+ return element == null ? null : myManager.getElementImage(element, ((URL)key).toExternalForm());
+ }
+ };
private static class Context {
final SmartPsiElementPointer element;
@@ -178,6 +186,14 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
GraphicsUtil.setupAntialiasing(g);
super.paintComponent(g);
}
+
+ @Override
+ public void setDocument(Document doc) {
+ super.setDocument(doc);
+ if (doc instanceof StyledDocument) {
+ doc.putProperty("imageCache", myImageProvider);
+ }
+ }
};
DataProvider helpDataProvider = new DataProvider() {
@Override
@@ -308,6 +324,10 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
if (additionalActions != null) {
for (final AnAction action : additionalActions) {
actions.add(action);
+ ShortcutSet shortcutSet = action.getShortcutSet();
+ if (shortcutSet != null) {
+ action.registerCustomShortcutSet(shortcutSet, this);
+ }
}
}
@@ -378,7 +398,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
myFontSizeSlider.setSnapToTicks(true);
UIUtil.setSliderIsFilled(myFontSizeSlider, true);
result.add(myFontSizeSlider);
- result.setBorder(BorderFactory.createLineBorder(UIUtil.getBorderColor(), 1));
+ result.setBorder(BorderFactory.createLineBorder(JBColor.border(), 1));
myFontSizeSlider.addChangeListener(new ChangeListener() {
@Override
@@ -418,11 +438,11 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
}
}
- public synchronized boolean isEmpty() {
+ public boolean isEmpty() {
return myIsEmpty;
}
- public synchronized void startWait() {
+ public void startWait() {
myIsEmpty = true;
}
@@ -473,7 +493,8 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
}
public void replaceText(String text, PsiElement element) {
- if (element == null || getElement() != element) return;
+ PsiElement current = getElement();
+ if (current == null || !current.getManager().areElementsEquivalent(current, element)) return;
setText(text, element, false);
if (!myBackStack.empty()) myBackStack.pop();
}
@@ -530,6 +551,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
myText = text;
}
+ //noinspection SSBasedInspection
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
@@ -544,7 +566,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
return;
}
- StyledDocument styledDocument = (StyledDocument)document;
+ final StyledDocument styledDocument = (StyledDocument)document;
if (myFontSizeStyle == null) {
myFontSizeStyle = styledDocument.addStyle("active", null);
}
@@ -555,7 +577,14 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
if (Registry.is("documentation.component.editor.font")) {
StyleConstants.setFontFamily(myFontSizeStyle, scheme.getEditorFontName());
}
- styledDocument.setCharacterAttributes(0, document.getLength(), myFontSizeStyle, false);
+
+ final Style sizeStyle = myFontSizeStyle;
+ ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
+ @Override
+ public void run() {
+ styledDocument.setCharacterAttributes(0, styledDocument.getLength(), sizeStyle, false);
+ }
+ });
}
private void goBack() {
@@ -631,15 +660,10 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
private class EditDocumentationSourceAction extends BaseNavigateToSourceAction {
- protected EditDocumentationSourceAction() {
+ EditDocumentationSourceAction() {
super(true);
- }
-
- @Override
- public void update(AnActionEvent event) {
- super.update(event);
- event.getPresentation().setIcon(AllIcons.Actions.EditSource);
- event.getPresentation().setText("Edit Source");
+ getTemplatePresentation().setIcon(AllIcons.Actions.EditSource);
+ getTemplatePresentation().setText("Edit Source");
}
@Override
@@ -678,8 +702,8 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
final PsiElement originalElement = DocumentationManager.getOriginalElement(element);
boolean processed = false;
if (provider instanceof CompositeDocumentationProvider) {
- for (final DocumentationProvider documentationProvider : ((CompositeDocumentationProvider)provider).getProviders()) {
- if (documentationProvider instanceof ExternalDocumentationHandler && ((ExternalDocumentationHandler)documentationProvider).handleExternal(element, originalElement)) {
+ for (DocumentationProvider p : ((CompositeDocumentationProvider)provider).getAllProviders()) {
+ if (p instanceof ExternalDocumentationHandler && ((ExternalDocumentationHandler)p).handleExternal(element, originalElement)) {
processed = true;
break;
}
@@ -874,4 +898,36 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
mySettingsPanel.setVisible(true);
}
}
+
+ private static abstract class MyDictionary<K, V> extends Dictionary<K, V> {
+ @Override
+ public int size() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Enumeration<K> keys() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Enumeration<V> elements() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public V put(K key, V value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public V remove(Object key) {
+ throw new UnsupportedOperationException();
+ }
+ }
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java
index 05a1e01c6aa1..63484f890225 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java
@@ -36,9 +36,11 @@ import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.ActionManagerEx;
import com.intellij.openapi.actionSystem.ex.AnActionListener;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.OrderEntry;
@@ -58,13 +60,13 @@ import com.intellij.psi.util.PsiUtilCore;
import com.intellij.ui.ListScrollingUtil;
import com.intellij.ui.content.Content;
import com.intellij.ui.popup.AbstractPopup;
-import com.intellij.ui.popup.NotLookupOrSearchCondition;
import com.intellij.ui.popup.PopupPositionManager;
import com.intellij.ui.popup.PopupUpdateProcessor;
import com.intellij.util.Alarm;
import com.intellij.util.BooleanFunction;
import com.intellij.util.Consumer;
import com.intellij.util.Processor;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -125,6 +127,24 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
return "Auto Show Documentation for Selected Element";
}
+ @NotNull
+ @Override
+ protected AnAction createRestorePopupAction() {
+ AnAction restorePopupAction = super.createRestorePopupAction();
+ ShortcutSet quickDocShortcut = ActionManager.getInstance().getAction(IdeActions.ACTION_QUICK_JAVADOC).getShortcutSet();
+ restorePopupAction.registerCustomShortcutSet(quickDocShortcut, null);
+ return restorePopupAction;
+ }
+
+ @Override
+ protected void restorePopupBehavior() {
+ if (myPreviouslyFocused != null) {
+ IdeFocusManager.getInstance(myProject).requestFocus(myPreviouslyFocused, true);
+ }
+ super.restorePopupBehavior();
+ updateComponent();
+ }
+
/**
* @return <code>true</code> if quick doc control is configured to not prevent user-IDE interaction (e.g. should be closed if
* the user presses a key);
@@ -165,7 +185,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
@Override
public void beforeEditorTyping(char c, DataContext dataContext) {
final JBPopup hint = getDocInfoHint();
- if (hint != null) {
+ if (hint != null && LookupManager.getActiveLookup(myEditor) == null) {
hint.cancel();
}
}
@@ -213,7 +233,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
}
public void showJavaDocInfo(@NotNull final PsiElement element, final PsiElement original) {
- showJavaDocInfo(element, original, false, null);
+ showJavaDocInfo(element, original, null);
}
/**
@@ -229,35 +249,31 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
* two possible situations - the quick doc is shown automatically on mouse over element; the quick doc is shown
* on explicit action call (Ctrl+Q). We want to close the doc on, say, editor viewport position change
* at the first situation but don't want to do that at the second
- * @param allowReuse defines whether currently requested documentation should reuse existing doc control (if any)
*/
public void showJavaDocInfo(@NotNull Editor editor,
@NotNull final PsiElement element,
@NotNull final PsiElement original,
@Nullable Runnable closeCallback,
- boolean closeOnSneeze,
- boolean allowReuse)
+ boolean closeOnSneeze)
{
myEditor = editor;
myCloseOnSneeze = closeOnSneeze;
- showJavaDocInfo(element, original, allowReuse, closeCallback);
+ showJavaDocInfo(element, original, closeCallback);
}
public void showJavaDocInfo(@NotNull final PsiElement element,
final PsiElement original,
- boolean allowReuse,
- @Nullable Runnable closeCallback)
- {
+ @Nullable Runnable closeCallback) {
PopupUpdateProcessor updateProcessor = new PopupUpdateProcessor(element.getProject()) {
@Override
public void updatePopup(Object lookupItemObject) {
if (lookupItemObject instanceof PsiElement) {
- doShowJavaDocInfo((PsiElement)lookupItemObject, false, this, original, false);
+ doShowJavaDocInfo((PsiElement)lookupItemObject, false, this, original, null);
}
}
};
- doShowJavaDocInfo(element, false, updateProcessor, original, allowReuse, closeCallback);
+ doShowJavaDocInfo(element, false, updateProcessor, original, closeCallback);
}
public void showJavaDocInfo(final Editor editor, @Nullable final PsiFile file, boolean requestFocus) {
@@ -267,14 +283,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
public void showJavaDocInfo(final Editor editor,
@Nullable final PsiFile file,
boolean requestFocus,
- final Runnable closeCallback) {
- showJavaDocInfo(editor, file, requestFocus, true, closeCallback);
- }
-
- private void showJavaDocInfo(final Editor editor,
- @Nullable final PsiFile file,
- boolean requestFocus,
- final boolean autoupdate, @Nullable final Runnable closeCallback) {
+ @Nullable final Runnable closeCallback) {
myEditor = editor;
final Project project = getProject(file);
PsiDocumentManager.getInstance(project).commitAllDocuments();
@@ -324,7 +333,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
return;
}
if (lookupIteObject instanceof PsiElement) {
- doShowJavaDocInfo((PsiElement)lookupIteObject, false, this, originalElement, autoupdate, closeCallback);
+ doShowJavaDocInfo((PsiElement)lookupIteObject, false, this, originalElement, closeCallback);
return;
}
@@ -347,12 +356,12 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
}
}
else {
- doShowJavaDocInfo(element, false, this, originalElement, autoupdate, closeCallback);
+ doShowJavaDocInfo(element, false, this, originalElement, closeCallback);
}
}
};
- doShowJavaDocInfo(element, requestFocus, updateProcessor, originalElement, autoupdate, closeCallback);
+ doShowJavaDocInfo(element, requestFocus, updateProcessor, originalElement, closeCallback);
}
public PsiElement findTargetElement(Editor editor, PsiFile file) {
@@ -363,54 +372,56 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
return file != null ? file.findElementAt(editor.getCaretModel().getOffset()) : null;
}
- private void doShowJavaDocInfo(final PsiElement element, boolean requestFocus, PopupUpdateProcessor updateProcessor,
- final PsiElement originalElement, final boolean autoupdate)
- {
- doShowJavaDocInfo(element, requestFocus, updateProcessor, originalElement, autoupdate, null);
- }
-
private void doShowJavaDocInfo(@NotNull final PsiElement element,
boolean requestFocus,
PopupUpdateProcessor updateProcessor,
final PsiElement originalElement,
- final boolean allowReuse,
- @Nullable final Runnable closeCallback)
- {
+ @Nullable final Runnable closeCallback) {
Project project = getProject(element);
storeOriginalElement(project, originalElement, element);
+ myPreviouslyFocused = WindowManagerEx.getInstanceEx().getFocusedComponent(project);
+
+ JBPopup _oldHint = getDocInfoHint();
if (myToolWindow == null && PropertiesComponent.getInstance().isTrueValue(SHOW_DOCUMENTATION_IN_TOOL_WINDOW)) {
createToolWindow(element, originalElement);
- return;
}
else if (myToolWindow != null) {
- if (allowReuse && !myToolWindow.isAutoHide()) {
- final Content content = myToolWindow.getContentManager().getSelectedContent();
- if (content != null) {
- final DocumentationComponent component = (DocumentationComponent)content.getComponent();
- if (component.getElement() != element) {
- content.setDisplayName(getTitle(element, true));
- fetchDocInfo(getDefaultCollector(element, originalElement), component, true);
+ Content content = myToolWindow.getContentManager().getSelectedContent();
+ if (content != null) {
+ DocumentationComponent component = (DocumentationComponent)content.getComponent();
+ if (element.getManager().areElementsEquivalent(component.getElement(), element)) {
+ JComponent preferredFocusableComponent = content.getPreferredFocusableComponent();
+ // focus toolwindow on the second actionPerformed
+ boolean focus = requestFocus || CommandProcessor.getInstance().getCurrentCommand() != null;
+ if (preferredFocusableComponent != null && focus) {
+ IdeFocusManager.getInstance(myProject).requestFocus(preferredFocusableComponent, true);
}
}
-
- if (!myToolWindow.isVisible()) {
- myToolWindow.show(null);
+ else {
+ content.setDisplayName(getTitle(element, true));
+ fetchDocInfo(getDefaultCollector(element, originalElement), component, true);
}
- return;
}
- else {
- restorePopupBehavior();
+
+ if (!myToolWindow.isVisible()) {
+ myToolWindow.show(null);
}
}
-
- final JBPopup _oldHint = getDocInfoHint();
- if (_oldHint != null && _oldHint.isVisible() && _oldHint instanceof AbstractPopup) {
- final DocumentationComponent oldComponent = (DocumentationComponent)((AbstractPopup)_oldHint).getComponent();
+ else if (_oldHint != null && _oldHint.isVisible() && _oldHint instanceof AbstractPopup) {
+ DocumentationComponent oldComponent = (DocumentationComponent)((AbstractPopup)_oldHint).getComponent();
fetchDocInfo(getDefaultCollector(element, originalElement), oldComponent);
- return;
}
+ else {
+ showInPopup(element, requestFocus, updateProcessor, originalElement, closeCallback);
+ }
+ }
+ private void showInPopup(@NotNull final PsiElement element,
+ boolean requestFocus,
+ PopupUpdateProcessor updateProcessor,
+ final PsiElement originalElement,
+ @Nullable final Runnable closeCallback) {
final DocumentationComponent component = new DocumentationComponent(this);
component.setNavigateCallback(new Consumer<PsiElement>() {
@Override
@@ -426,26 +437,30 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
@Override
public boolean process(JBPopup popup) {
createToolWindow(element, originalElement);
+ myToolWindow.setAutoHide(false);
popup.cancel();
return false;
}
};
- final KeyboardShortcut keyboardShortcut = ActionManagerEx.getInstanceEx().getKeyboardShortcut("QuickJavaDoc");
- final List<Pair<ActionListener, KeyStroke>> actions =
- Collections.singletonList(Pair.<ActionListener, KeyStroke>create(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- createToolWindow(element, originalElement);
- final JBPopup hint = getDocInfoHint();
- if (hint != null && hint.isVisible()) hint.cancel();
- }
- }, keyboardShortcut != null ? keyboardShortcut.getFirstKeyStroke() : null)); // Null keyStroke is ok here
+ ActionListener actionListener = new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ createToolWindow(element, originalElement);
+ final JBPopup hint = getDocInfoHint();
+ if (hint != null && hint.isVisible()) hint.cancel();
+ }
+ };
+ List<Pair<ActionListener, KeyStroke>> actions = ContainerUtil.newSmartList();
+ AnAction quickDocAction = ActionManagerEx.getInstanceEx().getAction(IdeActions.ACTION_QUICK_JAVADOC);
+ for (Shortcut shortcut : quickDocAction.getShortcutSet().getShortcuts()) {
+ if (!(shortcut instanceof KeyboardShortcut)) continue;
+ actions.add(Pair.create(actionListener, ((KeyboardShortcut)shortcut).getFirstKeyStroke()));
+ }
boolean hasLookup = LookupManager.getActiveLookup(myEditor) != null;
final JBPopup hint = JBPopupFactory.getInstance().createComponentPopupBuilder(component, component)
- .setRequestFocusCondition(project, NotLookupOrSearchCondition.INSTANCE)
- .setProject(project)
+ .setProject(element.getProject())
.addListener(updateProcessor)
.addUserData(updateProcessor)
.setKeyboardActions(actions)
@@ -490,20 +505,6 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
})
.createPopup();
-
- AbstractPopup oldHint = (AbstractPopup)getDocInfoHint();
- if (oldHint != null) {
- DocumentationComponent oldComponent = (DocumentationComponent)oldHint.getComponent();
- PsiElement element1 = oldComponent.getElement();
- if (Comparing.equal(element, element1)) {
- if (requestFocus) {
- component.getComponent().requestFocus();
- }
- return;
- }
- oldHint.cancel();
- }
-
component.setHint(hint);
if (myEditor == null) {
@@ -515,7 +516,6 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
fetchDocInfo(getDefaultCollector(element, originalElement), component);
myDocInfoHintRef = new WeakReference<JBPopup>(hint);
- myPreviouslyFocused = WindowManagerEx.getInstanceEx().getFocusedComponent(project);
if (fromQuickSearch() && myPreviouslyFocused != null) {
((ChooseByNameBase.JPanelProvider)myPreviouslyFocused.getParent()).registerHint(hint);
@@ -666,11 +666,12 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
private ActionCallback doFetchDocInfo(final DocumentationComponent component, final DocumentationCollector provider, final boolean cancelRequests, final boolean clearHistory) {
final ActionCallback callback = new ActionCallback();
+ boolean wasEmpty = component.isEmpty();
component.startWait();
if (cancelRequests) {
myUpdateDocAlarm.cancelAllRequests();
}
- if (component.isEmpty()) {
+ if (wasEmpty) {
component.setText(CodeInsightBundle.message("javadoc.fetching.progress"), null, clearHistory);
final AbstractPopup jbPopup = (AbstractPopup)getDocInfoHint();
if (jbPopup != null) {
@@ -845,7 +846,26 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
} else if (url.startsWith(PSI_ELEMENT_PROTOCOL)) {
final String refText = url.substring(PSI_ELEMENT_PROTOCOL.length());
DocumentationProvider provider = getProviderFromElement(psiElement);
- final PsiElement targetElement = provider.getDocumentationElementForLink(manager, refText, psiElement);
+ PsiElement targetElement = provider.getDocumentationElementForLink(manager, refText, psiElement);
+ if (targetElement == null) {
+ for (DocumentationProvider documentationProvider : Extensions.getExtensions(DocumentationProvider.EP_NAME)) {
+ targetElement = documentationProvider.getDocumentationElementForLink(manager, refText, psiElement);
+ if (targetElement != null) {
+ break;
+ }
+ }
+ }
+ if (targetElement == null) {
+ for (Language language : Language.getRegisteredLanguages()) {
+ DocumentationProvider documentationProvider = LanguageDocumentation.INSTANCE.forLanguage(language);
+ if (documentationProvider != null) {
+ targetElement = documentationProvider.getDocumentationElementForLink(manager, refText, psiElement);
+ if (targetElement != null) {
+ break;
+ }
+ }
+ }
+ }
if (targetElement != null) {
fetchDocInfo(getDefaultCollector(targetElement, null), component);
}
@@ -854,33 +874,33 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
final DocumentationProvider provider = getProviderFromElement(psiElement);
boolean processed = false;
if (provider instanceof CompositeDocumentationProvider) {
- for (DocumentationProvider documentationProvider : ((CompositeDocumentationProvider)provider).getProviders()) {
- if (documentationProvider instanceof ExternalDocumentationHandler) {
- final ExternalDocumentationHandler externalDocumentationHandler = (ExternalDocumentationHandler)documentationProvider;
- if (externalDocumentationHandler.canFetchDocumentationLink(url)) {
- fetchDocInfo(new DocumentationCollector() {
- @Override
- public String getDocumentation() throws Exception {
- return externalDocumentationHandler.fetchExternalDocumentation(url, psiElement);
- }
+ for (DocumentationProvider p : ((CompositeDocumentationProvider)provider).getAllProviders()) {
+ if (!(p instanceof ExternalDocumentationHandler)) continue;
- @Override
- public PsiElement getElement() {
- return psiElement;
- }
+ final ExternalDocumentationHandler externalHandler = (ExternalDocumentationHandler)p;
+ if (externalHandler.canFetchDocumentationLink(url)) {
+ fetchDocInfo(new DocumentationCollector() {
+ @Override
+ public String getDocumentation() throws Exception {
+ return externalHandler.fetchExternalDocumentation(url, psiElement);
+ }
- @Nullable
- @Override
- public String getEffectiveExternalUrl() {
- return url;
- }
- }, component);
- processed = true;
- }
- else if (externalDocumentationHandler.handleExternalLink(manager, url, psiElement)) {
- processed = true;
- break;
- }
+ @Override
+ public PsiElement getElement() {
+ return psiElement;
+ }
+
+ @Nullable
+ @Override
+ public String getEffectiveExternalUrl() {
+ return url;
+ }
+ }, component);
+ processed = true;
+ }
+ else if (externalHandler.handleExternalLink(manager, url, psiElement)) {
+ processed = true;
+ break;
}
}
}
@@ -979,12 +999,12 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
@Override
protected void doUpdateComponent(Editor editor, PsiFile psiFile) {
- showJavaDocInfo(editor, psiFile, false, true, null);
+ showJavaDocInfo(editor, psiFile, false, null);
}
@Override
protected void doUpdateComponent(@NotNull PsiElement element) {
- showJavaDocInfo(element, element, true, null);
+ showJavaDocInfo(element, element, null);
}
@Override
@@ -992,6 +1012,20 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
return getTitle(element, true);
}
+ @Nullable
+ public Image getElementImage(@NotNull PsiElement element, @NotNull String imageSpec) {
+ DocumentationProvider provider = getProviderFromElement(element);
+ if (provider instanceof CompositeDocumentationProvider) {
+ for (DocumentationProvider p : ((CompositeDocumentationProvider)provider).getAllProviders()) {
+ if (p instanceof DocumentationProviderEx) {
+ Image image = ((DocumentationProviderEx)p).getLocalImageForElement(element, imageSpec);
+ if (image != null) return image;
+ }
+ }
+ }
+ return null;
+ }
+
private interface DocumentationCollector {
@Nullable
String getDocumentation() throws Exception;
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/QuickDocOnMouseOverManager.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/QuickDocOnMouseOverManager.java
index 47bf01f2e7c8..0cd18020ad54 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/QuickDocOnMouseOverManager.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/QuickDocOnMouseOverManager.java
@@ -301,7 +301,7 @@ public class QuickDocOnMouseOverManager {
info.editor.putUserData(PopupFactoryImpl.ANCHOR_POPUP_POSITION,
info.editor.offsetToVisualPosition(info.originalElement.getTextRange().getStartOffset()));
try {
- info.docManager.showJavaDocInfo(info.editor, info.targetElement, info.originalElement, myHintCloseCallback, true, true);
+ info.docManager.showJavaDocInfo(info.editor, info.targetElement, info.originalElement, myHintCloseCallback, true);
myDocumentationManager = new WeakReference<DocumentationManager>(info.docManager);
}
finally {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/QuickDocUtil.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/QuickDocUtil.java
new file mode 100644
index 000000000000..064bd020183b
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/QuickDocUtil.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.documentation;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.popup.JBPopup;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.wm.ToolWindow;
+import com.intellij.openapi.wm.ToolWindowId;
+import com.intellij.openapi.wm.ToolWindowManager;
+import com.intellij.psi.PsiElement;
+import com.intellij.ui.content.Content;
+import com.intellij.ui.popup.AbstractPopup;
+import com.intellij.util.Producer;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+
+/**
+ * @author gregsh
+ */
+public class QuickDocUtil {
+
+ public static void updateQuickDocAsync(@NotNull final PsiElement element, @NotNull final Producer<String> docProducer) {
+ final Project project = element.getProject();
+ ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
+ @Override
+ public void run() {
+ final String documentation = docProducer.produce();
+ if (StringUtil.isEmpty(documentation)) return;
+ // modal dialogs with fragment editors fix: can't guess proper modality state here
+ //noinspection SSBasedInspection
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ DocumentationManager documentationManager = DocumentationManager.getInstance(project);
+ DocumentationComponent component;
+ JBPopup hint = documentationManager.getDocInfoHint();
+ if (hint != null) {
+ component = (DocumentationComponent)((AbstractPopup)hint).getComponent();
+ }
+ else if (documentationManager.hasActiveDockedDocWindow()) {
+ ToolWindow toolWindow = ToolWindowManager.getInstance(project).getToolWindow(ToolWindowId.DOCUMENTATION);
+ Content selectedContent = toolWindow == null ? null : toolWindow.getContentManager().getSelectedContent();
+ component = selectedContent == null ? null : (DocumentationComponent)selectedContent.getComponent();
+ }
+ else {
+ component = null;
+ }
+ if (component != null) {
+ component.replaceText(documentation, element);
+ }
+ }
+ });
+ }
+ });
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java
index eb163245d23b..8010e76335bb 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java
@@ -44,13 +44,15 @@ public class CompletionAutoPopupHandler extends TypedHandlerDelegate {
@Override
public Result checkAutoPopup(char charTyped, final Project project, final Editor editor, final PsiFile file) {
- CompletionPhase oldPhase = CompletionServiceImpl.getCompletionPhase();
+ LookupImpl lookup = (LookupImpl)LookupManager.getActiveLookup(editor);
- if (oldPhase instanceof CompletionPhase.CommittingDocuments && ((CompletionPhase.CommittingDocuments)oldPhase).isRestartingCompletion()) {
- return Result.STOP;
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("checkAutoPopup: character=" + charTyped + ";");
+ LOG.debug("phase=" + CompletionServiceImpl.getCompletionPhase());
+ LOG.debug("lookup=" + lookup);
+ LOG.debug("currentCompletion=" + CompletionServiceImpl.getCompletionService().getCurrentCompletion());
}
- LookupImpl lookup = (LookupImpl)LookupManager.getActiveLookup(editor);
if (lookup != null) {
if (editor.getSelectionModel().hasSelection()) {
lookup.performGuardedChange(new Runnable() {
@@ -68,9 +70,6 @@ public class CompletionAutoPopupHandler extends TypedHandlerDelegate {
return Result.STOP;
}
- if (CompletionServiceImpl.isPhase(CompletionPhase.CommittingDocuments.class)) {
- CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion);
- }
return Result.CONTINUE;
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/JoinLinesHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/JoinLinesHandler.java
index 5f416dd307c4..1149576e4806 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/JoinLinesHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/JoinLinesHandler.java
@@ -29,6 +29,7 @@ import com.intellij.lang.ASTNode;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Caret;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.LogicalPosition;
import com.intellij.openapi.editor.ScrollType;
@@ -49,6 +50,7 @@ import com.intellij.util.IncorrectOperationException;
import com.intellij.util.NotNullFunction;
import com.intellij.util.text.CharArrayUtil;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import static com.intellij.codeInsight.editorActions.JoinLinesHandlerDelegate.CANNOT_JOIN;
@@ -61,66 +63,65 @@ public class JoinLinesHandler extends EditorWriteActionHandler {
myOriginalHandler = originalHandler;
}
- private static TextRange findStartAndEnd(CharSequence text, int start, int end, int maxoffset) {
+ @NotNull
+ private static TextRange findStartAndEnd(@NotNull CharSequence text, int start, int end, int maxoffset) {
while (start > 0 && (text.charAt(start) == ' ' || text.charAt(start) == '\t')) start--;
while (end < maxoffset && (text.charAt(end) == ' ' || text.charAt(end) == '\t')) end++;
return new TextRange(start, end);
}
@Override
- public void executeWriteAction(final Editor editor, final DataContext dataContext) {
+ public void executeWriteAction(@NotNull final Editor editor, @Nullable Caret caret, final DataContext dataContext) {
+ assert caret != null;
if (!(editor.getDocument() instanceof DocumentEx)) {
- myOriginalHandler.execute(editor, dataContext);
+ myOriginalHandler.execute(editor, caret, dataContext);
return;
}
final DocumentEx doc = (DocumentEx)editor.getDocument();
final Project project = CommonDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(editor.getContentComponent()));
- if (project == null) {
- return;
- }
-
- LogicalPosition caretPosition = editor.getCaretModel().getLogicalPosition();
+ if (project == null) return;
final PsiDocumentManager docManager = PsiDocumentManager.getInstance(project);
PsiFile psiFile = docManager.getPsiFile(doc);
if (psiFile == null) {
- myOriginalHandler.execute(editor, dataContext);
+ myOriginalHandler.execute(editor, caret, dataContext);
return;
}
+ LogicalPosition caretPosition = caret.getLogicalPosition();
int startLine = caretPosition.line;
int endLine = startLine + 1;
- if (editor.getSelectionModel().hasSelection()) {
- startLine = doc.getLineNumber(editor.getSelectionModel().getSelectionStart());
- endLine = doc.getLineNumber(editor.getSelectionModel().getSelectionEnd());
- if (doc.getLineStartOffset(endLine) == editor.getSelectionModel().getSelectionEnd()) endLine--;
+ if (caret.hasSelection()) {
+ startLine = doc.getLineNumber(caret.getSelectionStart());
+ endLine = doc.getLineNumber(caret.getSelectionEnd());
+ if (doc.getLineStartOffset(endLine) == caret.getSelectionEnd()) endLine--;
}
final int startReformatOffset = CharArrayUtil.shiftBackward(doc.getCharsSequence(), doc.getLineEndOffset(startLine), " \t");
CodeEditUtil.setNodeReformatStrategy(new NotNullFunction<ASTNode, Boolean>() {
@NotNull
@Override
- public Boolean fun(ASTNode node) {
+ public Boolean fun(@NotNull ASTNode node) {
return node.getTextRange().getStartOffset() >= startReformatOffset;
}
});
try {
- doJob(editor, doc, project, docManager, psiFile, startLine, endLine);
+ doJob(editor, doc, caret, project, docManager, psiFile, startLine, endLine);
}
finally {
CodeEditUtil.setNodeReformatStrategy(null);
}
}
- private static void doJob(Editor editor,
- DocumentEx doc,
- Project project,
- PsiDocumentManager docManager,
- PsiFile psiFile,
+ private static void doJob(@NotNull Editor editor,
+ @NotNull DocumentEx doc,
+ @NotNull Caret caret,
+ @NotNull Project project,
+ @NotNull PsiDocumentManager docManager,
+ @NotNull PsiFile psiFile,
int startLine,
- int endLine)
- {
+ int endLine) {
int caretRestoreOffset = -1;
// joining lines, several times if selection is multiline
for (int i = startLine; i < endLine; i++) {
@@ -262,17 +263,19 @@ public class JoinLinesHandler extends EditorWriteActionHandler {
}
docManager.commitDocument(doc); // cheap on an already-committed doc
- if (editor.getSelectionModel().hasSelection()) {
- editor.getCaretModel().moveToOffset(editor.getSelectionModel().getSelectionEnd());
+ if (caret.hasSelection()) {
+ caret.moveToOffset(caret.getSelectionEnd());
}
else if (caretRestoreOffset != CANNOT_JOIN) {
- editor.getCaretModel().moveToOffset(caretRestoreOffset);
- editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
- editor.getSelectionModel().removeSelection();
+ caret.moveToOffset(caretRestoreOffset);
+ if (caret == editor.getCaretModel().getPrimaryCaret()) { // performance
+ editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
+ }
+ caret.removeSelection();
}
}
- private static boolean isCommentElement(final PsiElement element) {
+ private static boolean isCommentElement(@Nullable final PsiElement element) {
return element != null && PsiTreeUtil.getParentOfType(element, PsiComment.class, false) != null;
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/generation/GenerateByPatternDialog.java b/platform/lang-impl/src/com/intellij/codeInsight/generation/GenerateByPatternDialog.java
index abdcf6c44047..f736a02d83bf 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/generation/GenerateByPatternDialog.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/generation/GenerateByPatternDialog.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.intellij.codeInsight.generation;
import com.intellij.codeInsight.template.Template;
@@ -13,6 +28,7 @@ import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.treeStructure.SimpleTree;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.containers.MultiMap;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -55,8 +71,9 @@ public class GenerateByPatternDialog extends DialogWrapper {
};
myTree.setRootVisible(false);
myTree.setCellRenderer(new DefaultTreeCellRenderer() {
+ @NotNull
@Override
- public Component getTreeCellRendererComponent(JTree tree,
+ public Component getTreeCellRendererComponent(@NotNull JTree tree,
Object value,
boolean sel,
boolean expanded,
@@ -78,7 +95,7 @@ public class GenerateByPatternDialog extends DialogWrapper {
myTree.setModel(new DefaultTreeModel(root));
myTree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() {
@Override
- public void valueChanged(TreeSelectionEvent e) {
+ public void valueChanged(@NotNull TreeSelectionEvent e) {
update();
}
});
@@ -141,6 +158,7 @@ public class GenerateByPatternDialog extends DialogWrapper {
private DefaultMutableTreeNode createNode(@Nullable PatternDescriptor descriptor) {
DefaultMutableTreeNode root = new DefaultMutableTreeNode(descriptor) {
+ @NotNull
@Override
public String toString() {
Object object = getUserObject();
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/highlighting/HighlightUsagesHandlerFactory.java b/platform/lang-impl/src/com/intellij/codeInsight/highlighting/HighlightUsagesHandlerFactory.java
index 786c14b68201..2de362f14074 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/highlighting/HighlightUsagesHandlerFactory.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/highlighting/HighlightUsagesHandlerFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,6 +23,8 @@ import org.jetbrains.annotations.Nullable;
/**
* @author yole
+ *
+ * @see com.intellij.codeInsight.highlighting.HighlightUsagesHandlerFactoryBase
*/
public interface HighlightUsagesHandlerFactory {
ExtensionPointName<HighlightUsagesHandlerFactory> EP_NAME = ExtensionPointName.create("com.intellij.highlightUsagesHandlerFactory");
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/highlighting/HighlightUsagesHandlerFactoryBase.java b/platform/lang-impl/src/com/intellij/codeInsight/highlighting/HighlightUsagesHandlerFactoryBase.java
new file mode 100644
index 000000000000..83c6cf35c57e
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/codeInsight/highlighting/HighlightUsagesHandlerFactoryBase.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.highlighting;
+
+import com.intellij.codeInsight.TargetElementUtilBase;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public abstract class HighlightUsagesHandlerFactoryBase implements HighlightUsagesHandlerFactory {
+ @Nullable
+ @Override
+ public final HighlightUsagesHandlerBase createHighlightUsagesHandler(Editor editor, PsiFile file) {
+ int offset = TargetElementUtilBase.adjustOffset(file, editor.getDocument(), editor.getCaretModel().getOffset());
+ PsiElement target = file.findElementAt(offset);
+ if (target == null) return null;
+ return createHighlightUsagesHandler(editor, file, target);
+ }
+
+ @Nullable
+ public abstract HighlightUsagesHandlerBase createHighlightUsagesHandler(@NotNull Editor editor, @NotNull PsiFile file, @NotNull PsiElement target);
+}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java
index 4e1a8e958d91..b1ad07f906d2 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java
@@ -22,7 +22,6 @@ import com.intellij.lang.parameterInfo.ParameterInfoUIContextEx;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.TextRange;
-import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.ui.Gray;
import com.intellij.ui.JBColor;
@@ -296,47 +295,50 @@ public class ParameterInfoComponent extends JPanel {
public String setup(final String[] texts, final EnumSet<ParameterInfoUIContextEx.Flag>[] flags, final Color background) {
StringBuilder buf = new StringBuilder();
removeAll();
- final String[] lines = UIUtil.splitText(StringUtil.join(texts), getFontMetrics(BOLD_FONT), myWidthLimit, ',');
-
+ setBackground(background);
int index = 0;
int curOffset = 0;
-
- myOneLineComponents = new OneLineComponent[lines.length];
+ final ArrayList<OneLineComponent> components = new ArrayList<OneLineComponent>();
Map<TextRange, ParameterInfoUIContextEx.Flag> flagsMap = new TreeMap<TextRange, ParameterInfoUIContextEx.Flag>(TEXT_RANGE_COMPARATOR);
- int added = 0;
+ String line = "";
for (int i = 0; i < texts.length; i++) {
- String line = escapeString(texts[i]);
- if (lines.length <= index) break;
- String text = lines[index];
- final int paramCount = StringUtil.split(text, ", ").size();
+ String paramText = escapeString(texts[i]);
+ if (paramText == null) break;
+ line += texts[i];
final EnumSet<ParameterInfoUIContextEx.Flag> flag = flags[i];
if (flag.contains(ParameterInfoUIContextEx.Flag.HIGHLIGHT)) {
- flagsMap.put(TextRange.create(curOffset, curOffset + line.trim().length()), ParameterInfoUIContextEx.Flag.HIGHLIGHT);
+ flagsMap.put(TextRange.create(curOffset, curOffset + paramText.trim().length()), ParameterInfoUIContextEx.Flag.HIGHLIGHT);
}
if (flag.contains(ParameterInfoUIContextEx.Flag.DISABLE)) {
- flagsMap.put(TextRange.create(curOffset, curOffset + line.trim().length()), ParameterInfoUIContextEx.Flag.DISABLE);
+ flagsMap.put(TextRange.create(curOffset, curOffset + paramText.trim().length()), ParameterInfoUIContextEx.Flag.DISABLE);
}
if (flag.contains(ParameterInfoUIContextEx.Flag.STRIKEOUT)) {
- flagsMap.put(TextRange.create(curOffset, curOffset + line.trim().length()), ParameterInfoUIContextEx.Flag.STRIKEOUT);
+ flagsMap.put(TextRange.create(curOffset, curOffset + paramText.trim().length()), ParameterInfoUIContextEx.Flag.STRIKEOUT);
}
- curOffset += line.length();
- if (i == paramCount + added - 1) {
- myOneLineComponents[index] = new OneLineComponent();
- setBackground(background);
- buf.append(myOneLineComponents[index].setup(escapeString(text), flagsMap, background));
- add(myOneLineComponents[index], new GridBagConstraints(0, index, 1, 1, 1, 0, GridBagConstraints.WEST,
+ curOffset += paramText.length();
+ if (line.length() >= 50) {
+ final OneLineComponent component = new OneLineComponent();
+ buf.append(component.setup(escapeString(line), flagsMap, background));
+ add(component, new GridBagConstraints(0, index, 1, 1, 1, 0, GridBagConstraints.WEST,
GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
index += 1;
flagsMap.clear();
- curOffset = 1;
- added += paramCount;
+ curOffset = 0;
+ line = "";
+ components.add(component);
}
}
+ final OneLineComponent component = new OneLineComponent();
+ buf.append(component.setup(escapeString(line), flagsMap, background));
+ add(component, new GridBagConstraints(0, index, 1, 1, 1, 0, GridBagConstraints.WEST,
+ GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ components.add(component);
+ myOneLineComponents = components.toArray(new OneLineComponent[components.size()]);
return buf.toString();
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java
index 4a7abe355380..afd7b230621c 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java
@@ -37,7 +37,6 @@ import com.intellij.openapi.progress.impl.BackgroundableProcessIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.JBPopupFactory;
-import com.intellij.openapi.ui.popup.LightweightWindowEvent;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vfs.VirtualFile;
@@ -48,7 +47,6 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.reference.SoftReference;
import com.intellij.ui.popup.AbstractPopup;
-import com.intellij.ui.popup.NotLookupOrSearchCondition;
import com.intellij.ui.popup.PopupPositionManager;
import com.intellij.ui.popup.PopupUpdateProcessor;
import com.intellij.usages.UsageView;
@@ -274,7 +272,6 @@ public class ShowImplementationsAction extends AnAction implements PopupAction {
};
popup = JBPopupFactory.getInstance().createComponentPopupBuilder(component, component.getPreferredFocusableComponent())
- .setRequestFocusCondition(project, NotLookupOrSearchCondition.INSTANCE)
.setProject(project)
.addListener(updateProcessor)
.addUserData(updateProcessor)
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditAction.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditAction.java
index 62e3bcba3a22..d168002f97a7 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditAction.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditAction.java
@@ -30,11 +30,15 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.psi.*;
+import com.intellij.psi.ElementManipulators;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiLanguageInjectionHost;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.impl.source.tree.injected.Place;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -93,14 +97,17 @@ public class QuickEditAction implements IntentionAction, LowPriorityAction {
}
public QuickEditHandler invokeImpl(@NotNull final Project project, final Editor editor, PsiFile file) throws IncorrectOperationException {
- final int offset = editor.getCaretModel().getOffset();
- final Pair<PsiElement, TextRange> pair = getRangePair(file, editor);
- assert pair != null;
- final PsiFile injectedFile = (PsiFile)pair.first;
- final int injectedOffset = ((DocumentWindow)PsiDocumentManager.getInstance(project).getDocument(injectedFile)).hostToInjected(offset);
+ int offset = editor.getCaretModel().getOffset();
+ Pair<PsiElement, TextRange> pair = ObjectUtils.assertNotNull(getRangePair(file, editor));
+
+ PsiFile injectedFile = (PsiFile)pair.first;
QuickEditHandler handler = getHandler(project, injectedFile, editor, file);
+
if (!ApplicationManager.getApplication().isUnitTestMode()) {
- handler.navigate(injectedOffset);
+ DocumentWindow documentWindow = InjectedLanguageUtil.getDocumentWindow(injectedFile);
+ if (documentWindow != null) {
+ handler.navigate(documentWindow.hostToInjected(offset));
+ }
}
return handler;
}
@@ -124,12 +131,15 @@ public class QuickEditAction implements IntentionAction, LowPriorityAction {
return handler;
}
- public static QuickEditHandler getExistingHandler(PsiFile injectedFile) {
+ public static QuickEditHandler getExistingHandler(@NotNull PsiFile injectedFile) {
Place shreds = InjectedLanguageUtil.getShreds(injectedFile);
- if (shreds == null) return null;
+ DocumentWindow documentWindow = InjectedLanguageUtil.getDocumentWindow(injectedFile);
+ if (shreds == null || documentWindow == null) return null;
+
TextRange hostRange = TextRange.create(shreds.get(0).getHostRangeMarker().getStartOffset(),
shreds.get(shreds.size() - 1).getHostRangeMarker().getEndOffset());
for (Editor editor : EditorFactory.getInstance().getAllEditors()) {
+ if (editor.getDocument() != documentWindow.getDelegate()) continue;
QuickEditHandler handler = editor.getUserData(QUICK_EDIT_HANDLER);
if (handler != null && handler.changesRange(hostRange)) return handler;
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java
index 2c5d8642e46d..517f23c5a198 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java
@@ -360,7 +360,7 @@ public class QuickEditHandler extends DocumentAdapter implements Disposable {
private void commitToOriginal() {
if (!isValid()) return;
- VirtualFile origVirtualFile = PsiUtilCore.getVirtualFile(ObjectUtils.assertNotNull(myNewFile.getContext()));
+ VirtualFile origVirtualFile = PsiUtilCore.getVirtualFile(myNewFile.getContext());
myCommittingToOriginal = true;
try {
if (origVirtualFile == null || !ReadonlyStatusHandler.getInstance(myProject).ensureFilesWritable(origVirtualFile).hasReadonlyFiles()) {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionManagerImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionManagerImpl.java
index 46842af23c34..ca0a51112f98 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionManagerImpl.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionManagerImpl.java
@@ -20,12 +20,13 @@ import com.intellij.codeInsight.daemon.HighlightDisplayKey;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInsight.intention.IntentionActionBean;
import com.intellij.codeInsight.intention.IntentionManager;
+import com.intellij.codeInspection.GlobalInspectionTool;
+import com.intellij.codeInspection.GlobalSimpleInspectionTool;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
+import com.intellij.codeInspection.actions.CleanupInspectionIntention;
import com.intellij.codeInspection.actions.RunInspectionIntention;
-import com.intellij.codeInspection.ex.DisableInspectionToolAction;
-import com.intellij.codeInspection.ex.EditInspectionToolsSettingsAction;
-import com.intellij.codeInspection.ex.EditInspectionToolsSettingsInSuppressedPlaceIntention;
+import com.intellij.codeInspection.ex.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.ExtensionPoint;
@@ -181,6 +182,32 @@ public class IntentionManagerImpl extends IntentionManager {
return options;
}
+ @Nullable
+ @Override
+ public IntentionAction createFixAllIntention(InspectionToolWrapper toolWrapper, IntentionAction action) {
+ if (toolWrapper instanceof LocalInspectionToolWrapper) {
+ Class aClass = action.getClass();
+ if (action instanceof QuickFixWrapper) {
+ aClass = ((QuickFixWrapper)action).getFix().getClass();
+ }
+ return new CleanupInspectionIntention(toolWrapper, aClass, action.getText());
+ }
+ else if (toolWrapper instanceof GlobalInspectionToolWrapper) {
+ GlobalInspectionTool wrappedTool = ((GlobalInspectionToolWrapper)toolWrapper).getTool();
+ if (wrappedTool instanceof GlobalSimpleInspectionTool && (action instanceof LocalQuickFix || action instanceof QuickFixWrapper)) {
+ Class aClass = action.getClass();
+ if (action instanceof QuickFixWrapper) {
+ aClass = ((QuickFixWrapper)action).getFix().getClass();
+ }
+ return new CleanupInspectionIntention(toolWrapper, aClass, action.getText());
+ }
+ }
+ else {
+ throw new AssertionError("unknown tool: " + toolWrapper);
+ }
+ return null;
+ }
+
@Override
@NotNull
public LocalQuickFix convertToFix(@NotNull final IntentionAction action) {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java
index 9a71909fcca8..869886d26523 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java
@@ -776,15 +776,13 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable,
@Override
public void valueChanged(@NotNull ListSelectionEvent e){
- final LookupElement item = getCurrentItem();
- if (oldItem != item && !myList.isEmpty()) { // do not update on temporary model wipe
- fireCurrentItemChanged(item);
- if (myDisposed) { //a listener may have decided to close us, what can we do?
- return;
- }
+ if (!myUpdating) {
+ final LookupElement item = getCurrentItem();
+ fireCurrentItemChanged(oldItem, item);
oldItem = item;
}
}
+
});
new ClickListener() {
@@ -876,9 +874,9 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable,
}
}
- void fireCurrentItemChanged(LookupElement item){
- if (!myListeners.isEmpty()){
- LookupEvent event = new LookupEvent(this, item, (char)0);
+ private void fireCurrentItemChanged(@Nullable LookupElement oldItem, @Nullable LookupElement currentItem) {
+ if (oldItem != currentItem && !myListeners.isEmpty()) {
+ LookupEvent event = new LookupEvent(this, currentItem, (char)0);
for (LookupListener listener : myListeners) {
listener.currentItemChanged(event);
}
@@ -1088,6 +1086,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable,
public void refreshUi(boolean mayCheckReused, boolean onExplicitAction) {
assert !myUpdating;
+ LookupElement prevItem = getCurrentItem();
myUpdating = true;
try {
final boolean reused = mayCheckReused && checkReused();
@@ -1100,6 +1099,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable,
}
finally {
myUpdating = false;
+ fireCurrentItemChanged(prevItem, getCurrentItem());
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/navigation/CtrlMouseHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/navigation/CtrlMouseHandler.java
index 2f56d3714943..5486a07f6f18 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/navigation/CtrlMouseHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/navigation/CtrlMouseHandler.java
@@ -455,7 +455,7 @@ public class CtrlMouseHandler extends AbstractProjectComponent {
@Override
public void showDocInfo(@NotNull DocumentationManager docManager) {
- docManager.showJavaDocInfo(myTargetElement, myElementAtPointer, true, null);
+ docManager.showJavaDocInfo(myTargetElement, myElementAtPointer, null);
docManager.setAllowContentUpdateFromContext(false);
}
}
@@ -1115,7 +1115,7 @@ public class CtrlMouseHandler extends AbstractProjectComponent {
if (hint != null) {
hint.hide(true);
}
- myDocumentationManager.showJavaDocInfo(targetElement, myContext, true, null);
+ myDocumentationManager.showJavaDocInfo(targetElement, myContext, null);
}
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoTargetHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoTargetHandler.java
index 6ef571f62a03..0d49a89d9c43 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoTargetHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoTargetHandler.java
@@ -42,6 +42,7 @@ import com.intellij.psi.PsiNamedElement;
import com.intellij.ui.CollectionListModel;
import com.intellij.ui.JBListWithHintProvider;
import com.intellij.ui.popup.AbstractPopup;
+import com.intellij.ui.popup.HintUpdateSupply;
import com.intellij.usages.UsageView;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
@@ -179,7 +180,7 @@ public abstract class GotoTargetHandler implements CodeInsightActionHandler {
setCancelCallback(new Computable<Boolean>() {
@Override
public Boolean compute() {
- list.hideHint();
+ HintUpdateSupply.hideHint(list);
return true;
}
}).
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/navigation/ImplementationSearcher.java b/platform/lang-impl/src/com/intellij/codeInsight/navigation/ImplementationSearcher.java
index 504ec1b13c41..a3fbbc62dd85 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/navigation/ImplementationSearcher.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/navigation/ImplementationSearcher.java
@@ -125,13 +125,12 @@ public class ImplementationSearcher {
public static class FirstImplementationsSearcher extends ImplementationSearcher {
@Override
protected PsiElement[] searchDefinitions(final PsiElement element, final Editor editor) {
- final PsiElement[][] result = new PsiElement[1][];
-
if (canShowPopupWithOneItem(element)) {
return new PsiElement[]{element};
}
final PsiElementProcessor.CollectElementsWithLimit<PsiElement> collectProcessor = new PsiElementProcessor.CollectElementsWithLimit<PsiElement>(2, new THashSet<PsiElement>());
+ final PsiElement[][] result = new PsiElement[1][];
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
@Override
public void run() {
@@ -139,8 +138,7 @@ public class ImplementationSearcher {
DefinitionsScopedSearch.search(element, getSearchScope(element, editor)).forEach(new PsiElementProcessorAdapter<PsiElement>(collectProcessor){
@Override
public boolean processInReadAction(PsiElement element) {
- if (!accept(element)) return true;
- return super.processInReadAction(element);
+ return !accept(element) || super.processInReadAction(element);
}
});
result[0] = collectProcessor.toArray();
@@ -165,7 +163,7 @@ public class ImplementationSearcher {
}
}
- public static abstract class BackgroundableImplementationSearcher extends ImplementationSearcher {
+ public abstract static class BackgroundableImplementationSearcher extends ImplementationSearcher {
@Override
protected PsiElement[] searchDefinitions(final PsiElement element, Editor editor) {
final CommonProcessors.CollectProcessor<PsiElement> processor = new CommonProcessors.CollectProcessor<PsiElement>() {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateLookupElementImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateLookupElementImpl.java
index 9ce023727820..2ddf92cfe1ff 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateLookupElementImpl.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateLookupElementImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,7 +24,7 @@ public class LiveTemplateLookupElementImpl extends LiveTemplateLookupElement {
private final TemplateImpl myTemplate;
public LiveTemplateLookupElementImpl(@NotNull TemplateImpl template, boolean sudden) {
- super(template.getKey(), StringUtil.notNullize(template.getDescription()), sudden, false);
+ super(template.getKey(), StringUtil.notNullize(template.getDescription()), sudden, LiveTemplateCompletionContributor.shouldShowAllTemplates());
myTemplate = template;
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateSettingsEditor.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateSettingsEditor.java
index 1988c9d1d8a4..c14eca966e5f 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateSettingsEditor.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateSettingsEditor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,7 +28,6 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.editor.event.DocumentAdapter;
import com.intellij.openapi.editor.event.DocumentEvent;
-import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.ui.popup.JBPopup;
@@ -52,7 +51,6 @@ import com.intellij.util.ui.tree.TreeUtil;
import com.intellij.util.ui.update.Activatable;
import com.intellij.util.ui.update.UiNotifyConnector;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
@@ -182,7 +180,7 @@ public class LiveTemplateSettingsEditor extends JPanel {
myEditVariablesButton.addActionListener(
new ActionListener(){
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
editVariables();
}
}
@@ -201,7 +199,7 @@ public class LiveTemplateSettingsEditor extends JPanel {
myTemplate.parseSegments();
}
- @Nullable
+ @NotNull
private JComponent createNorthPanel() {
JPanel panel = new JPanel(new GridBagLayout());
@@ -240,7 +238,7 @@ public class LiveTemplateSettingsEditor extends JPanel {
myExpandByCombo = new ComboBox(new String[]{myDefaultShortcutItem, SPACE, TAB, ENTER});
myExpandByCombo.addItemListener(new ItemListener() {
@Override
- public void itemStateChanged(ItemEvent e) {
+ public void itemStateChanged(@NotNull ItemEvent e) {
Object selectedItem = myExpandByCombo.getSelectedItem();
if(myDefaultShortcutItem.equals(selectedItem)) {
myTemplate.setShortcutChar(TemplateSettings.DEFAULT_CHAR);
@@ -278,7 +276,7 @@ public class LiveTemplateSettingsEditor extends JPanel {
cb.setSelected(myOptions.get(processor).booleanValue());
cb.addActionListener(new ActionListener() {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
myOptions.put(processor, cb.isSelected());
}
});
@@ -469,14 +467,7 @@ public class LiveTemplateSettingsEditor extends JPanel {
}
private void updateHighlighter() {
- List<TemplateContextType> applicableContexts = getApplicableContexts();
- if (!applicableContexts.isEmpty()) {
- TemplateContext contextByType = new TemplateContext();
- contextByType.setEnabled(applicableContexts.get(0), true);
- TemplateEditorUtil.setHighlighter(myTemplateEditor, contextByType);
- return;
- }
- ((EditorEx) myTemplateEditor).repaint(0, myTemplateEditor.getDocument().getTextLength());
+ TemplateEditorUtil.setHighlighter(myTemplateEditor, ContainerUtil.getFirstItem(getApplicableContexts()));
}
private void validateEditVariablesButton() {
@@ -520,7 +511,7 @@ public class LiveTemplateSettingsEditor extends JPanel {
myCbReformat.setSelected(myTemplate.isToReformat());
myCbReformat.addActionListener(new ActionListener() {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
myTemplate.setToReformat(myCbReformat.isSelected());
}
});
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateEditorUtil.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateEditorUtil.java
index 1570bb18c040..dd30df23a493 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateEditorUtil.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateEditorUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +18,6 @@ package com.intellij.codeInsight.template.impl;
import com.intellij.codeInsight.template.TemplateContextType;
import com.intellij.ide.DataManager;
-import com.intellij.lexer.CompositeLexer;
import com.intellij.lexer.Lexer;
import com.intellij.lexer.MergingLexerAdapter;
import com.intellij.openapi.actionSystem.CommonDataKeys;
@@ -31,7 +30,8 @@ import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.editor.ex.EditorEx;
-import com.intellij.openapi.editor.ex.util.LexerEditorHighlighter;
+import com.intellij.openapi.editor.ex.util.LayerDescriptor;
+import com.intellij.openapi.editor.ex.util.LayeredLexerEditorHighlighter;
import com.intellij.openapi.editor.highlighter.EditorHighlighter;
import com.intellij.openapi.editor.highlighter.EditorHighlighterFactory;
import com.intellij.openapi.fileEditor.FileDocumentManager;
@@ -42,6 +42,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
+import com.intellij.util.ObjectUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -87,54 +88,41 @@ public class TemplateEditorUtil {
if (file != null) {
EditorHighlighter highlighter = EditorHighlighterFactory.getInstance().createEditorHighlighter(file, scheme, project);
((EditorEx) editor).setHighlighter(highlighter);
+
}
return editor;
}
- public static void setHighlighter(Editor editor, TemplateContext templateContext) {
- SyntaxHighlighter baseHighlighter = null;
- for(TemplateContextType type: TemplateManagerImpl.getAllContextTypes()) {
- if (templateContext.isEnabled(type)) {
- baseHighlighter = type.createHighlighter();
- if (baseHighlighter != null) break;
+ public static void setHighlighter(Editor editor, @Nullable TemplateContext templateContext) {
+ SyntaxHighlighter highlighter = null;
+ if (templateContext != null) {
+ for(TemplateContextType type: TemplateManagerImpl.getAllContextTypes()) {
+ if (templateContext.isEnabled(type)) {
+ highlighter = type.createHighlighter();
+ if (highlighter != null) break;
+ }
}
}
- if (baseHighlighter == null) {
- baseHighlighter = new PlainSyntaxHighlighter();
- }
-
- SyntaxHighlighter highlighter = createTemplateTextHighlighter(baseHighlighter);
- ((EditorEx)editor).setHighlighter(new LexerEditorHighlighter(highlighter, EditorColorsManager.getInstance().getGlobalScheme()));
+ setHighlighter((EditorEx)editor, highlighter);
}
- private final static TokenSet TOKENS_TO_MERGE = TokenSet.create(TemplateTokenType.TEXT);
+ public static void setHighlighter(@NotNull Editor editor, @Nullable TemplateContextType templateContextType) {
+ setHighlighter((EditorEx)editor, templateContextType != null ? templateContextType.createHighlighter() : null);
+ }
- private static SyntaxHighlighter createTemplateTextHighlighter(final SyntaxHighlighter original) {
- return new TemplateHighlighter(original);
+ private static void setHighlighter(EditorEx editor, @Nullable SyntaxHighlighter highlighter) {
+ EditorColorsScheme editorColorsScheme = EditorColorsManager.getInstance().getGlobalScheme();
+ LayeredLexerEditorHighlighter layeredHighlighter = new LayeredLexerEditorHighlighter(new TemplateHighlighter(), editorColorsScheme);
+ layeredHighlighter.registerLayer(TemplateTokenType.TEXT, new LayerDescriptor(ObjectUtils.notNull(highlighter, new PlainSyntaxHighlighter()), ""));
+ editor.setHighlighter(layeredHighlighter);
}
private static class TemplateHighlighter extends SyntaxHighlighterBase {
private final Lexer myLexer;
- private final SyntaxHighlighter myOriginalHighlighter;
-
- public TemplateHighlighter(SyntaxHighlighter original) {
- myOriginalHighlighter = original;
- Lexer originalLexer = original.getHighlightingLexer();
- Lexer templateLexer = new TemplateTextLexer();
- templateLexer = new MergingLexerAdapter(templateLexer, TOKENS_TO_MERGE);
-
- myLexer = new CompositeLexer(originalLexer, templateLexer) {
- @Override
- protected IElementType getCompositeTokenType(IElementType type1, IElementType type2) {
- if (type2 == TemplateTokenType.VARIABLE) {
- return type2;
- }
- else {
- return type1;
- }
- }
- };
+
+ public TemplateHighlighter() {
+ myLexer = new MergingLexerAdapter(new TemplateTextLexer(), TokenSet.create(TemplateTokenType.TEXT));
}
@Override
@@ -146,11 +134,7 @@ public class TemplateEditorUtil {
@Override
@NotNull
public TextAttributesKey[] getTokenHighlights(IElementType tokenType) {
- if (tokenType == TemplateTokenType.VARIABLE) {
- return pack(myOriginalHighlighter.getTokenHighlights(tokenType), TemplateColors.TEMPLATE_VARIABLE_ATTRIBUTES);
- }
-
- return myOriginalHighlighter.getTokenHighlights(tokenType);
+ return tokenType == TemplateTokenType.VARIABLE ? pack(TemplateColors.TEMPLATE_VARIABLE_ATTRIBUTES) : EMPTY;
}
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateSettings.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateSettings.java
index e5f2fd4ae23d..abf28256aaef 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateSettings.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateSettings.java
@@ -105,7 +105,7 @@ public class TemplateSettings implements PersistentStateComponent<Element>, Expo
private int myMaxKeyLength = 0;
private char myDefaultShortcutChar = TAB_CHAR;
private final SchemesManager<TemplateGroup, TemplateGroup> mySchemesManager;
- private static final String FILE_SPEC = "$ROOT_CONFIG$/templates";
+ private static final String FILE_SPEC = StoragePathMacros.ROOT_CONFIG + "/templates";
public static class TemplateKey {
private String groupName;
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/settings/PostfixDescriptionPanel.form b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/settings/PostfixDescriptionPanel.form
index cd60a7de70f4..519481484dc7 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/settings/PostfixDescriptionPanel.form
+++ b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/settings/PostfixDescriptionPanel.form
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.codeInsight.template.postfix.settings.PostfixDescriptionPanel">
- <grid id="d0bf1" binding="myPanel" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="d0bf1" binding="myPanel" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="26" y="23" width="498" height="354"/>
@@ -19,7 +19,9 @@
<xy id="a6fdd" binding="myAfterPanel" layout-manager="XYLayout" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
- <grid row="5" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ <grid row="5" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
+ <minimum-size width="-1" height="125"/>
+ </grid>
</constraints>
<properties/>
<border type="none"/>
@@ -28,7 +30,9 @@
<xy id="fa495" binding="myBeforePanel" layout-manager="XYLayout" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
- <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
+ <minimum-size width="-1" height="125"/>
+ </grid>
</constraints>
<properties/>
<border type="none"/>
@@ -77,6 +81,11 @@
</component>
</children>
</grid>
+ <vspacer id="53ca7">
+ <constraints>
+ <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+ </constraints>
+ </vspacer>
</children>
</grid>
</form>
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixLiveTemplate.java b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixLiveTemplate.java
index 5cd822130538..0190fadbcf02 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixLiveTemplate.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixLiveTemplate.java
@@ -22,6 +22,7 @@ import com.intellij.codeInsight.template.impl.CustomLiveTemplateLookupElement;
import com.intellij.codeInsight.template.impl.TemplateSettings;
import com.intellij.codeInsight.template.postfix.completion.PostfixTemplateLookupElement;
import com.intellij.codeInsight.template.postfix.settings.PostfixTemplatesSettings;
+import com.intellij.diagnostic.AttachmentFactory;
import com.intellij.featureStatistics.FeatureUsageTracker;
import com.intellij.lang.Language;
import com.intellij.openapi.application.ApplicationManager;
@@ -137,7 +138,8 @@ public class PostfixLiveTemplate extends CustomLiveTemplateBase {
}
// don't care about errors in multiCaret mode
else if (editor.getCaretModel().getAllCarets().size() == 1) {
- LOG.error("Template not found by key: " + key);
+ LOG.error("Template not found by key: " + key + "; offset = " + callback.getOffset(),
+ AttachmentFactory.createAttachment(callback.getFile().getVirtualFile()));
}
return;
}
@@ -145,7 +147,8 @@ public class PostfixLiveTemplate extends CustomLiveTemplateBase {
// don't care about errors in multiCaret mode
if (editor.getCaretModel().getAllCarets().size() == 1) {
- LOG.error("Template not found by key: " + key);
+ LOG.error("Template not found by key: " + key + "; offset = " + callback.getOffset(),
+ AttachmentFactory.createAttachment(callback.getFile().getVirtualFile()));
}
}
diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/actions/CleanupInspectionIntention.java b/platform/lang-impl/src/com/intellij/codeInspection/actions/CleanupInspectionIntention.java
index d28c9a3874f5..b6a68ef88fb0 100644
--- a/platform/analysis-impl/src/com/intellij/codeInspection/actions/CleanupInspectionIntention.java
+++ b/platform/lang-impl/src/com/intellij/codeInspection/actions/CleanupInspectionIntention.java
@@ -17,6 +17,7 @@
package com.intellij.codeInspection.actions;
import com.intellij.codeInsight.FileModificationService;
+import com.intellij.codeInsight.hint.HintManager;
import com.intellij.codeInsight.intention.EmptyIntentionAction;
import com.intellij.codeInsight.intention.HighPriorityAction;
import com.intellij.codeInsight.intention.IntentionAction;
@@ -46,10 +47,12 @@ import java.util.List;
public class CleanupInspectionIntention implements IntentionAction, HighPriorityAction {
private final InspectionToolWrapper myToolWrapper;
private final Class myQuickfixClass;
+ private final String myText;
- public CleanupInspectionIntention(@NotNull InspectionToolWrapper toolWrapper, @NotNull Class quickFixClass) {
+ public CleanupInspectionIntention(@NotNull InspectionToolWrapper toolWrapper, @NotNull Class quickFixClass, String text) {
myToolWrapper = toolWrapper;
myQuickfixClass = quickFixClass;
+ myText = text;
}
@Override
@@ -84,6 +87,7 @@ public class CleanupInspectionIntention implements IntentionAction, HighPriority
return d2.getTextRange().getStartOffset() - d1.getTextRange().getStartOffset();
}
});
+ boolean applicableFixFound = false;
for (final ProblemDescriptor descriptor : descriptions) {
final QuickFix[] fixes = descriptor.getFixes();
if (fixes != null && fixes.length > 0) {
@@ -91,6 +95,7 @@ public class CleanupInspectionIntention implements IntentionAction, HighPriority
if (fix != null && fix.getClass().isAssignableFrom(myQuickfixClass)) {
final PsiElement element = descriptor.getPsiElement();
if (element != null && element.isValid()) {
+ applicableFixFound = true;
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
@@ -104,6 +109,10 @@ public class CleanupInspectionIntention implements IntentionAction, HighPriority
}
}
}
+
+ if (!applicableFixFound) {
+ HintManager.getInstance().showErrorHint(editor, "Unfortunately '" + myText + "' is currently not available for batch mode");
+ }
}
@Override
diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java
index 090d83389b6c..695c2a72d200 100644
--- a/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java
+++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -58,7 +58,6 @@ import com.intellij.psi.*;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.psi.util.PsiUtilCore;
import com.intellij.ui.content.*;
import com.intellij.util.Processor;
import com.intellij.util.SequentialModalProgressTask;
@@ -81,7 +80,7 @@ import java.util.*;
public class GlobalInspectionContextImpl extends GlobalInspectionContextBase implements GlobalInspectionContext {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ex.GlobalInspectionContextImpl");
- private static final NotificationGroup NOTIFICATION_GROUP = NotificationGroup.toolWindowGroup("Inspection Results", ToolWindowId.INSPECTION, true);
+ private static final NotificationGroup NOTIFICATION_GROUP = NotificationGroup.toolWindowGroup("Inspection Results", ToolWindowId.INSPECTION);
private final NotNullLazyValue<ContentManager> myContentManager;
private InspectionResultsView myView = null;
private Content myContent = null;
@@ -641,6 +640,8 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp
final Project project,
final Runnable postRunnable,
final String commandName) {
+ final int fileCount = scope.getFileCount();
+ final ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator();
final List<LocalInspectionToolWrapper> lTools = new ArrayList<LocalInspectionToolWrapper>();
final LinkedHashMap<PsiFile, List<HighlightInfo>> results = new LinkedHashMap<PsiFile, List<HighlightInfo>>();
@@ -655,8 +656,12 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp
range = null;
}
scope.accept(new PsiElementVisitor() {
+ private int myCount = 0;
@Override
public void visitFile(PsiFile file) {
+ if (progressIndicator != null) {
+ progressIndicator.setFraction(((double)++ myCount)/fileCount);
+ }
if (isBinary(file)) return;
for (final Tools tools : profile.getAllEnabledInspectionTools(project)) {
if (tools.getTool().getTool() instanceof CleanupLocalInspectionTool) {
@@ -704,7 +709,9 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
@Override
public void run() {
- CommandProcessor.getInstance().markCurrentCommandAsGlobal(project);
+ if (commandName != null) {
+ CommandProcessor.getInstance().markCurrentCommandAsGlobal(project);
+ }
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
@@ -718,7 +725,7 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp
}, commandName, null);
}
};
- if (ApplicationManager.getApplication().isUnitTestMode()) {
+ if (ApplicationManager.getApplication().isDispatchThread()) {
runnable.run();
} else {
ApplicationManager.getApplication().invokeLater(runnable);
diff --git a/platform/lang-impl/src/com/intellij/conversion/impl/ui/ConvertProjectDialog.java b/platform/lang-impl/src/com/intellij/conversion/impl/ui/ConvertProjectDialog.java
index e59d2d566698..cf73dba84a3a 100644
--- a/platform/lang-impl/src/com/intellij/conversion/impl/ui/ConvertProjectDialog.java
+++ b/platform/lang-impl/src/com/intellij/conversion/impl/ui/ConvertProjectDialog.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -106,10 +106,8 @@ public class ConvertProjectDialog extends DialogWrapper {
final List<File> nonexistentFiles = myContext.getNonExistingModuleFiles();
if (!nonexistentFiles.isEmpty() && !myNonExistingFilesMessageShown) {
final String filesString = getFilesString(nonexistentFiles);
- final int res = Messages.showYesNoDialog(getContentPane(), IdeBundle.message("message.files.doesn.t.exists.0.so.the.corresponding.modules.won.t.be.converted.do.you.want.to.continue",
- filesString),
- IdeBundle.message("dialog.title.convert.project"),
- Messages.getQuestionIcon());
+ final String message = IdeBundle.message("message.text.files.do.not.exist", filesString);
+ final int res = Messages.showYesNoDialog(getContentPane(), message, IdeBundle.message("dialog.title.convert.project"), Messages.getQuestionIcon());
if (res != Messages.YES) {
super.doOKAction();
return;
diff --git a/platform/lang-impl/src/com/intellij/execution/actions/ChooseRunConfigurationPopup.java b/platform/lang-impl/src/com/intellij/execution/actions/ChooseRunConfigurationPopup.java
index a4764dae0036..0c11e71e5886 100644
--- a/platform/lang-impl/src/com/intellij/execution/actions/ChooseRunConfigurationPopup.java
+++ b/platform/lang-impl/src/com/intellij/execution/actions/ChooseRunConfigurationPopup.java
@@ -30,6 +30,7 @@ import com.intellij.ide.util.PropertiesComponent;
import com.intellij.idea.ActionsBundle;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.ListPopupStep;
@@ -919,35 +920,77 @@ public class ChooseRunConfigurationPopup implements ExecutorProvider {
}
}
- public static ItemWrapper[] createSettingsList(@NotNull final Project project, @NotNull ExecutorProvider executorProvider, boolean createEditAction) {
- final RunManagerEx manager = RunManagerEx.getInstanceEx(project);
+ public static ItemWrapper[] createSettingsList(@NotNull Project project, @NotNull ExecutorProvider executorProvider, boolean createEditAction) {
+ List<ItemWrapper> result = new ArrayList<ItemWrapper>();
- final List<ItemWrapper> result = new ArrayList<ItemWrapper>();
+ if (createEditAction) {
+ ItemWrapper<Void> edit = new ItemWrapper<Void>(null) {
+ @Override
+ public Icon getIcon() {
+ return AllIcons.Actions.EditSource;
+ }
- final RunnerAndConfigurationSettings selectedConfiguration = manager.getSelectedConfiguration();
+ @Override
+ public String getText() {
+ return UIUtil.removeMnemonic(ActionsBundle.message("action.editRunConfigurations.text"));
+ }
+ @Override
+ public void perform(@NotNull final Project project, @NotNull final Executor executor, @NotNull DataContext context) {
+ if (new EditConfigurationsDialog(project) {
+ @Override
+ protected void init() {
+ setOKButtonText(executor.getStartActionText());
+ setOKButtonIcon(executor.getIcon());
+ myExecutor = executor;
+ super.init();
+ }
+ }.showAndGet()) {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ RunnerAndConfigurationSettings configuration = RunManager.getInstance(project).getSelectedConfiguration();
+ if (configuration != null) {
+ ExecutionUtil.runConfiguration(configuration, executor);
+ }
+ }
+ }, project.getDisposed());
+ }
+ }
+
+ @Override
+ public boolean available(Executor executor) {
+ return true;
+ }
+ };
+ edit.setMnemonic(0);
+ result.add(edit);
+ }
+
+ RunManagerEx manager = RunManagerEx.getInstanceEx(project);
+ final RunnerAndConfigurationSettings selectedConfiguration = manager.getSelectedConfiguration();
if (selectedConfiguration != null) {
boolean isFirst = true;
final ExecutionTarget activeTarget = ExecutionTargetManager.getActiveTarget(project);
- for (final ExecutionTarget eachTarget : ExecutionTargetManager.getTargetsToChooseFor(project, selectedConfiguration)) {
+ for (ExecutionTarget eachTarget : ExecutionTargetManager.getTargetsToChooseFor(project, selectedConfiguration)) {
result.add(new ItemWrapper<ExecutionTarget>(eachTarget, isFirst) {
{
- setChecked(eachTarget.equals(activeTarget));
+ setChecked(getValue().equals(activeTarget));
}
@Override
public Icon getIcon() {
- return eachTarget.getIcon();
+ return getValue().getIcon();
}
@Override
public String getText() {
- return eachTarget.getDisplayName();
+ return getValue().getDisplayName();
}
@Override
public void perform(@NotNull final Project project, @NotNull final Executor executor, @NotNull DataContext context) {
- ExecutionTargetManager.setActiveTarget(project, eachTarget);
+ ExecutionTargetManager.setActiveTarget(project, getValue());
ExecutionUtil.runConfiguration(selectedConfiguration, executor);
}
@@ -960,18 +1003,24 @@ public class ChooseRunConfigurationPopup implements ExecutorProvider {
}
}
- final Map<RunnerAndConfigurationSettings, ItemWrapper> wrappedExisting = new LinkedHashMap<RunnerAndConfigurationSettings, ItemWrapper>();
- final ConfigurationType[] types = manager.getConfigurationFactories();
- for (final ConfigurationType type : types) {
+ Map<RunnerAndConfigurationSettings, ItemWrapper> wrappedExisting = new LinkedHashMap<RunnerAndConfigurationSettings, ItemWrapper>();
+ for (ConfigurationType type : manager.getConfigurationFactories()) {
if (!(type instanceof UnknownConfigurationType)) {
Map<String, List<RunnerAndConfigurationSettings>> structure = manager.getStructure(type);
- for (final Map.Entry<String, List<RunnerAndConfigurationSettings>> entry : structure.entrySet()) {
- if (entry.getValue().isEmpty())
+ for (Map.Entry<String, List<RunnerAndConfigurationSettings>> entry : structure.entrySet()) {
+ if (entry.getValue().isEmpty()) {
continue;
+ }
+
final String key = entry.getKey();
- if (key != null){
+ if (key != null) {
boolean isSelected = entry.getValue().contains(selectedConfiguration);
- FolderWrapper folderWrapper = new FolderWrapper(project, executorProvider, key + (isSelected ? " (mnemonic is to \"" + selectedConfiguration.getName()+"\")" : ""), entry.getValue());
+ if (isSelected) {
+ assert selectedConfiguration != null;
+ }
+ FolderWrapper folderWrapper = new FolderWrapper(project, executorProvider,
+ key + (isSelected ? " (mnemonic is to \"" + selectedConfiguration.getName() + "\")" : ""),
+ entry.getValue());
if (isSelected) {
folderWrapper.setMnemonic(1);
}
@@ -992,53 +1041,6 @@ public class ChooseRunConfigurationPopup implements ExecutorProvider {
populateWithDynamicRunners(result, wrappedExisting, project, manager, selectedConfiguration);
result.addAll(wrappedExisting.values());
-
- //noinspection unchecked
- final ItemWrapper edit = new ItemWrapper(null) {
- @Override
- public Icon getIcon() {
- return AllIcons.Actions.EditSource;
- }
-
- @Override
- public String getText() {
- return UIUtil.removeMnemonic(ActionsBundle.message("action.editRunConfigurations.text"));
- }
-
- @Override
- public void perform(@NotNull final Project project, @NotNull final Executor executor, @NotNull DataContext context) {
- final EditConfigurationsDialog dialog = new EditConfigurationsDialog(project) {
- @Override
- protected void init() {
- setOKButtonText(executor.getStartActionText());
- setOKButtonIcon(executor.getIcon());
- myExecutor = executor;
- super.init();
- }
- };
-
- dialog.show();
- if (dialog.isOK()) {
- SwingUtilities.invokeLater(new Runnable() {
- @Override
- public void run() {
- ExecutionUtil.runConfiguration(RunManager.getInstance(project).getSelectedConfiguration(), executor);
- }
- });
- }
- }
-
- @Override
- public boolean available(Executor executor) {
- return true;
- }
- };
-
- edit.setMnemonic(0);
- if (createEditAction) {
- result.add(0, edit);
- }
-
return result.toArray(new ItemWrapper[result.size()]);
}
diff --git a/platform/lang-api/src/com/intellij/execution/configuration/EnvironmentVariablesComponent.java b/platform/lang-impl/src/com/intellij/execution/configuration/EnvironmentVariablesComponent.java
index 21c7deabff9f..4375e164fed4 100644
--- a/platform/lang-api/src/com/intellij/execution/configuration/EnvironmentVariablesComponent.java
+++ b/platform/lang-impl/src/com/intellij/execution/configuration/EnvironmentVariablesComponent.java
@@ -26,13 +26,13 @@ import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.util.Comparing;
import com.intellij.ui.UserActivityProviderComponent;
import com.intellij.util.ArrayUtil;
+import com.intellij.util.EnvironmentUtil;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import javax.swing.event.ChangeListener;
import java.io.File;
-import java.util.HashMap;
import java.util.Map;
public class EnvironmentVariablesComponent extends LabeledComponent<TextFieldWithBrowseButton> implements UserActivityProviderComponent {
@@ -113,19 +113,19 @@ public class EnvironmentVariablesComponent extends LabeledComponent<TextFieldWit
element.addContent(envsElement);
}
+ /**
+ * To be removed in IDEA 15
+ * @deprecated use {@link com.intellij.util.EnvironmentUtil#inlineParentOccurrences(java.util.Map)} instead
+ */
+ @Deprecated
public static void inlineParentOccurrences(final Map<String, String> envs) {
- final Map<String, String> parentParams = new HashMap<String, String>(System.getenv());
- for (String envKey : envs.keySet()) {
- final String val = envs.get(envKey);
- if (val != null) {
- final String parentVal = parentParams.get(envKey);
- if (parentVal != null && containsEnvKeySubstitution(envKey, val)) {
- envs.put(envKey, val.replace("$" + envKey + "$", parentVal));
- }
- }
- }
+ EnvironmentUtil.inlineParentOccurrences(envs);
}
+ /**
+ * To be removed in IDEA 15
+ */
+ @Deprecated
public static boolean containsEnvKeySubstitution(final String envKey, final String val) {
return ArrayUtil.find(val.split(File.pathSeparator), "$" + envKey + "$") != -1;
}
diff --git a/platform/lang-api/src/com/intellij/execution/configuration/EnvironmentVariablesTextFieldWithBrowseButton.java b/platform/lang-impl/src/com/intellij/execution/configuration/EnvironmentVariablesTextFieldWithBrowseButton.java
index 0fe445371186..5f3785f1de66 100644
--- a/platform/lang-api/src/com/intellij/execution/configuration/EnvironmentVariablesTextFieldWithBrowseButton.java
+++ b/platform/lang-impl/src/com/intellij/execution/configuration/EnvironmentVariablesTextFieldWithBrowseButton.java
@@ -15,13 +15,15 @@
*/
package com.intellij.execution.configuration;
+import com.google.common.collect.ImmutableMap;
import com.intellij.execution.ExecutionBundle;
import com.intellij.execution.util.EnvVariablesTable;
import com.intellij.execution.util.EnvironmentVariable;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
+import com.intellij.ui.UserActivityProviderComponent;
+import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
-import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -31,12 +33,14 @@ import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-import java.util.*;
+import java.util.Collections;
+import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
-public class EnvironmentVariablesTextFieldWithBrowseButton extends TextFieldWithBrowseButton {
+public class EnvironmentVariablesTextFieldWithBrowseButton extends TextFieldWithBrowseButton implements UserActivityProviderComponent {
- private final Map<String, String> myEnvs = new THashMap<String, String>();
+ private Map<String, String> myEnvs = Collections.emptyMap();
private boolean myPassParentEnvs;
private final List<ChangeListener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
@@ -51,14 +55,20 @@ public class EnvironmentVariablesTextFieldWithBrowseButton extends TextFieldWith
});
}
+ /**
+ * @return unmodifiable Map instance, use {@link #setEnvs(java.util.Map)} to update env vars
+ */
@NotNull
public Map<String, String> getEnvs() {
return myEnvs;
}
+ /**
+ * @param envs Map instance with reliable user-specified iteration order,
+ * like {@link java.util.LinkedHashMap} or {@link com.google.common.collect.ImmutableMap}
+ */
public void setEnvs(@NotNull Map<String, String> envs) {
- myEnvs.clear();
- myEnvs.putAll(envs);
+ myEnvs = ImmutableMap.copyOf(envs);
String envsStr = stringifyEnvs(myEnvs);
setText(envsStr);
}
@@ -89,10 +99,12 @@ public class EnvironmentVariablesTextFieldWithBrowseButton extends TextFieldWith
}
}
+ @Override
public void addChangeListener(ChangeListener changeListener) {
myListeners.add(changeListener);
}
+ @Override
public void removeChangeListener(ChangeListener changeListener) {
myListeners.remove(changeListener);
}
@@ -111,10 +123,12 @@ public class EnvironmentVariablesTextFieldWithBrowseButton extends TextFieldWith
protected MyEnvironmentVariablesDialog() {
super(EnvironmentVariablesTextFieldWithBrowseButton.this, true);
myEnvVariablesTable = new EnvVariablesTable();
- List<EnvironmentVariable> envVariables = ContainerUtil.newArrayList();
- for (Map.Entry<String, String> entry : myEnvs.entrySet()) {
- envVariables.add(new EnvironmentVariable(entry.getKey(), entry.getValue(), false));
- }
+ List<EnvironmentVariable> envVariables = ContainerUtil.map(myEnvs.entrySet(), new Function<Map.Entry<String, String>, EnvironmentVariable>() {
+ @Override
+ public EnvironmentVariable fun(Map.Entry<String, String> entry) {
+ return new EnvironmentVariable(entry.getKey(), entry.getValue(), false);
+ }
+ });
myEnvVariablesTable.setValues(envVariables);
myUseDefaultCb.setSelected(isPassParentEnvs());
myWholePanel.add(myEnvVariablesTable.getComponent(), BorderLayout.CENTER);
diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java
index 605d073945b5..3fce510e725e 100644
--- a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java
+++ b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java
@@ -674,7 +674,7 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
final Document document = myEditor.getDocument();
final RangeMarker lastProcessedOutput = document.createRangeMarker(document.getTextLength(), document.getTextLength());
final int caretOffset = myEditor.getCaretModel().getOffset();
- final boolean isAtLastLine = document.getLineNumber(caretOffset) >= document.getLineCount() - 1;
+ final boolean isAtLastLine = isCaretAtLastLine();
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
@Override
@@ -1078,6 +1078,9 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
};
if (immediately) {
model.runBatchFoldingOperation(operation);
+ if (isCaretAtLastLine()) {
+ EditorUtil.scrollToTheEnd(myEditor);
+ }
}
else {
model.runBatchFoldingOperationDoNotCollapseCaret(operation);
@@ -1092,6 +1095,12 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
}
}
+ private boolean isCaretAtLastLine() {
+ final Document document = myEditor.getDocument();
+ final int caretOffset = myEditor.getCaretModel().getOffset();
+ return document.getLineNumber(caretOffset) >= document.getLineCount() - 1;
+ }
+
private void addFolding(Document document, CharSequence chars, int line, List<FoldRegion> toAdd) {
String commandLinePlaceholder = myCommandLineFolding.getPlaceholder(line);
if (commandLinePlaceholder != null) {
diff --git a/platform/lang-impl/src/com/intellij/execution/impl/EditConfigurationsDialog.java b/platform/lang-impl/src/com/intellij/execution/impl/EditConfigurationsDialog.java
index d206283375e2..265d9c3f7410 100644
--- a/platform/lang-impl/src/com/intellij/execution/impl/EditConfigurationsDialog.java
+++ b/platform/lang-impl/src/com/intellij/execution/impl/EditConfigurationsDialog.java
@@ -26,7 +26,7 @@ public class EditConfigurationsDialog extends SingleConfigurableEditor implement
protected Executor myExecutor;
public EditConfigurationsDialog(final Project project) {
- super(project, new RunConfigurable(project), IdeModalityType.PROJECT);
+ super(project, new RunConfigurable(project), "#com.intellij.execution.impl.EditConfigurationsDialog", IdeModalityType.PROJECT);
((RunConfigurable)getConfigurable()).setRunDialog(this);
setTitle(ExecutionBundle.message("run.debug.dialog.title"));
setHorizontalStretch(1.3F);
@@ -42,11 +42,6 @@ public class EditConfigurationsDialog extends SingleConfigurableEditor implement
}
}
- @Override
- protected String getDimensionServiceKey() {
- return "#com.intellij.execution.impl.EditConfigurationsDialog";
- }
-
@Nullable
@Override
public Executor getExecutor() {
diff --git a/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java b/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java
index 3645439db470..95d4db09c297 100644
--- a/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java
+++ b/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java
@@ -589,8 +589,14 @@ class RunConfigurable extends BaseConfigurable {
@Override
public JComponent createComponent() {
for (RunConfigurationsSettings each : Extensions.getExtensions(RunConfigurationsSettings.EXTENSION_POINT)) {
- UnnamedConfigurable configurable = each.createConfigurable();
- myAdditionalSettings.add(Pair.create(configurable, configurable.createComponent()));
+ try {
+ UnnamedConfigurable configurable = each.createConfigurable(myProject);
+ myAdditionalSettings.add(Pair.create(configurable, configurable.createComponent()));
+ }
+ catch (NoSuchMethodError e) {
+ // in case someone has already implemented old RunConfigurationsSettings.createConfigurable()
+ LOG.error(e);
+ }
}
myWholePanel = new JPanel(new BorderLayout());
diff --git a/platform/lang-impl/src/com/intellij/execution/runners/AbstractConsoleRunnerWithHistory.java b/platform/lang-impl/src/com/intellij/execution/runners/AbstractConsoleRunnerWithHistory.java
index 7bcabebf256a..d1c3c4877493 100644
--- a/platform/lang-impl/src/com/intellij/execution/runners/AbstractConsoleRunnerWithHistory.java
+++ b/platform/lang-impl/src/com/intellij/execution/runners/AbstractConsoleRunnerWithHistory.java
@@ -104,6 +104,13 @@ public abstract class AbstractConsoleRunnerWithHistory<T extends LanguageConsole
myConsoleView.attachToProcess(myProcessHandler);
// Runner creating
+ createContentDescriptorAndActions();
+
+ // Run
+ myProcessHandler.startNotify();
+ }
+
+ protected void createContentDescriptorAndActions() {
final Executor defaultExecutor = DefaultRunExecutor.getRunExecutorInstance();
final DefaultActionGroup toolbarActions = new DefaultActionGroup();
final ActionToolbar actionToolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, toolbarActions, false);
@@ -134,9 +141,6 @@ public abstract class AbstractConsoleRunnerWithHistory<T extends LanguageConsole
panel.updateUI();
showConsole(defaultExecutor, contentDescriptor);
-
- // Run
- myProcessHandler.startNotify();
}
protected String constructConsoleTitle(final @NotNull String consoleTitle) {
diff --git a/platform/lang-impl/src/com/intellij/execution/runners/DefaultProgramRunner.java b/platform/lang-impl/src/com/intellij/execution/runners/DefaultProgramRunner.java
index 5f7321aa8068..f4cae36d1ffe 100644
--- a/platform/lang-impl/src/com/intellij/execution/runners/DefaultProgramRunner.java
+++ b/platform/lang-impl/src/com/intellij/execution/runners/DefaultProgramRunner.java
@@ -21,25 +21,19 @@ import com.intellij.execution.ExecutionResult;
import com.intellij.execution.configurations.RunProfileState;
import com.intellij.execution.ui.RunContentDescriptor;
import com.intellij.openapi.fileEditor.FileDocumentManager;
-import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
/**
* @author spleaner
*/
public abstract class DefaultProgramRunner extends GenericProgramRunner {
-
@Override
- protected RunContentDescriptor doExecute(@NotNull final Project project,
- @NotNull final RunProfileState state,
- final RunContentDescriptor contentToReuse,
- @NotNull final ExecutionEnvironment env) throws ExecutionException {
+ protected RunContentDescriptor doExecute(@NotNull RunProfileState state, @NotNull ExecutionEnvironment env) throws ExecutionException {
FileDocumentManager.getInstance().saveAllDocuments();
ExecutionResult executionResult = state.execute(env.getExecutor(), this);
if (executionResult == null) {
return null;
}
- return new RunContentBuilder(executionResult, env).showRunContent(contentToReuse);
+ return new RunContentBuilder(executionResult, env).showRunContent(env.getContentToReuse());
}
-
}
diff --git a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java
index b8225b0c238b..5384ea06de23 100644
--- a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java
+++ b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java
@@ -290,7 +290,8 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
final ContentManager manager = ContentFactory.SERVICE.getInstance().createContentManager(this, false, myProject);
Disposer.register((Disposable)myRunnerUi, manager);
manager.getComponent();
- } else {
+ }
+ else {
final DockManager dockManager = DockManager.getInstance(myProject);
if (dockManager != null) { //default project
dockManager.register(this);
@@ -518,13 +519,15 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
@Override
public void closeAll() {
final Content[] contents = myManager.getContents();
- for (Content content : contents) {
- getStateFor(content).setWindow(0);
- }
if (myOriginal != null) {
for (Content content : contents) {
+ getStateFor(content).setWindow(0);
myOriginal.myManager.addContent(content);
- myOriginal.findCellFor(content).minimize(content);
+ GridCell cell = myOriginal.findCellFor(content);
+ if (cell != null) {
+ myOriginal.restoreContent(content.getUserData(ViewImpl.ID));
+ cell.minimize(content);
+ }
}
}
myManager.removeAllContents(false);
@@ -1373,7 +1376,6 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
}
private class MyComponent extends Wrapper.FocusHolder implements DataProvider, QuickActionProvider {
-
private boolean myWasEverAdded;
public MyComponent() {
@@ -1388,9 +1390,13 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
if (KEY.is(dataId)) {
return RunnerContentUi.this;
}
- else {
- return null;
+
+ ContentManager originalContentManager = myOriginal == null ? null : myOriginal.getContentManager();
+ JComponent originalContentComponent = originalContentManager == null ? null : originalContentManager.getComponent();
+ if (originalContentComponent instanceof DataProvider) {
+ return ((DataProvider)originalContentComponent).getData(dataId);
}
+ return null;
}
@SuppressWarnings("NullableProblems")
@@ -1839,9 +1845,6 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
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;
}
diff --git a/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java b/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java
index 84776f4bf7ff..98975c8529dc 100644
--- a/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java
+++ b/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java
@@ -45,6 +45,7 @@ import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.pom.Navigatable;
@@ -859,7 +860,7 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
}
data.addAll(visibleNodes);
if (data.isEmpty()) {
- String progressText = UsageViewManagerImpl.getProgressTitle(presentation);
+ String progressText = StringUtil.escapeXml(UsageViewManagerImpl.getProgressTitle(presentation));
data.add(createStringNode(progressText));
}
Collections.sort(data, USAGE_NODE_COMPARATOR);
diff --git a/platform/lang-impl/src/com/intellij/find/findInProject/FindInProjectManager.java b/platform/lang-impl/src/com/intellij/find/findInProject/FindInProjectManager.java
index b78ce2c7ead7..87d0b78acf39 100644
--- a/platform/lang-impl/src/com/intellij/find/findInProject/FindInProjectManager.java
+++ b/platform/lang-impl/src/com/intellij/find/findInProject/FindInProjectManager.java
@@ -52,14 +52,14 @@ public class FindInProjectManager {
public void findInProject(@NotNull DataContext dataContext) {
final boolean isOpenInNewTabEnabled;
- final boolean[] toOpenInNewTab = new boolean[1];
+ final boolean toOpenInNewTab;
Content selectedContent = UsageViewManager.getInstance(myProject).getSelectedContent(true);
if (selectedContent != null && selectedContent.isPinned()) {
- toOpenInNewTab[0] = true;
+ toOpenInNewTab = true;
isOpenInNewTabEnabled = false;
}
else {
- toOpenInNewTab[0] = FindSettings.getInstance().isShowResultsInSeparateView();
+ toOpenInNewTab = FindSettings.getInstance().isShowResultsInSeparateView();
isOpenInNewTabEnabled = UsageViewManager.getInstance(myProject).getReusableContentsCount() > 0;
}
@@ -68,7 +68,7 @@ public class FindInProjectManager {
findModel.setReplaceState(false);
findModel.setOpenInNewTabVisible(true);
findModel.setOpenInNewTabEnabled(isOpenInNewTabEnabled);
- findModel.setOpenInNewTab(toOpenInNewTab[0]);
+ findModel.setOpenInNewTab(toOpenInNewTab);
FindInProjectUtil.setDirectoryName(findModel, dataContext);
String text = PlatformDataKeys.PREDEFINED_TEXT.getData(dataContext);
@@ -85,7 +85,7 @@ public class FindInProjectManager {
public void run() {
findModel.setOpenInNewTabVisible(false);
if (isOpenInNewTabEnabled) {
- FindSettings.getInstance().setShowResultsInSeparateView(toOpenInNewTab[0] = findModel.isOpenInNewTab());
+ FindSettings.getInstance().setShowResultsInSeparateView(findModel.isOpenInNewTab());
}
startFindInProject(findModel);
diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindInProjectTask.java b/platform/lang-impl/src/com/intellij/find/impl/FindInProjectTask.java
index 7e9e71d7a94d..7dfdbbce16d7 100644
--- a/platform/lang-impl/src/com/intellij/find/impl/FindInProjectTask.java
+++ b/platform/lang-impl/src/com/intellij/find/impl/FindInProjectTask.java
@@ -421,7 +421,7 @@ class FindInProjectTask {
SearchScope customScope = myFindModel.getCustomScope();
GlobalSearchScope scope = myPsiDirectory != null
- ? GlobalSearchScopesCore.directoryScope(myPsiDirectory, true)
+ ? GlobalSearchScopesCore.directoryScope(myPsiDirectory, myFindModel.isWithSubdirectories())
: myModule != null
? myModule.getModuleContentScope()
: customScope instanceof GlobalSearchScope
diff --git a/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreview.java b/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreview.java
index 4ba97e0151e5..995a67ecafa1 100644
--- a/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreview.java
+++ b/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreview.java
@@ -21,7 +21,10 @@ import com.intellij.find.FindModel;
import com.intellij.find.FindResult;
import com.intellij.ide.IdeTooltipManager;
import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.editor.*;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.SelectionModel;
+import com.intellij.openapi.editor.colors.CodeInsightColors;
import com.intellij.openapi.editor.colors.EditorColors;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.event.*;
@@ -46,7 +49,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
-import java.io.*;
+import java.io.PrintStream;
import java.util.*;
import java.util.List;
@@ -95,11 +98,8 @@ public class LivePreview extends DocumentAdapter implements SearchResults.Search
private RangeHighlighter myCursorHighlighter;
private final List<VisibleAreaListener> myVisibleAreaListenersToRemove = new ArrayList<VisibleAreaListener>();
- private static TextAttributes strikout(TextAttributes attributes) {
- TextAttributes textAttributes = attributes.clone();
- textAttributes.setEffectColor(Color.BLACK);
- textAttributes.setEffectType(EffectType.STRIKEOUT);
- return textAttributes;
+ private static TextAttributes strikout() {
+ return EditorColorsManager.getInstance().getGlobalScheme().getAttributes(CodeInsightColors.DEPRECATED_ATTRIBUTES).clone();
}
private Delegate myDelegate;
@@ -161,7 +161,7 @@ public class LivePreview extends DocumentAdapter implements SearchResults.Search
ranges.add(new Pair<Integer, Character>(editor.getDocument().getTextLength()+1, '\n'));
ContainerUtil.sort(ranges, new Comparator<Pair<Integer, Character>>() {
@Override
- public int compare(Pair<Integer, Character> pair, Pair<Integer, Character> pair2) {
+ public int compare(@NotNull Pair<Integer, Character> pair, @NotNull Pair<Integer, Character> pair2) {
int res = pair.first - pair2.first;
if (res == 0) {
@@ -210,7 +210,7 @@ public class LivePreview extends DocumentAdapter implements SearchResults.Search
}
myHighlighters.removeAll(unused);
Project project = mySearchResults.getProject();
- if (!project.isDisposed()) {
+ if (project != null && !project.isDisposed()) {
for (RangeHighlighter highlighter : unused) {
HighlightManager.getInstance(project).removeSegmentHighlighter(mySearchResults.getEditor(), highlighter);
}
@@ -240,7 +240,8 @@ public class LivePreview extends DocumentAdapter implements SearchResults.Search
Editor editor = mySearchResults.getEditor();
if (cursor != null) {
Set<RangeHighlighter> dummy = new HashSet<RangeHighlighter>();
- highlightRange(cursor, new TextAttributes(null, null, Color.BLACK, EffectType.ROUNDED_BOX, 0), dummy);
+ Color color = editor.getColorsScheme().getColor(EditorColors.CARET_COLOR);
+ highlightRange(cursor, new TextAttributes(null, null, color, EffectType.ROUNDED_BOX, 0), dummy);
if (!dummy.isEmpty()) {
myCursorHighlighter = dummy.iterator().next();
}
@@ -322,7 +323,7 @@ public class LivePreview extends DocumentAdapter implements SearchResults.Search
attributes.setEffectColor(attributes.getBackgroundColor());
}
if (mySearchResults.isExcluded(range)) {
- highlightRange(range, strikout(attributes), myHighlighters);
+ highlightRange(range, strikout(), myHighlighters);
} else {
highlightRange(range, attributes, myHighlighters);
}
@@ -389,18 +390,18 @@ public class LivePreview extends DocumentAdapter implements SearchResults.Search
final FindModel findModel = mySearchResults.getFindModel();
if (findModel.isRegularExpressions() && findModel.isReplaceState()) {
- showBalloon(cursor, editor, replacementPreviewText);
+ showBalloon(editor, replacementPreviewText);
}
}
}
- private void showBalloon(FindResult cursor, Editor editor, String replacementPreviewText) {
+ private void showBalloon(Editor editor, String replacementPreviewText) {
if (ApplicationManager.getApplication().isUnitTestMode()) {
myReplacementPreviewText = replacementPreviewText;
return;
}
- ReplacementView replacementView = new ReplacementView(replacementPreviewText, cursor);
+ ReplacementView replacementView = new ReplacementView(replacementPreviewText);
BalloonBuilder balloonBuilder = JBPopupFactory.getInstance().createBalloonBuilder(replacementView);
balloonBuilder.setFadeoutTime(0);
@@ -546,7 +547,7 @@ public class LivePreview extends DocumentAdapter implements SearchResults.Search
}
}
- private void requestBalloonHiding(final Balloon object) {
+ private static void requestBalloonHiding(final Balloon object) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
diff --git a/platform/lang-impl/src/com/intellij/find/impl/livePreview/ReplacementView.java b/platform/lang-impl/src/com/intellij/find/impl/livePreview/ReplacementView.java
index 4f87efd8c970..b9b01667a656 100644
--- a/platform/lang-impl/src/com/intellij/find/impl/livePreview/ReplacementView.java
+++ b/platform/lang-impl/src/com/intellij/find/impl/livePreview/ReplacementView.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,30 +15,28 @@
*/
package com.intellij.find.impl.livePreview;
-import com.intellij.find.FindResult;
+import com.intellij.ui.Gray;
import com.intellij.ui.JBColor;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
public class ReplacementView extends JPanel {
-
private static final String MALFORMED_REPLACEMENT_STRING = "Malformed replacement string";
- private final String myReplacement;
@Override
- protected void paintComponent(Graphics graphics) {
-
+ protected void paintComponent(@NotNull Graphics graphics) {
}
- public ReplacementView(final String replacement, final FindResult occurrence) {
- myReplacement = replacement;
- String textToShow = myReplacement;
- if (myReplacement == null) {
+ public ReplacementView(@Nullable String replacement) {
+ String textToShow = replacement;
+ if (replacement == null) {
textToShow = MALFORMED_REPLACEMENT_STRING;
}
JLabel jLabel = new JLabel(textToShow);
- jLabel.setForeground(myReplacement != null ? Color.WHITE : JBColor.RED);
+ jLabel.setForeground(replacement != null ? new JBColor(Gray._240, Gray._200) : JBColor.RED);
add(jLabel);
}
}
diff --git a/platform/lang-impl/src/com/intellij/find/replaceInProject/ReplaceInProjectManager.java b/platform/lang-impl/src/com/intellij/find/replaceInProject/ReplaceInProjectManager.java
index 7e220c149369..0c6a3766342d 100644
--- a/platform/lang-impl/src/com/intellij/find/replaceInProject/ReplaceInProjectManager.java
+++ b/platform/lang-impl/src/com/intellij/find/replaceInProject/ReplaceInProjectManager.java
@@ -20,6 +20,7 @@ import com.intellij.find.*;
import com.intellij.find.actions.FindInPathAction;
import com.intellij.find.findInProject.FindInProjectManager;
import com.intellij.find.impl.FindInProjectUtil;
+import com.intellij.find.impl.FindManagerImpl;
import com.intellij.ide.DataManager;
import com.intellij.notification.NotificationGroup;
import com.intellij.openapi.actionSystem.ActionManager;
@@ -38,6 +39,7 @@ import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Factory;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.Segment;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.ReadonlyStatusHandler;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
@@ -48,9 +50,8 @@ import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.ui.content.Content;
-import com.intellij.usageView.*;
+import com.intellij.usageView.UsageInfo;
import com.intellij.usages.*;
-import com.intellij.usages.UsageViewManager;
import com.intellij.usages.impl.UsageViewImpl;
import com.intellij.usages.rules.UsageInFile;
import com.intellij.util.AdapterProcessor;
@@ -115,9 +116,23 @@ public class ReplaceInProjectManager {
}
public void replaceInProject(@NotNull DataContext dataContext) {
+ final boolean isOpenInNewTabEnabled;
+ final boolean toOpenInNewTab;
+ final Content selectedContent = com.intellij.usageView.UsageViewManager.getInstance(myProject).getSelectedContent(true);
+ if (selectedContent != null && selectedContent.isPinned()) {
+ toOpenInNewTab = true;
+ isOpenInNewTabEnabled = false;
+ }
+ else {
+ toOpenInNewTab = FindSettings.getInstance().isShowResultsInSeparateView();
+ isOpenInNewTabEnabled = com.intellij.usageView.UsageViewManager.getInstance(myProject).getReusableContentsCount() > 0;
+ }
final FindManager findManager = FindManager.getInstance(myProject);
- final FindModel findModel = (FindModel)findManager.getFindInProjectModel().clone();
+ final FindModel findModel = findManager.getFindInProjectModel().clone();
findModel.setReplaceState(true);
+ findModel.setOpenInNewTabVisible(true);
+ findModel.setOpenInNewTabEnabled(isOpenInNewTabEnabled);
+ findModel.setOpenInNewTab(toOpenInNewTab);
FindInProjectUtil.setDirectoryName(findModel, dataContext);
Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
@@ -138,9 +153,9 @@ public class ReplaceInProjectManager {
if (manager == null) return;
findManager.getFindInProjectModel().copyFrom(findModel);
- final FindModel findModelCopy = (FindModel)findModel.clone();
+ final FindModel findModelCopy = findModel.clone();
- final UsageViewPresentation presentation = FindInProjectUtil.setupViewPresentation(true, findModelCopy);
+ final UsageViewPresentation presentation = FindInProjectUtil.setupViewPresentation(findModel.isOpenInNewTab(), findModelCopy);
final FindUsagesProcessPresentation processPresentation = FindInProjectUtil.setupProcessPresentation(myProject, true, presentation);
UsageSearcherFactory factory = new UsageSearcherFactory(findModelCopy, psiDirectory, processPresentation);
@@ -168,7 +183,7 @@ public class ReplaceInProjectManager {
@Override
public String getLongDescriptiveName() {
UsageViewPresentation presentation = FindInProjectUtil.setupViewPresentation(false, myFindModel);
- return "Replace "+presentation.getToolwindowTitle()+" with '"+ myFindModel.getStringToReplace()+"'";
+ return "Replace "+ StringUtil.decapitalize(presentation.getToolwindowTitle())+" with '"+ myFindModel.getStringToReplace()+"'";
}
@Override
@@ -193,7 +208,9 @@ public class ReplaceInProjectManager {
final FindManager findManager) {
presentation.setMergeDupLinesAvailable(false);
final ReplaceContext[] context = new ReplaceContext[1];
- manager.searchAndShowUsages(new UsageTarget[]{new ReplaceInProjectTarget(myProject, findModelCopy)},
+ final ReplaceInProjectTarget target = new ReplaceInProjectTarget(myProject, findModelCopy);
+ ((FindManagerImpl)FindManager.getInstance(myProject)).getFindUsagesManager().addToHistory(target);
+ manager.searchAndShowUsages(new UsageTarget[]{target},
usageSearcherFactory, processPresentation, presentation, new UsageViewManager.UsageViewStateListener() {
@Override
public void usageViewCreated(@NotNull UsageView usageView) {
diff --git a/platform/lang-impl/src/com/intellij/formatting/alignment/AlignmentStrategy.java b/platform/lang-impl/src/com/intellij/formatting/alignment/AlignmentStrategy.java
index 1844a0a217d2..0be9a469a03e 100644
--- a/platform/lang-impl/src/com/intellij/formatting/alignment/AlignmentStrategy.java
+++ b/platform/lang-impl/src/com/intellij/formatting/alignment/AlignmentStrategy.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -69,8 +69,7 @@ public abstract class AlignmentStrategy {
* @return alignment strategy for the given arguments
*/
public static AlignmentPerTypeStrategy createAlignmentPerTypeStrategy(@NotNull Collection<IElementType> targetTypes,
- boolean allowBackwardShift)
- {
+ boolean allowBackwardShift) {
return new AlignmentPerTypeStrategy(targetTypes, null, allowBackwardShift, Alignment.Anchor.LEFT);
}
@@ -85,8 +84,7 @@ public abstract class AlignmentStrategy {
* @return alignment retrieval strategy that follows the rules described above
*/
public static AlignmentPerTypeStrategy createAlignmentPerTypeStrategy(
- @NotNull Collection<IElementType> targetTypes, @Nullable IElementType parentType, boolean allowBackwardShift)
- {
+ @NotNull Collection<IElementType> targetTypes, @Nullable IElementType parentType, boolean allowBackwardShift) {
return createAlignmentPerTypeStrategy(targetTypes, parentType, allowBackwardShift, Alignment.Anchor.LEFT);
}
@@ -115,8 +113,7 @@ public abstract class AlignmentStrategy {
*/
public static AlignmentPerTypeStrategy createAlignmentPerTypeStrategy(
@NotNull Collection<IElementType> targetTypes, @Nullable IElementType parentType, boolean allowBackwardShift,
- @NotNull Alignment.Anchor anchor)
- {
+ @NotNull Alignment.Anchor anchor) {
return new AlignmentPerTypeStrategy(targetTypes, parentType, allowBackwardShift, anchor);
}
@@ -162,7 +159,7 @@ public abstract class AlignmentStrategy {
@Override
@Nullable
public Alignment getAlignment(@Nullable IElementType parentType, @Nullable IElementType childType) {
- return (myFilterElementTypes.contains(childType) ^ myIgnoreFilterTypes) ? myAlignment : null;
+ return myFilterElementTypes.contains(childType) ^ myIgnoreFilterTypes ? myAlignment : null;
}
}
@@ -171,7 +168,6 @@ public abstract class AlignmentStrategy {
* same types.
*/
public static class AlignmentPerTypeStrategy extends AlignmentStrategy {
-
private final Map<IElementType, Alignment> myAlignments = new HashMap<IElementType, Alignment>();
private final IElementType myParentType;
@@ -180,8 +176,7 @@ public abstract class AlignmentStrategy {
AlignmentPerTypeStrategy(Collection<IElementType> targetElementTypes,
IElementType parentType,
boolean allowBackwardShift,
- Alignment.Anchor anchor)
- {
+ Alignment.Anchor anchor) {
myParentType = parentType;
myAllowBackwardShift = allowBackwardShift;
for (IElementType elementType : targetElementTypes) {
diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/ExportableFileTemplateSettings.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/ExportableFileTemplateSettings.java
index b601f0542dab..29cf1b18644a 100644
--- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/ExportableFileTemplateSettings.java
+++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/ExportableFileTemplateSettings.java
@@ -40,7 +40,6 @@ import java.util.Locale;
)}
)
public class ExportableFileTemplateSettings extends FileTemplatesLoader implements PersistentStateComponent<Element>, ExportableComponent {
-
public final static String EXPORTABLE_SETTINGS_FILE = "file.template.settings.xml";
static final String ELEMENT_TEMPLATE = "template";
@@ -58,7 +57,6 @@ public class ExportableFileTemplateSettings extends FileTemplatesLoader implemen
return ServiceManager.getService(ExportableFileTemplateSettings.class);
}
-
@NotNull
@Override
public File[] getExportFiles() {
@@ -76,10 +74,9 @@ public class ExportableFileTemplateSettings extends FileTemplatesLoader implemen
@Nullable
@Override
public Element getState() {
- Element element = new Element("fileTemplateSettings");
+ Element element = null;
for (FTManager manager : getAllManagers()) {
- final Element templatesGroup = new Element(getXmlElementGroupName(manager));
- element.addContent(templatesGroup);
+ Element templatesGroup = null;
for (FileTemplateBase template : manager.getAllTemplates(true)) {
// save only those settings that differ from defaults
boolean shouldSave = template.isReformatCode() != FileTemplateBase.DEFAULT_REFORMAT_CODE_VALUE;
@@ -95,6 +92,14 @@ public class ExportableFileTemplateSettings extends FileTemplatesLoader implemen
if (template instanceof BundledFileTemplate) {
templateElement.setAttribute(ATTRIBUTE_ENABLED, Boolean.toString(((BundledFileTemplate)template).isEnabled()));
}
+
+ if (templatesGroup == null) {
+ templatesGroup = new Element(getXmlElementGroupName(manager));
+ if (element == null) {
+ element = new Element("fileTemplateSettings");
+ }
+ element.addContent(templatesGroup);
+ }
templatesGroup.addContent(templateElement);
}
}
diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateConfigurable.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateConfigurable.java
index be3be30fc247..21702dc68f4f 100644
--- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateConfigurable.java
+++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateConfigurable.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,7 +21,6 @@ import com.intellij.ide.DataManager;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.fileTemplates.FileTemplate;
import com.intellij.ide.fileTemplates.FileTemplateManager;
-import com.intellij.lexer.CompositeLexer;
import com.intellij.lexer.FlexAdapter;
import com.intellij.lexer.Lexer;
import com.intellij.lexer.MergingLexerAdapter;
@@ -38,7 +37,8 @@ import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.editor.event.DocumentAdapter;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.ex.EditorEx;
-import com.intellij.openapi.editor.ex.util.LexerEditorHighlighter;
+import com.intellij.openapi.editor.ex.util.LayerDescriptor;
+import com.intellij.openapi.editor.ex.util.LayeredLexerEditorHighlighter;
import com.intellij.openapi.editor.highlighter.EditorHighlighter;
import com.intellij.openapi.editor.highlighter.EditorHighlighterFactory;
import com.intellij.openapi.fileTypes.*;
@@ -99,7 +99,7 @@ public class FileTemplateConfigurable implements Configurable, Configurable.NoSc
private URL myDefaultDescriptionUrl;
private final Project myProject;
- private final List<ChangeListener> myChangeListeners = ContainerUtil.createLockFreeCopyOnWriteList();;
+ private final List<ChangeListener> myChangeListeners = ContainerUtil.createLockFreeCopyOnWriteList();
private Splitter mySplitter;
private final FileType myVelocityFileType = FileTypeManager.getInstance().getFileTypeByExtension("ft");
private JPanel myDescriptionPanel;
@@ -205,13 +205,13 @@ public class FileTemplateConfigurable implements Configurable, Configurable.NoSc
myNameField.addFocusListener(new FocusAdapter() {
@Override
- public void focusLost(FocusEvent e) {
+ public void focusLost(@NotNull FocusEvent e) {
onNameChanged();
}
});
myExtensionField.addFocusListener(new FocusAdapter() {
@Override
- public void focusLost(FocusEvent e) {
+ public void focusLost(@NotNull FocusEvent e) {
onNameChanged();
}
});
@@ -221,8 +221,11 @@ public class FileTemplateConfigurable implements Configurable, Configurable.NoSc
private Editor createEditor() {
EditorFactory editorFactory = EditorFactory.getInstance();
- Document doc = myFile == null ? editorFactory.createDocument(myTemplate == null ? "" : myTemplate.getText()) : PsiDocumentManager.getInstance(myFile.getProject()).getDocument(myFile);
- Editor editor = myProject == null ? editorFactory.createEditor(doc) : editorFactory.createEditor(doc, myProject);
+ Document doc = myFile == null
+ ? editorFactory.createDocument(myTemplate == null ? "" : myTemplate.getText())
+ : PsiDocumentManager.getInstance(myFile.getProject()).getDocument(myFile);
+ assert doc != null;
+ Editor editor = editorFactory.createEditor(doc, myProject);
EditorSettings editorSettings = editor.getSettings();
editorSettings.setVirtualSpace(false);
@@ -367,7 +370,7 @@ public class FileTemplateConfigurable implements Configurable, Configurable.NoSc
@Nullable
private PsiFile createFile(final String text, final String name) {
- if (myTemplate == null || myProject == null) return null;
+ if (myTemplate == null) return null;
final FileType fileType = myVelocityFileType;
if (fileType == FileTypes.UNKNOWN) return null;
@@ -388,7 +391,7 @@ public class FileTemplateConfigurable implements Configurable, Configurable.NoSc
}
private EditorHighlighter createHighlighter() {
- if (myTemplate != null && myProject != null && myVelocityFileType != FileTypes.UNKNOWN) {
+ if (myTemplate != null && myVelocityFileType != FileTypes.UNKNOWN) {
return EditorHighlighterFactory.getInstance().createEditorHighlighter(myProject, new LightVirtualFile("aaa." + myTemplate.getExtension() + ".ft"));
}
@@ -399,38 +402,27 @@ public class FileTemplateConfigurable implements Configurable, Configurable.NoSc
if (fileType == null) {
fileType = FileTypes.PLAIN_TEXT;
}
+
SyntaxHighlighter originalHighlighter = SyntaxHighlighterFactory.getSyntaxHighlighter(fileType, null, null);
- if (originalHighlighter == null) originalHighlighter = new PlainSyntaxHighlighter();
- return new LexerEditorHighlighter(new TemplateHighlighter(originalHighlighter), EditorColorsManager.getInstance().getGlobalScheme());
+ if (originalHighlighter == null) {
+ originalHighlighter = new PlainSyntaxHighlighter();
+ }
+
+ final EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme();
+ LayeredLexerEditorHighlighter highlighter = new LayeredLexerEditorHighlighter(new TemplateHighlighter(), scheme);
+ highlighter.registerLayer(FileTemplateTokenType.TEXT, new LayerDescriptor(originalHighlighter, ""));
+ return highlighter;
}
- private final static TokenSet TOKENS_TO_MERGE = TokenSet.create(FileTemplateTokenType.TEXT);
-
private static class TemplateHighlighter extends SyntaxHighlighterBase {
private final Lexer myLexer;
- private final SyntaxHighlighter myOriginalHighlighter;
-
- public TemplateHighlighter(SyntaxHighlighter original) {
- myOriginalHighlighter = original;
- Lexer originalLexer = original.getHighlightingLexer();
- Lexer templateLexer = new FlexAdapter(new FileTemplateTextLexer());
- templateLexer = new MergingLexerAdapter(templateLexer, TOKENS_TO_MERGE);
-
- myLexer = new CompositeLexer(originalLexer, templateLexer) {
- @Override
- protected IElementType getCompositeTokenType(IElementType type1, IElementType type2) {
- if (type2 == FileTemplateTokenType.MACRO || type2 == FileTemplateTokenType.DIRECTIVE) {
- return type2;
- }
- else {
- return type1;
- }
- }
- };
+
+ public TemplateHighlighter() {
+ myLexer = new MergingLexerAdapter(new FlexAdapter(new FileTemplateTextLexer()), TokenSet.create(FileTemplateTokenType.TEXT));
}
- @Override
@NotNull
+ @Override
public Lexer getHighlightingLexer() {
return myLexer;
}
@@ -438,14 +430,11 @@ public class FileTemplateConfigurable implements Configurable, Configurable.NoSc
@Override
@NotNull
public TextAttributesKey[] getTokenHighlights(IElementType tokenType) {
- if (tokenType == FileTemplateTokenType.MACRO) {
- return pack(myOriginalHighlighter.getTokenHighlights(tokenType), TemplateColors.TEMPLATE_VARIABLE_ATTRIBUTES);
- }
- else if (tokenType == FileTemplateTokenType.DIRECTIVE) {
- return pack(myOriginalHighlighter.getTokenHighlights(tokenType), TemplateColors.TEMPLATE_VARIABLE_ATTRIBUTES);
+ if (tokenType == FileTemplateTokenType.MACRO || tokenType == FileTemplateTokenType.DIRECTIVE) {
+ return pack(TemplateColors.TEMPLATE_VARIABLE_ATTRIBUTES);
}
- return myOriginalHighlighter.getTokenHighlights(tokenType);
+ return EMPTY;
}
}
diff --git a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarModel.java b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarModel.java
index a27ad87f70e4..9a80f455e4e1 100644
--- a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarModel.java
+++ b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarModel.java
@@ -222,9 +222,8 @@ public class NavBarModel {
psiElement = getOriginalElement(psiElement);
PsiElement resultElement = psiElement;
- for (final NavBarModelExtension modelExtension : Extensions.getExtensions(NavBarModelExtension.EP_NAME)) {
- resultElement = modelExtension.adjustElement(resultElement);
- }
+ resultElement = normalize(resultElement);
+ if (resultElement == null) return;
boolean foundByExtension = false;
for (final NavBarModelExtension modelExtension : Extensions.getExtensions(NavBarModelExtension.EP_NAME)) {
@@ -326,7 +325,7 @@ public class NavBarModel {
}
@Nullable
- private static PsiElement normalize(PsiElement child) {
+ private static PsiElement normalize(@Nullable PsiElement child) {
if (child == null) return null;
for (NavBarModelExtension modelExtension : Extensions.getExtensions(NavBarModelExtension.EP_NAME)) {
child = modelExtension.adjustElement(child);
diff --git a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPopup.java b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPopup.java
index d565c69f9df4..6c0374a5d744 100644
--- a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPopup.java
+++ b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPopup.java
@@ -27,6 +27,7 @@ import com.intellij.psi.PsiElement;
import com.intellij.ui.*;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.components.JBList;
+import com.intellij.ui.popup.HintUpdateSupply;
import com.intellij.ui.speedSearch.ListWithFilter;
import com.intellij.util.Function;
import com.intellij.util.NotNullFunction;
@@ -92,10 +93,8 @@ public class NavBarPopup extends LightweightHint implements Disposable{
protected void onPopupCancel() {
final JComponent component = getComponent();
if (component != null) {
- final Object o = component.getClientProperty(JBLIST_KEY);
- if (o instanceof JBListWithHintProvider) {
- ((JBListWithHintProvider)o).hideHint();
- }
+ Object o = component.getClientProperty(JBLIST_KEY);
+ if (o instanceof JComponent) HintUpdateSupply.hideHint((JComponent)o);
}
//noinspection unchecked
for (Disposable disposable : ((List<Disposable>)getList().getClientProperty(DISPOSED_OBJECTS))) {
diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/ProjectViewSettings.java b/platform/lang-impl/src/com/intellij/ide/projectView/ProjectViewSettings.java
new file mode 100644
index 000000000000..64e374097635
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/ide/projectView/ProjectViewSettings.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ide.projectView;
+
+/**
+ * @author nik
+ */
+public interface ProjectViewSettings extends ViewSettings {
+ boolean isShowExcludedFiles();
+}
diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewPane.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewPane.java
index 52e79d208147..bc2e509e085a 100644
--- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewPane.java
+++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewPane.java
@@ -23,15 +23,25 @@ import com.intellij.icons.AllIcons;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.SelectInTarget;
import com.intellij.ide.impl.ProjectPaneSelectInTarget;
+import com.intellij.ide.projectView.ProjectView;
+import com.intellij.ide.projectView.ProjectViewSettings;
import com.intellij.ide.projectView.ViewSettings;
import com.intellij.ide.projectView.impl.nodes.ProjectViewDirectoryHelper;
import com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode;
import com.intellij.ide.util.treeView.AbstractTreeBuilder;
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.ide.util.treeView.AbstractTreeUpdater;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.DefaultActionGroup;
+import com.intellij.openapi.actionSystem.Presentation;
+import com.intellij.openapi.actionSystem.ToggleAction;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.JDOMExternalizerUtil;
+import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.psi.PsiDirectory;
+import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -42,6 +52,8 @@ import java.awt.*;
public class ProjectViewPane extends AbstractProjectViewPSIPane {
@NonNls public static final String ID = "ProjectPane";
+ public static final String SHOW_EXCLUDED_FILES_OPTION = "show-excluded-files";
+ private boolean myShowExcludedFiles = true;
public ProjectViewPane(Project project) {
super(project);
@@ -76,12 +88,7 @@ public class ProjectViewPane extends AbstractProjectViewPSIPane {
@Override
protected ProjectAbstractTreeStructureBase createStructure() {
- return new ProjectTreeStructure(myProject, ID){
- @Override
- protected AbstractTreeNode createRoot(final Project project, ViewSettings settings) {
- return new ProjectViewProjectNode(project, settings);
- }
- };
+ return new ProjectViewPaneTreeStructure();
}
@Override
@@ -111,6 +118,25 @@ public class ProjectViewPane extends AbstractProjectViewPSIPane {
return "ProjectPane";
}
+ @Override
+ public void readExternal(Element element) throws InvalidDataException {
+ super.readExternal(element);
+ String showExcludedOption = JDOMExternalizerUtil.readField(element, SHOW_EXCLUDED_FILES_OPTION);
+ myShowExcludedFiles = showExcludedOption == null || Boolean.parseBoolean(showExcludedOption);
+ }
+
+ @Override
+ public void writeExternal(Element element) throws WriteExternalException {
+ super.writeExternal(element);
+ if (!myShowExcludedFiles) {
+ JDOMExternalizerUtil.writeField(element, SHOW_EXCLUDED_FILES_OPTION, String.valueOf(false));
+ }
+ }
+
+ @Override
+ public void addToolbarActions(DefaultActionGroup actionGroup) {
+ actionGroup.addAction(new ShowExcludedFilesAction()).setAsSecondary(true);
+ }
// should be first
@Override
@@ -148,4 +174,47 @@ public class ProjectViewPane extends AbstractProjectViewPSIPane {
return super.addSubtreeToUpdateByElement(element);
}
}
+
+ private class ProjectViewPaneTreeStructure extends ProjectTreeStructure implements ProjectViewSettings {
+ public ProjectViewPaneTreeStructure() {
+ super(ProjectViewPane.this.myProject, ID);
+ }
+
+ @Override
+ protected AbstractTreeNode createRoot(final Project project, ViewSettings settings) {
+ return new ProjectViewProjectNode(project, settings);
+ }
+
+ @Override
+ public boolean isShowExcludedFiles() {
+ return myShowExcludedFiles;
+ }
+ }
+
+ private final class ShowExcludedFilesAction extends ToggleAction {
+ private ShowExcludedFilesAction() {
+ super(IdeBundle.message("action.show.excluded.files"), IdeBundle.message("action.show.hide.excluded.files"), null);
+ }
+
+ @Override
+ public boolean isSelected(AnActionEvent event) {
+ return myShowExcludedFiles;
+ }
+
+ @Override
+ public void setSelected(AnActionEvent event, boolean flag) {
+ if (myShowExcludedFiles != flag) {
+ myShowExcludedFiles = flag;
+ updateFromRoot(true);
+ }
+ }
+
+ @Override
+ public void update(AnActionEvent e) {
+ super.update(e);
+ final Presentation presentation = e.getPresentation();
+ final ProjectView projectView = ProjectView.getInstance(myProject);
+ presentation.setVisible(projectView.getCurrentProjectViewPane() == ProjectViewPane.this);
+ }
+ }
}
diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewDirectoryHelper.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewDirectoryHelper.java
index 13ba91900521..36c09aff2218 100644
--- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewDirectoryHelper.java
+++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewDirectoryHelper.java
@@ -21,6 +21,7 @@
package com.intellij.ide.projectView.impl.nodes;
import com.intellij.ide.projectView.ProjectViewNode;
+import com.intellij.ide.projectView.ProjectViewSettings;
import com.intellij.ide.projectView.ViewSettings;
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.openapi.components.ServiceManager;
@@ -37,10 +38,8 @@ import com.intellij.openapi.roots.impl.DirectoryInfo;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.PsiDirectory;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.PsiManager;
+import com.intellij.psi.*;
+import com.intellij.psi.search.PsiElementProcessor;
import com.intellij.psi.util.PsiUtilCore;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
@@ -126,7 +125,7 @@ public class ProjectViewDirectoryHelper {
final Module module = fileIndex.getModuleForFile(psiDirectory.getVirtualFile());
final ModuleFileIndex moduleFileIndex = module == null ? null : ModuleRootManager.getInstance(module).getFileIndex();
if (!settings.isFlattenPackages() || skipDirectory(psiDirectory)) {
- processPsiDirectoryChildren(psiDirectory, directoryChildrenInProject(fileIndex, psiDirectory),
+ processPsiDirectoryChildren(psiDirectory, directoryChildrenInProject(psiDirectory, settings),
children, fileIndex, null, settings, withSubDirectories);
}
else { // source directory in "flatten packages" mode
@@ -172,10 +171,20 @@ public class ProjectViewDirectoryHelper {
return topLevelContentRoots;
}
- private PsiElement[] directoryChildrenInProject(ProjectFileIndex fileIndex, PsiDirectory psiDirectory) {
- VirtualFile dir = psiDirectory.getVirtualFile();
- if (isInProject(dir)) {
- return psiDirectory.getChildren();
+ private PsiElement[] directoryChildrenInProject(PsiDirectory psiDirectory, final ViewSettings settings) {
+ final VirtualFile dir = psiDirectory.getVirtualFile();
+ if (shouldBeShown(dir, settings)) {
+ final List<PsiElement> children = new ArrayList<PsiElement>();
+ psiDirectory.processChildren(new PsiElementProcessor<PsiFileSystemItem>() {
+ @Override
+ public boolean execute(@NotNull PsiFileSystemItem element) {
+ if (shouldBeShown(element.getVirtualFile(), settings)) {
+ children.add(element);
+ }
+ return true;
+ }
+ });
+ return PsiUtilCore.toPsiElementArray(children);
}
PsiManager manager = psiDirectory.getManager();
@@ -198,11 +207,11 @@ public class ProjectViewDirectoryHelper {
return PsiUtilCore.toPsiElementArray(directoriesOnTheWayToContentRoots);
}
- private boolean isInProject(VirtualFile dir) {
+ private boolean shouldBeShown(VirtualFile dir, ViewSettings settings) {
DirectoryInfo directoryInfo = myIndex.getInfoForFile(dir);
if (directoryInfo.isInProject()) return true;
- if (!Registry.is("ide.hide.excluded.files")) {
+ if (!Registry.is("ide.hide.excluded.files") && settings instanceof ProjectViewSettings && ((ProjectViewSettings)settings).isShowExcludedFiles()) {
return directoryInfo.isExcluded();
}
return false;
@@ -230,7 +239,7 @@ public class ProjectViewDirectoryHelper {
vFile = dir.getVirtualFile();
if (!vFile.equals(projectFileIndex.getSourceRootForFile(vFile))) { // if is not a source root
if (viewSettings.isHideEmptyMiddlePackages() && !skipDirectory(psiDir) && isEmptyMiddleDirectory(dir, true)) {
- processPsiDirectoryChildren(dir, directoryChildrenInProject(projectFileIndex, dir),
+ processPsiDirectoryChildren(dir, directoryChildrenInProject(dir, viewSettings),
container, projectFileIndex, moduleFileIndex, viewSettings, withSubDirectories); // expand it recursively
continue;
}
diff --git a/platform/lang-impl/src/com/intellij/ide/todo/ScopeBasedTodosPanel.java b/platform/lang-impl/src/com/intellij/ide/todo/ScopeBasedTodosPanel.java
index 97b3f8720f60..057082105eeb 100644
--- a/platform/lang-impl/src/com/intellij/ide/todo/ScopeBasedTodosPanel.java
+++ b/platform/lang-impl/src/com/intellij/ide/todo/ScopeBasedTodosPanel.java
@@ -22,6 +22,7 @@ package com.intellij.ide.todo;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.ide.util.scopeChooser.IgnoringComboBox;
+import com.intellij.ide.util.scopeChooser.ScopeChooserCombo;
import com.intellij.openapi.project.Project;
import com.intellij.packageDependencies.DependencyValidationManager;
import com.intellij.psi.search.scope.NonProjectFilesScope;
@@ -44,47 +45,18 @@ import java.util.List;
public class ScopeBasedTodosPanel extends TodoPanel {
private static final String SELECTED_SCOPE = "TODO_SCOPE";
private final Alarm myAlarm;
- private JComboBox myScopes;
- private final NamedScopesHolder.ScopeListener myScopeListener;
- private final NamedScopeManager myNamedScopeManager;
- private final DependencyValidationManager myValidationManager;
+ private ScopeChooserCombo myScopes;
public ScopeBasedTodosPanel(final Project project, TodoPanelSettings settings, Content content){
super(project,settings,false,content);
myAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD, project);
- final String scopeName = PropertiesComponent.getInstance(project).getValue(SELECTED_SCOPE);
- rebuildModel(project, scopeName);
-
- myScopeListener = new NamedScopesHolder.ScopeListener() {
- @Override
- public void scopesChanged() {
- final ScopeWrapper scope = (ScopeWrapper)myScopes.getSelectedItem();
- rebuildModel(project, scope != null ? scope.getName() : null);
- }
- };
-
- myNamedScopeManager = NamedScopeManager.getInstance(project);
- myNamedScopeManager.addScopeListener(myScopeListener);
-
- myValidationManager = DependencyValidationManager.getInstance(project);
- myValidationManager.addScopeListener(myScopeListener);
-
- myScopes.setRenderer(new ListCellRendererWrapper<ScopeWrapper>(){
- @Override
- public void customize(JList list, ScopeWrapper value, int index, boolean selected, boolean hasFocus) {
- setText(value.getName());
- if (value.isSeparator()) {
- setSeparator();
- }
- }
- });
- myScopes.addActionListener(new ActionListener() {
+ myScopes.getChildComponent().addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
rebuildWithAlarm(ScopeBasedTodosPanel.this.myAlarm);
- final ScopeWrapper selectedItem = (ScopeWrapper)myScopes.getSelectedItem();
- if (selectedItem != null) {
- PropertiesComponent.getInstance(myProject).setValue(SELECTED_SCOPE, selectedItem.getName());
+ final String selectedItemName = myScopes.getSelectedScopeName();
+ if (selectedItemName != null) {
+ PropertiesComponent.getInstance(myProject).setValue(SELECTED_SCOPE, selectedItemName);
}
}
});
@@ -92,67 +64,14 @@ public class ScopeBasedTodosPanel extends TodoPanel {
}
@Override
- public void dispose() {
- myNamedScopeManager.removeScopeListener(myScopeListener);
- myValidationManager.removeScopeListener(myScopeListener);
- super.dispose();
- }
-
- private void rebuildModel(Project project, String scopeName) {
- final ArrayList<ScopeWrapper> scopes = new ArrayList<ScopeWrapper>();
- final DependencyValidationManager manager = DependencyValidationManager.getInstance(project);
-
- scopes.add(new ScopeWrapper("Predefined Scopes"));
- List<NamedScope> predefinedScopesList = manager.getPredefinedScopes();
- NamedScope[] predefinedScopes = predefinedScopesList.toArray(new NamedScope[predefinedScopesList.size()]);
- predefinedScopes = NonProjectFilesScope.removeFromList(predefinedScopes);
- for (NamedScope predefinedScope : predefinedScopes) {
- scopes.add(new ScopeWrapper(predefinedScope));
- }
-
- collectEditableScopes(scopes, manager, "Custom Project Scopes");
- collectEditableScopes(scopes, NamedScopeManager.getInstance(project), "Custom Local Scopes");
-
- myScopes.setModel(new DefaultComboBoxModel(scopes.toArray(new ScopeWrapper[scopes.size()])));
- setSelection(scopeName, scopes);
- }
-
- private void setSelection(@Nullable String scopeName, ArrayList<ScopeWrapper> scopes) {
- boolean hasNonSeparators = false;
- for (ScopeWrapper scope : scopes) {
- if (!scope.isSeparator()) {
- hasNonSeparators = true;
- if (scopeName == null || scopeName.equals(scope.getName())) {
- myScopes.setSelectedItem(scope);
- return;
- }
- }
- }
- assert hasNonSeparators;
- setSelection(null, scopes);
- }
-
- private static void collectEditableScopes(ArrayList<ScopeWrapper> scopes, NamedScopesHolder manager, String separatorTitle) {
- NamedScope[] editableScopes = manager.getEditableScopes();
- if (editableScopes.length > 0) {
- scopes.add(new ScopeWrapper(separatorTitle));
- for (NamedScope scope : editableScopes) {
- scopes.add(new ScopeWrapper(scope));
- }
- }
- }
-
- @Override
protected JComponent createCenterComponent() {
JPanel panel = new JPanel(new BorderLayout());
final JComponent component = super.createCenterComponent();
panel.add(component, BorderLayout.CENTER);
- myScopes = new IgnoringComboBox() {
- @Override
- protected boolean isIgnored(Object item) {
- return item instanceof ScopeWrapper && ((ScopeWrapper)item).isSeparator();
- }
- };
+ String preselect = PropertiesComponent.getInstance(myProject).getValue(SELECTED_SCOPE);
+ myScopes = new ScopeChooserCombo(myProject, false, true, preselect);
+ myScopes.setCurrentSelection(false);
+ myScopes.setUsageView(false);
JPanel chooserPanel = new JPanel(new GridBagLayout());
final JLabel scopesLabel = new JLabel("Scope:");
@@ -177,32 +96,4 @@ public class ScopeBasedTodosPanel extends TodoPanel {
builder.init();
return builder;
}
-
- public static class ScopeWrapper {
- private final String myName;
- private final boolean mySeparator;
- private NamedScope myNamedScope;
-
- private ScopeWrapper(NamedScope namedScope) {
- mySeparator = false;
- myNamedScope = namedScope;
- myName = myNamedScope.getName();
- }
- private ScopeWrapper(String name) {
- mySeparator = true;
- myName = name;
- }
-
- public String getName() {
- return myName;
- }
-
- public NamedScope getNamedScope() {
- return myNamedScope;
- }
-
- public boolean isSeparator() {
- return mySeparator;
- }
- }
} \ No newline at end of file
diff --git a/platform/lang-impl/src/com/intellij/ide/todo/ScopeBasedTodosTreeBuilder.java b/platform/lang-impl/src/com/intellij/ide/todo/ScopeBasedTodosTreeBuilder.java
index 2d7163a0d5b1..0dc79f911852 100644
--- a/platform/lang-impl/src/com/intellij/ide/todo/ScopeBasedTodosTreeBuilder.java
+++ b/platform/lang-impl/src/com/intellij/ide/todo/ScopeBasedTodosTreeBuilder.java
@@ -19,6 +19,7 @@
*/
package com.intellij.ide.todo;
+import com.intellij.ide.util.scopeChooser.ScopeChooserCombo;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
@@ -26,9 +27,9 @@ import javax.swing.*;
import javax.swing.tree.DefaultTreeModel;
public class ScopeBasedTodosTreeBuilder extends TodoTreeBuilder{
- private final JComboBox myScopes;
+ private final ScopeChooserCombo myScopes;
- public ScopeBasedTodosTreeBuilder(JTree tree, DefaultTreeModel treeModel, Project project, JComboBox scopes){
+ public ScopeBasedTodosTreeBuilder(JTree tree, DefaultTreeModel treeModel, Project project, ScopeChooserCombo scopes){
super(tree,treeModel,project);
myScopes = scopes;
}
diff --git a/platform/lang-impl/src/com/intellij/ide/todo/ScopeBasedTodosTreeStructure.java b/platform/lang-impl/src/com/intellij/ide/todo/ScopeBasedTodosTreeStructure.java
index 322cc44bc99c..500e17b56534 100644
--- a/platform/lang-impl/src/com/intellij/ide/todo/ScopeBasedTodosTreeStructure.java
+++ b/platform/lang-impl/src/com/intellij/ide/todo/ScopeBasedTodosTreeStructure.java
@@ -24,22 +24,14 @@ import com.intellij.ide.todo.nodes.ToDoRootNode;
import com.intellij.ide.util.scopeChooser.ScopeChooserCombo;
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vcs.changes.Change;
-import com.intellij.openapi.vcs.changes.ChangeListManager;
-import com.intellij.openapi.vfs.VfsUtil;
-import com.intellij.packageDependencies.DependencyValidationManager;
import com.intellij.psi.PsiFile;
-import com.intellij.psi.search.scope.packageSet.NamedScope;
-import com.intellij.psi.search.scope.packageSet.NamedScopesHolder;
-import com.intellij.psi.search.scope.packageSet.PackageSet;
-
-import javax.swing.*;
-import java.util.Collection;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.SearchScope;
public class ScopeBasedTodosTreeStructure extends TodoTreeStructure {
- private final JComboBox myScopes;
+ private final ScopeChooserCombo myScopes;
- public ScopeBasedTodosTreeStructure(Project project, JComboBox scopes) {
+ public ScopeBasedTodosTreeStructure(Project project, ScopeChooserCombo scopes) {
super(project);
myScopes = scopes;
}
@@ -48,12 +40,9 @@ public class ScopeBasedTodosTreeStructure extends TodoTreeStructure {
public boolean accept(final PsiFile psiFile) {
if (!psiFile.isValid()) return false;
boolean isAffected = false;
- final ScopeBasedTodosPanel.ScopeWrapper scope = (ScopeBasedTodosPanel.ScopeWrapper)myScopes.getSelectedItem();
- if (scope != null) {
- final PackageSet value = scope.getNamedScope().getValue();
- if (value != null) {
- isAffected = value.contains(psiFile, NamedScopesHolder.getHolder(myProject, scope.getName(), DependencyValidationManager.getInstance(myProject)));
- }
+ SearchScope scope = myScopes.getSelectedScope();
+ if (scope instanceof GlobalSearchScope) {
+ isAffected = ((GlobalSearchScope)scope).contains(psiFile.getVirtualFile());
}
return isAffected && (myTodoFilter != null && myTodoFilter.accept(mySearchHelper, psiFile) ||
(myTodoFilter == null && mySearchHelper.getTodoItemsCount(psiFile) > 0));
diff --git a/platform/lang-impl/src/com/intellij/ide/ui/search/TraverseUIStarter.java b/platform/lang-impl/src/com/intellij/ide/ui/search/TraverseUIStarter.java
index eb22b72eb810..37248fe8a909 100644
--- a/platform/lang-impl/src/com/intellij/ide/ui/search/TraverseUIStarter.java
+++ b/platform/lang-impl/src/com/intellij/ide/ui/search/TraverseUIStarter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,7 +26,7 @@ import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.impl.ActionManagerImpl;
import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.application.ApplicationStarter;
+import com.intellij.openapi.application.ApplicationStarterEx;
import com.intellij.openapi.application.ex.ApplicationEx;
import com.intellij.openapi.keymap.impl.ui.KeymapPanel;
import com.intellij.openapi.options.SearchableConfigurable;
@@ -50,8 +50,7 @@ import java.util.TreeSet;
* Pass corresponding -Didea.platform.prefix=YOUR_IDE_PREFIX to vm options and choose main_YOUR_IDE module
*/
@SuppressWarnings({"CallToPrintStackTrace", "SynchronizeOnThis"})
-public class TraverseUIStarter implements ApplicationStarter {
- private String OUTPUT_PATH;
+public class TraverseUIStarter extends ApplicationStarterEx {
@NonNls private static final String OPTIONS = "options";
@NonNls private static final String CONFIGURABLE = "configurable";
@NonNls private static final String ID = "id";
@@ -61,13 +60,19 @@ public class TraverseUIStarter implements ApplicationStarter {
@NonNls private static final String PATH = "path";
@NonNls private static final String HIT = "hit";
+ private String OUTPUT_PATH;
+
+ @Override
+ public boolean isHeadless() {
+ return true;
+ }
+
@Override
@NonNls
public String getCommandName() {
return "traverseUI";
}
-
@Override
public void premain(String[] args) {
OUTPUT_PATH = args[1];
diff --git a/platform/lang-impl/src/com/intellij/ide/util/PsiElementListCellRenderer.java b/platform/lang-impl/src/com/intellij/ide/util/PsiElementListCellRenderer.java
index f51ec554485a..d0a0648285d6 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/PsiElementListCellRenderer.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/PsiElementListCellRenderer.java
@@ -102,7 +102,7 @@ public abstract class PsiElementListCellRenderer<T extends PsiElement> extends J
setPaintFocusBorder(hasFocus && UIUtil.isToUseDottedCellBorder() && myFocusBorderEnabled);
if (value instanceof PsiElement) {
T element = (T)value;
- String name = getElementText(element);
+ String name = element.isValid() ? getElementText(element) : "INVALID";
PsiFile psiFile = element.isValid() ? element.getContainingFile() : null;
boolean isProblemFile = false;
diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java
index 3e90f2310884..53d71d9794fa 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java
@@ -54,6 +54,8 @@ import com.intellij.openapi.util.*;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.IdeFocusManager;
+import com.intellij.openapi.wm.ToolWindow;
+import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.openapi.wm.ex.WindowManagerEx;
import com.intellij.psi.PsiElement;
@@ -518,23 +520,33 @@ public abstract class ChooseByNameBase {
else {
Component oppositeComponent = e.getOppositeComponent();
if (oppositeComponent == myCheckBox) {
- myTextField.requestFocus();
+ IdeFocusManager.getInstance(myProject).requestFocus(myTextField, true);
return;
}
if (oppositeComponent != null && !(oppositeComponent instanceof JFrame) &&
myList.isShowing() &&
(oppositeComponent == myList || SwingUtilities.isDescendingFrom(myList, oppositeComponent))) {
- myTextField.requestFocus();// Otherwise me may skip some KeyEvents
+ IdeFocusManager.getInstance(myProject).requestFocus(myTextField, true);// Otherwise me may skip some KeyEvents
return;
}
+ if (oppositeComponent != null) {
+ ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(myProject);
+ ToolWindow toolWindow = toolWindowManager.getToolWindow(toolWindowManager.getActiveToolWindowId());
+ if (toolWindow != null) {
+ JComponent toolWindowComponent = toolWindow.getComponent();
+ if (SwingUtilities.isDescendingFrom(oppositeComponent, toolWindowComponent)) {
+ return; // Allow toolwindows to gain focus (used by QuickDoc shown in a toolwindow)
+ }
+ }
+ }
+
EventQueue queue = Toolkit.getDefaultToolkit().getSystemEventQueue();
if (queue instanceof IdeEventQueue) {
if (!((IdeEventQueue)queue).wasRootRecentlyClicked(oppositeComponent)) {
Component root = SwingUtilities.getRoot(myTextField);
if (root != null && root.isShowing()) {
- root.requestFocus();
- myTextField.requestFocus();
+ IdeFocusManager.getInstance(myProject).requestFocus(myTextField, true);
return;
}
}
@@ -641,7 +653,7 @@ public abstract class ChooseByNameBase {
@Override
public boolean onClick(@NotNull MouseEvent e, int clickCount) {
if (!myTextField.hasFocus()) {
- myTextField.requestFocus();
+ IdeFocusManager.getInstance(myProject).requestFocus(myTextField, true);
}
if (clickCount == 2) {
diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java
index c40831d276de..c26bd353de50 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java
@@ -62,6 +62,7 @@ public abstract class ContributorsBasedGotoByModel implements ChooseByNameModelE
protected ContributorsBasedGotoByModel(@NotNull Project project, @NotNull ChooseByNameContributor[] contributors) {
myProject = project;
myContributors = contributors;
+ assert !Arrays.asList(contributors).contains(null);
}
@Override
@@ -95,7 +96,7 @@ public abstract class ContributorsBasedGotoByModel implements ChooseByNameModelE
ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
Processor<ChooseByNameContributor> processor = new ReadActionProcessor<ChooseByNameContributor>() {
@Override
- public boolean processInReadAction(ChooseByNameContributor contributor) {
+ public boolean processInReadAction(@NotNull ChooseByNameContributor contributor) {
try {
if (!myProject.isDisposed()) {
long contributorStarted = System.currentTimeMillis();
@@ -185,13 +186,15 @@ public abstract class ContributorsBasedGotoByModel implements ChooseByNameModelE
}
@NotNull
- public Object[] getElementsByName(final String name, final FindSymbolParameters parameters, @NotNull final ProgressIndicator canceled) {
+ public Object[] getElementsByName(@NotNull final String name,
+ @NotNull final FindSymbolParameters parameters,
+ @NotNull final ProgressIndicator canceled) {
long elementByNameStarted = System.currentTimeMillis();
final List<NavigationItem> items = Collections.synchronizedList(new ArrayList<NavigationItem>());
Processor<ChooseByNameContributor> processor = new Processor<ChooseByNameContributor>() {
@Override
- public boolean process(ChooseByNameContributor contributor) {
+ public boolean process(@NotNull ChooseByNameContributor contributor) {
if (myProject.isDisposed()) {
return true;
}
diff --git a/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java b/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java
index aef7c9a17e74..8297a3db8e1f 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java
@@ -71,6 +71,8 @@ public class ScopeChooserCombo extends ComboboxWithBrowseButton implements Dispo
private NamedScopesHolder.ScopeListener myScopeListener;
private NamedScopeManager myNamedScopeManager;
private DependencyValidationManager myValidationManager;
+ private boolean myCurrentSelection = true;
+ private boolean myUsageView = true;
public ScopeChooserCombo() {
super(new IgnoringComboBox(){
@@ -118,6 +120,14 @@ public class ScopeChooserCombo extends ComboboxWithBrowseButton implements Dispo
selectScope(preselect);
}
+ public void setCurrentSelection(boolean currentSelection) {
+ myCurrentSelection = currentSelection;
+ }
+
+ public void setUsageView(boolean usageView) {
+ myUsageView = usageView;
+ }
+
@Override
public void dispose() {
super.dispose();
@@ -220,7 +230,7 @@ public class ScopeChooserCombo extends ComboboxWithBrowseButton implements Dispo
private void createPredefinedScopeDescriptors(DefaultComboBoxModel model) {
@SuppressWarnings("deprecation") final DataContext context = DataManager.getInstance().getDataContext();
- for (SearchScope scope : getPredefinedScopes(myProject, context, mySuggestSearchInLibs, myPrevSearchFiles, true, true)) {
+ for (SearchScope scope : getPredefinedScopes(myProject, context, mySuggestSearchInLibs, myPrevSearchFiles, myCurrentSelection, myUsageView)) {
model.addElement(new ScopeDescriptor(scope));
}
for (ScopeDescriptorProvider provider : Extensions.getExtensions(ScopeDescriptorProvider.EP_NAME)) {
diff --git a/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeDescriptorProvider.java b/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeDescriptorProvider.java
index fb879abd2595..44baafa0b86e 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeDescriptorProvider.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeDescriptorProvider.java
@@ -25,6 +25,7 @@ import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
public interface ScopeDescriptorProvider {
+ ScopeDescriptor[] EMPTY = new ScopeDescriptor[0];
ExtensionPointName<ScopeDescriptorProvider> EP_NAME = ExtensionPointName.create("com.intellij.scopeDescriptorProvider");
@NotNull
diff --git a/platform/lang-impl/src/com/intellij/injected/editor/CaretModelWindow.java b/platform/lang-impl/src/com/intellij/injected/editor/CaretModelWindow.java
index d0288d71a9a2..da44ae6c123c 100644
--- a/platform/lang-impl/src/com/intellij/injected/editor/CaretModelWindow.java
+++ b/platform/lang-impl/src/com/intellij/injected/editor/CaretModelWindow.java
@@ -212,13 +212,24 @@ public class CaretModelWindow implements CaretModel {
@Override
public void setCaretsAndSelections(@NotNull List<CaretState> caretStates) {
+ List<CaretState> convertedStates = convertCaretStates(caretStates);
+ myDelegate.setCaretsAndSelections(convertedStates);
+ }
+
+ @Override
+ public void setCaretsAndSelections(@NotNull List<CaretState> caretStates, boolean updateSystemSelection) {
+ List<CaretState> convertedStates = convertCaretStates(caretStates);
+ myDelegate.setCaretsAndSelections(convertedStates, updateSystemSelection);
+ }
+
+ private List<CaretState> convertCaretStates(List<CaretState> caretStates) {
List<CaretState> convertedStates = new ArrayList<CaretState>(caretStates.size());
for (CaretState state : caretStates) {
convertedStates.add(new CaretState(injectedToHost(state.getCaretPosition()),
injectedToHost(state.getSelectionStart()),
injectedToHost(state.getSelectionEnd())));
}
- myDelegate.setCaretsAndSelections(convertedStates);
+ return convertedStates;
}
private LogicalPosition injectedToHost(@Nullable LogicalPosition position) {
diff --git a/platform/lang-impl/src/com/intellij/injected/editor/InjectedCaret.java b/platform/lang-impl/src/com/intellij/injected/editor/InjectedCaret.java
index e52fa66ccefc..ec958fdc557a 100644
--- a/platform/lang-impl/src/com/intellij/injected/editor/InjectedCaret.java
+++ b/platform/lang-impl/src/com/intellij/injected/editor/InjectedCaret.java
@@ -165,6 +165,12 @@ public class InjectedCaret implements Caret {
}
@Override
+ public void setSelection(int startOffset, int endOffset, boolean updateSystemSelection) {
+ TextRange hostRange = myEditorWindow.getDocument().injectedToHost(new ProperTextRange(startOffset, endOffset));
+ myDelegate.setSelection(hostRange.getStartOffset(), hostRange.getEndOffset(), updateSystemSelection);
+ }
+
+ @Override
public void setSelection(int startOffset, @Nullable VisualPosition endPosition, int endOffset) {
TextRange hostRange = myEditorWindow.getDocument().injectedToHost(new ProperTextRange(startOffset, endOffset));
myDelegate.setSelection(hostRange.getStartOffset(), endPosition, hostRange.getEndOffset());
@@ -177,6 +183,12 @@ public class InjectedCaret implements Caret {
}
@Override
+ public void setSelection(@Nullable VisualPosition startPosition, int startOffset, @Nullable VisualPosition endPosition, int endOffset, boolean updateSystemSelection) {
+ TextRange hostRange = myEditorWindow.getDocument().injectedToHost(new ProperTextRange(startOffset, endOffset));
+ myDelegate.setSelection(startPosition, hostRange.getStartOffset(), endPosition, hostRange.getEndOffset(), updateSystemSelection);
+ }
+
+ @Override
public void removeSelection() {
myDelegate.removeSelection();
}
diff --git a/platform/lang-impl/src/com/intellij/internal/ImageDuplicateResultsDialog.java b/platform/lang-impl/src/com/intellij/internal/ImageDuplicateResultsDialog.java
index c7c62288c158..53d4a3edd7ef 100644
--- a/platform/lang-impl/src/com/intellij/internal/ImageDuplicateResultsDialog.java
+++ b/platform/lang-impl/src/com/intellij/internal/ImageDuplicateResultsDialog.java
@@ -39,7 +39,6 @@ import com.intellij.ui.*;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.components.JBList;
import com.intellij.ui.components.JBScrollPane;
-import com.intellij.ui.popup.NotLookupOrSearchCondition;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.Function;
import com.intellij.util.NotNullFunction;
@@ -232,7 +231,6 @@ public class ImageDuplicateResultsDialog extends DialogWrapper {
final JBPopup popup =
JBPopupFactory.getInstance().createComponentPopupBuilder(viewComponent, viewComponent.getPreferredFocusableComponent())
- .setRequestFocusCondition(myProject, NotLookupOrSearchCondition.INSTANCE)
.setProject(myProject)
.setDimensionServiceKey(myProject, DocumentationManager.JAVADOC_LOCATION_AND_SIZE, false)
.setResizable(true)
diff --git a/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java b/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java
index dfaa6501831b..cd1ec63d1879 100644
--- a/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java
+++ b/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java
@@ -101,7 +101,7 @@ import java.util.regex.Pattern;
*/
public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disposable {
private static final String REFS_CACHE = "References Resolve Cache";
- private static final Color SELECTION_BG_COLOR = new JBColor(new Color(0x009999), new Color(0, 80, 80));
+ private static final Color BOX_COLOR = new JBColor(new Color(0xFC6C00), new Color(0xDE6C01));
private static final Logger LOG = Logger.getInstance("#com.intellij.internal.psiView.PsiViewerDialog");
private final Project myProject;
@@ -133,7 +133,6 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
@Nullable
private BlockTreeBuilder myBlockTreeBuilder;
private RangeHighlighter myHighlighter;
- private RangeHighlighter myIntersectHighlighter;
private HashMap<PsiElement, BlockTreeNode> myPsiToBlockMap;
private final Set<SourceWrapper> mySourceWrappers = ContainerUtil.newTreeSet();
@@ -163,7 +162,7 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
}
@Override
- public int compare(String o1, String o2) {
+ public int compare(@NotNull String o1, @NotNull String o2) {
if (o1.equals(myOnTop)) return -1;
if (o2.equals(myOnTop)) return 1;
return o1.compareToIgnoreCase(o2);
@@ -194,8 +193,8 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
}
@Override
- public int compareTo(final SourceWrapper o) {
- return o == null ? -1 : getText().compareToIgnoreCase(o.getText());
+ public int compareTo(@NotNull final SourceWrapper o) {
+ return getText().compareToIgnoreCase(o.getText());
}
}
@@ -242,7 +241,7 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
final TreeCellRenderer renderer = myPsiTree.getCellRenderer();
myPsiTree.setCellRenderer(new TreeCellRenderer() {
@Override
- public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
+ public Component getTreeCellRendererComponent(@NotNull JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
final Component c = renderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
if (value instanceof DefaultMutableTreeNode) {
final Object userObject = ((DefaultMutableTreeNode)value).getUserObject();
@@ -251,7 +250,7 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
if (c instanceof NodeRenderer) {
((NodeRenderer)c).setToolTipText(element == null ? null : element.getClass().getName());
}
- if ((element instanceof PsiElement && FileContextUtil.getFileContext(((PsiElement)element).getContainingFile()) != null) ||
+ if (element instanceof PsiElement && FileContextUtil.getFileContext(((PsiElement)element).getContainingFile()) != null ||
element instanceof ViewerTreeStructure.Inject) {
final TextAttributes attr = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(EditorColors.INJECTED_LANGUAGE_FRAGMENT);
c.setBackground(attr.getBackgroundColor());
@@ -271,7 +270,7 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
myRefs.getSelectionModel().addListSelectionListener(listener);
myRefs.setCellRenderer(new DefaultListCellRenderer() {
@Override
- public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
+ public Component getListCellRendererComponent(@NotNull JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
final Component comp = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (resolve(index) == null) {
comp.setForeground(JBColor.RED);
@@ -289,7 +288,7 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
getPeer().getWindow().setFocusTraversalPolicy(new LayoutFocusTraversalPolicy() {
@Override
- public Component getInitialComponent(Window window) {
+ public Component getInitialComponent(@NotNull Window window) {
return myEditor.getComponent();
}
});
@@ -324,7 +323,7 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
mySourceWrappers.add(wrapper);
if (lastUsed == null && wrapper.getText().equals(type)) lastUsed = wrapper;
if (myCurrentFile != null && wrapper.myFileType instanceof LanguageFileType &&
- ((LanguageFileType)wrapper.myFileType).equals(curLanguage.getAssociatedFileType())) {
+ wrapper.myFileType.equals(curLanguage.getAssociatedFileType())) {
lastUsed = wrapper;
}
}
@@ -347,7 +346,7 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
};
myFileTypeComboBox.addActionListener(new ActionListener() {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
updateDialectsCombo(null);
updateExtensionsCombo();
updateEditor();
@@ -355,7 +354,7 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
});
myDialectComboBox.addActionListener(new ActionListener() {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
updateEditor();
}
});
@@ -382,14 +381,14 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
final ViewerTreeStructure psiTreeStructure = (ViewerTreeStructure)myPsiTreeBuilder.getTreeStructure();
myShowWhiteSpacesBox.addActionListener(new ActionListener() {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
psiTreeStructure.setShowWhiteSpaces(myShowWhiteSpacesBox.isSelected());
myPsiTreeBuilder.queueUpdate();
}
});
myShowTreeNodesCheckBox.addActionListener(new ActionListener() {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
psiTreeStructure.setShowTreeNodes(myShowTreeNodesCheckBox.isSelected());
myPsiTreeBuilder.queueUpdate();
}
@@ -402,7 +401,7 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
myBlockStructurePanel.setVisible(settings.showBlocks);
myShowBlocksCheckBox.addActionListener(new ActionListener() {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
if (!myShowBlocksCheckBox.isSelected()) {
settings.blockRefDividerLocation = myBlockRefSplitPane.getDividerLocation();
}
@@ -473,14 +472,14 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
registerKeyboardAction(new ActionListener() {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
focusEditor();
}
}, KeyStroke.getKeyStroke(KeyEvent.VK_T, mask));
registerKeyboardAction(new ActionListener() {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
focusTree();
}
}, KeyStroke.getKeyStroke(KeyEvent.VK_S, mask));
@@ -488,21 +487,21 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
registerKeyboardAction(new ActionListener() {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
focusBlockTree();
}
}, KeyStroke.getKeyStroke(KeyEvent.VK_K, mask));
registerKeyboardAction(new ActionListener() {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
focusRefs();
}
}, KeyStroke.getKeyStroke(KeyEvent.VK_R, mask));
registerKeyboardAction(new ActionListener() {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
if (myRefs.isFocusOwner()) {
focusBlockTree();
}
@@ -548,26 +547,6 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
myBlockTreeSeparator.setLabelFor(myBlockTree);
}
- private void updateIntersectHighlighter(int highlightStart, int highlightEnd) {
- if (myIntersectHighlighter != null) {
- myEditor.getMarkupModel().removeHighlighter(myIntersectHighlighter);
- myIntersectHighlighter.dispose();
- }
- if (myEditor.getSelectionModel().hasSelection()) {
- int selectionStart = myEditor.getSelectionModel().getSelectionStart();
- int selectionEnd = myEditor.getSelectionModel().getSelectionEnd();
- TextRange resRange = new TextRange(highlightStart, highlightEnd).intersection(new TextRange(selectionStart, selectionEnd));
- if (resRange != null) {
- TextAttributes attributes = new TextAttributes();
- attributes.setBackgroundColor(Color.LIGHT_GRAY);
- attributes.setForegroundColor(Color.white);
- myIntersectHighlighter = myEditor.getMarkupModel()
- .addRangeHighlighter(resRange.getStartOffset(), resRange.getEndOffset(), HighlighterLayer.LAST + 1, attributes,
- HighlighterTargetArea.EXACT_RANGE);
- }
- }
- }
-
@Nullable
private PsiElement getPsiElement() {
final TreePath path = myPsiTree.getSelectionPath();
@@ -676,7 +655,7 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
protected Action[] createActions() {
AbstractAction copyPsi = new AbstractAction("Cop&y PSI") {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
PsiElement element = parseText(myEditor.getDocument().getText());
List<PsiElement> allToParse = new ArrayList<PsiElement>();
if (element instanceof PsiFile) {
@@ -735,7 +714,7 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
myPsiToBlockMap = new HashMap<PsiElement, BlockTreeNode>();
final PsiElement psiFile = ((ViewerTreeStructure)myPsiTreeBuilder.getTreeStructure()).getRootPsiElement();
initMap(rootNode, psiFile);
- PsiElement rootPsi = (rootNode.getBlock() instanceof ASTBlock) ?
+ PsiElement rootPsi = rootNode.getBlock() instanceof ASTBlock ?
((ASTBlock)rootNode.getBlock()).getNode().getPsi() : rootElement;
BlockTreeNode blockNode = myPsiToBlockMap.get(rootPsi);
@@ -856,12 +835,12 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
public MyPsiTreeSelectionListener() {
myAttributes = new TextAttributes();
- myAttributes.setBackgroundColor(SELECTION_BG_COLOR);
- myAttributes.setForegroundColor(Color.white);
+ myAttributes.setEffectColor(BOX_COLOR);
+ myAttributes.setEffectType(EffectType.ROUNDED_BOX);
}
@Override
- public void valueChanged(TreeSelectionEvent e) {
+ public void valueChanged(@NotNull TreeSelectionEvent e) {
if (!myEditor.getDocument().getText().equals(myLastParsedText) || myBlockTree.hasFocus()) return;
TreePath path = myPsiTree.getSelectionPath();
clearSelection();
@@ -887,8 +866,6 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
final int textLength = myEditor.getDocument().getTextLength();
if (end <= textLength) {
myHighlighter = myEditor.getMarkupModel().addRangeHighlighter(start, end, HighlighterLayer.LAST, myAttributes, HighlighterTargetArea.EXACT_RANGE);
- updateIntersectHighlighter(start, end);
-
if (myPsiTree.hasFocus()) {
myEditor.getCaretModel().moveToOffset(start);
myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
@@ -946,12 +923,12 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
public MyBlockTreeSelectionListener() {
myAttributes = new TextAttributes();
- myAttributes.setBackgroundColor(SELECTION_BG_COLOR);
- myAttributes.setForegroundColor(Color.white);
+ myAttributes.setEffectColor(BOX_COLOR);
+ myAttributes.setEffectType(EffectType.ROUNDED_BOX);
}
@Override
- public void valueChanged(TreeSelectionEvent e) {
+ public void valueChanged(@NotNull TreeSelectionEvent e) {
if (myIgnoreBlockTreeSelectionMarker > 0 || myBlockTreeBuilder == null) {
return;
}
@@ -988,7 +965,6 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
if (end <= textLength) {
myHighlighter = myEditor.getMarkupModel()
.addRangeHighlighter(start, end, HighlighterLayer.LAST, myAttributes, HighlighterTargetArea.EXACT_RANGE);
- updateIntersectHighlighter(start, end);
myEditor.getCaretModel().moveToOffset(start);
myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
@@ -1112,7 +1088,7 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
private class GoToListener implements KeyListener, MouseListener, ListSelectionListener {
private RangeHighlighter myListenerHighlighter;
private final TextAttributes myAttributes =
- new TextAttributes(Color.white, SELECTION_BG_COLOR, JBColor.RED, EffectType.BOXED, Font.PLAIN);
+ new TextAttributes(JBColor.RED, null, null, null, Font.PLAIN);
private void navigate() {
final Object value = myRefs.getSelectedValue();
@@ -1124,21 +1100,21 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
}
@Override
- public void keyPressed(KeyEvent e) {
+ public void keyPressed(@NotNull KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
navigate();
}
}
@Override
- public void mouseClicked(MouseEvent e) {
+ public void mouseClicked(@NotNull MouseEvent e) {
if (e.getClickCount() > 1) {
navigate();
}
}
@Override
- public void valueChanged(ListSelectionEvent e) {
+ public void valueChanged(@NotNull ListSelectionEvent e) {
clearSelection();
updateDialectsCombo(null);
updateExtensionsCombo();
@@ -1176,17 +1152,17 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
}
@Override
- public void keyTyped(KeyEvent e) {}
+ public void keyTyped(@NotNull KeyEvent e) {}
@Override
public void keyReleased(KeyEvent e) {}
@Override
- public void mousePressed(MouseEvent e) {}
+ public void mousePressed(@NotNull MouseEvent e) {}
@Override
- public void mouseReleased(MouseEvent e) {}
+ public void mouseReleased(@NotNull MouseEvent e) {}
@Override
- public void mouseEntered(MouseEvent e) {}
+ public void mouseEntered(@NotNull MouseEvent e) {}
@Override
- public void mouseExited(MouseEvent e) {}
+ public void mouseExited(@NotNull MouseEvent e) {}
}
private void updateEditor() {
@@ -1247,7 +1223,6 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
if (myEditor.getContentComponent().hasFocus()) {
TextRange rangeInHostFile = InjectedLanguageManager.getInstance(myProject).injectedToHost(element, element.getTextRange());
selectBlockNode(findBlockNode(rangeInHostFile, true));
- updateIntersectHighlighter(myHighlighter.getStartOffset(), myHighlighter.getEndOffset());
}
}
myPsiTreeBuilder.select(element);
@@ -1270,13 +1245,6 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
return myLastParsedTextHashCode == myNewDocumentHashCode && myEditor.getContentComponent().hasFocus();
}
- @Nullable
- private PsiFile getPsiFile() {
- ViewerTreeStructure treeStructure = (ViewerTreeStructure)myPsiTreeBuilder.getTreeStructure();
- final PsiElement root = treeStructure != null ? treeStructure.getRootPsiElement() : null;
- return root instanceof PsiFile ? (PsiFile)root : null;
- }
-
@Override
public void beforeDocumentChange(DocumentEvent event) {
@@ -1297,7 +1265,7 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
}
@Override
- public void focusGained(final FocusEvent e) {
+ public void focusGained(@NotNull final FocusEvent e) {
final Component from = e.getOppositeComponent();
if (!e.isTemporary() && from != null && !myComboBox.isPopupVisible() && isUnder(from, myParent)) {
myComboBox.setPopupVisible(true);
diff --git a/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ModuleStateStorageManager.java b/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ModuleStateStorageManager.java
index c62954177884..ea6d2fcc59fc 100644
--- a/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ModuleStateStorageManager.java
+++ b/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ModuleStateStorageManager.java
@@ -37,6 +37,7 @@ class ModuleStateStorageManager extends StateStorageManagerImpl {
return new ModuleStoreImpl.ModuleFileData(ROOT_TAG_NAME, myModule);
}
+ @Nullable
@Override
protected String getOldStorageSpec(Object component, final String componentName, final StateStorageOperation operation) {
return ModuleStoreImpl.DEFAULT_STATE_STORAGE;
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/PushedFilePropertiesUpdaterImpl.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/PushedFilePropertiesUpdaterImpl.java
index a96432e2b64c..962aa81c3e59 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/PushedFilePropertiesUpdaterImpl.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/PushedFilePropertiesUpdaterImpl.java
@@ -37,8 +37,12 @@ import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.EmptyRunnable;
-import com.intellij.openapi.vfs.*;
-import com.intellij.openapi.vfs.impl.BulkVirtualFileListenerAdapter;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileManager;
+import com.intellij.openapi.vfs.newvfs.BulkFileListener;
+import com.intellij.openapi.vfs.newvfs.events.VFileCreateEvent;
+import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
+import com.intellij.openapi.vfs.newvfs.events.VFileMoveEvent;
import com.intellij.psi.PsiManager;
import com.intellij.psi.impl.PsiManagerEx;
import com.intellij.psi.impl.file.impl.FileManagerImpl;
@@ -48,8 +52,11 @@ import com.intellij.util.indexing.FileBasedIndexProjectHandler;
import com.intellij.util.messages.MessageBusConnection;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
@@ -86,33 +93,39 @@ public class PushedFilePropertiesUpdaterImpl extends PushedFilePropertiesUpdater
}
});
- myConnection.subscribe(VirtualFileManager.VFS_CHANGES, new BulkVirtualFileListenerAdapter(new VirtualFileAdapter() {
+ myConnection.subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener.Adapter() {
@Override
- public void fileCreated(@NotNull final VirtualFileEvent event) {
- final VirtualFile file = event.getFile();
- final FilePropertyPusher[] pushers = file.isDirectory() ? myPushers : myFilePushers;
- if (!event.isFromRefresh() || !file.isDirectory()) {
- // push synchronously to avoid entering dumb mode in the middle of a meaningful write action
- // avoid dumb mode for just one file
- doPushRecursively(file, pushers, ProjectRootManager.getInstance(myProject).getFileIndex());
- }
- else {
- schedulePushRecursively(file, pushers);
- }
- }
+ public void after(@NotNull List<? extends VFileEvent> events) {
+ List<Runnable> delayedTasks = ContainerUtil.newArrayList();
+ for (VFileEvent event : events) {
+ final VirtualFile file = event.getFile();
+ if (file == null) continue;
- @Override
- public void fileMoved(@NotNull final VirtualFileMoveEvent event) {
- final VirtualFile file = event.getFile();
- final FilePropertyPusher[] pushers = file.isDirectory() ? myPushers : myFilePushers;
- if (pushers.length == 0) return;
- for (FilePropertyPusher pusher : pushers) {
- file.putUserData(pusher.getFileDataKey(), null);
+ final FilePropertyPusher[] pushers = file.isDirectory() ? myPushers : myFilePushers;
+ if (pushers.length == 0) continue;
+
+ if (event instanceof VFileCreateEvent) {
+ if (!event.isFromRefresh() || !file.isDirectory()) {
+ // push synchronously to avoid entering dumb mode in the middle of a meaningful write action
+ // avoid dumb mode for just one file
+ doPushRecursively(file, pushers, ProjectRootManager.getInstance(myProject).getFileIndex());
+ }
+ else {
+ ContainerUtil.addIfNotNull(delayedTasks, createRecursivePushTask(file, pushers));
+ }
+ } else if (event instanceof VFileMoveEvent) {
+ for (FilePropertyPusher pusher : pushers) {
+ file.putUserData(pusher.getFileDataKey(), null);
+ }
+ // push synchronously to avoid entering dumb mode in the middle of a meaningful write action
+ doPushRecursively(file, pushers, ProjectRootManager.getInstance(myProject).getFileIndex());
+ }
+ }
+ if (!delayedTasks.isEmpty()) {
+ queueTasks(delayedTasks);
}
- // push synchronously to avoid entering dumb mode in the middle of a meaningful write action
- doPushRecursively(file, pushers, ProjectRootManager.getInstance(myProject).getFileIndex());
}
- }));
+ });
}
});
}
@@ -128,7 +141,7 @@ public class PushedFilePropertiesUpdaterImpl extends PushedFilePropertiesUpdater
@Override
public void pushRecursively(VirtualFile file, Project project) {
- PushedFilePropertiesUpdaterImpl.this.schedulePushRecursively(file, pusher);
+ queueTasks(ContainerUtil.createMaybeSingletonList(createRecursivePushTask(file, new FilePropertyPusher[]{pusher})));
}
});
}
@@ -140,16 +153,17 @@ public class PushedFilePropertiesUpdaterImpl extends PushedFilePropertiesUpdater
doPushAll(myPushers);
}
- private void schedulePushRecursively(final VirtualFile dir, final FilePropertyPusher... pushers) {
- if (pushers.length == 0) return;
+ @Nullable
+ private Runnable createRecursivePushTask(final VirtualFile dir, final FilePropertyPusher[] pushers) {
+ if (pushers.length == 0) return null;
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
- if (!fileIndex.isInContent(dir)) return;
- queueTask(new Runnable() {
+ if (!fileIndex.isInContent(dir)) return null;
+ return new Runnable() {
@Override
public void run() {
doPushRecursively(dir, pushers, fileIndex);
}
- });
+ };
}
private void doPushRecursively(VirtualFile dir, final FilePropertyPusher[] pushers, ProjectFileIndex fileIndex) {
@@ -162,8 +176,10 @@ public class PushedFilePropertiesUpdaterImpl extends PushedFilePropertiesUpdater
});
}
- private void queueTask(Runnable action) {
- myTasks.offer(action);
+ private void queueTasks(List<? extends Runnable> actions) {
+ for (Runnable action : actions) {
+ myTasks.offer(action);
+ }
final DumbModeTask task = new DumbModeTask() {
@Override
public void performInDumbMode(@NotNull ProgressIndicator indicator) {
@@ -221,12 +237,12 @@ public class PushedFilePropertiesUpdaterImpl extends PushedFilePropertiesUpdater
@Override
public void pushAll(final FilePropertyPusher... pushers) {
- queueTask(new Runnable() {
+ queueTasks(Arrays.asList(new Runnable() {
@Override
public void run() {
doPushAll(pushers);
}
- });
+ }));
}
private void doPushAll(final FilePropertyPusher[] pushers) {
diff --git a/platform/lang-impl/src/com/intellij/openapi/util/registry/RegistryUi.java b/platform/lang-impl/src/com/intellij/openapi/util/registry/RegistryUi.java
index 0978f8f09ec7..65f2d758fcfd 100644
--- a/platform/lang-impl/src/com/intellij/openapi/util/registry/RegistryUi.java
+++ b/platform/lang-impl/src/com/intellij/openapi/util/registry/RegistryUi.java
@@ -17,6 +17,7 @@
package com.intellij.openapi.util.registry;
import com.intellij.icons.AllIcons;
+import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationInfo;
@@ -27,6 +28,7 @@ import com.intellij.openapi.application.impl.LaterInvocator;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.ShadowAction;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.*;
import com.intellij.ui.table.JBTable;
import com.intellij.util.PlatformIcons;
@@ -54,6 +56,7 @@ import java.util.List;
* @author Konstantin Bulenkov
*/
public class RegistryUi implements Disposable {
+ private static final String RECENT_PROPERTIES_KEY = "RegistryRecentKeys";
private final JBTable myTable;
private final JTextArea myDescriptionLabel;
@@ -143,6 +146,7 @@ public class RegistryUi implements Disposable {
RegistryValue rv = myModel.getRegistryValue(row);
if (rv.isBoolean()) {
rv.setValue(!rv.asBoolean());
+ keyChanged(rv.getKey());
for (int i : new int[]{0, 1, 2}) myModel.fireTableCellUpdated(row, i);
revaliateActions();
if (search.isPopupActive()) search.hidePopup();
@@ -217,10 +221,21 @@ public class RegistryUi implements Disposable {
private MyTableModel() {
myAll = Registry.getAll();
+ final List<String> recent = getRecent();
+
Collections.sort(myAll, new Comparator<RegistryValue>() {
@Override
public int compare(@NotNull RegistryValue o1, @NotNull RegistryValue o2) {
- return o1.getKey().compareTo(o2.getKey());
+ final String key1 = o1.getKey();
+ final String key2 = o2.getKey();
+ final int i1 = recent.indexOf(key1);
+ final int i2 = recent.indexOf(key2);
+ final boolean c1 = i1 != -1;
+ final boolean c2 = i2 != -1;
+ if (c1 && !c2) return -1;
+ if (!c1 && c2) return 1;
+ if (c1 && c2) return i1 - i2;
+ return key1.compareToIgnoreCase(key2);
}
});
}
@@ -264,6 +279,19 @@ public class RegistryUi implements Disposable {
}
}
+ private static List<String> getRecent() {
+ String value = PropertiesComponent.getInstance().getValue(RECENT_PROPERTIES_KEY);
+ return StringUtil.isEmpty(value) ? new ArrayList<String>(0) : StringUtil.split(value, "=");
+ }
+
+ private static void keyChanged(String key) {
+ final List<String> recent = getRecent();
+ recent.remove(key);
+ recent.add(0, key);
+ final String newValue = StringUtil.join(recent, "=");
+ PropertiesComponent.getInstance().setValue(RECENT_PROPERTIES_KEY, newValue);
+ }
+
public boolean show() {
DialogWrapper dialog = new DialogWrapper(true) {
{
@@ -468,6 +496,7 @@ public class RegistryUi implements Disposable {
} else {
myValue.setValue(myField.getText().trim());
}
+ keyChanged(myValue.getKey());
}
revaliateActions();
return super.stopCellEditing();
diff --git a/platform/lang-impl/src/com/intellij/openapi/vcs/checkin/CheckinHandlerUtil.java b/platform/lang-impl/src/com/intellij/openapi/vcs/checkin/CheckinHandlerUtil.java
index 7a6b61f4722b..4a5a644d4fbe 100644
--- a/platform/lang-impl/src/com/intellij/openapi/vcs/checkin/CheckinHandlerUtil.java
+++ b/platform/lang-impl/src/com/intellij/openapi/vcs/checkin/CheckinHandlerUtil.java
@@ -20,6 +20,7 @@ import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ex.ProjectEx;
+import com.intellij.openapi.roots.GeneratedSourcesFilter;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.vfs.VfsUtilCore;
@@ -34,11 +35,22 @@ import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes;
import javax.swing.*;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.List;
/**
* @author oleg
*/
public class CheckinHandlerUtil {
+ public static List<VirtualFile> filterOutGeneratedAndExcludedFiles(@NotNull Collection<VirtualFile> files, @NotNull Project project) {
+ ProjectFileIndex fileIndex = ProjectFileIndex.SERVICE.getInstance(project);
+ List<VirtualFile> result = new ArrayList<VirtualFile>(files.size());
+ for (VirtualFile file : files) {
+ if (!fileIndex.isExcluded(file) && !GeneratedSourcesFilter.isGeneratedSourceByAnyFilter(file, project)) {
+ result.add(file);
+ }
+ }
+ return result;
+ }
public static PsiFile[] getPsiFiles(final Project project, final Collection<VirtualFile> selectedFiles) {
ArrayList<PsiFile> result = new ArrayList<PsiFile>();
diff --git a/platform/lang-impl/src/com/intellij/packageDependencies/actions/AnalyzeDependenciesOnSpecifiedTargetHandler.java b/platform/lang-impl/src/com/intellij/packageDependencies/actions/AnalyzeDependenciesOnSpecifiedTargetHandler.java
index ffc682269563..7aebba7dfe41 100644
--- a/platform/lang-impl/src/com/intellij/packageDependencies/actions/AnalyzeDependenciesOnSpecifiedTargetHandler.java
+++ b/platform/lang-impl/src/com/intellij/packageDependencies/actions/AnalyzeDependenciesOnSpecifiedTargetHandler.java
@@ -36,7 +36,7 @@ import java.util.*;
*/
public class AnalyzeDependenciesOnSpecifiedTargetHandler extends DependenciesHandlerBase {
private static final NotificationGroup NOTIFICATION_GROUP =
- NotificationGroup.toolWindowGroup("Dependencies", ToolWindowId.DEPENDENCIES, true);
+ NotificationGroup.toolWindowGroup("Dependencies", ToolWindowId.DEPENDENCIES);
private final GlobalSearchScope myTargetScope;
public AnalyzeDependenciesOnSpecifiedTargetHandler(@NotNull Project project, @NotNull AnalysisScope scope, @NotNull GlobalSearchScope targetScope) {
diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/InspectionsConfigTreeRenderer.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/InspectionsConfigTreeRenderer.java
index 43b791cbe6a2..280f436b7bc5 100644
--- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/InspectionsConfigTreeRenderer.java
+++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/InspectionsConfigTreeRenderer.java
@@ -27,35 +27,36 @@ import com.intellij.codeInspection.ex.InspectionToolWrapper;
import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;
import com.intellij.ide.ui.search.SearchUtil;
import com.intellij.profile.codeInspection.ui.ToolDescriptors;
-import com.intellij.ui.ColoredTreeCellRenderer;
+import com.intellij.ui.SimpleColoredComponent;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.ui.PlatformColors;
import com.intellij.util.ui.UIUtil;
+import org.jdesktop.swingx.renderer.DefaultTreeRenderer;
import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
-public abstract class InspectionsConfigTreeRenderer extends ColoredTreeCellRenderer {
+public abstract class InspectionsConfigTreeRenderer extends DefaultTreeRenderer {
protected abstract String getFilter();
@Override
- public void customizeCellRenderer(@NotNull final JTree tree,
- final Object value,
- final boolean selected,
- final boolean expanded,
- final boolean leaf,
- final int row,
- final boolean hasFocus) {
- if (!(value instanceof InspectionConfigTreeNode)) return;
+ public Component getTreeCellRendererComponent(JTree tree,
+ Object value,
+ boolean selected,
+ boolean expanded,
+ boolean leaf,
+ int row,
+ boolean hasFocus) {
+ final SimpleColoredComponent component = new SimpleColoredComponent();
+ if (!(value instanceof InspectionConfigTreeNode)) return component;
InspectionConfigTreeNode node = (InspectionConfigTreeNode)value;
Object object = node.getUserObject();
final Color background = selected ? UIUtil.getTreeSelectionBackground() : UIUtil.getTreeTextBackground();
- UIUtil.changeBackGround(this, background);
+ UIUtil.changeBackGround(component, background);
Color foreground =
selected ? UIUtil.getTreeSelectionForeground() : node.isProperSetting() ? PlatformColors.BLUE : UIUtil.getTreeTextForeground();
@@ -75,12 +76,13 @@ public abstract class InspectionsConfigTreeRenderer extends ColoredTreeCellRende
}
if (text != null) {
- SearchUtil.appendFragments(getFilter(), text, style, foreground, background, this);
+ SearchUtil.appendFragments(getFilter(), text, style, foreground, background, component);
}
if (hint != null) {
- append(" " + hint, selected ? new SimpleTextAttributes(Font.PLAIN, foreground) : SimpleTextAttributes.GRAYED_ATTRIBUTES);
+ component.append(" " + hint, selected ? new SimpleTextAttributes(Font.PLAIN, foreground) : SimpleTextAttributes.GRAYED_ATTRIBUTES);
}
- setForeground(foreground);
+ component.setForeground(foreground);
+ return component;
}
@Nullable
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/DocumentCommitThread.java b/platform/lang-impl/src/com/intellij/psi/impl/DocumentCommitThread.java
index 32a2e38384d9..76377ef6b98e 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/DocumentCommitThread.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/DocumentCommitThread.java
@@ -554,22 +554,4 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run
boolean isEnabled() {
return myEnabled;
}
-
- @TestOnly
- public void waitUntilAllCommitted(long timeout) throws InterruptedException {
- if (!myEnabled) {
- throw new IllegalStateException("DocumentCommitThread is disabled");
- }
- int attempts = 0;
- int delay = 100;
- synchronized (documentsToCommit) {
- while(!documentsToCommit.isEmpty() || currentTask != null) {
- documentsToCommit.wait(delay);
- if (delay * attempts > timeout) {
- throw new RuntimeException("timeout");
- }
- attempts++;
- }
- }
- }
}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/file/impl/PsiVFSListener.java b/platform/lang-impl/src/com/intellij/psi/impl/file/impl/PsiVFSListener.java
index 17dd2bca1f17..8b629875209b 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/file/impl/PsiVFSListener.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/file/impl/PsiVFSListener.java
@@ -33,6 +33,7 @@ import com.intellij.openapi.roots.*;
import com.intellij.openapi.roots.impl.PushedFilePropertiesUpdater;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.io.FileUtilRt;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.impl.BulkVirtualFileListenerAdapter;
import com.intellij.psi.*;
@@ -237,7 +238,7 @@ public class PsiVFSListener extends VirtualFileAdapter {
}
}
else {
- if (!isExcludeRoot(vFile) && !myFileTypeManager.isFileIgnored(newName)) {
+ if ((!Registry.is("ide.hide.excluded.files") || !isExcludeRoot(vFile)) && !myFileTypeManager.isFileIgnored(newName)) {
myManager.beforeChildAddition(treeEvent);
}
}
@@ -443,7 +444,8 @@ public class PsiVFSListener extends VirtualFileAdapter {
public void run() {
PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager);
- boolean isExcluded = vFile.isDirectory() && myProjectRootManager.getFileIndex().isExcluded(vFile);
+ boolean isExcluded = vFile.isDirectory() &&
+ Registry.is("ide.hide.excluded.files") && myProjectRootManager.getFileIndex().isExcluded(vFile);
if (oldParentDir != null && !isExcluded) {
if (newParentDir != null) {
treeEvent.setOldParent(oldParentDir);
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java b/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java
index c5b183c3594b..f99d47201a20 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java
@@ -56,20 +56,22 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.TestOnly;
import java.util.*;
-import java.util.concurrent.atomic.AtomicInteger;
public class PostprocessReformattingAspect implements PomModelAspect {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PostprocessReformattingAspect");
private final Project myProject;
private final PsiManager myPsiManager;
private final TreeAspect myTreeAspect;
- private final Map<FileViewProvider, List<ASTNode>> myReformatElements = new HashMap<FileViewProvider, List<ASTNode>>();
- private volatile int myDisabledCounter = 0;
- private final Set<FileViewProvider> myUpdatedProviders = new HashSet<FileViewProvider>();
- private final AtomicInteger myPostponedCounter = new AtomicInteger();
private static final Key<Throwable> REFORMAT_ORIGINATOR = Key.create("REFORMAT_ORIGINATOR");
private static final boolean STORE_REFORMAT_ORIGINATOR_STACKTRACE = ApplicationManager.getApplication().isInternal();
+ private final ThreadLocal<Context> myContext = new ThreadLocal<Context>() {
+ @Override
+ protected Context initialValue() {
+ return new Context();
+ }
+ };
+
public PostprocessReformattingAspect(Project project, PsiManager psiManager, TreeAspect treeAspect,final CommandProcessor processor) {
myProject = project;
myPsiManager = psiManager;
@@ -113,12 +115,12 @@ public class PostprocessReformattingAspect implements PomModelAspect {
public <T> T disablePostprocessFormattingInside(@NotNull Computable<T> computable) {
try {
- myDisabledCounter++;
+ getContext().myDisabledCounter++;
return computable.compute();
}
finally {
- myDisabledCounter--;
- LOG.assertTrue(myDisabledCounter > 0 || !isDisabled());
+ getContext().myDisabledCounter--;
+ LOG.assertTrue(getContext().myDisabledCounter > 0 || !isDisabled());
}
}
@@ -145,13 +147,13 @@ public class PostprocessReformattingAspect implements PomModelAspect {
}
private void incrementPostponedCounter() {
- myPostponedCounter.incrementAndGet();
+ getContext().myPostponedCounter++;
}
private void decrementPostponedCounter() {
Application application = ApplicationManager.getApplication();
application.assertIsDispatchThread();
- if (myPostponedCounter.decrementAndGet() == 0) {
+ if (--getContext().myPostponedCounter == 0) {
if (application.isWriteAccessAllowed()) {
doPostponedFormatting();
}
@@ -175,7 +177,7 @@ public class PostprocessReformattingAspect implements PomModelAspect {
atomic(new Runnable() {
@Override
public void run() {
- if (isDisabled() || myPostponedCounter.get() == 0 && !ApplicationManager.getApplication().isUnitTestMode()) return;
+ if (isDisabled() || getContext().myPostponedCounter == 0 && !ApplicationManager.getApplication().isUnitTestMode()) return;
final TreeChangeEvent changeSet = (TreeChangeEvent)event.getChangeSet(myTreeAspect);
if (changeSet == null) return;
final PsiElement psiElement = changeSet.getRootElement().getPsi();
@@ -184,7 +186,7 @@ public class PostprocessReformattingAspect implements PomModelAspect {
final FileViewProvider viewProvider = containingFile.getViewProvider();
if (!viewProvider.isEventSystemEnabled()) return;
- myUpdatedProviders.add(viewProvider);
+ getContext().myUpdatedProviders.add(viewProvider);
for (final ASTNode node : changeSet.getChangedElements()) {
final TreeChange treeChange = changeSet.getChangesByElement(node);
for (final ASTNode affectedChild : treeChange.getAffectedChildren()) {
@@ -221,7 +223,7 @@ public class PostprocessReformattingAspect implements PomModelAspect {
public void run() {
if (isDisabled()) return;
try {
- FileViewProvider[] viewProviders = myUpdatedProviders.toArray(new FileViewProvider[myUpdatedProviders.size()]);
+ FileViewProvider[] viewProviders = getContext().myUpdatedProviders.toArray(new FileViewProvider[getContext().myUpdatedProviders.size()]);
for (final FileViewProvider viewProvider : viewProviders) {
doPostponedFormatting(viewProvider);
}
@@ -230,7 +232,7 @@ public class PostprocessReformattingAspect implements PomModelAspect {
LOG.error(e);
}
finally {
- LOG.assertTrue(myReformatElements.isEmpty(), myReformatElements);
+ LOG.assertTrue(getContext().myReformatElements.isEmpty(), getContext().myReformatElements);
}
}
});
@@ -248,7 +250,7 @@ public class PostprocessReformattingAspect implements PomModelAspect {
atomic(new Runnable() {
@Override
public void run() {
- if (isDisabled() || check && !myUpdatedProviders.contains(viewProvider)) return;
+ if (isDisabled() || check && !getContext().myUpdatedProviders.contains(viewProvider)) return;
try {
disablePostprocessFormattingInside(new Runnable() {
@@ -259,8 +261,8 @@ public class PostprocessReformattingAspect implements PomModelAspect {
});
}
finally {
- myUpdatedProviders.remove(viewProvider);
- myReformatElements.remove(viewProvider);
+ getContext().myUpdatedProviders.remove(viewProvider);
+ getContext().myReformatElements.remove(viewProvider);
viewProvider.putUserData(REFORMAT_ORIGINATOR, null);
}
}
@@ -268,7 +270,7 @@ public class PostprocessReformattingAspect implements PomModelAspect {
}
public boolean isViewProviderLocked(@NotNull FileViewProvider fileViewProvider) {
- return myReformatElements.containsKey(fileViewProvider);
+ return getContext().myReformatElements.containsKey(fileViewProvider);
}
public void beforeDocumentChanged(@NotNull FileViewProvider viewProvider) {
@@ -292,10 +294,10 @@ public class PostprocessReformattingAspect implements PomModelAspect {
LOG.assertTrue(oldIndent >= 0,
"for not generated items old indentation must be defined: element=" + child + ", text=" + child.getText());
}
- List<ASTNode> list = myReformatElements.get(viewProvider);
+ List<ASTNode> list = getContext().myReformatElements.get(viewProvider);
if (list == null) {
list = new ArrayList<ASTNode>();
- myReformatElements.put(viewProvider, list);
+ getContext().myReformatElements.put(viewProvider, list);
if (STORE_REFORMAT_ORIGINATOR_STACKTRACE) {
viewProvider.putUserData(REFORMAT_ORIGINATOR, new Throwable());
}
@@ -304,7 +306,7 @@ public class PostprocessReformattingAspect implements PomModelAspect {
}
private void doPostponedFormattingInner(@NotNull FileViewProvider key) {
- final List<ASTNode> astNodes = myReformatElements.remove(key);
+ final List<ASTNode> astNodes = getContext().myReformatElements.remove(key);
final Document document = key.getDocument();
// Sort ranges by end offsets so that we won't need any offset adjustment after reformat or reindent
if (document == null) return;
@@ -370,7 +372,7 @@ public class PostprocessReformattingAspect implements PomModelAspect {
String expectedPsi = treeDebugBuilder.psiToString(psi);
if (!expectedPsi.equals(actualPsiTree)) {
- myReformatElements.clear();
+ getContext().myReformatElements.clear();
assert expectedPsi.equals(actualPsiTree) : "Refactored psi should be the same as result of parsing";
}
}
@@ -627,7 +629,7 @@ public class PostprocessReformattingAspect implements PomModelAspect {
}
public boolean isDisabled() {
- return myDisabledCounter > 0;
+ return getContext().myDisabledCounter > 0;
}
@NotNull
@@ -769,6 +771,17 @@ public class PostprocessReformattingAspect implements PomModelAspect {
@TestOnly
public void clear() {
- myReformatElements.clear();
+ getContext().myReformatElements.clear();
+ }
+
+ private Context getContext() {
+ return myContext.get();
+ }
+
+ private static class Context {
+ private int myPostponedCounter = 0;
+ private int myDisabledCounter = 0;
+ private final Set<FileViewProvider> myUpdatedProviders = new HashSet<FileViewProvider>();
+ private final Map<FileViewProvider, List<ASTNode>> myReformatElements = new HashMap<FileViewProvider, List<ASTNode>>();
}
}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java
index d51ef1216a59..a9fbe1b4b988 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java
@@ -58,8 +58,7 @@ import java.util.List;
import java.util.concurrent.TimeUnit;
public class CodeStyleManagerImpl extends CodeStyleManager {
-
- private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.codeStyle.CodeStyleManagerImpl");
+ private static final Logger LOG = Logger.getInstance(CodeStyleManagerImpl.class);
private static final ThreadLocal<ProcessingUnderProgressInfo> SEQUENTIAL_PROCESSING_ALLOWED
= new ThreadLocal<ProcessingUnderProgressInfo>()
{
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleSchemesImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleSchemesImpl.java
index 40ee4adf70f2..b12dee17e9fd 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleSchemesImpl.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleSchemesImpl.java
@@ -13,11 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package com.intellij.psi.impl.source.codeStyle;
import com.intellij.openapi.components.ExportableComponent;
import com.intellij.openapi.components.RoamingType;
+import com.intellij.openapi.components.StoragePathMacros;
import com.intellij.openapi.options.BaseSchemeProcessor;
import com.intellij.openapi.options.SchemeProcessor;
import com.intellij.openapi.options.SchemesManager;
@@ -44,10 +44,10 @@ public abstract class CodeStyleSchemesImpl extends CodeStyleSchemes implements E
public String CURRENT_SCHEME_NAME = DEFAULT_SCHEME_NAME;
private boolean myIsInitialized = false;
- @NonNls static final String CODESTYLES_DIRECTORY = "codestyles";
+ @NonNls static final String CODE_STYLES_DIRECTORY = "codestyles";
private final SchemesManager<CodeStyleScheme, CodeStyleSchemeImpl> mySchemesManager;
- @NonNls private static final String FILE_SPEC = "$ROOT_CONFIG$/" + CODESTYLES_DIRECTORY;
+ @NonNls private static final String FILE_SPEC = StoragePathMacros.ROOT_CONFIG + "/" + CODE_STYLES_DIRECTORY;
public CodeStyleSchemesImpl(SchemesManagerFactory schemesManagerFactory) {
SchemeProcessor<CodeStyleSchemeImpl> processor = new BaseSchemeProcessor<CodeStyleSchemeImpl>() {
@@ -97,6 +97,7 @@ public abstract class CodeStyleSchemesImpl extends CodeStyleSchemes implements E
CURRENT_SCHEME_NAME = schemeName;
}
+ @SuppressWarnings("ForLoopThatDoesntUseLoopVariable")
@Override
public CodeStyleScheme createNewScheme(String preferredName, CodeStyleScheme parentScheme) {
String name;
@@ -154,10 +155,6 @@ public abstract class CodeStyleSchemesImpl extends CodeStyleSchemes implements E
mySchemesManager.addNewScheme(scheme, true);
}
- protected void removeScheme(CodeStyleScheme scheme) {
- mySchemesManager.removeScheme(scheme);
- }
-
protected void init() {
if (myIsInitialized) return;
myIsInitialized = true;
@@ -173,6 +170,4 @@ public abstract class CodeStyleSchemesImpl extends CodeStyleSchemes implements E
public SchemesManager<CodeStyleScheme, CodeStyleSchemeImpl> getSchemesManager() {
return mySchemesManager;
}
-
-
}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/PersistableCodeStyleSchemes.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/PersistableCodeStyleSchemes.java
index 3e2acf553815..e3f4fb760fbf 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/PersistableCodeStyleSchemes.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/PersistableCodeStyleSchemes.java
@@ -18,8 +18,6 @@ package com.intellij.psi.impl.source.codeStyle;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.components.*;
import com.intellij.openapi.options.SchemesManagerFactory;
-import com.intellij.openapi.ui.Messages;
-import com.intellij.psi.PsiBundle;
import com.intellij.psi.codeStyle.CodeStyleScheme;
import com.intellij.util.xmlb.Accessor;
import com.intellij.util.xmlb.SerializationFilter;
@@ -99,23 +97,7 @@ public class PersistableCodeStyleSchemes extends CodeStyleSchemesImpl implements
@Override
@NotNull
public File[] getExportFiles() {
- File schemesFile = new File(PathManager.getOptionsPath() + File.separator + CODE_STYLE_SCHEMES_FILE);
- return new File[]{getDir(true), schemesFile};
+ return new File[]{new File(PathManager.getConfigPath() + File.separator + CODE_STYLES_DIRECTORY),
+ new File(PathManager.getOptionsPath() + File.separator + CODE_STYLE_SCHEMES_FILE)};
}
-
- @Nullable
- private static File getDir(boolean create) {
- String directoryPath = PathManager.getConfigPath() + File.separator + CODESTYLES_DIRECTORY;
- File directory = new File(directoryPath);
- if (!directory.exists()) {
- if (!create) return null;
- if (!directory.mkdir()) {
- Messages.showErrorDialog(PsiBundle.message("codestyle.cannot.save.settings.directory.cant.be.created.message", directoryPath),
- PsiBundle.message("codestyle.cannot.save.settings.directory.cant.be.created.title"));
- return null;
- }
- }
- return directory;
- }
-
}
diff --git a/platform/lang-impl/src/com/intellij/psi/stubs/StubIndexState.java b/platform/lang-impl/src/com/intellij/psi/stubs/StubIndexState.java
index 53785b7b6fda..2acd63308b48 100644
--- a/platform/lang-impl/src/com/intellij/psi/stubs/StubIndexState.java
+++ b/platform/lang-impl/src/com/intellij/psi/stubs/StubIndexState.java
@@ -19,6 +19,8 @@
*/
package com.intellij.psi.stubs;
+import org.jetbrains.annotations.NotNull;
+
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -29,9 +31,9 @@ public class StubIndexState {
public StubIndexState() {
}
- public StubIndexState(Collection<StubIndexKey<?, ?>> keys) {
+ public StubIndexState(@NotNull Collection<StubIndexKey<?, ?>> keys) {
for (StubIndexKey key : keys) {
registeredIndices.add(key.toString());
}
}
-} \ No newline at end of file
+}
diff --git a/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java b/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java
index f83dcfe4788f..93921cd6c1dc 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java
@@ -431,8 +431,14 @@ public abstract class BaseRefactoringProcessor implements Runnable {
final Runnable prepareHelpersRunnable = new Runnable() {
@Override
public void run() {
- for (RefactoringHelper helper : Extensions.getExtensions(RefactoringHelper.EP_NAME)) {
- preparedData.put(helper, helper.prepareOperation(writableUsageInfos));
+ for (final RefactoringHelper helper : Extensions.getExtensions(RefactoringHelper.EP_NAME)) {
+ Object operation = ApplicationManager.getApplication().runReadAction(new Computable<Object>() {
+ @Override
+ public Object compute() {
+ return helper.prepareOperation(writableUsageInfos);
+ }
+ });
+ preparedData.put(helper, operation);
}
}
};
diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/RenameProcessor.java b/platform/lang-impl/src/com/intellij/refactoring/rename/RenameProcessor.java
index a34d30dc5401..dd20f5a7d3e7 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/rename/RenameProcessor.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/rename/RenameProcessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@ import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.IdeFrame;
@@ -184,9 +185,14 @@ public class RenameProcessor extends BaseRefactoringProcessor {
final Runnable runnable = new Runnable() {
@Override
public void run() {
- for (Map.Entry<PsiElement, String> entry : renames.entrySet()) {
+ for (final Map.Entry<PsiElement, String> entry : renames.entrySet()) {
final UsageInfo[] usages =
- RenameUtil.findUsages(entry.getKey(), entry.getValue(), mySearchInComments, mySearchTextOccurrences, myAllRenames);
+ ApplicationManager.getApplication().runReadAction(new Computable<UsageInfo[]>() {
+ @Override
+ public UsageInfo[] compute() {
+ return RenameUtil.findUsages(entry.getKey(), entry.getValue(), mySearchInComments, mySearchTextOccurrences, myAllRenames);
+ }
+ });
Collections.addAll(variableUsages, usages);
}
}
@@ -223,9 +229,14 @@ public class RenameProcessor extends BaseRefactoringProcessor {
final Runnable runnable = new Runnable() {
@Override
public void run() {
- for (final AutomaticRenamer renamer : myRenamers) {
- renamer.findUsages(variableUsages, mySearchInComments, mySearchTextOccurrences, mySkippedUsages, myAllRenames);
- }
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ @Override
+ public void run() {
+ for (final AutomaticRenamer renamer : myRenamers) {
+ renamer.findUsages(variableUsages, mySearchInComments, mySearchTextOccurrences, mySkippedUsages, myAllRenames);
+ }
+ }
+ });
}
};
diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java
index 6fa0ed27d8c8..0f9011308533 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -245,7 +245,12 @@ public class VariableInplaceRenamer extends InplaceRefactoring {
final Runnable runnable = new Runnable() {
@Override
public void run() {
- renamer.findUsages(usages, false, false);
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ @Override
+ public void run() {
+ renamer.findUsages(usages, false, false);
+ }
+ });
}
};
diff --git a/platform/lang-impl/src/com/intellij/semantic/SemServiceImpl.java b/platform/lang-impl/src/com/intellij/semantic/SemServiceImpl.java
index 102a439e11f8..1624c48f2ae5 100644
--- a/platform/lang-impl/src/com/intellij/semantic/SemServiceImpl.java
+++ b/platform/lang-impl/src/com/intellij/semantic/SemServiceImpl.java
@@ -17,8 +17,6 @@ package com.intellij.semantic;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.project.ProjectManager;
-import com.intellij.openapi.project.ProjectManagerAdapter;
import com.intellij.openapi.util.LowMemoryWatcher;
import com.intellij.openapi.util.RecursionGuard;
import com.intellij.openapi.util.RecursionManager;
@@ -83,7 +81,7 @@ public class SemServiceImpl extends SemService{
});
- final LowMemoryWatcher watcher = LowMemoryWatcher.register(new Runnable() {
+ LowMemoryWatcher.register(new Runnable() {
@Override
public void run() {
if (myCreatingSem.get() == 0) {
@@ -91,13 +89,7 @@ public class SemServiceImpl extends SemService{
}
//System.out.println("SemService cache flushed");
}
- });
- ProjectManager.getInstance().addProjectManagerListener(project, new ProjectManagerAdapter() {
- @Override
- public void projectClosing(Project project) {
- watcher.stop();
- }
- });
+ }, project);
}
private static MultiMap<SemKey, SemKey> cacheKeyHierarchy(Collection<SemKey> allKeys) {
diff --git a/platform/lang-impl/src/com/intellij/tools/ToolConfigurable.java b/platform/lang-impl/src/com/intellij/tools/ToolConfigurable.java
index 0f39ab8a176c..e410895b087e 100644
--- a/platform/lang-impl/src/com/intellij/tools/ToolConfigurable.java
+++ b/platform/lang-impl/src/com/intellij/tools/ToolConfigurable.java
@@ -35,14 +35,18 @@ public class ToolConfigurable implements SearchableConfigurable, Configurable.No
@Override
public JComponent createComponent() {
- myPanel = new ToolsPanel();
+ if (myPanel == null) {
+ myPanel = new ToolsPanel();
+ }
return myPanel;
}
@Override
public void apply() throws ConfigurationException {
try {
- myPanel.apply();
+ if (myPanel != null) {
+ myPanel.apply();
+ }
}
catch (IOException e) {
throw new ConfigurationException(e.getMessage());
@@ -51,12 +55,14 @@ public class ToolConfigurable implements SearchableConfigurable, Configurable.No
@Override
public boolean isModified() {
- return myPanel.isModified();
+ return myPanel != null && myPanel.isModified();
}
@Override
public void reset() {
- myPanel.reset();
+ if (myPanel != null) {
+ myPanel.reset();
+ }
}
@Override
@@ -73,7 +79,7 @@ public class ToolConfigurable implements SearchableConfigurable, Configurable.No
@Override
@NotNull
public String getId() {
- return getHelpTopic();
+ return "preferences.externalTools";
}
@Override
diff --git a/platform/lang-impl/src/com/intellij/tools/ToolManager.java b/platform/lang-impl/src/com/intellij/tools/ToolManager.java
index 59a17bea67ed..0722090527bb 100644
--- a/platform/lang-impl/src/com/intellij/tools/ToolManager.java
+++ b/platform/lang-impl/src/com/intellij/tools/ToolManager.java
@@ -17,6 +17,7 @@ package com.intellij.tools;
import com.intellij.openapi.actionSystem.ex.ActionManagerEx;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.components.StoragePathMacros;
import com.intellij.openapi.options.SchemeProcessor;
import com.intellij.openapi.options.SchemesManagerFactory;
import org.jetbrains.annotations.NotNull;
@@ -32,7 +33,7 @@ public class ToolManager extends BaseToolManager<Tool> {
@Override
protected String getSchemesPath() {
- return "$ROOT_CONFIG$/tools";
+ return StoragePathMacros.ROOT_CONFIG + "/tools";
}
@Override
diff --git a/platform/lang-impl/src/com/intellij/ui/JBTableWithHintProvider.java b/platform/lang-impl/src/com/intellij/ui/JBTableWithHintProvider.java
index f31de9281ea4..750331f1e49a 100644
--- a/platform/lang-impl/src/com/intellij/ui/JBTableWithHintProvider.java
+++ b/platform/lang-impl/src/com/intellij/ui/JBTableWithHintProvider.java
@@ -17,66 +17,53 @@ package com.intellij.ui;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.psi.PsiElement;
-import com.intellij.ui.popup.PopupUpdateProcessor;
+import com.intellij.ui.popup.HintUpdateSupply;
import com.intellij.ui.table.JBTable;
+import com.intellij.util.ObjectUtils;
-import javax.swing.*;
-import javax.swing.event.ListSelectionEvent;
-import javax.swing.event.ListSelectionListener;
+import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
+/**
+ * @deprecated
+ * @see com.intellij.ui.popup.HintUpdateSupply
+ */
public abstract class JBTableWithHintProvider extends JBTable {
- private JBPopup myHint;
+
+ {
+ new HintUpdateSupply(this) {
+ @Override
+ protected PsiElement getPsiElementForHint(Object selectedValue) {
+ return JBTableWithHintProvider.this.getPsiElementForHint(selectedValue);
+ }
+ };
+ }
public JBTableWithHintProvider() {
- addSelectionListener();
}
protected JBTableWithHintProvider(TableModel model) {
super(model);
}
- private void addSelectionListener() {
- getSelectionModel().addListSelectionListener(new ListSelectionListener() {
- @Override
- public void valueChanged(final ListSelectionEvent e) {
- if (getClientProperty(ListUtil.SELECTED_BY_MOUSE_EVENT) != Boolean.TRUE) {
-
- final int selected = ((ListSelectionModel)e.getSource()).getLeadSelectionIndex();
- int rowCount = getRowCount();
- if (selected == -1 || rowCount == 0) return;
-
- PsiElement element = getPsiElementForHint(getValueAt(Math.min(selected, rowCount -1), 0));
- if (element != null && element.isValid()) {
- updateHint(element);
- }
- }
- }
- });
+ public JBTableWithHintProvider(TableModel model, TableColumnModel columnModel) {
+ super(model, columnModel);
}
protected abstract PsiElement getPsiElementForHint(final Object selectedValue);
- public void registerHint(final JBPopup hint) {
- hideHint();
- myHint = hint;
+ @Deprecated
+ public void registerHint(JBPopup hint) {
+ ObjectUtils.assertNotNull(HintUpdateSupply.getSupply(this)).registerHint(hint);
}
-
- public void hideHint() {
- if (myHint != null && myHint.isVisible()) {
- myHint.cancel();
- }
- myHint = null;
+ @Deprecated
+ public void hideHint() {
+ ObjectUtils.assertNotNull(HintUpdateSupply.getSupply(this)).hideHint();
}
-
- public void updateHint(PsiElement element) {
- if (myHint == null || !myHint.isVisible()) return;
- final PopupUpdateProcessor updateProcessor = myHint.getUserData(PopupUpdateProcessor.class);
- if (updateProcessor != null) {
- updateProcessor.updatePopup(element);
- }
+ @Deprecated
+ public void updateHint(PsiElement element) {
+ ObjectUtils.assertNotNull(HintUpdateSupply.getSupply(this)).updateHint(element);
}
-
}
diff --git a/platform/lang-impl/src/com/intellij/ui/JBTreeWithHintProvider.java b/platform/lang-impl/src/com/intellij/ui/JBTreeWithHintProvider.java
index c22eeb16127f..023ed3998829 100644
--- a/platform/lang-impl/src/com/intellij/ui/JBTreeWithHintProvider.java
+++ b/platform/lang-impl/src/com/intellij/ui/JBTreeWithHintProvider.java
@@ -18,84 +18,58 @@ package com.intellij.ui;
import com.intellij.ide.DataManager;
import com.intellij.ide.dnd.aware.DnDAwareTree;
import com.intellij.openapi.actionSystem.CommonDataKeys;
-import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.psi.PsiElement;
-import com.intellij.ui.popup.PopupUpdateProcessor;
+import com.intellij.ui.popup.HintUpdateSupply;
+import com.intellij.util.ObjectUtils;
import org.jetbrains.annotations.Nullable;
-import javax.swing.event.TreeSelectionEvent;
-import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreeNode;
-import javax.swing.tree.TreePath;
/**
* @author Konstantin Bulenkov
+ * @deprecated
+ * @see com.intellij.ui.popup.HintUpdateSupply
*/
public class JBTreeWithHintProvider extends DnDAwareTree {
- private JBPopup myHint;
+ {
+ new HintUpdateSupply(this) {
+ @Override
+ protected PsiElement getPsiElementForHint(Object selectedValue) {
+ return JBTreeWithHintProvider.this.getPsiElementForHint(selectedValue);
+ }
+ };
+ }
public JBTreeWithHintProvider() {
- addSelectionListener();
}
public JBTreeWithHintProvider(TreeModel treemodel) {
super(treemodel);
- addSelectionListener();
}
public JBTreeWithHintProvider(TreeNode root) {
super(root);
- addSelectionListener();
- }
-
- private void addSelectionListener() {
- addTreeSelectionListener(new TreeSelectionListener() {
- @Override
- public void valueChanged(final TreeSelectionEvent e) {
- if (isHintBeingShown() && getClientProperty(ListUtil.SELECTED_BY_MOUSE_EVENT) != Boolean.TRUE) {
- final TreePath path = getSelectionPath();
- if (path != null) {
- final PsiElement psiElement = getPsiElementForHint(path.getLastPathComponent());
- if (psiElement != null && psiElement.isValid()) {
- updateHint(psiElement);
- }
- }
- }
- }
- });
}
@Nullable
protected PsiElement getPsiElementForHint(final Object selectedValue) {
- // default implementation
return CommonDataKeys.PSI_ELEMENT.getData(DataManager.getInstance().getDataContext(this));
}
- public void registerHint(final JBPopup hint) {
- hideHint();
- myHint = hint;
+ @Deprecated
+ public void registerHint(JBPopup hint) {
+ ObjectUtils.assertNotNull(HintUpdateSupply.getSupply(this)).registerHint(hint);
}
+ @Deprecated
public void hideHint() {
- if (isHintBeingShown()) {
- myHint.cancel();
- }
-
- myHint = null;
+ ObjectUtils.assertNotNull(HintUpdateSupply.getSupply(this)).hideHint();
}
+ @Deprecated
public void updateHint(PsiElement element) {
- if (!isHintBeingShown()) return;
-
- final PopupUpdateProcessor updateProcessor = myHint.getUserData(PopupUpdateProcessor.class);
- if (updateProcessor != null) {
- updateProcessor.updatePopup(element);
- }
- }
-
- private boolean isHintBeingShown() {
- return myHint != null && myHint.isVisible();
+ ObjectUtils.assertNotNull(HintUpdateSupply.getSupply(this)).updateHint(element);
}
}
diff --git a/platform/lang-impl/src/com/intellij/ui/popup/PopupUpdateProcessor.java b/platform/lang-impl/src/com/intellij/ui/popup/PopupUpdateProcessor.java
index f02111c5ee11..d5b5bdf09194 100644
--- a/platform/lang-impl/src/com/intellij/ui/popup/PopupUpdateProcessor.java
+++ b/platform/lang-impl/src/com/intellij/ui/popup/PopupUpdateProcessor.java
@@ -24,10 +24,8 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.LightweightWindowEvent;
import com.intellij.openapi.wm.ex.WindowManagerEx;
import com.intellij.psi.PsiElement;
-import com.intellij.ui.JBListWithHintProvider;
-import com.intellij.ui.JBTableWithHintProvider;
-import com.intellij.ui.JBTreeWithHintProvider;
+import javax.swing.*;
import java.awt.*;
/**
@@ -39,7 +37,6 @@ public abstract class PopupUpdateProcessor extends PopupUpdateProcessorBase {
protected PopupUpdateProcessor(Project project) {
myProject = project;
-
}
@Override
@@ -71,14 +68,10 @@ public abstract class PopupUpdateProcessor extends PopupUpdateProcessorBase {
if (fromQuickSearch) {
ChooseByNameBase.JPanelProvider panelProvider = (ChooseByNameBase.JPanelProvider)focusedComponent.getParent();
panelProvider.registerHint(windowEvent.asPopup());
- } else if (focusedComponent != null) {
- if (focusedComponent instanceof JBListWithHintProvider) {
- ((JBListWithHintProvider)focusedComponent).registerHint(windowEvent.asPopup());
- } else if (focusedComponent instanceof JBTableWithHintProvider) {
- ((JBTableWithHintProvider)focusedComponent).registerHint(windowEvent.asPopup());
- } else if (focusedComponent instanceof JBTreeWithHintProvider) {
- ((JBTreeWithHintProvider)focusedComponent).registerHint(windowEvent.asPopup());
- }
+ }
+ else if (focusedComponent instanceof JComponent) {
+ HintUpdateSupply supply = HintUpdateSupply.getSupply((JComponent)focusedComponent);
+ if (supply != null) supply.registerHint(windowEvent.asPopup());
}
}
}
diff --git a/platform/lang-impl/src/com/intellij/usageView/UsageViewUtil.java b/platform/lang-impl/src/com/intellij/usageView/UsageViewUtil.java
index 4dee56707ae0..eb06160d4280 100644
--- a/platform/lang-impl/src/com/intellij/usageView/UsageViewUtil.java
+++ b/platform/lang-impl/src/com/intellij/usageView/UsageViewUtil.java
@@ -167,7 +167,9 @@ public class UsageViewUtil {
int offset = info.getNavigationOffset();
VirtualFile file = info.getVirtualFile();
Project project = info.getProject();
- FileEditorManager.getInstance(project).openTextEditor(new OpenFileDescriptor(project, file, offset), requestFocus);
+ if (file != null) {
+ FileEditorManager.getInstance(project).openTextEditor(new OpenFileDescriptor(project, file, offset), requestFocus);
+ }
}
public static Set<UsageInfo> getNotExcludedUsageInfos(final UsageView usageView) {
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
index da85132806e5..019b3172817f 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
@@ -1727,7 +1727,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
}
private static void cleanFileContent(@NotNull FileContentImpl fc, PsiFile psiFile) {
- if (psiFile != null) psiFile.putUserData(PsiFileImpl.BUILDING_STUB, false);
+ if (psiFile != null) psiFile.putUserData(PsiFileImpl.BUILDING_STUB, null);
fc.putUserData(IndexingDataKeys.PSI_FILE, null);
}
diff --git a/platform/lang-impl/src/com/intellij/webcore/packaging/ManagePackagesDialog.java b/platform/lang-impl/src/com/intellij/webcore/packaging/ManagePackagesDialog.java
index fcbaa21f330b..f66982282fa0 100644
--- a/platform/lang-impl/src/com/intellij/webcore/packaging/ManagePackagesDialog.java
+++ b/platform/lang-impl/src/com/intellij/webcore/packaging/ManagePackagesDialog.java
@@ -419,7 +419,7 @@ public class ManagePackagesDialog extends DialogWrapper {
else {
myFilteredOut.add(repoPackage);
}
- if (StringUtil.equals(packageName, filter)) toSelect = repoPackage;
+ if (StringUtil.equalsIgnoreCase(packageName, filter)) toSelect = repoPackage;
}
filter(filtered, toSelect);
}
diff --git a/platform/platform-api/platform-api.iml b/platform/platform-api/platform-api.iml
index 127cfb114b38..38016f147d1a 100644
--- a/platform/platform-api/platform-api.iml
+++ b/platform/platform-api/platform-api.iml
@@ -14,7 +14,7 @@
<orderEntry type="module" module-name="bootstrap" />
<orderEntry type="library" exported="" name="jgoodies-forms" level="project" />
<orderEntry type="module" module-name="forms_rt" exported="" />
- <orderEntry type="library" exported="" name="commons-codec" level="project" />
+ <orderEntry type="library" name="commons-codec" level="project" />
<orderEntry type="module" module-name="platform-resources-en" exported="" />
<orderEntry type="library" name="OroMatcher" level="project" />
<orderEntry type="module" module-name="icons" />
diff --git a/platform/platform-api/src/com/intellij/execution/configurations/GeneralCommandLine.java b/platform/platform-api/src/com/intellij/execution/configurations/GeneralCommandLine.java
index 939680ea372a..93a3caf6efd9 100644
--- a/platform/platform-api/src/com/intellij/execution/configurations/GeneralCommandLine.java
+++ b/platform/platform-api/src/com/intellij/execution/configurations/GeneralCommandLine.java
@@ -197,6 +197,10 @@ public class GeneralCommandLine implements UserDataHolder {
* @return single-string representation of this command line.
*/
public String getCommandLineString(@Nullable final String exeName) {
+ return ParametersList.join(getCommandLineList(exeName));
+ }
+
+ public List<String> getCommandLineList(@Nullable final String exeName) {
final List<String> commands = new ArrayList<String>();
if (exeName != null) {
commands.add(exeName);
@@ -208,7 +212,7 @@ public class GeneralCommandLine implements UserDataHolder {
commands.add("<null>");
}
commands.addAll(myProgramParams.getList());
- return ParametersList.join(commands);
+ return commands;
}
/**
@@ -224,6 +228,7 @@ public class GeneralCommandLine implements UserDataHolder {
return StringUtil.join(CommandLineUtil.toCommandLine(exePath, myProgramParams.getList(), platform), "\n");
}
+ @NotNull
public Process createProcess() throws ExecutionException {
if (LOG.isDebugEnabled()) {
LOG.debug("Executing [" + getCommandLineString() + "]");
@@ -253,6 +258,7 @@ public class GeneralCommandLine implements UserDataHolder {
}
}
+ @NotNull
protected Process startProcess(@NotNull List<String> commands) throws IOException {
ProcessBuilder builder = new ProcessBuilder(commands);
setupEnvironment(builder.environment());
diff --git a/platform/platform-api/src/com/intellij/execution/configurations/PathEnvironmentVariableUtil.java b/platform/platform-api/src/com/intellij/execution/configurations/PathEnvironmentVariableUtil.java
index 7e879f496c1b..bab90cfcd9b5 100644
--- a/platform/platform-api/src/com/intellij/execution/configurations/PathEnvironmentVariableUtil.java
+++ b/platform/platform-api/src/com/intellij/execution/configurations/PathEnvironmentVariableUtil.java
@@ -24,6 +24,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
+import java.io.FileFilter;
import java.util.Collections;
import java.util.List;
@@ -51,6 +52,19 @@ public class PathEnvironmentVariableUtil {
/**
* Finds an executable file with the specified base name, that is located in a directory
+ * listed in PATH environment variable and is accepted by filter.
+ *
+ * @param fileBaseName file base name
+ * @param filter exe file filter
+ * @return {@code File} instance or null if not found
+ */
+ @Nullable
+ public static File findInPath(@NotNull String fileBaseName, @Nullable FileFilter filter) {
+ return findInPath(fileBaseName, false, filter);
+ }
+
+ /**
+ * Finds an executable file with the specified base name, that is located in a directory
* listed in PATH environment variable.
*
* @param fileBaseName file base name
@@ -59,7 +73,12 @@ public class PathEnvironmentVariableUtil {
*/
@Nullable
public static File findInPath(@NotNull String fileBaseName, boolean logDetails) {
- List<File> exeFiles = findExeFilesInPath(fileBaseName, true, logDetails);
+ return findInPath(fileBaseName, logDetails, null);
+ }
+
+ @Nullable
+ private static File findInPath(@NotNull String fileBaseName, boolean logDetails, @Nullable FileFilter filter) {
+ List<File> exeFiles = findExeFilesInPath(fileBaseName, true, logDetails, filter);
return exeFiles.size() > 0 ? exeFiles.get(0) : null;
}
@@ -79,7 +98,7 @@ public class PathEnvironmentVariableUtil {
else {
originalPath = EnvironmentUtil.getValue(PATH_ENV_VAR_NAME);
}
- List<File> exeFiles = doFindExeFilesInPath(originalPath, fileBaseName, true, false);
+ List<File> exeFiles = doFindExeFilesInPath(originalPath, fileBaseName, true, false, null);
return exeFiles.size() > 0 ? exeFiles.get(0) : null;
}
@@ -92,22 +111,29 @@ public class PathEnvironmentVariableUtil {
*/
@NotNull
public static List<File> findAllExeFilesInPath(@NotNull String fileBaseName) {
- return findExeFilesInPath(fileBaseName, false, false);
+ return findAllExeFilesInPath(fileBaseName, null);
+ }
+
+ @NotNull
+ public static List<File> findAllExeFilesInPath(@NotNull String fileBaseName, @Nullable FileFilter filter) {
+ return findExeFilesInPath(fileBaseName, false, false, filter);
}
@NotNull
private static List<File> findExeFilesInPath(@NotNull String fileBaseName,
boolean stopAfterFirstMatch,
- boolean logDetails) {
+ boolean logDetails,
+ @Nullable FileFilter filter) {
String systemPath = EnvironmentUtil.getValue(PATH_ENV_VAR_NAME);
- return doFindExeFilesInPath(systemPath, fileBaseName, stopAfterFirstMatch, logDetails);
+ return doFindExeFilesInPath(systemPath, fileBaseName, stopAfterFirstMatch, logDetails, filter);
}
@NotNull
private static List<File> doFindExeFilesInPath(@Nullable String pathEnvVarValue,
@NotNull String fileBaseName,
boolean stopAfterFirstMatch,
- boolean logDetails) {
+ boolean logDetails,
+ @Nullable FileFilter filter) {
if (logDetails) {
LOG.info("Finding files in PATH (base name=" + fileBaseName + ", PATH=" + StringUtil.notNullize(pathEnvVarValue) + ").");
}
@@ -124,11 +150,13 @@ public class PathEnvironmentVariableUtil {
+ ", file.isFile:" + file.isFile() + ", file.canExecute:" + file.canExecute());
}
if (dir.isAbsolute() && dir.isDirectory()) {
- File file = new File(dir, fileBaseName);
- if (file.isFile() && file.canExecute()) {
- result.add(file);
- if (stopAfterFirstMatch) {
- return result;
+ File exeFile = new File(dir, fileBaseName);
+ if (exeFile.isFile() && exeFile.canExecute()) {
+ if (filter == null || filter.accept(exeFile)) {
+ result.add(exeFile);
+ if (stopAfterFirstMatch) {
+ return result;
+ }
}
}
}
diff --git a/platform/platform-api/src/com/intellij/execution/configurations/PtyCommandLine.java b/platform/platform-api/src/com/intellij/execution/configurations/PtyCommandLine.java
index 5e3d74caa1f6..182d347de4c1 100644
--- a/platform/platform-api/src/com/intellij/execution/configurations/PtyCommandLine.java
+++ b/platform/platform-api/src/com/intellij/execution/configurations/PtyCommandLine.java
@@ -37,6 +37,7 @@ public class PtyCommandLine extends GeneralCommandLine {
public PtyCommandLine() { }
+ @NotNull
@Override
protected Process startProcess(@NotNull List<String> commands) throws IOException {
if (SystemInfo.isUnix) {
diff --git a/platform/platform-api/src/com/intellij/execution/process/AnsiEscapeDecoder.java b/platform/platform-api/src/com/intellij/execution/process/AnsiEscapeDecoder.java
index 58a8e40db2d6..67c4af413e74 100644
--- a/platform/platform-api/src/com/intellij/execution/process/AnsiEscapeDecoder.java
+++ b/platform/platform-api/src/com/intellij/execution/process/AnsiEscapeDecoder.java
@@ -17,6 +17,7 @@ package com.intellij.execution.process;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -59,11 +60,13 @@ public class AnsiEscapeDecoder {
if (escSeqEndInd < 0) {
break;
}
- String escSeq = text.substring(escSeqBeginInd, escSeqEndInd);
- // this is a simple fix for RUBY-8996:
- // we replace several consecutive escape sequences with one which contains all these sequences
- String colorAttribute = INNER_PATTERN.matcher(escSeq).replaceAll(";");
- myCurrentTextAttributes = ColoredOutputTypeRegistry.getInstance().getOutputKey(colorAttribute);
+ if (text.charAt(escSeqEndInd - 1) == 'm') {
+ String escSeq = text.substring(escSeqBeginInd, escSeqEndInd);
+ // this is a simple fix for RUBY-8996:
+ // we replace several consecutive escape sequences with one which contains all these sequences
+ String colorAttribute = INNER_PATTERN.matcher(escSeq).replaceAll(";");
+ myCurrentTextAttributes = ColoredOutputTypeRegistry.getInstance().getOutputKey(colorAttribute);
+ }
pos = escSeqEndInd;
}
if (pos < text.length()) {
@@ -78,16 +81,41 @@ public class AnsiEscapeDecoder {
* Selects all consecutive escape sequences and returns escape sequence end index (exclusive).
* If the escape sequence isn't finished, returns -1.
*/
- private static int findEscSeqEndIndex(@NotNull String text, int escSeqBeginInd) {
- escSeqBeginInd = text.indexOf('m', escSeqBeginInd);
- while (escSeqBeginInd >= 0) {
- escSeqBeginInd++;
- if (!text.regionMatches(escSeqBeginInd, CSI, 0, CSI.length())) {
+ private static int findEscSeqEndIndex(@NotNull String text, final int escSeqBeginInd) {
+ int beginInd = escSeqBeginInd;
+ while (true) {
+ int letterInd = findEscSeqLetterIndex(text, beginInd);
+ if (letterInd == -1) {
+ return beginInd == escSeqBeginInd ? -1 : beginInd;
+ }
+ if (text.charAt(letterInd) != 'm') {
+ return beginInd == escSeqBeginInd ? letterInd + 1 : beginInd;
+ }
+ beginInd = letterInd + 1;
+ }
+ }
+
+ private static int findEscSeqLetterIndex(@NotNull String text, int escSeqBeginInd) {
+ if (!text.regionMatches(escSeqBeginInd, CSI, 0, CSI.length())) {
+ return -1;
+ }
+ int parameterEndInd = escSeqBeginInd + 2;
+ while (parameterEndInd < text.length()) {
+ char ch = text.charAt(parameterEndInd);
+ if (Character.isDigit(ch) || ch == ';') {
+ parameterEndInd++;
+ }
+ else {
break;
}
- escSeqBeginInd = text.indexOf('m', escSeqBeginInd);
}
- return escSeqBeginInd;
+ if (parameterEndInd < text.length()) {
+ char letter = text.charAt(parameterEndInd);
+ if (StringUtil.containsChar("ABCDEFGHJKSTfmisu", letter)) {
+ return parameterEndInd;
+ }
+ }
+ return -1;
}
@Nullable
diff --git a/platform/platform-api/src/com/intellij/ide/UiActivity.java b/platform/platform-api/src/com/intellij/ide/UiActivity.java
index 9066837fb0a8..49fcd1a74ada 100644
--- a/platform/platform-api/src/com/intellij/ide/UiActivity.java
+++ b/platform/platform-api/src/com/intellij/ide/UiActivity.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,13 +26,13 @@ import java.util.List;
public class UiActivity implements ComparableObject{
- private List<String> myElements = new ArrayList<String>();
+ private final List<String> myElements = new ArrayList<String>();
- public UiActivity(String ... elements) {
+ public UiActivity(@NotNull String ... elements) {
this(elements, null);
}
- protected UiActivity(String[] elements1, @Nullable String[] elements2) {
+ protected UiActivity(@NotNull String[] elements1, @Nullable String[] elements2) {
myElements.addAll(Arrays.asList(elements1));
if (elements2 != null) {
myElements.addAll(Arrays.asList(elements2));
diff --git a/platform/platform-api/src/com/intellij/ide/UiActivityMonitor.java b/platform/platform-api/src/com/intellij/ide/UiActivityMonitor.java
index 8591383dc6d5..3ecb5727cc30 100644
--- a/platform/platform-api/src/com/intellij/ide/UiActivityMonitor.java
+++ b/platform/platform-api/src/com/intellij/ide/UiActivityMonitor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,10 +22,11 @@ import com.intellij.openapi.util.BusyObject;
import org.jetbrains.annotations.NotNull;
public abstract class UiActivityMonitor {
+ @NotNull
+ public abstract BusyObject getBusy(@NotNull Project project, @NotNull UiActivity ... toWatch);
- public abstract BusyObject getBusy(@NotNull Project project, UiActivity ... toWatch);
-
- public abstract BusyObject getBusy(UiActivity ... toWatch);
+ @NotNull
+ public abstract BusyObject getBusy(@NotNull UiActivity ... toWatch);
public abstract void addActivity(@NotNull Project project, @NotNull UiActivity activity);
diff --git a/platform/platform-api/src/com/intellij/ide/browsers/BrowserLauncherAppless.java b/platform/platform-api/src/com/intellij/ide/browsers/BrowserLauncherAppless.java
index 736dcd8afe22..c5843b3d53c8 100644
--- a/platform/platform-api/src/com/intellij/ide/browsers/BrowserLauncherAppless.java
+++ b/platform/platform-api/src/com/intellij/ide/browsers/BrowserLauncherAppless.java
@@ -127,6 +127,7 @@ public class BrowserLauncherAppless extends BrowserLauncher {
GeneralSettings settings = getGeneralSettingsInstance();
if (settings.isUseDefaultBrowser()) {
+ boolean tryToUseCli = true;
if (isDesktopActionSupported(Desktop.Action.BROWSE)) {
try {
Desktop.getDesktop().browse(uri);
@@ -135,13 +136,17 @@ public class BrowserLauncherAppless extends BrowserLauncher {
}
catch (Exception e) {
LOG.warn("Error while using Desktop API, fallback to CLI", e);
+ // if "No application knows how to open", then we must not try to use OS open
+ tryToUseCli = !e.getMessage().contains("Error code: -10814");
}
}
- List<String> command = getDefaultBrowserCommand();
- if (command != null) {
- doLaunch(uri.toString(), command, null, project, ArrayUtil.EMPTY_STRING_ARRAY, null);
- return;
+ if (tryToUseCli) {
+ List<String> command = getDefaultBrowserCommand();
+ if (command != null) {
+ doLaunch(uri.toString(), command, null, project, ArrayUtil.EMPTY_STRING_ARRAY, null);
+ return;
+ }
}
}
@@ -171,7 +176,7 @@ public class BrowserLauncherAppless extends BrowserLauncher {
File file = new File(url);
if (!browse && isDesktopActionSupported(Desktop.Action.OPEN)) {
if (!file.exists()) {
- doShowError(IdeBundle.message("error.file.does.not.exist", file.getPath()), null, null, null, null);
+ showError(IdeBundle.message("error.file.does.not.exist", file.getPath()), null, null, null, null);
return;
}
@@ -189,10 +194,10 @@ public class BrowserLauncherAppless extends BrowserLauncher {
}
if (uri == null) {
- doShowError(IdeBundle.message("error.malformed.url", url), null, project, null, null);
+ showError(IdeBundle.message("error.malformed.url", url), null, project, null, null);
}
else {
- browse(uri);
+ browse(uri, project);
}
}
@@ -438,7 +443,7 @@ public class BrowserLauncherAppless extends BrowserLauncher {
String message = browser != null ? browser.getBrowserNotFoundMessage() :
IdeBundle.message("error.please.specify.path.to.web.browser", CommonBundle.settingsActionPath());
- doShowError(message, browser, project, IdeBundle.message("title.browser.not.found"), launchTask);
+ showError(message, browser, project, IdeBundle.message("title.browser.not.found"), launchTask);
return false;
}
@@ -475,7 +480,7 @@ public class BrowserLauncherAppless extends BrowserLauncher {
return true;
}
catch (ExecutionException e) {
- doShowError(e.getMessage(), browser, project, null, null);
+ showError(e.getMessage(), browser, project, null, null);
return false;
}
}
@@ -487,7 +492,7 @@ public class BrowserLauncherAppless extends BrowserLauncher {
@Nullable Runnable launchTask) {
}
- protected void doShowError(@Nullable String error, @Nullable WebBrowser browser, @Nullable Project project, String title, @Nullable Runnable launchTask) {
+ protected void showError(@Nullable String error, @Nullable WebBrowser browser, @Nullable Project project, String title, @Nullable Runnable launchTask) {
// Not started yet. Not able to show message up. (Could happen in License panel under Linux).
LOG.warn(error);
}
diff --git a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java
index 202483d0117b..10285d05fbee 100644
--- a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java
+++ b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java
@@ -83,7 +83,7 @@ public class AbstractTreeUi {
}
};
long myOwnComparatorStamp;
- long myLastComparatorStamp;
+ private long myLastComparatorStamp;
private DefaultMutableTreeNode myRootNode;
private final Map<Object, Object> myElementToNodeMap = new HashMap<Object, Object>();
@@ -109,7 +109,7 @@ public class AbstractTreeUi {
private final Map<Object, List<NodeAction>> myNodeChildrenActions = new HashMap<Object, List<NodeAction>>();
private long myClearOnHideDelay = -1;
- private final Map<AbstractTreeUi, Long> ourUi2Countdown = Collections.synchronizedMap(new WeakHashMap<AbstractTreeUi, Long>());
+ private volatile long ourUi2Countdown;
private final Set<Runnable> myDeferredSelections = new HashSet<Runnable>();
private final Set<Runnable> myDeferredExpansions = new HashSet<Runnable>();
@@ -263,7 +263,7 @@ public class AbstractTreeUi {
}
- boolean isNodeActionsPending() {
+ private boolean isNodeActionsPending() {
return !myNodeActions.isEmpty() || !myNodeChildrenActions.isEmpty();
}
@@ -310,28 +310,23 @@ public class AbstractTreeUi {
private void cleanUpAll() {
final long now = System.currentTimeMillis();
- final AbstractTreeUi[] uis = ourUi2Countdown.keySet().toArray(new AbstractTreeUi[ourUi2Countdown.size()]);
- for (AbstractTreeUi eachUi : uis) {
- if (eachUi == null) continue;
- final Long timeToCleanup = ourUi2Countdown.get(eachUi);
- if (timeToCleanup == null) continue;
- if (now >= timeToCleanup.longValue()) {
- ourUi2Countdown.remove(eachUi);
- Runnable runnable = new Runnable() {
- @Override
- public void run() {
- if (!canInitiateNewActivity()) return;
+ final long timeToCleanup = ourUi2Countdown;
+ if (timeToCleanup != 0 && now >= timeToCleanup) {
+ ourUi2Countdown = 0;
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ if (!canInitiateNewActivity()) return;
- myCleanupTask = null;
- getBuilder().cleanUp();
- }
- };
- if (isPassthroughMode()) {
- runnable.run();
- }
- else {
- invokeLaterIfNeeded(false, runnable);
+ myCleanupTask = null;
+ getBuilder().cleanUp();
}
+ };
+ if (isPassthroughMode()) {
+ runnable.run();
+ }
+ else {
+ invokeLaterIfNeeded(false, runnable);
}
}
}
@@ -390,7 +385,7 @@ public class AbstractTreeUi {
cancelCurrentCleanupTask();
myCanProcessDeferredSelections = true;
- ourUi2Countdown.remove(this);
+ ourUi2Countdown = 0;
if (!myWasEverShown || myUpdateFromRootRequested || myUpdateIfInactive) {
getBuilder().updateFromRoot();
@@ -408,7 +403,7 @@ public class AbstractTreeUi {
}
}
- public void deactivate() {
+ void deactivate() {
getUpdater().hideNotify();
myBusyAlarm.cancelAllRequests();
@@ -420,7 +415,7 @@ public class AbstractTreeUi {
}
if (getClearOnHideDelay() >= 0) {
- ourUi2Countdown.put(this, System.currentTimeMillis() + getClearOnHideDelay());
+ ourUi2Countdown = System.currentTimeMillis() + getClearOnHideDelay();
scheduleCleanUpAll();
}
}
@@ -687,7 +682,7 @@ public class AbstractTreeUi {
wasCleanedUp = true;
}
- if (myRootNodeWasQueuedToInitialize) return wasCleanedUp;
+ if (myRootNodeWasQueuedToInitialize) return true;
myRootNodeWasQueuedToInitialize = true;
@@ -2878,7 +2873,7 @@ public class AbstractTreeUi {
if (!getBuilder().isSmartExpand()) return false;
boolean smartExpand = !myNotForSmartExpand.contains(node) && canSmartExpand;
- return smartExpand && validateAutoExpand(smartExpand, getElementFor(node));
+ return smartExpand && validateAutoExpand(true, getElementFor(node));
}
private void processSmartExpand(@NotNull final DefaultMutableTreeNode node, final boolean canSmartExpand, boolean forced) {
@@ -3778,7 +3773,7 @@ public class AbstractTreeUi {
final boolean oldCanProcessDeferredSelection = myCanProcessDeferredSelections;
- if (!deferred && wasRootNodeInitialized() && willAffectSelection) {
+ if (!deferred && wasRootNodeInitialized()) {
_getReady().doWhenDone(new Runnable() {
@Override
public void run() {
@@ -4357,12 +4352,13 @@ public class AbstractTreeUi {
Object eachElement = element;
DefaultMutableTreeNode firstVisible = null;
while (true) {
- if (!isValid(eachElement) || eachElement == null) break;
+ if (eachElement == null || !isValid(eachElement)) break;
final int preselected = getRowIfUnderSelection(eachElement);
if (preselected >= 0) {
firstVisible = (DefaultMutableTreeNode)getTree().getPathForRow(preselected).getLastPathComponent();
- } else {
+ }
+ else {
firstVisible = getNodeForElement(eachElement, true);
}
@@ -4371,15 +4367,20 @@ public class AbstractTreeUi {
kidsToExpand.add(eachElement);
}
if (firstVisible != null) break;
- eachElement = eachElement != null ? getTreeStructure().getParentElement(eachElement) : null;
+ eachElement = getTreeStructure().getParentElement(eachElement);
if (eachElement == null) {
firstVisible = null;
break;
}
- if (kidsToExpand.contains(eachElement)) {
+ int i = kidsToExpand.indexOf(eachElement);
+ if (i != -1) {
try {
- LOG.error("Tree path contains equal elements at different levels: element=" + eachElement + " class=" + eachElement.getClass() + " path=" + kidsToExpand + " tree structure=" + myTreeStructure);
+ Object existing = kidsToExpand.get(i);
+ LOG.error("Tree path contains equal elements at different levels:\n" +
+ " element: '" + eachElement + "'; " + eachElement.getClass() + " ("+System.identityHashCode(eachElement)+");\n" +
+ "existing: '" + existing + "'; " + existing.getClass()+ " ("+System.identityHashCode(existing)+"); " +
+ "path='" + kidsToExpand + "'; tree structure=" + myTreeStructure);
}
catch (AssertionError ignored) {
}
@@ -5044,6 +5045,7 @@ public class AbstractTreeUi {
return myUpdateChildren;
}
+ @Override
@NotNull
@NonNls
public synchronized String toString() {
diff --git a/platform/platform-api/src/com/intellij/mock/MockProgressIndicator.java b/platform/platform-api/src/com/intellij/mock/MockProgressIndicator.java
index f69cf9b0b963..bc2fd80a5efa 100644
--- a/platform/platform-api/src/com/intellij/mock/MockProgressIndicator.java
+++ b/platform/platform-api/src/com/intellij/mock/MockProgressIndicator.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,97 +15,11 @@
*/
package com.intellij.mock;
-import com.intellij.openapi.application.ModalityState;
-import com.intellij.openapi.progress.ProgressIndicator;
-import org.jetbrains.annotations.NotNull;
+import com.intellij.openapi.progress.EmptyProgressIndicator;
+import org.jetbrains.annotations.TestOnly;
-public class MockProgressIndicator implements ProgressIndicator {
- private boolean myIsRunning = false;
- private boolean myIsCanceled = false;
-
- public void start() {
- myIsRunning = true;
- myIsCanceled = false;
- }
-
- public void stop() {
- myIsRunning = false;
- }
-
- public boolean isRunning() {
- return myIsRunning;
- }
-
- public void cancel() {
- myIsCanceled = true;
- }
-
- public boolean isCanceled() {
- return myIsCanceled;
- }
-
- public void setText(String text) {
- }
-
- public String getText() {
- return "";
- }
-
- public void setText2(String text) {
- }
-
- public String getText2() {
- return "";
- }
-
- public double getFraction() {
- return 1;
- }
-
- public void setFraction(double fraction) {
- }
-
- public void pushState() {
- }
-
- public void popState() {
- }
-
- public void startNonCancelableSection() {
- }
-
- public void finishNonCancelableSection() {
- }
-
- public boolean isModal() {
- return false;
- }
-
- @NotNull
- public ModalityState getModalityState() {
- return ModalityState.NON_MODAL;
- }
-
- public void setModalityProgress(ProgressIndicator modalityProgress) {
- }
-
- public boolean isIndeterminate() {
- return false;
- }
-
- public void setIndeterminate(boolean indeterminate) {
- }
-
- public void checkCanceled() {
- }
-
- @Override
- public boolean isPopupWasShown() {
- return false;
- }
-
- @Override
- public boolean isShowing() {
- return false;
+public class MockProgressIndicator extends EmptyProgressIndicator {
+ @TestOnly
+ public MockProgressIndicator() {
}
}
diff --git a/platform/platform-api/src/com/intellij/notification/NotificationGroup.java b/platform/platform-api/src/com/intellij/notification/NotificationGroup.java
index 7285a8e1ffd6..df68daff1584 100644
--- a/platform/platform-api/src/com/intellij/notification/NotificationGroup.java
+++ b/platform/platform-api/src/com/intellij/notification/NotificationGroup.java
@@ -66,6 +66,10 @@ public final class NotificationGroup {
return new NotificationGroup(displayId, NotificationDisplayType.TOOL_WINDOW, logByDefault, toolWindowId);
}
+ public static NotificationGroup toolWindowGroup(@NotNull String displayId, @NotNull String toolWindowId) {
+ return toolWindowGroup(displayId, toolWindowId, true);
+ }
+
public String getDisplayId() {
return myDisplayId;
}
diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/ActionPlaces.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/ActionPlaces.java
index e3248b863aba..16a81d2218d2 100644
--- a/platform/platform-api/src/com/intellij/openapi/actionSystem/ActionPlaces.java
+++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/ActionPlaces.java
@@ -76,6 +76,7 @@ public abstract class ActionPlaces {
public static final String ANT_MESSAGES_TOOLBAR = "AntMessagesToolbar";
public static final String ANT_EXPLORER_POPUP = "AntExplorerPopup";
public static final String ANT_EXPLORER_TOOLBAR = "AntExplorerToolbar";
+ public static final String GULP_VIEW_POPUP = "JavaScriptGulpPopup";
//todo: probably these context should be splitted into several contexts
public static final String CODE_INSPECTION = "CodeInspection";
@@ -133,7 +134,7 @@ public abstract class ActionPlaces {
FILEVIEW_POPUP, CHECKOUT_POPUP, LVCS_DIRECTORY_HISTORY_POPUP, GUI_DESIGNER_EDITOR_POPUP, GUI_DESIGNER_COMPONENT_TREE_POPUP,
GUI_DESIGNER_PROPERTY_INSPECTOR_POPUP,
CREATE_EJB_POPUP, CHANGES_VIEW_POPUP, REMOTE_HOST_VIEW_POPUP, REMOTE_HOST_DIALOG_POPUP, TFS_TREE_POPUP,
- ACTION_PLACE_VCS_QUICK_LIST_POPUP_ACTION, PHING_EXPLORER_POPUP, NAVIGATION_BAR_POPUP
+ ACTION_PLACE_VCS_QUICK_LIST_POPUP_ACTION, PHING_EXPLORER_POPUP, NAVIGATION_BAR_POPUP, GULP_VIEW_POPUP
};
public static boolean isPopupPlace(@NotNull String place) {
diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/ActionStub.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/ActionStub.java
index 09896aaf0da8..c96ce2aa3371 100644
--- a/platform/platform-api/src/com/intellij/openapi/actionSystem/ActionStub.java
+++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/ActionStub.java
@@ -29,6 +29,7 @@ public class ActionStub extends AnAction{
private static final Logger LOG=Logger.getInstance("#com.intellij.openapi.actionSystem.ActionStub");
private final String myClassName;
+ private final String myProjectType;
private final String myId;
private final String myText;
private final ClassLoader myLoader;
@@ -40,9 +41,10 @@ public class ActionStub extends AnAction{
@NotNull String text,
ClassLoader loader,
PluginId pluginId,
- String iconPath) {
+ String iconPath, String projectType) {
myLoader = loader;
myClassName=actionClass;
+ myProjectType = projectType;
LOG.assertTrue(!id.isEmpty());
myId=id;
myText=text;
@@ -102,4 +104,7 @@ public class ActionStub extends AnAction{
targetAction.setShortcutSet(getShortcutSet());
}
+ public String getProjectType() {
+ return myProjectType;
+ }
}
diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/CommonShortcuts.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/CommonShortcuts.java
index 994dd130c384..a1441565d90b 100644
--- a/platform/platform-api/src/com/intellij/openapi/actionSystem/CommonShortcuts.java
+++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/CommonShortcuts.java
@@ -15,9 +15,11 @@
*/
package com.intellij.openapi.actionSystem;
+import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.keymap.KeymapManager;
import com.intellij.openapi.util.SystemInfo;
+import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.event.InputEvent;
@@ -148,9 +150,13 @@ public class CommonShortcuts {
return shortcutsById(IdeActions.ACTION_DELETE);
}
+ @NotNull
private static CustomShortcutSet shortcutsById(String actionId) {
- if (ApplicationManager.getApplication() == null) return new CustomShortcutSet(Shortcut.EMPTY_ARRAY);
-
- return new CustomShortcutSet(KeymapManager.getInstance().getActiveKeymap().getShortcuts(actionId));
+ Application application = ApplicationManager.getApplication();
+ KeymapManager keymapManager = application == null ? null : application.getComponent(KeymapManager.class);
+ if (keymapManager == null) {
+ return new CustomShortcutSet(Shortcut.EMPTY_ARRAY);
+ }
+ return new CustomShortcutSet(keymapManager.getActiveKeymap().getShortcuts(actionId));
}
}
diff --git a/platform/platform-api/src/com/intellij/openapi/application/ApplicationStarter.java b/platform/platform-api/src/com/intellij/openapi/application/ApplicationStarter.java
index cd0dd2aef263..ffacf59315cd 100644
--- a/platform/platform-api/src/com/intellij/openapi/application/ApplicationStarter.java
+++ b/platform/platform-api/src/com/intellij/openapi/application/ApplicationStarter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,8 +20,8 @@ import com.intellij.openapi.extensions.ExtensionPointName;
import org.jetbrains.annotations.NonNls;
/**
- * Implementors of this interface declared via {@link com.intellij.ExtensionPoints#APPLICATION_STARTER} contribute a
- * command line application based on IDEA platform.
+ * Implementers of the interface declared via {@link com.intellij.ExtensionPoints#APPLICATION_STARTER}
+ * contribute to a command-line processing capability of an application.
*
* @author max
* @see ApplicationStarterEx
@@ -30,25 +30,26 @@ public interface ApplicationStarter {
ExtensionPointName<ApplicationStarter> EP_NAME = ExtensionPointName.create(ExtensionPoints.APPLICATION_STARTER);
/**
- * Command line switch to start with this runner. For example return "inspect" if you'd like to start app with
- * <code>idea.exe inspect</code> cmdline.
- * @return command line selector.
+ * Command-line switch to start with this runner.
+ * For example return {@code "inspect"} if you'd like to start an app with {@code "idea.exe inspect ..."} command).
+ *
+ * @return command-line selector.
*/
@NonNls
String getCommandName();
/**
- * Called before application initialization. Invoked in awt dispatch thread.
- * @param args cmdline arguments including declared selector. For example <code>"idea.exe inspect myproject.ipr"</code>
- * will pass <code>{"inspect", "myproject.ipr"}</code>
+ * Called before application initialization. Invoked in event dispatch thread.
+ *
+ * @param args program arguments (including the selector)
*/
void premain(String[] args);
/**
- * Called when application have been initialized. Invoked in awt dispatch thread. An application starter should take care terminating
- * JVM itself when appropriate by calling {@link java.lang.System#exit}(0);
- * @param args cmdline arguments including declared selector. For example <code>"idea.exe inspect myproject.ipr"</code>
- * will pass <code>{"inspect", "myproject.ipr"}</code>
+ * <p>Called when application has been initialized. Invoked in event dispatch thread.</p>
+ * <p>An application starter should take care of terminating JVM when appropriate by calling {@link System#exit}.</p>
+ *
+ * @param args program arguments (including the selector)
*/
void main(String[] args);
}
diff --git a/platform/platform-api/src/com/intellij/openapi/application/ApplicationStarterEx.java b/platform/platform-api/src/com/intellij/openapi/application/ApplicationStarterEx.java
index f84fc1481547..c4b3a6384f56 100644
--- a/platform/platform-api/src/com/intellij/openapi/application/ApplicationStarterEx.java
+++ b/platform/platform-api/src/com/intellij/openapi/application/ApplicationStarterEx.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,11 +16,17 @@
package com.intellij.openapi.application;
/**
- * Implementors of this interface declared via {@link com.intellij.ExtensionPoints#APPLICATION_STARTER} are also capable of processing
- * an external command line within a running IntelliJ Platform instance.
-
+ * Implementers of the interface declared via {@link com.intellij.ExtensionPoints#APPLICATION_STARTER}
+ * may be capable of processing an external command line within a running IntelliJ Platform instance.
+ *
* @author yole
*/
-public interface ApplicationStarterEx extends ApplicationStarter {
- void processExternalCommandLine(String[] args);
+public abstract class ApplicationStarterEx implements ApplicationStarter {
+ public abstract boolean isHeadless();
+
+ public boolean canProcessExternalCommandLine() {
+ return false;
+ }
+
+ public void processExternalCommandLine(String[] args) { }
}
diff --git a/platform/platform-api/src/com/intellij/openapi/diff/ActionButtonPresentation.java b/platform/platform-api/src/com/intellij/openapi/diff/ActionButtonPresentation.java
index a8dbcdbc45e0..c4ae87fb1e02 100644
--- a/platform/platform-api/src/com/intellij/openapi/diff/ActionButtonPresentation.java
+++ b/platform/platform-api/src/com/intellij/openapi/diff/ActionButtonPresentation.java
@@ -29,7 +29,7 @@ public abstract class ActionButtonPresentation {
}
};
- public static ActionButtonPresentation CANCEL_WITH_PROMPT = new ActionButtonPresentation(CommonBundle.getCancelButtonText()) {
+ public static ActionButtonPresentation CANCEL_WITH_PROMPT = new ActionButtonPresentation("Revert") {
@Override
public void run(DialogWrapper dialog) {
if (Messages.showYesNoDialog(dialog.getRootPane(),
diff --git a/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptor.java b/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptor.java
index c19173c7e906..7509394a2368 100644
--- a/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptor.java
+++ b/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptor.java
@@ -18,6 +18,7 @@ package com.intellij.openapi.fileChooser;
import com.intellij.openapi.actionSystem.DataKey;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.fileTypes.FileTypes;
+import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Iconable;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VFileProperty;
@@ -51,6 +52,7 @@ public class FileChooserDescriptor implements Cloneable {
private boolean myShowFileSystemRoots = true;
private boolean myTreeRootVisible = false;
private boolean myShowHiddenFiles = false;
+ private Condition<VirtualFile> myFileFilter = null;
private final Map<String, Object> myUserData = new HashMap<String, Object>();
@@ -218,18 +220,15 @@ public class FileChooserDescriptor implements Cloneable {
}
/**
- * Defines whether file can be chosen or not
+ * Sets simple boolean condition for use in {@link #isFileVisible(VirtualFile, boolean)} and {@link #isFileSelectable(VirtualFile)}.
*/
- public boolean isFileSelectable(VirtualFile file) {
- if (file == null) return false;
- if (file.isDirectory() && myChooseFolders) return true;
- if (acceptAsJarFile(file)) return true;
- if (acceptAsGeneralFile(file)) return true;
- return false;
+ public FileChooserDescriptor withFileFilter(@Nullable Condition<VirtualFile> filter) {
+ myFileFilter = filter;
+ return this;
}
/**
- * Defines whether file is visible in the tree
+ * Defines whether a file is visible in the tree.
*/
public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) {
if (!file.isDirectory()) {
@@ -238,28 +237,47 @@ public class FileChooserDescriptor implements Cloneable {
return false;
}
}
- else {
- if (!myChooseFiles) {
- return false;
- }
+ else if (!myChooseFiles) {
+ return false;
+ }
+ if (myFileFilter != null && !myFileFilter.value(file)) {
+ return false;
}
}
- // do not include ignored files
if (isHideIgnored() && FileTypeManager.getInstance().isFileIgnored(file)) {
return false;
}
- // do not include hidden files
- if (!showHiddenFiles) {
- if (FileElement.isFileHidden(file)) {
- return false;
- }
+ if (!showHiddenFiles && FileElement.isFileHidden(file)) {
+ return false;
}
return true;
}
+ /**
+ * Defines whether a file can be chosen.
+ */
+ public boolean isFileSelectable(VirtualFile file) {
+ if (file == null) return false;
+
+ if (file.isDirectory() && myChooseFolders) {
+ return true;
+ }
+ if (acceptAsJarFile(file)) {
+ return true;
+ }
+ if (acceptAsGeneralFile(file)) {
+ return true;
+ }
+ if (myFileFilter != null && !file.isDirectory() && myFileFilter.value(file)) {
+ return true;
+ }
+
+ return false;
+ }
+
public Icon getIcon(final VirtualFile file) {
if (file.isDirectory()) {
return dressIcon(file, PlatformIcons.DIRECTORY_CLOSED_ICON);
diff --git a/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptorFactory.java b/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptorFactory.java
index c958dbca878e..2eee60aa3061 100644
--- a/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptorFactory.java
+++ b/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptorFactory.java
@@ -16,14 +16,13 @@
package com.intellij.openapi.fileChooser;
import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.ui.UIBundle;
-import org.jetbrains.annotations.NotNull;
public class FileChooserDescriptorFactory {
- private FileChooserDescriptorFactory() {
- }
+ private FileChooserDescriptorFactory() { }
public static FileChooserDescriptor createAllButJarContentsDescriptor() {
return new FileChooserDescriptor(true, true, true, true, false, true);
@@ -45,13 +44,7 @@ public class FileChooserDescriptorFactory {
return new FileChooserDescriptor(true, false, false, false, false, false) {
@Override
public boolean isFileSelectable(VirtualFile file) {
- if (super.isFileSelectable(file)) return true;
-
- if (SystemInfo.isMac && file.isDirectory() && "app".equals(file.getExtension())) {
- return true;
- }
-
- return false;
+ return super.isFileSelectable(file) || SystemInfo.isMac && file.isDirectory() && "app".equals(file.getExtension());
}
};
}
@@ -60,6 +53,24 @@ public class FileChooserDescriptorFactory {
return new FileChooserDescriptor(true, true, true, true, false, false);
}
+ public static FileChooserDescriptor createSingleFileDescriptor(final FileType fileType) {
+ return new FileChooserDescriptor(true, false, false, false, false, false).withFileFilter(new Condition<VirtualFile>() {
+ @Override
+ public boolean value(VirtualFile file) {
+ return file.getFileType() == fileType;
+ }
+ });
+ }
+
+ public static FileChooserDescriptor createSingleFileDescriptor(final String extension) {
+ return new FileChooserDescriptor(true, false, false, false, false, false).withFileFilter(new Condition<VirtualFile>() {
+ @Override
+ public boolean value(VirtualFile file) {
+ return Comparing.equal(file.getExtension(), extension, SystemInfo.isFileSystemCaseSensitive);
+ }
+ });
+ }
+
public static FileChooserDescriptor createSingleFolderDescriptor() {
return new FileChooserDescriptor(false, true, false, false, false, false);
}
@@ -72,54 +83,40 @@ public class FileChooserDescriptorFactory {
return new FileChooserDescriptor(true, true, false, false, false, false);
}
- public static FileChooserDescriptor getDirectoryChooserDescriptor(String aSearchedObjectName) {
- final FileChooserDescriptor singleFolderDescriptor = createSingleFolderDescriptor();
- singleFolderDescriptor.setTitle(UIBundle.message("file.chooser.select.object.title", aSearchedObjectName));
- return singleFolderDescriptor;
+ public static FileChooserDescriptor createSingleFileOrFolderDescriptor(final FileType fileType) {
+ return new FileChooserDescriptor(true, true, false, false, false, false).withFileFilter(new Condition<VirtualFile>() {
+ @Override
+ public boolean value(VirtualFile file) {
+ return file.getFileType() == fileType;
+ }
+ });
}
- public static FileChooserDescriptor getFileChooserDescriptor(String aSearchedObjectName) {
- final FileChooserDescriptor fileChooserDescriptor = createSingleFileNoJarsDescriptor();
- fileChooserDescriptor.setTitle(UIBundle.message("file.chooser.select.object.title", aSearchedObjectName));
- return fileChooserDescriptor;
+ /** @deprecated use {@link #createSingleFileDescriptor(FileType)} or {@link #createSingleFileOrFolderDescriptor(FileType)} (to be removed in IDEA 14) */
+ @SuppressWarnings("UnusedDeclaration")
+ public static FileChooserDescriptor createSingleFileDescriptor(final FileType fileType, final boolean supportDirectories) {
+ return supportDirectories ? createSingleFileOrFolderDescriptor(fileType) : createSingleFileDescriptor(fileType);
}
- public static FileChooserDescriptor createSingleFileDescriptor(final FileType fileType) {
- return createSingleFileDescriptor(fileType, false);
+ /** @deprecated not very useful (to be removed in IDEA 15) */
+ @SuppressWarnings("UnusedDeclaration")
+ public static FileChooserDescriptor getDirectoryChooserDescriptor(String objectName) {
+ return createSingleFolderDescriptor().withTitle("Select " + objectName);
}
- /**
- * Creates file descriptor with certain type and (possible) folders.
- * @param fileType supported type
- * @param supportDirectories support directories or not
- * @return descriptor
- */
- @NotNull
- public static FileChooserDescriptor createSingleFileDescriptor(final FileType fileType, final boolean supportDirectories) {
- return new FileChooserDescriptor(true, supportDirectories, false, false, false, false) {
- @Override
- public boolean isFileVisible(final VirtualFile file, final boolean showHiddenFiles) {
- return file.isDirectory() || file.getFileType() == fileType;
- }
-
- @Override
- public boolean isFileSelectable(final VirtualFile file) {
- return super.isFileSelectable(file) && (file.getFileType() == fileType || ((file.isDirectory() && supportDirectories)));
- }
- };
+ /** @deprecated not very useful (to be removed in IDEA 15) */
+ @SuppressWarnings("UnusedDeclaration")
+ public static FileChooserDescriptor getFileChooserDescriptor(String objectName) {
+ return createSingleFileNoJarsDescriptor().withTitle("Select " + objectName);
}
- /**
- * @deprecated use {@link #createSingleFileNoJarsDescriptor()} (to be removed in IDEA 15)
- */
+ /** @deprecated use {@link #createSingleFileNoJarsDescriptor()} (to be removed in IDEA 15) */
@SuppressWarnings({"UnusedDeclaration", "deprecation"})
public static FileChooserDescriptorBuilder onlyFiles() {
return FileChooserDescriptorBuilder.onlyFiles();
}
- /**
- * @deprecated use {@link #createSingleFileOrFolderDescriptor()} ()} (to be removed in IDEA 15)
- */
+ /** @deprecated use {@link #createSingleFileOrFolderDescriptor()} ()} (to be removed in IDEA 15) */
@SuppressWarnings({"UnusedDeclaration", "deprecation"})
public static FileChooserDescriptorBuilder filesAndFolders() {
return FileChooserDescriptorBuilder.filesAndFolders();
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ConfigurableBase.java b/platform/platform-api/src/com/intellij/openapi/options/ConfigurableBase.java
index d7c7dca2f19b..d7c7dca2f19b 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/ConfigurableBase.java
+++ b/platform/platform-api/src/com/intellij/openapi/options/ConfigurableBase.java
diff --git a/platform/platform-api/src/com/intellij/openapi/options/ConfigurableEP.java b/platform/platform-api/src/com/intellij/openapi/options/ConfigurableEP.java
index 11c8bdd90052..78a4c1ece130 100644
--- a/platform/platform-api/src/com/intellij/openapi/options/ConfigurableEP.java
+++ b/platform/platform-api/src/com/intellij/openapi/options/ConfigurableEP.java
@@ -93,6 +93,9 @@ public class ConfigurableEP<T extends UnnamedConfigurable> extends AbstractExten
@Attribute("groupId")
public String groupId;
+ @Attribute("groupWeight")
+ public int groupWeight;
+
/** Marks project level configurables that do not apply to the default project. */
@Attribute("nonDefaultProject")
public boolean nonDefaultProject;
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ConfigurableUi.java b/platform/platform-api/src/com/intellij/openapi/options/ConfigurableUi.java
index 0ecb19a7ce8e..0ecb19a7ce8e 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/ConfigurableUi.java
+++ b/platform/platform-api/src/com/intellij/openapi/options/ConfigurableUi.java
diff --git a/platform/platform-api/src/com/intellij/openapi/options/ShowSettingsUtil.java b/platform/platform-api/src/com/intellij/openapi/options/ShowSettingsUtil.java
index aa6d9618482a..34eaf920d78d 100644
--- a/platform/platform-api/src/com/intellij/openapi/options/ShowSettingsUtil.java
+++ b/platform/platform-api/src/com/intellij/openapi/options/ShowSettingsUtil.java
@@ -41,21 +41,25 @@ public abstract class ShowSettingsUtil {
public abstract boolean editConfigurable(@Nullable Project project, Configurable configurable, @Nullable Runnable advancedInitialization);
- public abstract boolean editConfigurable(Component parent, Configurable configurable);
+ public abstract boolean editConfigurable(@Nullable Component parent, @NotNull Configurable configurable);
- public abstract boolean editConfigurable(Component parent, Configurable configurable, Runnable advancedInitialization);
+ public abstract boolean editConfigurable(Component parent, Configurable configurable, @NotNull Runnable advancedInitialization);
public abstract boolean editConfigurable(Project project, @NonNls String dimensionServiceKey, Configurable configurable);
+ public abstract boolean editConfigurable(Project project, @NonNls String dimensionServiceKey, Configurable configurable, boolean showApplyButton);
+
public abstract boolean editConfigurable(Component parent, String dimensionServiceKey, Configurable configurable);
/**
* @deprecated create a new instance of configurable instead
+ * to remove in IDEA 15
*/
public abstract <T extends Configurable> T findProjectConfigurable(Project project, Class<T> confClass);
/**
* @deprecated create a new instance of configurable instead
+ * to remove in IDEA 15
*/
public abstract <T extends Configurable> T findApplicationConfigurable(Class<T> confClass);
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/SimpleConfigurable.java b/platform/platform-api/src/com/intellij/openapi/options/SimpleConfigurable.java
index 9812165932a2..9812165932a2 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/SimpleConfigurable.java
+++ b/platform/platform-api/src/com/intellij/openapi/options/SimpleConfigurable.java
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/Banner.java b/platform/platform-api/src/com/intellij/openapi/ui/Banner.java
index 8dbe02228bae..59f99ad46a05 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/Banner.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/Banner.java
@@ -18,6 +18,7 @@ package com.intellij.openapi.ui;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.options.OptionsBundle;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.ui.components.labels.LinkLabel;
import com.intellij.ui.components.labels.LinkListener;
import com.intellij.ui.components.panels.NonOpaquePanel;
@@ -45,7 +46,7 @@ class Banner extends NonOpaquePanel implements PropertyChangeListener{
public Banner() {
setLayout(new BorderLayout());
- setBorder(new EmptyBorder(2, 6, 2, 4));
+ setBorder(new EmptyBorder(2, Registry.is("ide.new.settings.dialog") ? 12 : 6, 2, 4));
myProjectIcon.setVisible(false);
myProjectIcon.setBorder(new EmptyBorder(0, 12, 0, 4));
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/DetailsComponent.java b/platform/platform-api/src/com/intellij/openapi/ui/DetailsComponent.java
index 463d950ae900..00440b0dd8a6 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/DetailsComponent.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/DetailsComponent.java
@@ -17,6 +17,7 @@
package com.intellij.openapi.ui;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.ui.components.panels.NonOpaquePanel;
import com.intellij.ui.components.panels.Wrapper;
import com.intellij.util.ArrayUtil;
@@ -65,47 +66,54 @@ public class DetailsComponent {
protected void paintComponent(final Graphics g) {
if (NullableComponent.Check.isNull(myContent) || !myDetailsEnabled) return;
- GraphicsConfig c = new GraphicsConfig(g);
- c.setAntialiasing(true);
-
- Insets insets = getInsets();
- if (insets == null) {
- insets = new Insets(0, 0, 0, 0);
+ GraphicsConfig c = null;
+ Insets insets = null;
+ final int leftX;
+ final int rightX;
+ final int rightY;
+ if (!Registry.is("ide.new.settings.dialog")) {
+ c = new GraphicsConfig(g);
+ c.setAntialiasing(true);
+
+ insets = getInsets();
+ if (insets == null) {
+ insets = new Insets(0, 0, 0, 0);
+ }
+
+ g.setColor(UIUtil.getFocusedFillColor());
+
+ final Rectangle banner = myBanner.getBounds();
+ final GeneralPath header = new GeneralPath();
+
+ leftX = insets.left;
+ final int leftY = insets.top;
+ rightX = insets.left + getWidth() - 1 - insets.right;
+ rightY = banner.y + banner.height;
+
+ header.moveTo(leftX, rightY);
+ int arc = 8;
+ header.lineTo(leftX, leftY + arc);
+ header.quadTo(leftX, leftY, leftX + arc, leftY);
+ header.lineTo(rightX - arc, leftY);
+ header.quadTo(rightX, leftY, rightX, leftY + arc);
+ header.lineTo(rightX, rightY);
+ header.closePath();
+
+ c.getG().fill(header);
+
+ g.setColor(UIUtil.getFocusedBoundsColor());
+
+ c.getG().draw(header);
+
+
+ if (myPaintBorder) {
+ final int down = getHeight() - insets.top - insets.bottom - 1;
+ g.drawLine(leftX, rightY, leftX, down);
+ g.drawLine(rightX, rightY, rightX, down);
+ g.drawLine(leftX, down, rightX, down);
+ }
+ c.restore();
}
-
- g.setColor(UIUtil.getFocusedFillColor());
-
- final Rectangle banner = myBanner.getBounds();
- final GeneralPath header = new GeneralPath();
-
- final int leftX = insets.left;
- final int leftY = insets.top;
- final int rightX = insets.left + getWidth() - 1 - insets.right;
- final int rightY = banner.y + banner.height;
-
- header.moveTo(leftX, rightY);
- int arc = 8;
- header.lineTo(leftX, leftY + arc);
- header.quadTo(leftX, leftY, leftX + arc, leftY);
- header.lineTo(rightX - arc, leftY);
- header.quadTo(rightX, leftY, rightX, leftY + arc);
- header.lineTo(rightX, rightY);
- header.closePath();
-
- c.getG().fill(header);
-
- g.setColor(UIUtil.getFocusedBoundsColor());
-
- c.getG().draw(header);
-
- if (myPaintBorder) {
- final int down = getHeight() - insets.top - insets.bottom - 1;
- g.drawLine(leftX, rightY, leftX, down);
- g.drawLine(rightX, rightY, rightX, down);
- g.drawLine(leftX, down, rightX, down);
- }
-
- c.restore();
}
};
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/DialogBuilder.java b/platform/platform-api/src/com/intellij/openapi/ui/DialogBuilder.java
index ed374a905462..e4c8c6852727 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/DialogBuilder.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/DialogBuilder.java
@@ -21,6 +21,7 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.help.HelpManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.containers.ContainerUtil;
import org.intellij.lang.annotations.MagicConstant;
import org.jetbrains.annotations.NonNls;
@@ -55,26 +56,34 @@ public class DialogBuilder implements Disposable {
return showImpl(true).getExitCode();
}
+ public boolean showAndGet() {
+ return showImpl(true).isOK();
+ }
+
public void showNotModal() {
showImpl(false);
}
- public DialogBuilder(Project project) {
+ public DialogBuilder(@Nullable Project project) {
myDialogWrapper = new MyDialogWrapper(project, true);
Disposer.register(myDialogWrapper.getDisposable(), this);
}
- public DialogBuilder(Component parent) {
+ public DialogBuilder(@Nullable Component parent) {
myDialogWrapper = new MyDialogWrapper(parent, true);
Disposer.register(myDialogWrapper.getDisposable(), this);
}
+ public DialogBuilder() {
+ this(((Project)null));
+ }
+
@Override
public void dispose() {
}
private MyDialogWrapper showImpl(boolean isModal) {
- LOG.assertTrue(myTitle != null && myTitle.trim().length() != 0,
+ LOG.assertTrue(!StringUtil.isEmptyOrSpaces(myTitle),
String.format("Dialog title shouldn't be empty or null: [%s]", myTitle));
myDialogWrapper.setTitle(myTitle);
myDialogWrapper.init();
@@ -91,6 +100,12 @@ public class DialogBuilder implements Disposable {
}
@NotNull
+ public DialogBuilder centerPanel(@NotNull JComponent centerPanel) {
+ myCenterPanel = centerPanel;
+ return this;
+ }
+
+ @NotNull
public DialogBuilder setNorthPanel(@NotNull JComponent northPanel) {
myNorthPanel = northPanel;
return this;
@@ -100,6 +115,7 @@ public class DialogBuilder implements Disposable {
myTitle = title;
}
+ @NotNull
public DialogBuilder title(@NotNull String title) {
myTitle = title;
return this;
@@ -196,6 +212,18 @@ public class DialogBuilder implements Disposable {
myDialogWrapper.setOKActionEnabled(isEnabled);
}
+ @NotNull
+ public DialogBuilder okActionEnabled(boolean isEnabled) {
+ myDialogWrapper.setOKActionEnabled(isEnabled);
+ return this;
+ }
+
+ @NotNull
+ public DialogBuilder resizable(boolean resizable) {
+ myDialogWrapper.setResizable(resizable);
+ return this;
+ }
+
public CustomizableAction getOkAction() {
return get(getActionDescriptors(), OkActionDescriptor.class);
}
@@ -267,7 +295,7 @@ public class DialogBuilder implements Disposable {
protected Action createAction(final DialogWrapper dialogWrapper) {
return new AbstractAction(){
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
dialogWrapper.close(myExitCode);
}
};
@@ -325,7 +353,7 @@ public class DialogBuilder implements Disposable {
private class MyDialogWrapper extends DialogWrapper {
private String myHelpId = null;
- private MyDialogWrapper(Project project, boolean canBeParent) {
+ private MyDialogWrapper(@Nullable Project project, boolean canBeParent) {
super(project, canBeParent);
}
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java b/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java
index 75cb4de7af74..741f67dee2c4 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java
@@ -1233,6 +1233,7 @@ public abstract class DialogWrapper {
if (SystemInfo.isWindows) {
installEnterHook(root);
}
+ myErrorTextAlarm.setActivationComponent(root);
}
@NotNull
@@ -1838,15 +1839,14 @@ public abstract class DialogWrapper {
return;
}
myLastErrorText = text;
- if (myActualSize == null && !StringUtil.isEmpty(text)) {
- myActualSize = getSize();
- }
-
myErrorTextAlarm.cancelAllRequests();
myErrorTextAlarm.addRequest(new Runnable() {
@Override
public void run() {
final String text = myLastErrorText;
+ if (myActualSize == null && !StringUtil.isEmpty(text)) {
+ myActualSize = getSize();
+ }
myErrorText.setError(text);
if (text != null && text.length() > myMaxErrorTextLength) {
// during the first update, resize only for growing. during a subsequent update,
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapperPeerFactory.java b/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapperPeerFactory.java
index c9515a884f97..c1239e523896 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapperPeerFactory.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapperPeerFactory.java
@@ -24,17 +24,24 @@ import org.jetbrains.annotations.Nullable;
import java.awt.*;
public abstract class DialogWrapperPeerFactory {
+ @NotNull
public static DialogWrapperPeerFactory getInstance() {
if (ApplicationManager.getApplication() == null) {
- try {
- return (DialogWrapperPeerFactory)Class.forName("com.intellij.openapi.ui.impl.DialogWrapperPeerFactoryImpl").newInstance();
- }
- catch (Exception e) {
- throw new RuntimeException("Can't instantiate DialogWrapperPeerFactory", e);
- }
+ return getInstanceByName();
}
- return ServiceManager.getService(DialogWrapperPeerFactory.class);
+ DialogWrapperPeerFactory factory = ServiceManager.getService(DialogWrapperPeerFactory.class);
+ return factory == null ? getInstanceByName() : factory;
+ }
+
+ @NotNull
+ private static DialogWrapperPeerFactory getInstanceByName() {
+ try {
+ return (DialogWrapperPeerFactory)Class.forName("com.intellij.openapi.ui.impl.DialogWrapperPeerFactoryImpl").newInstance();
+ }
+ catch (Exception e) {
+ throw new RuntimeException("Can't instantiate DialogWrapperPeerFactory", e);
+ }
}
@NotNull
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/MessageDialogBuilder.java b/platform/platform-api/src/com/intellij/openapi/ui/MessageDialogBuilder.java
index ab193aff20c2..7819ef68a7e5 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/MessageDialogBuilder.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/MessageDialogBuilder.java
@@ -40,6 +40,7 @@ public abstract class MessageDialogBuilder<T extends MessageDialogBuilder> {
myMessage = message;
}
+ @NotNull
public static YesNo yesNo(@NotNull String title, @NotNull String message) {
return new YesNo(title, message).icon(Messages.getQuestionIcon());
}
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/Messages.java b/platform/platform-api/src/com/intellij/openapi/ui/Messages.java
index dae35d4b685d..1a07b33d696d 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/Messages.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/Messages.java
@@ -143,9 +143,12 @@ public class Messages {
try {
if (canShowMacSheetPanel()) {
- Window parentWindow = WindowManager.getInstance().suggestParentWindow(project);
- return MacMessages.getInstance()
- .showMessageDialog(title, message, options, false, parentWindow, defaultOptionIndex, defaultOptionIndex, doNotAskOption);
+ WindowManager windowManager = WindowManager.getInstance();
+ if (windowManager != null) {
+ Window parentWindow = windowManager.suggestParentWindow(project);
+ return MacMessages.getInstance()
+ .showMessageDialog(title, message, options, false, parentWindow, defaultOptionIndex, defaultOptionIndex, doNotAskOption);
+ }
}
}
catch (Exception exception) {
diff --git a/platform/platform-api/src/com/intellij/openapi/util/PasswordUtil.java b/platform/platform-api/src/com/intellij/openapi/util/PasswordUtil.java
index 4ba3fa7c1516..c4995a34ac27 100644
--- a/platform/platform-api/src/com/intellij/openapi/util/PasswordUtil.java
+++ b/platform/platform-api/src/com/intellij/openapi/util/PasswordUtil.java
@@ -15,13 +15,17 @@
*/
package com.intellij.openapi.util;
+import org.jetbrains.annotations.Nullable;
+
public class PasswordUtil {
private PasswordUtil() { }
// weak encryption just to avoid plain text passwords in text files
- public static String encodePassword(String password) {
+ public static String encodePassword(@Nullable String password) {
String result = "";
- if (password == null) return result;
+ if (password == null) {
+ return result;
+ }
for (int i = 0; i < password.length(); i++) {
int c = password.charAt(i);
c ^= 0xdfaa;
@@ -30,9 +34,11 @@ public class PasswordUtil {
return result;
}
- public static String decodePassword(String password) throws NumberFormatException {
+ public static String decodePassword(@Nullable String password) throws NumberFormatException {
String result = "";
- if (password == null) return result;
+ if (password == null) {
+ return result;
+ }
for (int i = 0; i < password.length(); i += 4) {
String s = password.substring(i, i + 4);
int c = Integer.parseInt(s, 16);
diff --git a/platform/platform-api/src/com/intellij/openapi/util/registry/RegistryState.java b/platform/platform-api/src/com/intellij/openapi/util/registry/RegistryState.java
index 7a6c15ef495f..cf10656a24ed 100644
--- a/platform/platform-api/src/com/intellij/openapi/util/registry/RegistryState.java
+++ b/platform/platform-api/src/com/intellij/openapi/util/registry/RegistryState.java
@@ -16,9 +16,14 @@
package com.intellij.openapi.util.registry;
import com.intellij.openapi.components.*;
+import com.intellij.openapi.diagnostic.Logger;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
@State(
name = "Registry",
storages = {
@@ -26,6 +31,7 @@ import org.jetbrains.annotations.NotNull;
file = StoragePathMacros.APP_CONFIG + "/other.xml")}
)
public class RegistryState implements BaseComponent, PersistentStateComponent<Element> {
+ private static final Logger LOG = Logger.getInstance(RegistryState.class);
public RegistryState() {
}
@@ -36,6 +42,14 @@ public class RegistryState implements BaseComponent, PersistentStateComponent<El
public void loadState(Element state) {
Registry.getInstance().loadState(state);
+ SortedMap<String, String> userProperties = new TreeMap<String, String>(Registry.getInstance().getUserProperties());
+ userProperties.remove("ide.firstStartup");
+ if (!userProperties.isEmpty()) {
+ LOG.info("Registry values changed by user:");
+ for (Map.Entry<String, String> entry : userProperties.entrySet()) {
+ LOG.info(" " + entry.getKey() + " = " + entry.getValue());
+ }
+ }
}
@NotNull
diff --git a/platform/platform-api/src/com/intellij/openapi/wm/ToolWindowId.java b/platform/platform-api/src/com/intellij/openapi/wm/ToolWindowId.java
index edcf3b87ae2a..7adbfd16b324 100644
--- a/platform/platform-api/src/com/intellij/openapi/wm/ToolWindowId.java
+++ b/platform/platform-api/src/com/intellij/openapi/wm/ToolWindowId.java
@@ -38,4 +38,5 @@ public interface ToolWindowId {
String DOCUMENTATION = UIBundle.message("tool.window.name.documentation");
String TASKS = UIBundle.message("tool.window.name.tasks");
String DATABASE_VIEW = UIBundle.message("tool.window.name.database");
+ String PREVIEW = UIBundle.message("tool.window.name.preview");
} \ No newline at end of file
diff --git a/platform/platform-api/src/com/intellij/ui/ColoredListCellRenderer.java b/platform/platform-api/src/com/intellij/ui/ColoredListCellRenderer.java
index b7ec8556f3d9..67ca238ce077 100644
--- a/platform/platform-api/src/com/intellij/ui/ColoredListCellRenderer.java
+++ b/platform/platform-api/src/com/intellij/ui/ColoredListCellRenderer.java
@@ -17,6 +17,7 @@ package com.intellij.ui;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
@@ -30,8 +31,15 @@ public abstract class ColoredListCellRenderer<T> extends SimpleColoredComponent
protected boolean mySelected;
protected Color myForeground;
protected Color mySelectionForeground;
+ @Nullable
+ private final JComboBox myComboBox;
public ColoredListCellRenderer() {
+ this(null);
+ }
+
+ public ColoredListCellRenderer(@Nullable JComboBox comboBox) {
+ myComboBox = comboBox;
setFocusBorderAroundIcon(true);
getIpad().left = UIUtil.getListCellHPadding();
getIpad().right = UIUtil.getListCellHPadding();
@@ -40,6 +48,9 @@ public abstract class ColoredListCellRenderer<T> extends SimpleColoredComponent
public Component getListCellRendererComponent(JList list, Object value, int index, boolean selected, boolean hasFocus) {
clear();
+ if (myComboBox != null) {
+ setEnabled(myComboBox.isEnabled());
+ }
setFont(list.getFont());
mySelected = selected;
myForeground = list.getForeground();
diff --git a/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java b/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java
index 76bacb9cb452..a2e8aacc046f 100644
--- a/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java
+++ b/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java
@@ -165,22 +165,22 @@ public abstract class GroupedElementsRenderer {
}
@Override
- protected final Color getSelectionBackground() {
+ protected Color getSelectionBackground() {
return UIUtil.getTreeSelectionBackground();
}
@Override
- protected final Color getSelectionForeground() {
+ protected Color getSelectionForeground() {
return UIUtil.getTreeSelectionForeground();
}
@Override
- protected final Color getBackground() {
+ protected Color getBackground() {
return UIUtil.getTreeTextBackground();
}
@Override
- protected final Color getForeground() {
+ protected Color getForeground() {
return UIUtil.getTreeTextForeground();
}
}
diff --git a/platform/platform-api/src/com/intellij/ui/GuiUtils.java b/platform/platform-api/src/com/intellij/ui/GuiUtils.java
index ec378977f76e..9d5dcbea7edf 100644
--- a/platform/platform-api/src/com/intellij/ui/GuiUtils.java
+++ b/platform/platform-api/src/com/intellij/ui/GuiUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,7 +26,7 @@ import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.CharFilter;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Consumer;
@@ -47,11 +47,9 @@ import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
public class GuiUtils {
-
private static final Insets paddingFromDialogBoundaries = new Insets(7, 5, 7, 5);
private static final Insets paddingInsideDialog = new Insets(5, 5, 5, 5);
- public static final int lengthForFileField = 25;
private static final CharFilter NOT_MNEMONIC_CHAR_FILTER = new CharFilter() {
@Override
public boolean accept(char ch) {
@@ -78,33 +76,33 @@ public class GuiUtils {
return result;
}
- public static JPanel constructDirectoryBrowserField(final JTextField aTextField, final String aSearchedObjectName) {
- return constructFieldWithBrowseButton(aTextField, new ActionListener() {
+ public static JPanel constructDirectoryBrowserField(final JTextField field, final String objectName) {
+ return constructFieldWithBrowseButton(field, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
- FileChooserDescriptor descriptor = FileChooserDescriptorFactory.getDirectoryChooserDescriptor(aSearchedObjectName);
- VirtualFile file = FileChooser.chooseFile(descriptor, aTextField, null, null);
+ FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor().withTitle("Select " + objectName);
+ VirtualFile file = FileChooser.chooseFile(descriptor, field, null, null);
if (file != null) {
- aTextField.setText(FileUtil.toSystemDependentName(file.getPath()));
- aTextField.postActionEvent();
+ field.setText(FileUtil.toSystemDependentName(file.getPath()));
+ field.postActionEvent();
}
}
});
}
- public static JPanel constructFileURLBrowserField(final TextFieldWithHistory aFieldWithHistory,
- final String aSearchedObjectName) {
- return constructFieldWithBrowseButton(aFieldWithHistory, new ActionListener() {
+ public static JPanel constructFileURLBrowserField(final TextFieldWithHistory field, final String objectName) {
+ return constructFieldWithBrowseButton(field, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
- FileChooserDescriptor descriptor = FileChooserDescriptorFactory.getFileChooserDescriptor(aSearchedObjectName);
- VirtualFile file = FileChooser.chooseFile(descriptor, aFieldWithHistory, null, null);
+ FileChooserDescriptor descriptor =
+ FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor().withTitle("Select " + objectName);
+ VirtualFile file = FileChooser.chooseFile(descriptor, field, null, null);
if (file != null) {
try {
- aFieldWithHistory.setText(VfsUtil.virtualToIoFile(file).toURL().toString());
+ field.setText(VfsUtilCore.virtualToIoFile(file).toURI().toURL().toString());
}
catch (MalformedURLException e1) {
- aFieldWithHistory.setText("");
+ field.setText("");
}
}
}
diff --git a/platform/platform-api/src/com/intellij/ui/HyperlinkLabel.java b/platform/platform-api/src/com/intellij/ui/HyperlinkLabel.java
index 27324c9d9781..6a99624a620b 100644
--- a/platform/platform-api/src/com/intellij/ui/HyperlinkLabel.java
+++ b/platform/platform-api/src/com/intellij/ui/HyperlinkLabel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,9 +20,11 @@ import com.intellij.ide.BrowserUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.markup.EffectType;
import com.intellij.openapi.editor.markup.TextAttributes;
+import com.intellij.util.NotNullProducer;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.PlatformColors;
import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -42,7 +44,14 @@ import java.util.List;
* @author Eugene Belyaev
*/
public class HyperlinkLabel extends HighlightableComponent {
- private static final TextAttributes BOLD_ATTRIBUTES = new TextAttributes(UIUtil.getLabelTextForeground(), null, null, null, Font.BOLD);
+ private static final TextAttributes BOLD_ATTRIBUTES = new TextAttributes(new JBColor(new NotNullProducer<Color>() {
+ @NotNull
+ @Override
+ public Color produce() {
+ final Color foreground = UIUtil.getLabelTextForeground();
+ return foreground == null ? UIUtil.getLabelForeground() : foreground;
+ }
+ }), null, null, null, Font.BOLD);
private static final Logger LOG = Logger.getInstance(HyperlinkLabel.class.getName());
@@ -59,7 +68,13 @@ public class HyperlinkLabel extends HighlightableComponent {
public HyperlinkLabel(String text) {
this(text,
PlatformColors.BLUE,
- UIUtil.getLabelBackground(),
+ new JBColor(new NotNullProducer<Color>() {
+ @NotNull
+ @Override
+ public Color produce() {
+ return UIUtil.getLabelBackground();
+ }
+ }),
PlatformColors.BLUE);
}
@@ -209,7 +224,9 @@ public class HyperlinkLabel extends HighlightableComponent {
LOG.error(e);
}
highlightedText.applyToComponent(this);
- ((JComponent)getParent()).revalidate();
+ final JComponent parent = (JComponent)getParent();
+ parent.revalidate();
+ parent.repaint();
adjustSize();
}
diff --git a/platform/platform-api/src/com/intellij/ui/InplaceButton.java b/platform/platform-api/src/com/intellij/ui/InplaceButton.java
index 04ea9161f99c..89dd0dfc34e2 100644
--- a/platform/platform-api/src/com/intellij/ui/InplaceButton.java
+++ b/platform/platform-api/src/com/intellij/ui/InplaceButton.java
@@ -101,7 +101,11 @@ public class InplaceButton extends JComponent implements ActiveComponent {
setIcons(source.getRegular(), source.getInactive(), source.getHovered());
}
- public void setIcons(final Icon regular, final Icon inactive, final Icon hovered) {
+ public void setIcons(final Icon regular, Icon inactive, Icon hovered) {
+ if (regular == null) return;
+ if (inactive == null) inactive = regular;
+ if (hovered == null) hovered = regular;
+
int width = Math.max(regular.getIconWidth(), inactive.getIconWidth());
width = Math.max(width, hovered.getIconWidth());
int height = Math.max(regular.getIconHeight(), inactive.getIconHeight());
diff --git a/platform/platform-api/src/com/intellij/ui/JBListWithHintProvider.java b/platform/platform-api/src/com/intellij/ui/JBListWithHintProvider.java
index 5ef516210e0d..f859421bbbee 100644
--- a/platform/platform-api/src/com/intellij/ui/JBListWithHintProvider.java
+++ b/platform/platform-api/src/com/intellij/ui/JBListWithHintProvider.java
@@ -18,79 +18,59 @@ package com.intellij.ui;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.psi.PsiElement;
import com.intellij.ui.components.JBList;
-import com.intellij.ui.popup.PopupUpdateProcessorBase;
+import com.intellij.ui.popup.HintUpdateSupply;
+import com.intellij.util.ObjectUtils;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
-import javax.swing.event.ListSelectionEvent;
-import javax.swing.event.ListSelectionListener;
import java.util.Collection;
/**
* @author pegov
+ * @deprecated
+ * @see com.intellij.ui.popup.HintUpdateSupply
*/
public abstract class JBListWithHintProvider extends JBList {
- private JBPopup myHint;
+ {
+ new HintUpdateSupply(this) {
+ @Override
+ protected PsiElement getPsiElementForHint(Object selectedValue) {
+ return JBListWithHintProvider.this.getPsiElementForHint(selectedValue);
+ }
+ };
+ }
public JBListWithHintProvider() {
- addSelectionListener();
}
public JBListWithHintProvider(ListModel dataModel) {
super(dataModel);
- addSelectionListener();
}
public JBListWithHintProvider(Object... listData) {
super(listData);
- addSelectionListener();
}
public JBListWithHintProvider(Collection items) {
super(items);
- addSelectionListener();
}
- private void addSelectionListener() {
- addListSelectionListener(new ListSelectionListener() {
- @Override
- public void valueChanged(final ListSelectionEvent e) {
- if (getClientProperty(ListUtil.SELECTED_BY_MOUSE_EVENT) != Boolean.TRUE) {
- final Object[] selectedValues = ((JList)e.getSource()).getSelectedValues();
- if (selectedValues.length != 1) return;
-
- final PsiElement element = getPsiElementForHint(selectedValues[0]);
- if (element != null && element.isValid()) {
- updateHint(element);
- }
- }
- }
- });
- }
-
@Nullable
protected abstract PsiElement getPsiElementForHint(final Object selectedValue);
- public void registerHint(final JBPopup hint) {
- hideHint();
- myHint = hint;
+ @Deprecated
+ public void registerHint(JBPopup hint) {
+ ObjectUtils.assertNotNull(HintUpdateSupply.getSupply(this)).registerHint(hint);
}
-
- public void hideHint() {
- if (myHint != null && myHint.isVisible()) {
- myHint.cancel();
- }
- myHint = null;
+ @Deprecated
+ public void hideHint() {
+ ObjectUtils.assertNotNull(HintUpdateSupply.getSupply(this)).hideHint();
}
-
- public void updateHint(PsiElement element) {
- if (myHint == null || !myHint.isVisible()) return;
- final PopupUpdateProcessorBase updateProcessor = myHint.getUserData(PopupUpdateProcessorBase.class);
- if (updateProcessor != null) {
- updateProcessor.updatePopup(element);
- }
+ @Deprecated
+ public void updateHint(PsiElement element) {
+ ObjectUtils.assertNotNull(HintUpdateSupply.getSupply(this)).updateHint(element);
}
-
+
}
diff --git a/platform/platform-api/src/com/intellij/ui/ScreenUtil.java b/platform/platform-api/src/com/intellij/ui/ScreenUtil.java
index 75769d25c0db..74fe7bb31108 100644
--- a/platform/platform-api/src/com/intellij/ui/ScreenUtil.java
+++ b/platform/platform-api/src/com/intellij/ui/ScreenUtil.java
@@ -56,22 +56,14 @@ public class ScreenUtil {
}
public static Rectangle getMainScreenBounds() {
- GraphicsConfiguration graphicsConfiguration =
- GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
- Rectangle bounds = graphicsConfiguration.getBounds();
- applyInsets(bounds, getScreenInsets(graphicsConfiguration));
- return bounds;
+ return getScreenRectangle(GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice());
}
private static Rectangle[] getAllScreenBounds() {
- final GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
- final GraphicsDevice[] devices = env.getScreenDevices();
+ GraphicsDevice[] devices = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
Rectangle[] result = new Rectangle[devices.length];
for (int i = 0; i < devices.length; i++) {
- GraphicsDevice device = devices[i];
- GraphicsConfiguration configuration = device.getDefaultConfiguration();
- result[i] = new Rectangle(configuration.getBounds());
- applyInsets(result[i], getScreenInsets(configuration));
+ result[i] = getScreenRectangle(devices[i]);
}
return result;
}
@@ -86,27 +78,7 @@ public class ScreenUtil {
}
public static Rectangle getScreenRectangle(@NotNull Point p) {
- double distance = -1;
- Rectangle answer = null;
-
- Rectangle[] allScreenBounds = getAllScreenBounds();
- for (Rectangle rect : allScreenBounds) {
- if (rect.contains(p)) {
- return rect;
- }
-
- final double d = findNearestPointOnBorder(rect, p).distance(p.x, p.y);
- if (answer == null || distance > d) {
- distance = d;
- answer = rect;
- }
- }
-
- if (answer == null) {
- throw new IllegalStateException("It's impossible to determine target graphics environment for point (" + p.x + "," + p.y + ")");
- }
-
- return answer;
+ return getScreenRectangle(p.x, p.y);
}
public static GraphicsDevice getScreenDevice(Rectangle bounds) {
@@ -150,11 +122,12 @@ public class ScreenUtil {
}
private static Rectangle applyInsets(Rectangle rect, Insets i) {
- if (i == null) {
- return rect;
- }
-
- return new Rectangle(rect.x + i.left, rect.y + i.top, rect.width - (i.left + i.right), rect.height - (i.top + i.bottom));
+ return (i == null)
+ ? new Rectangle(rect)
+ : new Rectangle(rect.x + i.left,
+ rect.y + i.top,
+ rect.width - (i.left + i.right),
+ rect.height - (i.top + i.bottom));
}
public static Insets getScreenInsets(final GraphicsConfiguration gc) {
@@ -181,8 +154,83 @@ public class ScreenUtil {
return Toolkit.getDefaultToolkit().getScreenInsets(gc);
}
+ /**
+ * Returns a visible area for the specified graphics device.
+ *
+ * @param device one of available devices
+ * @return a visible area rectangle
+ */
+ private static Rectangle getScreenRectangle(GraphicsDevice device) {
+ GraphicsConfiguration configuration = device.getDefaultConfiguration();
+ return applyInsets(configuration.getBounds(), getScreenInsets(configuration));
+ }
+
+ /**
+ * Finds a device that is the closest to the specified point and
+ * returns its visible area.
+ *
+ * @param x the X coordinate of the specified point
+ * @param y the Y coordinate of the specified point
+ * @return a visible area rectangle
+ */
public static Rectangle getScreenRectangle(int x, int y) {
- return getScreenRectangle(new Point(x, y));
+ GraphicsDevice[] devices = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
+ if (devices.length == 0) {
+ return new Rectangle(x, y, 0, 0);
+ }
+ if (devices.length == 1) {
+ return getScreenRectangle(devices[0]);
+ }
+ Rectangle[] rectangles = new Rectangle[devices.length];
+ for (int i = 0; i < devices.length; i++) {
+ GraphicsConfiguration configuration = devices[i].getDefaultConfiguration();
+ Rectangle bounds = configuration.getBounds();
+ rectangles[i] = applyInsets(bounds, getScreenInsets(configuration));
+ if (bounds.contains(x, y)) {
+ return rectangles[i];
+ }
+ }
+ Rectangle bounds = rectangles[0];
+ int minimum = distance(bounds, x, y);
+ for (int i = 1; i < rectangles.length; i++) {
+ int distance = distance(rectangles[i], x, y);
+ if (minimum > distance) {
+ minimum = distance;
+ bounds = rectangles[i];
+ }
+ }
+ return bounds;
+ }
+
+ /**
+ * Normalizes a specified value in the specified range.
+ * If value less than the minimal value,
+ * the method returns the minimal value.
+ * If value greater than the maximal value,
+ * the method returns the maximal value.
+ *
+ * @param value the value to normalize
+ * @param min the minimal value of the range
+ * @param max the maximal value of the range
+ * @return a normalized value
+ */
+ private static int normalize(int value, int min, int max) {
+ return value < min ? min : value > max ? max : value;
+ }
+
+ /**
+ * Returns a square of the distance from
+ * the specified point to the specified rectangle,
+ * which does not contain the specified point.
+ *
+ * @param x the X coordinate of the specified point
+ * @param y the Y coordinate of the specified point
+ * @return a square of the distance
+ */
+ private static int distance(Rectangle bounds, int x, int y) {
+ x -= normalize(x, bounds.x, bounds.x + bounds.width);
+ y -= normalize(y, bounds.y, bounds.y + bounds.height);
+ return x * x + y * y;
}
public static boolean isOutsideOnTheRightOFScreen(Rectangle rect) {
diff --git a/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java b/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java
index 97a42176a25b..51535b67f9af 100644
--- a/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java
+++ b/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java
@@ -235,7 +235,7 @@ public class JBScrollPane extends JScrollPane {
}
if (colHead != null) {
Rectangle headerBounds = colHead.getBounds();
- headerBounds.width = viewportBounds.width - headerBounds.x;
+ headerBounds.width = viewportBounds.width;
colHead.setBounds(headerBounds);
}
hideFromView(layout.getCorner(UPPER_RIGHT_CORNER));
@@ -249,7 +249,7 @@ public class JBScrollPane extends JScrollPane {
}
if (rowHead != null) {
Rectangle headerBounds = rowHead.getBounds();
- headerBounds.height = viewportBounds.height - headerBounds.y;
+ headerBounds.height = viewportBounds.height;
rowHead.setBounds(headerBounds);
}
diff --git a/platform/platform-api/src/com/intellij/ui/popup/HintUpdateSupply.java b/platform/platform-api/src/com/intellij/ui/popup/HintUpdateSupply.java
new file mode 100644
index 000000000000..54b071ab0b94
--- /dev/null
+++ b/platform/platform-api/src/com/intellij/ui/popup/HintUpdateSupply.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.ui.popup;
+
+import com.intellij.openapi.ui.popup.JBPopup;
+import com.intellij.openapi.util.Key;
+import com.intellij.psi.PsiElement;
+import com.intellij.ui.ListUtil;
+import com.intellij.ui.components.JBList;
+import com.intellij.ui.table.JBTable;
+import com.intellij.ui.treeStructure.Tree;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.tree.TreePath;
+
+/**
+ * Use this class to make various hints like QuickDocumentation, ShowImplementations, etc.
+ * respond to the selection change in the original component like ProjectView, various GoTo popups, etc.
+ *
+ * @author gregsh
+ */
+public abstract class HintUpdateSupply {
+ private static final Key<HintUpdateSupply> HINT_UPDATE_MARKER = Key.create("HINT_UPDATE_MARKER");
+
+ @Nullable
+ private JBPopup myHint;
+
+ @Nullable
+ public static HintUpdateSupply getSupply(@NotNull JComponent component) {
+ return (HintUpdateSupply)component.getClientProperty(HINT_UPDATE_MARKER);
+ }
+
+ public static void hideHint(@NotNull JComponent component) {
+ HintUpdateSupply supply = getSupply(component);
+ if (supply != null) supply.hideHint();
+ }
+
+ protected HintUpdateSupply(@NotNull JComponent component) {
+ installSupply(component);
+ }
+
+ public HintUpdateSupply(@NotNull final JBTable table) {
+ installSupply(table);
+ ListSelectionListener listener = new ListSelectionListener() {
+ @Override
+ public void valueChanged(final ListSelectionEvent e) {
+ if (!isHintVisible(HintUpdateSupply.this.myHint) || isSelectedByMouse(table)) return;
+
+ int selected = ((ListSelectionModel)e.getSource()).getLeadSelectionIndex();
+ int rowCount = table.getRowCount();
+ if (selected == -1 || rowCount == 0) return;
+
+ PsiElement element = getPsiElementForHint(table.getValueAt(Math.min(selected, rowCount - 1), 0));
+ if (element != null && element.isValid()) {
+ updateHint(element);
+ }
+ }
+ };
+ table.getSelectionModel().addListSelectionListener(listener);
+ table.getColumnModel().getSelectionModel().addListSelectionListener(listener);
+ }
+
+ public HintUpdateSupply(@NotNull final Tree tree) {
+ installSupply(tree);
+ tree.addTreeSelectionListener(new TreeSelectionListener() {
+ @Override
+ public void valueChanged(final TreeSelectionEvent e) {
+ if (!isHintVisible(HintUpdateSupply.this.myHint) || isSelectedByMouse(tree)) return;
+
+ TreePath path = tree.getSelectionPath();
+ if (path != null) {
+ final PsiElement psiElement = getPsiElementForHint(path.getLastPathComponent());
+ if (psiElement != null && psiElement.isValid()) {
+ updateHint(psiElement);
+ }
+ }
+ }
+ });
+ }
+
+ public HintUpdateSupply(@NotNull final JBList list) {
+ installSupply(list);
+ list.addListSelectionListener(new ListSelectionListener() {
+ @Override
+ public void valueChanged(final ListSelectionEvent e) {
+ if (!isHintVisible(HintUpdateSupply.this.myHint) || isSelectedByMouse(list)) return;
+
+ Object[] selectedValues = ((JList)e.getSource()).getSelectedValues();
+ if (selectedValues.length != 1) return;
+
+ PsiElement element = getPsiElementForHint(selectedValues[0]);
+ if (element != null && element.isValid()) {
+ updateHint(element);
+ }
+ }
+ });
+ }
+
+ @Nullable
+ protected abstract PsiElement getPsiElementForHint(@Nullable Object selectedValue);
+
+ private void installSupply(@NotNull JComponent component) {
+ component.putClientProperty(HINT_UPDATE_MARKER, this);
+ }
+
+ public void registerHint(JBPopup hint) {
+ hideHint();
+ myHint = hint;
+ }
+
+ public void hideHint() {
+ if (isHintVisible(myHint)) {
+ myHint.cancel();
+ }
+
+ myHint = null;
+ }
+
+ public void updateHint(PsiElement element) {
+ if (!isHintVisible(myHint)) return;
+
+ PopupUpdateProcessorBase updateProcessor = myHint.getUserData(PopupUpdateProcessorBase.class);
+ if (updateProcessor != null) {
+ updateProcessor.updatePopup(element);
+ }
+ }
+
+ @Contract("!null->true")
+ private static boolean isHintVisible(JBPopup hint) {
+ return hint != null && hint.isVisible();
+ }
+
+ private static boolean isSelectedByMouse(@NotNull JComponent c) {
+ return Boolean.TRUE.equals(c.getClientProperty(ListUtil.SELECTED_BY_MOUSE_EVENT));
+ }
+}
diff --git a/platform/platform-api/src/com/intellij/ui/table/JBTable.java b/platform/platform-api/src/com/intellij/ui/table/JBTable.java
index bda230eb767e..c1146be40aba 100644
--- a/platform/platform-api/src/com/intellij/ui/table/JBTable.java
+++ b/platform/platform-api/src/com/intellij/ui/table/JBTable.java
@@ -424,7 +424,7 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component
if (e instanceof KeyEvent) {
// do not start editing in autoStartsEdit mode on Ctrl-Z and other non-typed events
- if (!UIUtil.isReallyTypedEvent((KeyEvent)e)) return false;
+ if (!UIUtil.isReallyTypedEvent((KeyEvent)e) || ((KeyEvent)e).getKeyChar() == KeyEvent.CHAR_UNDEFINED) return false;
SpeedSearchSupply supply = SpeedSearchSupply.getSupply(this);
if (supply != null && supply.isPopupActive()) {
@@ -743,7 +743,7 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component
@Override
public void setColor(Color color) {
- if (!UIUtil.isUnderDarcula() || !JBTable.this.getBackground().equals(color)) {
+ if (color != null && (!UIUtil.isUnderDarcula() || !JBTable.this.getBackground().equals(color))) {
//noinspection UseJBColor
color = new Color(UIUtil.getGrayFilter().filterRGB(0, 0, color.getRGB()));
}
diff --git a/platform/platform-api/src/com/intellij/util/PlatformUtils.java b/platform/platform-api/src/com/intellij/util/PlatformUtils.java
index 064b5ccc48b6..dfcb5ccf624f 100644
--- a/platform/platform-api/src/com/intellij/util/PlatformUtils.java
+++ b/platform/platform-api/src/com/intellij/util/PlatformUtils.java
@@ -28,7 +28,7 @@ public class PlatformUtils {
public static final String IDEA_PREFIX = PlatformUtilsCore.IDEA_PREFIX;
public static final String IDEA_CE_PREFIX = PlatformUtilsCore.COMMUNITY_PREFIX;
public static final String APPCODE_PREFIX = PlatformUtilsCore.APPCODE_PREFIX;
- public static final String CPP_PREFIX = PlatformUtilsCore.CPP_PREFIX;
+ public static final String CLION_PREFIX = PlatformUtilsCore.CLION_PREFIX;
public static final String PYCHARM_PREFIX = PlatformUtilsCore.PYCHARM_PREFIX;
public static final String PYCHARM_CE_PREFIX = PlatformUtilsCore.PYCHARM_PREFIX2;
public static final String RUBY_PREFIX = PlatformUtilsCore.RUBY_PREFIX;
@@ -66,12 +66,12 @@ public class PlatformUtils {
return PlatformUtilsCore.isAppCode();
}
- public static boolean isCppIde() {
- return PlatformUtilsCore.isCppIde();
+ public static boolean isCLion() {
+ return PlatformUtilsCore.isCLion();
}
public static boolean isCidr() {
- return isAppCode() || isCppIde();
+ return isAppCode() || isCLion();
}
public static boolean isPyCharm() {
diff --git a/platform/platform-api/src/com/intellij/util/net/AuthenticationDialog.java b/platform/platform-api/src/com/intellij/util/net/AuthenticationDialog.java
index 246f1e449d5d..83cca8a039df 100644
--- a/platform/platform-api/src/com/intellij/util/net/AuthenticationDialog.java
+++ b/platform/platform-api/src/com/intellij/util/net/AuthenticationDialog.java
@@ -23,13 +23,6 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
-/**
- * Created by IntelliJ IDEA.
- * User: stathik
- * Date: Oct 7, 2003
- * Time: 3:56:25 PM
- * To change this template use Options | File Templates.
- */
public class AuthenticationDialog extends DialogWrapper {
private final AuthenticationPanel panel;
@@ -42,7 +35,7 @@ public class AuthenticationDialog extends DialogWrapper {
final Window window = getWindow();
if (window instanceof JDialog) {
- ((JDialog) window).setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+ ((JDialog) window).setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
}
init();
@@ -57,7 +50,7 @@ public class AuthenticationDialog extends DialogWrapper {
final Window window = getWindow();
if (window instanceof JDialog) {
- ((JDialog) window).setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+ ((JDialog) window).setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
}
init();
@@ -69,6 +62,7 @@ public class AuthenticationDialog extends DialogWrapper {
return panel.getPreferredFocusedComponent();
}
+ @Override
@Nullable
protected JComponent createCenterPanel() {
return panel;
diff --git a/platform/platform-api/src/com/intellij/util/net/HTTPProxySettingsDialog.java b/platform/platform-api/src/com/intellij/util/net/HTTPProxySettingsDialog.java
index 52dfa7e7e5ab..5d7d807095f1 100644
--- a/platform/platform-api/src/com/intellij/util/net/HTTPProxySettingsDialog.java
+++ b/platform/platform-api/src/com/intellij/util/net/HTTPProxySettingsDialog.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,43 +22,48 @@ import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.event.ActionEvent;
+@Deprecated
+@SuppressWarnings("UnusedDeclaration")
/**
- * Created by IntelliJ IDEA.
- * User: stathik
- * Date: Oct 21, 2003
- * Time: 4:35:44 PM
- * To change this template use Options | File Templates.
+ * @deprecated Use {@link com.intellij.util.net.HttpConfigurable#editConfigurable(javax.swing.JComponent)}
+ * to remove in IDEA 15
*/
public class HTTPProxySettingsDialog extends DialogWrapper {
- private final HTTPProxySettingsPanel panel;
+ private final HttpProxySettingsUi panel;
private final Action okAction;
private final Action cancelAction;
public HTTPProxySettingsDialog() {
super(false);
+
setTitle(CommonBundle.message("title.http.proxy.settings"));
- panel = new HTTPProxySettingsPanel(HttpConfigurable.getInstance());
- panel.reset();
+ final HttpConfigurable settings = HttpConfigurable.getInstance();
+ panel = new HttpProxySettingsUi(settings);
+ panel.reset(settings);
okAction = new AbstractAction(CommonBundle.getOkButtonText()) {
- public void actionPerformed(ActionEvent e) {
- panel.apply();
+ @Override
+ public void actionPerformed(@NotNull ActionEvent e) {
+ panel.apply(settings);
close(OK_EXIT_CODE);
}
};
okAction.putValue(DEFAULT_ACTION, Boolean.TRUE.toString());
cancelAction = new AbstractAction(CommonBundle.getCancelButtonText()) {
- public void actionPerformed(ActionEvent e) {
+ @Override
+ public void actionPerformed(@NotNull ActionEvent e) {
close(CANCEL_EXIT_CODE);
}
};
init();
}
+ @Override
protected JComponent createCenterPanel() {
- return panel.createComponent();
+ return panel.getComponent();
}
+ @Override
@NotNull
protected Action[] createActions() {
return new Action[]{okAction, cancelAction};
diff --git a/platform/platform-api/src/com/intellij/util/net/HTTPProxySettingsPanel.java b/platform/platform-api/src/com/intellij/util/net/HTTPProxySettingsPanel.java
index 46ea422a3f69..f53c88f372e5 100644
--- a/platform/platform-api/src/com/intellij/util/net/HTTPProxySettingsPanel.java
+++ b/platform/platform-api/src/com/intellij/util/net/HTTPProxySettingsPanel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,389 +15,18 @@
*/
package com.intellij.util.net;
-import com.intellij.openapi.application.Application;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.options.Configurable;
-import com.intellij.openapi.options.SearchableConfigurable;
-import com.intellij.openapi.ui.Messages;
-import com.intellij.openapi.ui.MultiLineLabelUI;
-import com.intellij.openapi.util.Comparing;
-import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.openapi.wm.IdeFocusManager;
-import com.intellij.openapi.wm.IdeFrame;
-import com.intellij.ui.components.JBLabel;
-import com.intellij.ui.components.JBRadioButton;
-import com.intellij.util.proxy.CommonProxy;
-import com.intellij.util.proxy.JavaProxyProperty;
-import com.intellij.util.ui.UIUtil;
-import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
-import javax.swing.*;
-import javax.swing.event.DocumentEvent;
-import javax.swing.event.DocumentListener;
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.util.concurrent.atomic.AtomicReference;
-
+@SuppressWarnings("UnusedDeclaration")
+@Deprecated
/**
- * Created by IntelliJ IDEA.
- * User: stathik
- * Date: Aug 28, 2003
- * Time: 3:52:47 PM
- * To change this template use Options | File Templates.
+ * @deprecated Use {@link HttpProxyConfigurable}
+ * to remove in IDEA 15
*/
-public class HTTPProxySettingsPanel implements SearchableConfigurable, Configurable.NoScroll {
+public class HTTPProxySettingsPanel extends HttpProxyConfigurable {
public static final String NAME = "Proxy";
- private JPanel myMainPanel;
-
- private JTextField myProxyLoginTextField;
- private JPasswordField myProxyPasswordTextField;
- private JCheckBox myProxyAuthCheckBox;
- private JTextField myProxyPortTextField;
- private JTextField myProxyHostTextField;
- private JCheckBox myRememberProxyPasswordCheckBox;
-
- private JLabel myProxyLoginLabel;
- private JLabel myProxyPasswordLabel;
- private JLabel myHostNameLabel;
- private JLabel myPortNumberLabel;
- private JBRadioButton myAutoDetectProxyRb;
- private JBRadioButton myUseHTTPProxyRb;
- private JBLabel mySystemProxyDefined;
- private JBRadioButton myNoProxyRb;
- private JBRadioButton myHTTP;
- private JBRadioButton mySocks;
- private JButton myClearPasswordsButton;
- private JLabel myErrorLabel;
- private JButton myCheckButton;
- private JBLabel myOtherWarning;
- private JLabel myProxyExceptionsLabel;
- private JTextArea myProxyExceptions;
- private JLabel myNoProxyForLabel;
- private JCheckBox myPacUrlCheckBox;
- private JTextField myPacUrlTextField;
- private final HttpConfigurable myHttpConfigurable;
- private volatile boolean myConnectionCheckInProgress;
-
- public boolean isModified() {
- boolean isModified = false;
- HttpConfigurable httpConfigurable = myHttpConfigurable;
- if (! Comparing.equal(myProxyExceptions.getText().trim(), httpConfigurable.PROXY_EXCEPTIONS)) return true;
- isModified |= httpConfigurable.USE_PROXY_PAC != myAutoDetectProxyRb.isSelected();
- isModified |= httpConfigurable.USE_PAC_URL != myPacUrlCheckBox.isSelected();
- isModified |= !Comparing.strEqual(httpConfigurable.PAC_URL, myPacUrlTextField.getText());
- isModified |= httpConfigurable.USE_HTTP_PROXY != myUseHTTPProxyRb.isSelected();
- isModified |= httpConfigurable.PROXY_AUTHENTICATION != myProxyAuthCheckBox.isSelected();
- isModified |= httpConfigurable.KEEP_PROXY_PASSWORD != myRememberProxyPasswordCheckBox.isSelected();
- isModified |= httpConfigurable.PROXY_TYPE_IS_SOCKS != mySocks.isSelected();
-
- isModified |= !Comparing.strEqual(httpConfigurable.PROXY_LOGIN, myProxyLoginTextField.getText());
- isModified |= !Comparing.strEqual(httpConfigurable.getPlainProxyPassword(),new String (myProxyPasswordTextField.getPassword()));
-
- try {
- isModified |= httpConfigurable.PROXY_PORT != Integer.valueOf(myProxyPortTextField.getText()).intValue();
- } catch (NumberFormatException e) {
- isModified = true;
- }
- isModified |= !Comparing.strEqual(httpConfigurable.PROXY_HOST, myProxyHostTextField.getText());
- return isModified;
- }
-
- public HTTPProxySettingsPanel(final HttpConfigurable httpConfigurable) {
- final ButtonGroup group = new ButtonGroup();
- group.add(myUseHTTPProxyRb);
- group.add(myAutoDetectProxyRb);
- group.add(myNoProxyRb);
- myNoProxyRb.setSelected(true);
-
- final ButtonGroup proxyTypeGroup = new ButtonGroup();
- proxyTypeGroup.add(myHTTP);
- proxyTypeGroup.add(mySocks);
- myHTTP.setSelected(true);
-
- myProxyExceptions.setBorder(UIUtil.getTextFieldBorder());
-
- final Boolean property = Boolean.getBoolean(JavaProxyProperty.USE_SYSTEM_PROXY);
- mySystemProxyDefined.setVisible(Boolean.TRUE.equals(property));
- if (Boolean.TRUE.equals(property)) {
- mySystemProxyDefined.setIcon(Messages.getWarningIcon());
- mySystemProxyDefined.setFont(mySystemProxyDefined.getFont().deriveFont(Font.BOLD));
- mySystemProxyDefined.setUI(new MultiLineLabelUI());
- }
-
- myProxyAuthCheckBox.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- enableProxyAuthentication(myProxyAuthCheckBox.isSelected());
- }
- });
- myPacUrlCheckBox.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- myPacUrlTextField.setEnabled(myPacUrlCheckBox.isSelected());
- }
- });
-
- final ActionListener listener = new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- enableProxy(myUseHTTPProxyRb.isSelected());
- }
- };
- myUseHTTPProxyRb.addActionListener(listener);
- myAutoDetectProxyRb.addActionListener(listener);
- myNoProxyRb.addActionListener(listener);
- myHttpConfigurable = httpConfigurable;
-
- myClearPasswordsButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- myHttpConfigurable.clearGenericPasswords();
- Messages.showMessageDialog(myMainPanel, "Proxy passwords were cleared.", "Auto-detected proxy", Messages.getInformationIcon());
- }
- });
-
- if (HttpConfigurable.getInstance() != null) {
- myCheckButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- final String title = "Check Proxy Settings";
- final String answer = Messages
- .showInputDialog(myMainPanel, "Warning: your settings will be saved.\n\nEnter any URL to check connection to:",
- title, Messages.getQuestionIcon(), "http://", null);
- if (! StringUtil.isEmptyOrSpaces(answer)) {
- apply();
- final HttpConfigurable instance = HttpConfigurable.getInstance();
- final AtomicReference<IOException> exc = new AtomicReference<IOException>();
- myCheckButton.setEnabled(false);
- myCheckButton.setText("Check connection (in progress...)");
- myConnectionCheckInProgress = true;
- final Application application = ApplicationManager.getApplication();
- application.executeOnPooledThread(new Runnable() {
- @Override
- public void run() {
- HttpURLConnection connection = null;
- try {
- //already checked for null above
- //noinspection ConstantConditions
- connection = instance.openHttpConnection(answer);
- connection.setReadTimeout(3 * 1000);
- connection.setConnectTimeout(3 * 1000);
- connection.connect();
- final int code = connection.getResponseCode();
- if (HttpURLConnection.HTTP_OK != code) {
- exc.set(new IOException("Error code: " + code));
- }
- }
- catch (IOException e1) {
- exc.set(e1);
- }
- finally {
- if (connection != null) {
- connection.disconnect();
- }
- }
- //noinspection SSBasedInspection
- SwingUtilities.invokeLater(new Runnable() {
- @Override
- public void run() {
- myConnectionCheckInProgress = false;
- reset(); // since password might have been set
- Component parent = null;
- if (myMainPanel.isShowing()) {
- parent = myMainPanel;
- myCheckButton.setText("Check connection");
- myCheckButton.setEnabled(canEnableConnectionCheck());
- } else {
- final IdeFrame frame = IdeFocusManager.findInstance().getLastFocusedFrame();
- if (frame == null) {
- return;
- }
- parent = frame.getComponent();
- }
- //noinspection ThrowableResultOfMethodCallIgnored
- final IOException exception = exc.get();
- if (exception == null) {
- Messages.showMessageDialog(parent, "Connection successful", title, Messages.getInformationIcon());
- }
- else {
- final String message = exception.getMessage();
- if (instance.USE_HTTP_PROXY) {
- instance.LAST_ERROR = message;
- }
- Messages.showErrorDialog(parent, errorText(message));
- }
- }
- });
- }
- });
- }
- }
- });
- } else {
- myCheckButton.setVisible(false);
- }
- }
-
- private boolean canEnableConnectionCheck() {
- return ! myNoProxyRb.isSelected() && ! myConnectionCheckInProgress;
- }
-
- public void reset() {
- myNoProxyRb.setSelected(true); // default
- HttpConfigurable httpConfigurable = myHttpConfigurable;
- myAutoDetectProxyRb.setSelected(httpConfigurable.USE_PROXY_PAC);
- myPacUrlCheckBox.setSelected(httpConfigurable.USE_PAC_URL);
- myPacUrlTextField.setText(httpConfigurable.PAC_URL);
- myUseHTTPProxyRb.setSelected(httpConfigurable.USE_HTTP_PROXY);
- myProxyAuthCheckBox.setSelected(httpConfigurable.PROXY_AUTHENTICATION);
-
- enableProxy(httpConfigurable.USE_HTTP_PROXY);
-
- myProxyLoginTextField.setText(httpConfigurable.PROXY_LOGIN);
- myProxyPasswordTextField.setText(httpConfigurable.getPlainProxyPassword());
-
- myProxyPortTextField.setText(Integer.toString(httpConfigurable.PROXY_PORT));
- myProxyHostTextField.setText(httpConfigurable.PROXY_HOST);
- myProxyExceptions.setText(httpConfigurable.PROXY_EXCEPTIONS);
-
- myRememberProxyPasswordCheckBox.setSelected(httpConfigurable.KEEP_PROXY_PASSWORD);
- mySocks.setSelected(httpConfigurable.PROXY_TYPE_IS_SOCKS);
- myHTTP.setSelected(!httpConfigurable.PROXY_TYPE_IS_SOCKS);
-
- final boolean showError = !StringUtil.isEmptyOrSpaces(httpConfigurable.LAST_ERROR);
- myErrorLabel.setVisible(showError);
- myErrorLabel.setText(showError ? errorText(httpConfigurable.LAST_ERROR) : "");
-
- final String oldStyleText = CommonProxy.getMessageFromProps(CommonProxy.getOldStyleProperties());
- myOtherWarning.setVisible(oldStyleText != null);
- if (oldStyleText != null) {
- myOtherWarning.setText(oldStyleText);
- myOtherWarning.setUI(new MultiLineLabelUI());
- myOtherWarning.setIcon(Messages.getWarningIcon());
- }
- }
-
- private String errorText(final String s) {
- return "Problem with connection: " + s;
- }
-
- public void apply () {
- HttpConfigurable httpConfigurable = myHttpConfigurable;
- if (isModified()){
- httpConfigurable.AUTHENTICATION_CANCELLED = false;
- }
- httpConfigurable.USE_PROXY_PAC = myAutoDetectProxyRb.isSelected();
- httpConfigurable.USE_PAC_URL = myPacUrlCheckBox.isSelected();
- httpConfigurable.PAC_URL = trimFieldText(myPacUrlTextField);
- httpConfigurable.USE_HTTP_PROXY = myUseHTTPProxyRb.isSelected();
- httpConfigurable.PROXY_TYPE_IS_SOCKS = mySocks.isSelected();
- httpConfigurable.PROXY_AUTHENTICATION = myProxyAuthCheckBox.isSelected();
- httpConfigurable.KEEP_PROXY_PASSWORD = myRememberProxyPasswordCheckBox.isSelected();
-
- httpConfigurable.PROXY_LOGIN = trimFieldText(myProxyLoginTextField);
- httpConfigurable.setPlainProxyPassword(new String(myProxyPasswordTextField.getPassword()));
- httpConfigurable.PROXY_EXCEPTIONS = myProxyExceptions.getText();
-
- try {
- httpConfigurable.PROXY_PORT = Integer.valueOf(trimFieldText(myProxyPortTextField)).intValue();
- } catch (NumberFormatException e) {
- httpConfigurable.PROXY_PORT = 80;
- }
- httpConfigurable.PROXY_HOST = trimFieldText(myProxyHostTextField);
- }
-
- private static String trimFieldText(JTextField field) {
- String trimmed = field.getText().trim();
- field.setText(trimmed);
- return trimmed;
- }
-
- private void enableProxy (boolean enabled) {
- myHostNameLabel.setEnabled(enabled);
- myPortNumberLabel.setEnabled(enabled);
- myProxyHostTextField.setEnabled(enabled);
- myProxyPortTextField.setEnabled(enabled);
- mySocks.setEnabled(enabled);
- myHTTP.setEnabled(enabled);
- myProxyExceptions.setEnabled(enabled);
- myProxyExceptions.setBackground(myProxyPortTextField.getBackground());
- myProxyExceptionsLabel.setEnabled(enabled);
- myNoProxyForLabel.setEnabled(enabled);
-
- myProxyAuthCheckBox.setEnabled(enabled);
- enableProxyAuthentication(enabled && myProxyAuthCheckBox.isSelected());
- myCheckButton.setEnabled(canEnableConnectionCheck());
-
- final boolean autoDetectProxy = myAutoDetectProxyRb.isSelected();
- myPacUrlCheckBox.setEnabled(autoDetectProxy);
- myClearPasswordsButton.setEnabled(autoDetectProxy);
- myPacUrlTextField.setEnabled(autoDetectProxy && myPacUrlCheckBox.isSelected());
- }
-
- private void enableProxyAuthentication (boolean enabled) {
- myProxyPasswordLabel.setEnabled(enabled);
- myProxyLoginLabel.setEnabled(enabled);
-
- myProxyLoginTextField.setEnabled(enabled);
- myProxyPasswordTextField.setEnabled(enabled);
-
- myRememberProxyPasswordCheckBox.setEnabled(enabled);
- }
-
- public JComponent getComponent() {
- return myMainPanel;
- }
-
- public JComponent createComponent() {
- return myMainPanel;
- }
-
- @NotNull
- public String getId() {
- return getHelpTopic();
- }
-
- public Runnable enableSearch(final String option) {
- return null;
- }
-
- @Nls
- public String getDisplayName() {
- return NAME;
- }
-
- public String getHelpTopic() {
- return "http.proxy";
- }
-
- public void addActionListener(final ActionListener actionListener) {
- myProxyLoginTextField.addActionListener(actionListener);
- DocumentListener docListener = new DocumentListener() {
- public void insertUpdate(DocumentEvent e) {
- actionListener.actionPerformed(null);
- }
-
- public void removeUpdate(DocumentEvent e) {
- actionListener.actionPerformed(null);
- }
-
- public void changedUpdate(DocumentEvent e) {
- actionListener.actionPerformed(null);
- }
- };
- myProxyPasswordTextField.getDocument().addDocumentListener(docListener);
- myProxyAuthCheckBox.addActionListener(actionListener);
- myProxyPortTextField.getDocument().addDocumentListener(docListener);
- myProxyHostTextField.getDocument().addDocumentListener(docListener);
- myUseHTTPProxyRb.addActionListener(actionListener);
- myRememberProxyPasswordCheckBox.addActionListener(actionListener);
-
- }
- @Override
- public void disposeUIResources() {
+ public HTTPProxySettingsPanel(@NotNull HttpConfigurable settings) {
+ super(settings);
}
-}
+} \ No newline at end of file
diff --git a/platform/platform-api/src/com/intellij/util/net/HttpConfigurable.java b/platform/platform-api/src/com/intellij/util/net/HttpConfigurable.java
index d51891a8ffe4..0f9855001b63 100644
--- a/platform/platform-api/src/com/intellij/util/net/HttpConfigurable.java
+++ b/platform/platform-api/src/com/intellij/util/net/HttpConfigurable.java
@@ -21,22 +21,28 @@ import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.components.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.options.ShowSettingsUtil;
+import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.popup.util.PopupUtil;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.openapi.wm.IdeFrame;
+import com.intellij.util.Base64;
import com.intellij.util.SystemProperties;
import com.intellij.util.WaitForProgressToShow;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.proxy.CommonProxy;
import com.intellij.util.proxy.JavaProxyProperty;
import com.intellij.util.xmlb.XmlSerializer;
import com.intellij.util.xmlb.XmlSerializerUtil;
import com.intellij.util.xmlb.annotations.Transient;
-import org.apache.commons.codec.binary.Base64;
+import gnu.trove.THashMap;
+import gnu.trove.THashSet;
+import gnu.trove.TObjectObjectProcedure;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -48,75 +54,74 @@ import java.lang.reflect.InvocationTargetException;
import java.net.*;
import java.util.*;
-/**
- * Created by IntelliJ IDEA.
- * User: stathik
- * Date: Oct 7, 2003
- * Time: 3:58:23 PM
- * To change this template use Options | File Templates.
- */
@State(
name = "HttpConfigurable",
storages = {
- @Storage( file = StoragePathMacros.APP_CONFIG + "/other.xml" ),
- @Storage( file = StoragePathMacros.APP_CONFIG + "/proxy.settings.xml" )
+ // we use two storages due to backward compatibility, see http://crucible.labs.intellij.net/cru/CR-IC-5142
+ @Storage(file = StoragePathMacros.APP_CONFIG + "/other.xml"),
+ @Storage(file = StoragePathMacros.APP_CONFIG + "/proxy.settings.xml")
},
storageChooser = HttpConfigurable.StorageChooser.class
)
-public class HttpConfigurable implements PersistentStateComponent<HttpConfigurable>, ApplicationComponent,
- ExportableApplicationComponent {
+public class HttpConfigurable implements PersistentStateComponent<HttpConfigurable>, ExportableApplicationComponent {
public static final int CONNECTION_TIMEOUT = SystemProperties.getIntProperty("idea.connection.timeout", 10000);
- private static final Logger LOG = Logger.getInstance("#com.intellij.util.net.HttpConfigurable");
- public boolean PROXY_TYPE_IS_SOCKS = false;
- public boolean USE_HTTP_PROXY = false;
- public boolean USE_PROXY_PAC = false;
- public volatile transient boolean AUTHENTICATION_CANCELLED = false;
- public String PROXY_HOST = "";
+ private static final Logger LOG = Logger.getInstance(HttpConfigurable.class);
+
+ public boolean PROXY_TYPE_IS_SOCKS;
+ public boolean USE_HTTP_PROXY;
+ public boolean USE_PROXY_PAC;
+ public volatile transient boolean AUTHENTICATION_CANCELLED;
+ public String PROXY_HOST;
public int PROXY_PORT = 80;
- public volatile boolean PROXY_AUTHENTICATION = false;
- public volatile String PROXY_LOGIN = "";
- public volatile String PROXY_PASSWORD_CRYPT = "";
- public boolean KEEP_PROXY_PASSWORD = false;
+ public volatile boolean PROXY_AUTHENTICATION;
+ public volatile String PROXY_LOGIN;
+ public volatile String PROXY_PASSWORD_CRYPT;
+ public boolean KEEP_PROXY_PASSWORD;
public transient String LAST_ERROR;
- public Map<CommonProxy.HostInfo, ProxyInfo> myGenericPasswords = new HashMap<CommonProxy.HostInfo, ProxyInfo>();
- public Set<CommonProxy.HostInfo> myGenericCancelled = new HashSet<CommonProxy.HostInfo>();
+
+ private final THashMap<CommonProxy.HostInfo, ProxyInfo> myGenericPasswords = new THashMap<CommonProxy.HostInfo, ProxyInfo>();
+ private final Set<CommonProxy.HostInfo> myGenericCancelled = new THashSet<CommonProxy.HostInfo>();
+
+ public String PROXY_EXCEPTIONS;
+ public boolean USE_PAC_URL;
+ public String PAC_URL;
+
+ private transient IdeaWideProxySelector mySelector;
+
private transient final Object myLock = new Object();
- private IdeaWideProxySelector mySelector;
- private IdeaWideAuthenticator myAuthenticator;
+
+ @SuppressWarnings("UnusedDeclaration")
public transient Getter<PasswordAuthentication> myTestAuthRunnable = new StaticGetter<PasswordAuthentication>(null);
public transient Getter<PasswordAuthentication> myTestGenericAuthRunnable = new StaticGetter<PasswordAuthentication>(null);
- public String PROXY_EXCEPTIONS = "";
- public boolean USE_PAC_URL = false;
- public String PAC_URL = "";
public static HttpConfigurable getInstance() {
return ServiceManager.getService(HttpConfigurable.class);
}
- public static boolean editConfigurable(final JComponent parent) {
- return ShowSettingsUtil.getInstance().editConfigurable(parent, new HTTPProxySettingsPanel(getInstance()));
+ public static boolean editConfigurable(@Nullable JComponent parent) {
+ return ShowSettingsUtil.getInstance().editConfigurable(parent, new HttpProxyConfigurable());
}
@Override
public HttpConfigurable getState() {
CommonProxy.isInstalledAssertion();
- final HttpConfigurable state = new HttpConfigurable();
+
+ HttpConfigurable state = new HttpConfigurable();
XmlSerializerUtil.copyBean(this, state);
if (!KEEP_PROXY_PASSWORD) {
- state.PROXY_PASSWORD_CRYPT = "";
+ state.PROXY_PASSWORD_CRYPT = null;
}
- correctPasswords(this, state);
+ correctPasswords(state);
return state;
}
@Override
public void initComponent() {
mySelector = new IdeaWideProxySelector(this);
- myAuthenticator = new IdeaWideAuthenticator(this);
- final String name = getClass().getName();
+ String name = getClass().getName();
CommonProxy.getInstance().setCustom(name, mySelector);
- CommonProxy.getInstance().setCustomAuth(name, myAuthenticator);
+ CommonProxy.getInstance().setCustomAuth(name, new IdeaWideAuthenticator(this));
}
@NotNull
@@ -137,62 +142,64 @@ public class HttpConfigurable implements PersistentStateComponent<HttpConfigurab
return getClass().getName();
}
- private void correctPasswords(HttpConfigurable from, HttpConfigurable to) {
+ private void correctPasswords(@NotNull HttpConfigurable to) {
synchronized (myLock) {
- to.myGenericPasswords = new HashMap<CommonProxy.HostInfo, ProxyInfo>();
- for (Map.Entry<CommonProxy.HostInfo, ProxyInfo> entry : from.myGenericPasswords.entrySet()) {
- if (Boolean.TRUE.equals(entry.getValue().isStore())) {
- to.myGenericPasswords.put(entry.getKey(), entry.getValue());
+ to.myGenericPasswords.retainEntries(new TObjectObjectProcedure<CommonProxy.HostInfo, ProxyInfo>() {
+ @Override
+ public boolean execute(CommonProxy.HostInfo hostInfo, ProxyInfo proxyInfo) {
+ return proxyInfo.isStore();
}
- }
+ });
}
}
@Override
- public void loadState(HttpConfigurable state) {
+ public void loadState(@NotNull HttpConfigurable state) {
XmlSerializerUtil.copyBean(state, this);
if (!KEEP_PROXY_PASSWORD) {
- PROXY_PASSWORD_CRYPT = "";
+ PROXY_PASSWORD_CRYPT = null;
}
- correctPasswords(state, this);
+ correctPasswords(this);
}
- public boolean isGenericPasswordCanceled(final String host, final int port) {
+ public boolean isGenericPasswordCanceled(@NotNull String host, int port) {
synchronized (myLock) {
- return myGenericCancelled.contains(Pair.create(host, port));
+ return myGenericCancelled.contains(new CommonProxy.HostInfo(null, host, port));
}
}
public void setGenericPasswordCanceled(final String host, final int port) {
synchronized (myLock) {
- myGenericCancelled.add(new CommonProxy.HostInfo("", host, port));
+ myGenericCancelled.add(new CommonProxy.HostInfo(null, host, port));
}
}
- public PasswordAuthentication getGenericPassword(final String host, final int port) {
+ public PasswordAuthentication getGenericPassword(@NotNull String host, int port) {
final ProxyInfo proxyInfo;
synchronized (myLock) {
- proxyInfo = myGenericPasswords.get(new CommonProxy.HostInfo("", host, port));
+ proxyInfo = myGenericPasswords.get(new CommonProxy.HostInfo(null, host, port));
+ }
+ if (proxyInfo == null) {
+ return null;
}
- if (proxyInfo == null) return null;
return new PasswordAuthentication(proxyInfo.getUsername(), decode(String.valueOf(proxyInfo.getPasswordCrypt())).toCharArray());
}
- public void putGenericPassword(final String host, final int port, final PasswordAuthentication authentication, final boolean remember) {
- final PasswordAuthentication coded = new PasswordAuthentication(authentication.getUserName(), encode(String.valueOf(authentication.getPassword())).toCharArray());
+ public void putGenericPassword(final String host, final int port, @NotNull PasswordAuthentication authentication, boolean remember) {
+ PasswordAuthentication coded = new PasswordAuthentication(authentication.getUserName(), encode(String.valueOf(authentication.getPassword())).toCharArray());
synchronized (myLock) {
- myGenericPasswords.put(new CommonProxy.HostInfo("", host, port), new ProxyInfo(remember, coded.getUserName(), String.valueOf(
- coded.getPassword())));
+ myGenericPasswords.put(new CommonProxy.HostInfo(null, host, port), new ProxyInfo(remember, coded.getUserName(), String.valueOf(coded.getPassword())));
}
}
@Transient
+ @Nullable
public String getPlainProxyPassword() {
- return decode(PROXY_PASSWORD_CRYPT);
+ return PROXY_PASSWORD_CRYPT == null ? null : decode(PROXY_PASSWORD_CRYPT);
}
- private String decode(String value) {
- return new String(new Base64().decode(value.getBytes()));
+ private static String decode(String value) {
+ return new String(Base64.decode(value));
}
@Transient
@@ -200,42 +207,50 @@ public class HttpConfigurable implements PersistentStateComponent<HttpConfigurab
PROXY_PASSWORD_CRYPT = encode(password);
}
- private String encode(String password) {
- return new String(new Base64().encode(password.getBytes()));
+ private static String encode(String password) {
+ return new String(Base64.encode(password.getBytes(CharsetToolkit.UTF8_CHARSET)));
}
public PasswordAuthentication getGenericPromptedAuthentication(final String prefix, final String host, final String prompt, final int port, final boolean remember) {
if (ApplicationManager.getApplication().isUnitTestMode()) {
return myTestGenericAuthRunnable.get();
}
- final PasswordAuthentication[] value = new PasswordAuthentication[1];
- final Runnable runnable = new Runnable() {
+
+ final Ref<PasswordAuthentication> value = Ref.create();
+ runAboveAll(new Runnable() {
+ @Override
public void run() {
- if (isGenericPasswordCanceled(host, port)) return;
- final PasswordAuthentication password = getGenericPassword(host, port);
+ if (isGenericPasswordCanceled(host, port)) {
+ return;
+ }
+
+ PasswordAuthentication password = getGenericPassword(host, port);
if (password != null) {
- value[0] = password;
+ value.set(password);
return;
}
- final AuthenticationDialog dlg = new AuthenticationDialog(PopupUtil.getActiveComponent(), prefix + host,
- "Please enter credentials for: " + prompt, "", "", remember);
- dlg.show();
- if (dlg.getExitCode() == DialogWrapper.OK_EXIT_CODE) {
- final AuthenticationPanel panel = dlg.getPanel();
- final boolean remember1 = remember && panel.isRememberPassword();
- value[0] = new PasswordAuthentication(panel.getLogin(), panel.getPassword());
- putGenericPassword(host, port, value[0], remember1);
- } else {
+
+ AuthenticationDialog dialog = new AuthenticationDialog(PopupUtil.getActiveComponent(), prefix + host,
+ "Please enter credentials for: " + prompt, "", "", remember);
+ dialog.show();
+ if (dialog.getExitCode() == DialogWrapper.OK_EXIT_CODE) {
+ AuthenticationPanel panel = dialog.getPanel();
+ PasswordAuthentication passwordAuthentication = new PasswordAuthentication(panel.getLogin(), panel.getPassword());
+ putGenericPassword(host, port, passwordAuthentication, remember && panel.isRememberPassword());
+ value.set(passwordAuthentication);
+ }
+ else {
setGenericPasswordCanceled(host, port);
}
}
- };
- runAboveAll(runnable);
- return value[0];
+ });
+ return value.get();
}
public PasswordAuthentication getPromptedAuthentication(final String host, final String prompt) {
- if (AUTHENTICATION_CANCELLED) return null;
+ if (AUTHENTICATION_CANCELLED) {
+ return null;
+ }
final String password = getPlainProxyPassword();
if (PROXY_AUTHENTICATION && ! StringUtil.isEmptyOrSpaces(PROXY_LOGIN) && ! StringUtil.isEmptyOrSpaces(password)) {
return new PasswordAuthentication(PROXY_LOGIN, password.toCharArray());
@@ -248,63 +263,63 @@ public class HttpConfigurable implements PersistentStateComponent<HttpConfigurab
if (ApplicationManager.getApplication().isUnitTestMode()) {
return myTestGenericAuthRunnable.get();
}
- final String login = PROXY_LOGIN == null ? "" : PROXY_LOGIN;
final PasswordAuthentication[] value = new PasswordAuthentication[1];
- final Runnable runnable = new Runnable() {
+ runAboveAll(new Runnable() {
+ @Override
public void run() {
- if (AUTHENTICATION_CANCELLED) return;
+ if (AUTHENTICATION_CANCELLED) {
+ return;
+ }
+
// password might have changed, and the check below is for that
- final String password = getPlainProxyPassword();
+ String password = getPlainProxyPassword();
if (PROXY_AUTHENTICATION && ! StringUtil.isEmptyOrSpaces(PROXY_LOGIN) && ! StringUtil.isEmptyOrSpaces(password)) {
value[0] = new PasswordAuthentication(PROXY_LOGIN, password.toCharArray());
return;
}
- final AuthenticationDialog dlg = new AuthenticationDialog(PopupUtil.getActiveComponent(), "Proxy authentication: " + host,
- "Please enter credentials for: " + prompt, login, "", KEEP_PROXY_PASSWORD);
- dlg.show();
- if (dlg.getExitCode() == DialogWrapper.OK_EXIT_CODE) {
+ AuthenticationDialog dialog = new AuthenticationDialog(PopupUtil.getActiveComponent(), "Proxy authentication: " + host,
+ "Please enter credentials for: " + prompt, PROXY_LOGIN, "", KEEP_PROXY_PASSWORD);
+ dialog.show();
+ if (dialog.getExitCode() == DialogWrapper.OK_EXIT_CODE) {
PROXY_AUTHENTICATION = true;
- final AuthenticationPanel panel = dlg.getPanel();
+ AuthenticationPanel panel = dialog.getPanel();
KEEP_PROXY_PASSWORD = panel.isRememberPassword();
- PROXY_LOGIN = panel.getLogin();
+ PROXY_LOGIN = StringUtil.nullize(panel.getLogin());
setPlainProxyPassword(String.valueOf(panel.getPassword()));
value[0] = new PasswordAuthentication(panel.getLogin(), panel.getPassword());
} else {
AUTHENTICATION_CANCELLED = true;
}
}
- };
- runAboveAll(runnable);
+ });
return value[0];
}
- @SuppressWarnings("MethodMayBeStatic")
- private void runAboveAll(final Runnable runnable) {
+ private static void runAboveAll(@NotNull final Runnable runnable) {
final Runnable throughSwing = new Runnable() {
@Override
public void run() {
if (SwingUtilities.isEventDispatchThread()) {
runnable.run();
- return;
}
- try {
- SwingUtilities.invokeAndWait(runnable);
- }
- catch (InterruptedException e) {
- LOG.info(e);
- }
- catch (InvocationTargetException e) {
- LOG.info(e);
+ else {
+ try {
+ SwingUtilities.invokeAndWait(runnable);
+ }
+ catch (InterruptedException e) {
+ LOG.info(e);
+ }
+ catch (InvocationTargetException e) {
+ LOG.info(e);
+ }
}
}
};
- if (ProgressManager.getInstance().getProgressIndicator() != null) {
- if (ProgressManager.getInstance().getProgressIndicator().isModal()) {
- WaitForProgressToShow.runOrInvokeAndWaitAboveProgress(runnable);
- } else {
- throughSwing.run();
- }
- } else {
+ ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator();
+ if (progressIndicator != null && progressIndicator.isModal()) {
+ WaitForProgressToShow.runOrInvokeAndWaitAboveProgress(runnable);
+ }
+ else {
throughSwing.run();
}
}
@@ -312,22 +327,23 @@ public class HttpConfigurable implements PersistentStateComponent<HttpConfigurab
//these methods are preserved for compatibility with com.intellij.openapi.project.impl.IdeaServerSettings
@Deprecated
public void readExternal(Element element) throws InvalidDataException {
+ //noinspection ConstantConditions
loadState(XmlSerializer.deserialize(element, HttpConfigurable.class));
}
@Deprecated
public void writeExternal(Element element) throws WriteExternalException {
XmlSerializer.serializeInto(getState(), element);
- if (USE_PROXY_PAC && USE_HTTP_PROXY && ! ApplicationManager.getApplication().isDisposed()) {
+ if (USE_PROXY_PAC && USE_HTTP_PROXY && !ApplicationManager.getApplication().isDisposed()) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
- final IdeFrame frame = IdeFocusManager.findInstance().getLastFocusedFrame();
+ IdeFrame frame = IdeFocusManager.findInstance().getLastFocusedFrame();
if (frame != null) {
USE_PROXY_PAC = false;
Messages.showMessageDialog(frame.getComponent(), "Proxy: both 'use proxy' and 'autodetect proxy' settings were set." +
"\nOnly one of these options should be selected.\nPlease re-configure.",
- "Proxy setup", Messages.getWarningIcon());
+ "Proxy Setup", Messages.getWarningIcon());
editConfigurable(frame.getComponent());
}
}
@@ -344,51 +360,52 @@ public class HttpConfigurable implements PersistentStateComponent<HttpConfigurab
* @param url URL for HTTP connection
* @throws IOException
*/
- public void prepareURL (String url) throws IOException {
- //setAuthenticator();
- CommonProxy.isInstalledAssertion();
-
- final URLConnection connection = openConnection(url);
+ public void prepareURL(@NotNull String url) throws IOException {
+ URLConnection connection = openConnection(url);
try {
connection.connect();
connection.getInputStream();
}
- catch (Throwable e) {
- if (e instanceof IOException) {
- throw (IOException)e;
- }
- } finally {
+ catch (IOException e) {
+ throw e;
+ }
+ catch (Throwable ignored) {
+ }
+ finally {
if (connection instanceof HttpURLConnection) {
((HttpURLConnection)connection).disconnect();
}
}
}
+ @NotNull
public URLConnection openConnection(@NotNull String location) throws IOException {
CommonProxy.isInstalledAssertion();
final URL url = new URL(location);
URLConnection urlConnection = null;
final List<Proxy> proxies = CommonProxy.getInstance().select(url);
- if (proxies == null || proxies.isEmpty()) {
+ if (ContainerUtil.isEmpty(proxies)) {
urlConnection = url.openConnection();
- } else {
- IOException ioe = null;
+ }
+ else {
+ IOException exception = null;
for (Proxy proxy : proxies) {
try {
urlConnection = url.openConnection(proxy);
- } catch (IOException e) {
+ }
+ catch (IOException e) {
// continue iteration
- ioe = e;
+ exception = e;
}
}
- if (urlConnection == null && ioe != null) {
- throw ioe;
+ if (urlConnection == null && exception != null) {
+ throw exception;
}
}
- if (urlConnection != null) {
- urlConnection.setReadTimeout(CONNECTION_TIMEOUT);
- urlConnection.setConnectTimeout(CONNECTION_TIMEOUT);
- }
+
+ assert urlConnection != null;
+ urlConnection.setReadTimeout(CONNECTION_TIMEOUT);
+ urlConnection.setConnectTimeout(CONNECTION_TIMEOUT);
return urlConnection;
}
@@ -461,12 +478,15 @@ public class HttpConfigurable implements PersistentStateComponent<HttpConfigurab
return result;
}
- public static boolean isRealProxy(Proxy proxy) {
- return ! Proxy.NO_PROXY.equals(proxy) && ! Proxy.Type.DIRECT.equals(proxy.type());
+ public static boolean isRealProxy(@NotNull Proxy proxy) {
+ return !Proxy.NO_PROXY.equals(proxy) && !Proxy.Type.DIRECT.equals(proxy.type());
}
+ @NotNull
public static List<String> convertArguments(@NotNull final List<KeyValue<String, String>> list) {
- if (list.isEmpty()) return Collections.emptyList();
+ if (list.isEmpty()) {
+ return Collections.emptyList();
+ }
final List<String> result = new ArrayList<String>(list.size());
for (KeyValue<String, String> value : list) {
result.add("-D" + value.getKey() + "=" + value.getValue());
@@ -481,7 +501,7 @@ public class HttpConfigurable implements PersistentStateComponent<HttpConfigurab
}
}
- public void removeGeneric(CommonProxy.HostInfo info) {
+ public void removeGeneric(@NotNull CommonProxy.HostInfo info) {
synchronized (myLock) {
myGenericPasswords.remove(info);
}
@@ -518,6 +538,7 @@ public class HttpConfigurable implements PersistentStateComponent<HttpConfigurab
public String myUsername;
public String myPasswordCrypt;
+ @SuppressWarnings("UnusedDeclaration")
public ProxyInfo() {
}
@@ -547,6 +568,7 @@ public class HttpConfigurable implements PersistentStateComponent<HttpConfigurab
return myPasswordCrypt;
}
+ @SuppressWarnings("UnusedDeclaration")
public void setPasswordCrypt(String passwordCrypt) {
myPasswordCrypt = passwordCrypt;
}
diff --git a/platform/platform-api/src/com/intellij/util/net/HttpProxyConfigurable.java b/platform/platform-api/src/com/intellij/util/net/HttpProxyConfigurable.java
new file mode 100644
index 000000000000..4778c811d63e
--- /dev/null
+++ b/platform/platform-api/src/com/intellij/util/net/HttpProxyConfigurable.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.util.net;
+
+import com.intellij.openapi.options.ConfigurableBase;
+import org.jetbrains.annotations.NotNull;
+
+public class HttpProxyConfigurable extends ConfigurableBase<HttpProxySettingsUi, HttpConfigurable> {
+ private final HttpConfigurable settings;
+
+ public HttpProxyConfigurable() {
+ this(HttpConfigurable.getInstance());
+ }
+
+ public HttpProxyConfigurable(@NotNull HttpConfigurable settings) {
+ super("http.proxy", "HTTP Proxy", "http.proxy");
+
+ this.settings = settings;
+ }
+
+ @NotNull
+ @Override
+ protected HttpConfigurable getSettings() {
+ return settings;
+ }
+
+ @Override
+ protected HttpProxySettingsUi createUi() {
+ return new HttpProxySettingsUi(settings);
+ }
+} \ No newline at end of file
diff --git a/platform/platform-api/src/com/intellij/util/net/HTTPProxySettings.form b/platform/platform-api/src/com/intellij/util/net/HttpProxySettingsUi.form
index 5ffe378667d3..3d2ae0575e1f 100644
--- a/platform/platform-api/src/com/intellij/util/net/HTTPProxySettings.form
+++ b/platform/platform-api/src/com/intellij/util/net/HttpProxySettingsUi.form
@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
-<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.util.net.HTTPProxySettingsPanel">
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.util.net.HttpProxySettingsUi">
<grid id="111c4" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="11" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
- <xy x="111" y="44" width="1040" height="521"/>
+ <xy x="111" y="44" width="1369" height="608"/>
</constraints>
<properties/>
<border type="none"/>
<children>
- <grid id="fe3b6" layout-manager="GridLayoutManager" row-count="8" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="fe3b6" layout-manager="GridLayoutManager" row-count="8" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="5" left="20" bottom="10" right="10"/>
<constraints>
<grid row="7" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
@@ -34,19 +34,9 @@
<text resource-bundle="messages/CommonBundle" key="editbox.port.number"/>
</properties>
</component>
- <component id="2008d" class="javax.swing.JTextField" binding="myProxyHostTextField">
- <constraints>
- <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
- <preferred-size width="150" height="-1"/>
- </grid>
- </constraints>
- <properties/>
- </component>
- <component id="7e62" class="javax.swing.JTextField" binding="myProxyPortTextField">
+ <component id="7e62" class="com.intellij.ui.PortField" binding="myProxyPortTextField">
<constraints>
- <grid row="1" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
- <preferred-size width="150" height="-1"/>
- </grid>
+ <grid row="1" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
@@ -105,11 +95,6 @@
<text resource-bundle="messages/CommonBundle" key="checkbox.remember.password"/>
</properties>
</component>
- <hspacer id="92b79">
- <constraints>
- <grid row="5" column="3" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
- </constraints>
- </hspacer>
<component id="a16e5" class="javax.swing.JTextArea" binding="myProxyExceptions">
<constraints>
<grid row="2" column="2" row-span="1" col-span="1" vsize-policy="6" hsize-policy="6" anchor="0" fill="3" indent="0" use-parent-layout="false">
@@ -137,6 +122,14 @@
<text resource-bundle="messages/CommonBundle" key="label.proxy.exceptions.text"/>
</properties>
</component>
+ <component id="2008d" class="javax.swing.JTextField" binding="myProxyHostTextField">
+ <constraints>
+ <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+ <preferred-size width="150" height="-1"/>
+ </grid>
+ </constraints>
+ <properties/>
+ </component>
</children>
</grid>
<vspacer id="53d33">
@@ -177,7 +170,7 @@
<text resource-bundle="messages/CommonBundle" key="http.noproxy"/>
</properties>
</component>
- <grid id="1bb9b" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="1bb9b" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="6" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
@@ -193,11 +186,6 @@
<text resource-bundle="messages/CommonBundle" key="http.proxy.type"/>
</properties>
</component>
- <hspacer id="14ffd">
- <constraints>
- <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
- </constraints>
- </hspacer>
<component id="2538c" class="com.intellij.ui.components.JBRadioButton" binding="mySocks">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="2" use-parent-layout="false"/>
@@ -230,7 +218,7 @@
</constraints>
<properties/>
</component>
- <grid id="fee34" layout-manager="GridLayoutManager" row-count="2" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="fee34" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="true"/>
@@ -262,11 +250,6 @@
</constraints>
<properties/>
</component>
- <hspacer id="21dc">
- <constraints>
- <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
- </constraints>
- </hspacer>
</children>
</grid>
</children>
diff --git a/platform/platform-api/src/com/intellij/util/net/HttpProxySettingsUi.java b/platform/platform-api/src/com/intellij/util/net/HttpProxySettingsUi.java
new file mode 100644
index 000000000000..e71d8e5af4ec
--- /dev/null
+++ b/platform/platform-api/src/com/intellij/util/net/HttpProxySettingsUi.java
@@ -0,0 +1,386 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.util.net;
+
+import com.google.common.net.HostAndPort;
+import com.google.common.net.InetAddresses;
+import com.google.common.net.InternetDomainName;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.options.ConfigurableUi;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.ui.MultiLineLabelUI;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.wm.IdeFocusManager;
+import com.intellij.openapi.wm.IdeFrame;
+import com.intellij.ui.PortField;
+import com.intellij.ui.components.JBLabel;
+import com.intellij.ui.components.JBRadioButton;
+import com.intellij.util.proxy.CommonProxy;
+import com.intellij.util.proxy.JavaProxyProperty;
+import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.util.concurrent.atomic.AtomicReference;
+
+class HttpProxySettingsUi implements ConfigurableUi<HttpConfigurable> {
+ private JPanel myMainPanel;
+
+ private JTextField myProxyLoginTextField;
+ private JPasswordField myProxyPasswordTextField;
+ private JCheckBox myProxyAuthCheckBox;
+ private PortField myProxyPortTextField;
+ private JTextField myProxyHostTextField;
+ private JCheckBox myRememberProxyPasswordCheckBox;
+
+ private JLabel myProxyLoginLabel;
+ private JLabel myProxyPasswordLabel;
+ private JLabel myHostNameLabel;
+ private JLabel myPortNumberLabel;
+ private JBRadioButton myAutoDetectProxyRb;
+ private JBRadioButton myUseHTTPProxyRb;
+ private JBLabel mySystemProxyDefined;
+ private JBRadioButton myNoProxyRb;
+ private JBRadioButton myHTTP;
+ private JBRadioButton mySocks;
+ private JButton myClearPasswordsButton;
+ private JLabel myErrorLabel;
+ private JButton myCheckButton;
+ private JBLabel myOtherWarning;
+ private JLabel myProxyExceptionsLabel;
+ private JTextArea myProxyExceptions;
+ private JLabel myNoProxyForLabel;
+ private JCheckBox myPacUrlCheckBox;
+ private JTextField myPacUrlTextField;
+ private volatile boolean myConnectionCheckInProgress;
+
+ @Override
+ public boolean isModified(@NotNull HttpConfigurable settings) {
+ if (!isValid()) {
+ return false;
+ }
+
+ return !Comparing.strEqual(myProxyExceptions.getText().trim(), settings.PROXY_EXCEPTIONS) ||
+ settings.USE_PROXY_PAC != myAutoDetectProxyRb.isSelected() ||
+ settings.USE_PAC_URL != myPacUrlCheckBox.isSelected() ||
+ !Comparing.strEqual(settings.PAC_URL, myPacUrlTextField.getText()) ||
+ settings.USE_HTTP_PROXY != myUseHTTPProxyRb.isSelected() ||
+ settings.PROXY_AUTHENTICATION != myProxyAuthCheckBox.isSelected() ||
+ settings.KEEP_PROXY_PASSWORD != myRememberProxyPasswordCheckBox.isSelected() ||
+ settings.PROXY_TYPE_IS_SOCKS != mySocks.isSelected() ||
+ !Comparing.strEqual(settings.PROXY_LOGIN, myProxyLoginTextField.getText()) ||
+ !Comparing.strEqual(settings.getPlainProxyPassword(), new String(myProxyPasswordTextField.getPassword())) ||
+ settings.PROXY_PORT != myProxyPortTextField.getNumber() ||
+ !Comparing.strEqual(settings.PROXY_HOST, myProxyHostTextField.getText());
+ }
+
+ public HttpProxySettingsUi(@NotNull final HttpConfigurable settings) {
+ ButtonGroup group = new ButtonGroup();
+ group.add(myUseHTTPProxyRb);
+ group.add(myAutoDetectProxyRb);
+ group.add(myNoProxyRb);
+ myNoProxyRb.setSelected(true);
+
+ ButtonGroup proxyTypeGroup = new ButtonGroup();
+ proxyTypeGroup.add(myHTTP);
+ proxyTypeGroup.add(mySocks);
+ myHTTP.setSelected(true);
+
+ myProxyExceptions.setBorder(UIUtil.getTextFieldBorder());
+
+ Boolean property = Boolean.getBoolean(JavaProxyProperty.USE_SYSTEM_PROXY);
+ mySystemProxyDefined.setVisible(Boolean.TRUE.equals(property));
+ if (Boolean.TRUE.equals(property)) {
+ mySystemProxyDefined.setIcon(Messages.getWarningIcon());
+ mySystemProxyDefined.setFont(mySystemProxyDefined.getFont().deriveFont(Font.BOLD));
+ mySystemProxyDefined.setUI(new MultiLineLabelUI());
+ }
+
+ myProxyAuthCheckBox.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(@NotNull ActionEvent e) {
+ enableProxyAuthentication(myProxyAuthCheckBox.isSelected());
+ }
+ });
+ myPacUrlCheckBox.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(@NotNull ActionEvent e) {
+ myPacUrlTextField.setEnabled(myPacUrlCheckBox.isSelected());
+ }
+ });
+
+ ActionListener listener = new ActionListener() {
+ @Override
+ public void actionPerformed(@NotNull ActionEvent e) {
+ enableProxy(myUseHTTPProxyRb.isSelected());
+ }
+ };
+ myUseHTTPProxyRb.addActionListener(listener);
+ myAutoDetectProxyRb.addActionListener(listener);
+ myNoProxyRb.addActionListener(listener);
+
+ myClearPasswordsButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(@NotNull ActionEvent e) {
+ settings.clearGenericPasswords();
+ //noinspection DialogTitleCapitalization
+ Messages.showMessageDialog(myMainPanel, "Proxy passwords were cleared.", "Auto-detected Proxy", Messages.getInformationIcon());
+ }
+ });
+
+ configureCheckButton();
+ }
+
+ private void configureCheckButton() {
+ if (HttpConfigurable.getInstance() == null) {
+ myCheckButton.setVisible(false);
+ return;
+ }
+
+ myCheckButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(@NotNull ActionEvent e) {
+ final String title = "Check Proxy Settings";
+ final String answer = Messages.showInputDialog(myMainPanel, "Warning: your settings will be saved.\n\nEnter any URL to check connection to:",
+ title, Messages.getQuestionIcon(), "http://", null);
+ if (StringUtil.isEmptyOrSpaces(answer)) {
+ return;
+ }
+
+ final HttpConfigurable settings = HttpConfigurable.getInstance();
+ apply(settings);
+ final AtomicReference<IOException> exceptionReference = new AtomicReference<IOException>();
+ myCheckButton.setEnabled(false);
+ myCheckButton.setText("Check connection (in progress...)");
+ myConnectionCheckInProgress = true;
+ ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
+ @Override
+ public void run() {
+ HttpURLConnection connection = null;
+ try {
+ //already checked for null above
+ //noinspection ConstantConditions
+ connection = settings.openHttpConnection(answer);
+ connection.setReadTimeout(3 * 1000);
+ connection.setConnectTimeout(3 * 1000);
+ connection.connect();
+ final int code = connection.getResponseCode();
+ if (HttpURLConnection.HTTP_OK != code) {
+ exceptionReference.set(new IOException("Error code: " + code));
+ }
+ }
+ catch (IOException e) {
+ exceptionReference.set(e);
+ }
+ finally {
+ if (connection != null) {
+ connection.disconnect();
+ }
+ }
+ //noinspection SSBasedInspection
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ myConnectionCheckInProgress = false;
+ reset(settings); // since password might have been set
+ Component parent;
+ if (myMainPanel.isShowing()) {
+ parent = myMainPanel;
+ myCheckButton.setText("Check connection");
+ myCheckButton.setEnabled(canEnableConnectionCheck());
+ }
+ else {
+ IdeFrame frame = IdeFocusManager.findInstance().getLastFocusedFrame();
+ if (frame == null) {
+ return;
+ }
+ parent = frame.getComponent();
+ }
+ //noinspection ThrowableResultOfMethodCallIgnored
+ final IOException exception = exceptionReference.get();
+ if (exception == null) {
+ Messages.showMessageDialog(parent, "Connection successful", title, Messages.getInformationIcon());
+ }
+ else {
+ final String message = exception.getMessage();
+ if (settings.USE_HTTP_PROXY) {
+ settings.LAST_ERROR = message;
+ }
+ Messages.showErrorDialog(parent, errorText(message));
+ }
+ }
+ });
+ }
+ });
+ }
+ });
+ }
+
+ private boolean canEnableConnectionCheck() {
+ return !myNoProxyRb.isSelected() && !myConnectionCheckInProgress;
+ }
+
+ @Override
+ public void reset(@NotNull HttpConfigurable settings) {
+ myNoProxyRb.setSelected(true); // default
+ myAutoDetectProxyRb.setSelected(settings.USE_PROXY_PAC);
+ myPacUrlCheckBox.setSelected(settings.USE_PAC_URL);
+ myPacUrlTextField.setText(settings.PAC_URL);
+ myUseHTTPProxyRb.setSelected(settings.USE_HTTP_PROXY);
+ myProxyAuthCheckBox.setSelected(settings.PROXY_AUTHENTICATION);
+
+ enableProxy(settings.USE_HTTP_PROXY);
+
+ myProxyLoginTextField.setText(settings.PROXY_LOGIN);
+ myProxyPasswordTextField.setText(settings.getPlainProxyPassword());
+
+ myProxyPortTextField.setNumber(settings.PROXY_PORT);
+ myProxyHostTextField.setText(settings.PROXY_HOST);
+ myProxyExceptions.setText(StringUtil.notNullize(settings.PROXY_EXCEPTIONS));
+
+ myRememberProxyPasswordCheckBox.setSelected(settings.KEEP_PROXY_PASSWORD);
+ mySocks.setSelected(settings.PROXY_TYPE_IS_SOCKS);
+ myHTTP.setSelected(!settings.PROXY_TYPE_IS_SOCKS);
+
+ boolean showError = !StringUtil.isEmptyOrSpaces(settings.LAST_ERROR);
+ myErrorLabel.setVisible(showError);
+ myErrorLabel.setText(showError ? errorText(settings.LAST_ERROR) : null);
+
+ final String oldStyleText = CommonProxy.getMessageFromProps(CommonProxy.getOldStyleProperties());
+ myOtherWarning.setVisible(oldStyleText != null);
+ if (oldStyleText != null) {
+ myOtherWarning.setText(oldStyleText);
+ myOtherWarning.setUI(new MultiLineLabelUI());
+ myOtherWarning.setIcon(Messages.getWarningIcon());
+ }
+ }
+
+ @NotNull
+ private static String errorText(@NotNull String s) {
+ return "Problem with connection: " + s;
+ }
+
+ private boolean isValid() {
+ if (myUseHTTPProxyRb.isSelected()) {
+ String host = getText(myProxyHostTextField);
+ if (host == null) {
+ return false;
+ }
+
+ try {
+ HostAndPort parsedHost = HostAndPort.fromString(host);
+ if (parsedHost.hasPort()) {
+ return false;
+ }
+ host = parsedHost.getHostText();
+
+ try {
+ InetAddresses.forString(host);
+ return true;
+ }
+ catch (IllegalArgumentException e) {
+ // it is not an IPv4 or IPv6 literal
+ }
+
+ InternetDomainName.from(host);
+ }
+ catch (IllegalArgumentException e) {
+ return false;
+ }
+
+ if (myProxyAuthCheckBox.isSelected()) {
+ return !StringUtil.isEmptyOrSpaces(myProxyLoginTextField.getText()) && myProxyPasswordTextField.getPassword().length > 0;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public void apply(@NotNull HttpConfigurable settings) {
+ if (!isValid()) {
+ return;
+ }
+
+ if (isModified(settings)) {
+ settings.AUTHENTICATION_CANCELLED = false;
+ }
+
+ settings.USE_PROXY_PAC = myAutoDetectProxyRb.isSelected();
+ settings.USE_PAC_URL = myPacUrlCheckBox.isSelected();
+ settings.PAC_URL = getText(myPacUrlTextField);
+ settings.USE_HTTP_PROXY = myUseHTTPProxyRb.isSelected();
+ settings.PROXY_TYPE_IS_SOCKS = mySocks.isSelected();
+ settings.PROXY_AUTHENTICATION = myProxyAuthCheckBox.isSelected();
+ settings.KEEP_PROXY_PASSWORD = myRememberProxyPasswordCheckBox.isSelected();
+
+ settings.PROXY_LOGIN = getText(myProxyLoginTextField);
+ settings.setPlainProxyPassword(new String(myProxyPasswordTextField.getPassword()));
+ settings.PROXY_EXCEPTIONS = StringUtil.nullize(myProxyExceptions.getText(), true);
+
+ settings.PROXY_PORT = myProxyPortTextField.getNumber();
+ settings.PROXY_HOST = getText(myProxyHostTextField);
+ }
+
+ @Nullable
+ private static String getText(@NotNull JTextField field) {
+ return StringUtil.nullize(field.getText(), true);
+ }
+
+ private void enableProxy(boolean enabled) {
+ myHostNameLabel.setEnabled(enabled);
+ myPortNumberLabel.setEnabled(enabled);
+ myProxyHostTextField.setEnabled(enabled);
+ myProxyPortTextField.setEnabled(enabled);
+ mySocks.setEnabled(enabled);
+ myHTTP.setEnabled(enabled);
+ myProxyExceptions.setEnabled(enabled);
+ myProxyExceptions.setBackground(myProxyPortTextField.getBackground());
+ myProxyExceptionsLabel.setEnabled(enabled);
+ myNoProxyForLabel.setEnabled(enabled);
+
+ myProxyAuthCheckBox.setEnabled(enabled);
+ enableProxyAuthentication(enabled && myProxyAuthCheckBox.isSelected());
+ myCheckButton.setEnabled(canEnableConnectionCheck());
+
+ final boolean autoDetectProxy = myAutoDetectProxyRb.isSelected();
+ myPacUrlCheckBox.setEnabled(autoDetectProxy);
+ myClearPasswordsButton.setEnabled(autoDetectProxy);
+ myPacUrlTextField.setEnabled(autoDetectProxy && myPacUrlCheckBox.isSelected());
+ }
+
+ private void enableProxyAuthentication(boolean enabled) {
+ myProxyPasswordLabel.setEnabled(enabled);
+ myProxyLoginLabel.setEnabled(enabled);
+
+ myProxyLoginTextField.setEnabled(enabled);
+ myProxyPasswordTextField.setEnabled(enabled);
+
+ myRememberProxyPasswordCheckBox.setEnabled(enabled);
+ }
+
+ @Override
+ @NotNull
+ public JComponent getComponent() {
+ return myMainPanel;
+ }
+}
diff --git a/platform/platform-api/src/com/intellij/util/net/IOExceptionDialog.java b/platform/platform-api/src/com/intellij/util/net/IOExceptionDialog.java
index f49eb983c3af..642125b275fa 100644
--- a/platform/platform-api/src/com/intellij/util/net/IOExceptionDialog.java
+++ b/platform/platform-api/src/com/intellij/util/net/IOExceptionDialog.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.Ref;
import com.intellij.ui.GuiUtils;
+import com.intellij.util.ObjectUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -28,16 +29,9 @@ import javax.swing.*;
import java.awt.event.ActionEvent;
import java.lang.reflect.InvocationTargetException;
-/**
- * Created by IntelliJ IDEA.
- * User: stathik
- * Date: Nov 19, 2003
- * Time: 10:04:14 PM
- * To change this template use Options | File Templates.
- */
public class IOExceptionDialog extends DialogWrapper {
private static final Logger LOG = Logger.getInstance(IOExceptionDialog.class);
- private JTextArea myErrorLabel;
+ private final JTextArea myErrorLabel;
public IOExceptionDialog(String title, String errorText) {
super((Project)null, true);
@@ -65,8 +59,8 @@ public class IOExceptionDialog extends DialogWrapper {
return new Action[] {
new AbstractAction(CommonBundle.message("dialog.ioexception.proxy")) {
@Override
- public void actionPerformed(ActionEvent e) {
- new HTTPProxySettingsDialog().show();
+ public void actionPerformed(@NotNull ActionEvent e) {
+ HttpConfigurable.editConfigurable(ObjectUtils.tryCast(e.getSource(), JComponent.class));
}
}
};
@@ -79,14 +73,14 @@ public class IOExceptionDialog extends DialogWrapper {
public static boolean showErrorDialog(final String title, final String text) {
final Ref<Boolean> ok = Ref.create(false);
try {
- final Runnable doRun = new Runnable() {
+ GuiUtils.runOrInvokeAndWait(new Runnable() {
+ @Override
public void run() {
IOExceptionDialog dialog = new IOExceptionDialog(title, text);
dialog.show();
ok.set(dialog.isOK());
}
- };
- GuiUtils.runOrInvokeAndWait(doRun);
+ });
}
catch (InterruptedException e) {
LOG.info(e);
diff --git a/platform/platform-api/src/com/intellij/util/net/IdeaWideAuthenticator.java b/platform/platform-api/src/com/intellij/util/net/IdeaWideAuthenticator.java
index fedcb359b03d..b3a8fff57763 100644
--- a/platform/platform-api/src/com/intellij/util/net/IdeaWideAuthenticator.java
+++ b/platform/platform-api/src/com/intellij/util/net/IdeaWideAuthenticator.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
*/
package com.intellij.util.net;
+import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.util.proxy.CommonProxy;
@@ -23,12 +24,6 @@ import com.intellij.util.proxy.NonStaticAuthenticator;
import java.net.Authenticator;
import java.net.PasswordAuthentication;
-/**
- * Created with IntelliJ IDEA.
- * User: Irina.Chernushina
- * Date: 1/30/13
- * Time: 5:58 PM
- */
public class IdeaWideAuthenticator extends NonStaticAuthenticator {
private final static Logger LOG = Logger.getInstance("#com.intellij.util.net.IdeaWideAuthenticator");
private final HttpConfigurable myHttpConfigurable;
@@ -42,12 +37,14 @@ public class IdeaWideAuthenticator extends NonStaticAuthenticator {
final String host = CommonProxy.getHostNameReliably(getRequestingHost(), getRequestingSite(), getRequestingURL());
final boolean isProxy = Authenticator.RequestorType.PROXY.equals(getRequestorType());
final String prefix = isProxy ? "Proxy authentication: " : "Server authentication: ";
+ Application application = ApplicationManager.getApplication();
if (isProxy) {
// according to idea-wide settings
if (myHttpConfigurable.USE_HTTP_PROXY) {
LOG.debug("CommonAuthenticator.getPasswordAuthentication will return common defined proxy");
return myHttpConfigurable.getPromptedAuthentication(host + ":" + getRequestingPort(), getRequestingPrompt());
- } else if (myHttpConfigurable.USE_PROXY_PAC) {
+ }
+ else if (myHttpConfigurable.USE_PROXY_PAC) {
LOG.debug("CommonAuthenticator.getPasswordAuthentication will return autodetected proxy");
if (myHttpConfigurable.isGenericPasswordCanceled(host, getRequestingPort())) return null;
// same but without remembering the results..
@@ -56,16 +53,19 @@ public class IdeaWideAuthenticator extends NonStaticAuthenticator {
return password;
}
// do not try to show any dialogs if application is exiting
- if (ApplicationManager.getApplication() == null || ApplicationManager.getApplication().isDisposeInProgress() ||
- ApplicationManager.getApplication().isDisposed()) return null;
+ if (application == null || application.isDisposeInProgress() ||
+ application.isDisposed()) {
+ return null;
+ }
return myHttpConfigurable.getGenericPromptedAuthentication(prefix, host, getRequestingPrompt(), getRequestingPort(), true);
}
}
// do not try to show any dialogs if application is exiting
- if (ApplicationManager.getApplication() == null || ApplicationManager.getApplication().isDisposeInProgress() ||
- ApplicationManager.getApplication().isDisposed()) return null;
+ if (application == null || application.isDisposeInProgress() || application.isDisposed()) {
+ return null;
+ }
LOG.debug("CommonAuthenticator.getPasswordAuthentication generic authentication will be asked");
//return myHttpConfigurable.getGenericPromptedAuthentication(prefix, host, getRequestingPrompt(), getRequestingPort(), false);
diff --git a/platform/platform-api/src/com/intellij/util/net/IdeaWideProxySelector.java b/platform/platform-api/src/com/intellij/util/net/IdeaWideProxySelector.java
index df986ea946c4..62199b335425 100644
--- a/platform/platform-api/src/com/intellij/util/net/IdeaWideProxySelector.java
+++ b/platform/platform-api/src/com/intellij/util/net/IdeaWideProxySelector.java
@@ -17,7 +17,6 @@ package com.intellij.util.net;
import com.btr.proxy.search.ProxySearch;
import com.btr.proxy.selector.pac.PacProxySelector;
-import com.btr.proxy.selector.pac.PacScriptSource;
import com.btr.proxy.selector.pac.UrlPacScriptSource;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Comparing;
@@ -77,8 +76,7 @@ public class IdeaWideProxySelector extends ProxySelector {
if (myHttpConfigurable.USE_PROXY_PAC) {
ProxySelector pacProxySelector = myPacProxySelector.get();
if (myHttpConfigurable.USE_PAC_URL && !StringUtil.isEmpty(myHttpConfigurable.PAC_URL)) {
- PacScriptSource pacSource = new UrlPacScriptSource(myHttpConfigurable.PAC_URL);
- myPacProxySelector.set(new PacProxySelector(pacSource));
+ myPacProxySelector.set(new PacProxySelector(new UrlPacScriptSource(myHttpConfigurable.PAC_URL)));
}
else if (pacProxySelector == null) {
ProxySearch proxySearch = ProxySearch.getDefaultProxySearch();
diff --git a/platform/platform-api/src/com/intellij/util/net/NetUtils.java b/platform/platform-api/src/com/intellij/util/net/NetUtils.java
index eb56e08e4d64..b01d4db1f1cb 100644
--- a/platform/platform-api/src/com/intellij/util/net/NetUtils.java
+++ b/platform/platform-api/src/com/intellij/util/net/NetUtils.java
@@ -66,7 +66,7 @@ public class NetUtils {
}
public static boolean isLocalhost(@NotNull String host) {
- return host.equalsIgnoreCase("localhost") || host.equals("127.0.0.1");
+ return host.equalsIgnoreCase("localhost") || host.equals("127.0.0.1") || host.equals("::1");
}
private static boolean canBindToLocalSocket(String host, int port) {
diff --git a/platform/platform-api/src/com/intellij/util/proxy/CommonProxy.java b/platform/platform-api/src/com/intellij/util/proxy/CommonProxy.java
index eff28a5fbd1e..4aa63cd39f01 100644
--- a/platform/platform-api/src/com/intellij/util/proxy/CommonProxy.java
+++ b/platform/platform-api/src/com/intellij/util/proxy/CommonProxy.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,6 +22,8 @@ import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.net.NetUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -31,12 +33,6 @@ import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
-/**
- * Created with IntelliJ IDEA.
- * User: Irina.Chernushina
- * Date: 1/21/13
- * Time: 12:39 PM
- */
public class CommonProxy extends ProxySelector {
private final static CommonProxy ourInstance = new CommonProxy();
private final CommonAuthenticator myAuthenticator;
@@ -212,14 +208,12 @@ public class CommonProxy extends ProxySelector {
}
try {
ourReenterDefence.set(Boolean.TRUE);
- final String host = uri.getHost() == null ? "" : uri.getHost();
- final int port = correctPortByProtocol(uri);
- final String protocol = uri.getScheme();
- if ("localhost".equals(host) || "127.0.0.1".equals(host) || "::1".equals(host)) {
+ String host = StringUtil.notNullize(uri.getHost());
+ if (NetUtils.isLocalhost(host)) {
return NO_PROXY_LIST;
}
- final HostInfo info = new HostInfo(protocol, host, port);
+ final HostInfo info = new HostInfo(uri.getScheme(), host, correctPortByProtocol(uri));
final Map<String, ProxySelector> copy;
synchronized (myLock) {
if (myNoProxy.contains(Pair.create(info, Thread.currentThread()))) {
@@ -230,18 +224,19 @@ public class CommonProxy extends ProxySelector {
}
for (Map.Entry<String, ProxySelector> entry : copy.entrySet()) {
final List<Proxy> proxies = entry.getValue().select(uri);
- if (proxies != null && proxies.size() > 0) {
+ if (!ContainerUtil.isEmpty(proxies)) {
LOG.debug("CommonProxy.select returns custom proxy for " + uri.toString() + ", " + proxies.toString());
return proxies;
}
}
return NO_PROXY_LIST;
- } finally {
+ }
+ finally {
ourReenterDefence.remove();
}
}
- private int correctPortByProtocol(@NotNull URI uri) {
+ private static int correctPortByProtocol(@NotNull URI uri) {
if (uri.getPort() == -1) {
if ("http".equals(uri.getScheme())) {
return ProtocolDefaultPorts.HTTP;
@@ -330,7 +325,8 @@ public class CommonProxy extends ProxySelector {
if (host == null) {
if (site != null) {
host = site.getHostName();
- } else if (requestingUrl != null) {
+ }
+ else if (requestingUrl != null) {
host = requestingUrl.getHost();
}
}
@@ -351,7 +347,7 @@ public class CommonProxy extends ProxySelector {
public HostInfo() {
}
- public HostInfo(String protocol, @NotNull String host, int port) {
+ public HostInfo(@Nullable String protocol, @NotNull String host, int port) {
myPort = port;
myHost = host;
myProtocol = protocol;
@@ -371,16 +367,15 @@ public class CommonProxy extends ProxySelector {
@Override
public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
HostInfo info = (HostInfo)o;
-
- if (myPort != info.myPort) return false;
- if (!myHost.equals(info.myHost)) return false;
- if (myProtocol != null ? !myProtocol.equals(info.myProtocol) : info.myProtocol != null) return false;
-
- return true;
+ return myPort == info.myPort && myHost.equals(info.myHost) && Comparing.equal(myProtocol, info.myProtocol);
}
@Override
diff --git a/platform/platform-api/src/com/intellij/util/ui/ButtonlessScrollBarUI.java b/platform/platform-api/src/com/intellij/util/ui/ButtonlessScrollBarUI.java
index d73e21e8dc3a..b11ca7f3222f 100644
--- a/platform/platform-api/src/com/intellij/util/ui/ButtonlessScrollBarUI.java
+++ b/platform/platform-api/src/com/intellij/util/ui/ButtonlessScrollBarUI.java
@@ -223,10 +223,10 @@ public class ButtonlessScrollBarUI extends BasicScrollBarUI {
}
public int getDecrementButtonHeight() {
- return decrButton.getHeight();
+ return Math.max(0, decrButton.getHeight());
}
public int getIncrementButtonHeight() {
- return incrButton.getHeight();
+ return Math.max(0, incrButton.getHeight());
}
private void resetRegularThumbAnimator() {
@@ -276,6 +276,16 @@ public class ButtonlessScrollBarUI extends BasicScrollBarUI {
return new ButtonlessScrollBarUI();
}
+
+ public static BasicScrollBarUI createTransparent() {
+ return new ButtonlessScrollBarUI() {
+ @Override
+ public boolean alwaysShowTrack() {
+ return false;
+ }
+ };
+ }
+
@Override
public void installUI(JComponent c) {
super.installUI(c);
diff --git a/platform/platform-api/src/com/intellij/util/ui/StatusText.java b/platform/platform-api/src/com/intellij/util/ui/StatusText.java
index 60f8c5c6cbc1..479b968d4317 100644
--- a/platform/platform-api/src/com/intellij/util/ui/StatusText.java
+++ b/platform/platform-api/src/com/intellij/util/ui/StatusText.java
@@ -186,7 +186,8 @@ public abstract class StatusText {
}
public void paint(Component owner, Graphics g) {
- if (!isStatusVisible() || owner != myOwner) return;
+ boolean wrongComponent = owner != myOwner && owner != null && owner.getParent() != myOwner;
+ if (!isStatusVisible() || wrongComponent) return;
Rectangle b = getTextComponentBound();
myComponent.setBounds(0, 0, b.width, b.height);
diff --git a/platform/platform-impl/src/com/intellij/diagnostic/ErrorReportConfigurable.java b/platform/platform-impl/src/com/intellij/diagnostic/ErrorReportConfigurable.java
index 7d5688c9d1d8..3f865dd19abd 100644
--- a/platform/platform-impl/src/com/intellij/diagnostic/ErrorReportConfigurable.java
+++ b/platform/platform-impl/src/com/intellij/diagnostic/ErrorReportConfigurable.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,17 +21,11 @@ import com.intellij.openapi.util.DefaultJDOMExternalizer;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.JDOMExternalizable;
import com.intellij.openapi.util.WriteExternalException;
-import org.apache.commons.codec.binary.Base64;
+import com.intellij.openapi.vfs.CharsetToolkit;
+import com.intellij.util.Base64;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
-/**
- * Created by IntelliJ IDEA.
- * User: stathik
- * Date: Aug 11, 2003
- * Time: 8:59:04 PM
- * To change this template use Options | File Templates.
- */
public class ErrorReportConfigurable implements JDOMExternalizable, NamedComponent {
public String ITN_LOGIN = "";
public String ITN_PASSWORD_CRYPT = "";
@@ -43,31 +37,36 @@ public class ErrorReportConfigurable implements JDOMExternalizable, NamedCompone
return ServiceManager.getService(ErrorReportConfigurable.class);
}
+ @Override
public void readExternal(Element element) throws InvalidDataException {
DefaultJDOMExternalizer.readExternal(this, element);
- if (! KEEP_ITN_PASSWORD)
+ if (!KEEP_ITN_PASSWORD) {
ITN_PASSWORD_CRYPT = "";
+ }
}
+ @Override
public void writeExternal(Element element) throws WriteExternalException {
String itnPassword = ITN_PASSWORD_CRYPT;
- if (! KEEP_ITN_PASSWORD)
+ if (!KEEP_ITN_PASSWORD) {
ITN_PASSWORD_CRYPT = "";
+ }
DefaultJDOMExternalizer.writeExternal(this, element);
ITN_PASSWORD_CRYPT = itnPassword;
}
+ @Override
@NotNull
public String getComponentName() {
return "ErrorReportConfigurable";
}
- public String getPlainItnPassword () {
- return new String(new Base64().decode(ErrorReportConfigurable.getInstance().ITN_PASSWORD_CRYPT.getBytes()));
+ public String getPlainItnPassword() {
+ return new String(Base64.decode(getInstance().ITN_PASSWORD_CRYPT), CharsetToolkit.UTF8_CHARSET);
}
- public void setPlainItnPassword (String password) {
- ITN_PASSWORD_CRYPT = new String(new Base64().encode(password.getBytes()));
+ public void setPlainItnPassword(String password) {
+ ITN_PASSWORD_CRYPT = Base64.encode(password.getBytes(CharsetToolkit.UTF8_CHARSET));
}
}
diff --git a/platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountDialog.java b/platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountDialog.java
index 092c346d40b7..fb34ba2342cf 100644
--- a/platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountDialog.java
+++ b/platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountDialog.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,32 +19,25 @@ import com.intellij.ide.BrowserUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.ui.ClickListener;
-import com.intellij.util.net.HTTPProxySettingsDialog;
+import com.intellij.util.net.HttpConfigurable;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
-/**
- * Created by IntelliJ IDEA.
- * User: stathik
- * Date: Aug 8, 2003
- * Time: 3:49:50 PM
- * To change this template use Options | File Templates.
- */
public class JetBrainsAccountDialog extends DialogWrapper {
private JTextField myItnLoginTextField;
private JPasswordField myItnPasswordTextField;
private JCheckBox myRememberITNPasswordCheckBox;
- public void storeInfo () {
+ public void storeInfo() {
ErrorReportConfigurable.getInstance().ITN_LOGIN = myItnLoginTextField.getText();
ErrorReportConfigurable.getInstance().setPlainItnPassword(new String(myItnPasswordTextField.getPassword()));
ErrorReportConfigurable.getInstance().KEEP_ITN_PASSWORD = myRememberITNPasswordCheckBox.isSelected();
}
- public void loadInfo () {
+ public void loadInfo() {
myItnLoginTextField.setText(ErrorReportConfigurable.getInstance().ITN_LOGIN);
myItnPasswordTextField.setText(ErrorReportConfigurable.getInstance().getPlainItnPassword());
myRememberITNPasswordCheckBox.setSelected(ErrorReportConfigurable.getInstance().KEEP_ITN_PASSWORD);
@@ -64,6 +57,7 @@ public class JetBrainsAccountDialog extends DialogWrapper {
protected JLabel mySendingSettingsLabel;
private JLabel myCreateAccountLabel;
+ @Override
protected String getDimensionServiceKey() {
return "#com.intellij.diagnostic.AbstractSendErrorDialog";
}
@@ -73,6 +67,7 @@ public class JetBrainsAccountDialog extends DialogWrapper {
return myItnLoginTextField;
}
+ @Override
protected void init() {
setTitle(ReportMessages.ERROR_REPORT);
getContentPane().add(myMainPanel);
@@ -80,14 +75,12 @@ public class JetBrainsAccountDialog extends DialogWrapper {
new ClickListener() {
@Override
public boolean onClick(@NotNull MouseEvent e, int clickCount) {
- HTTPProxySettingsDialog settingsDialog = new HTTPProxySettingsDialog ();
- settingsDialog.pack();
- settingsDialog.show();
+ HttpConfigurable.editConfigurable(myMainPanel);
return true;
}
}.installOn(mySendingSettingsLabel);
- mySendingSettingsLabel.setCursor(new Cursor (Cursor.HAND_CURSOR));
+ mySendingSettingsLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
loadInfo();
@@ -98,9 +91,9 @@ public class JetBrainsAccountDialog extends DialogWrapper {
return true;
}
}.installOn(myCreateAccountLabel);
- myCreateAccountLabel.setCursor(new Cursor (Cursor.HAND_CURSOR));
+ myCreateAccountLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
- super.init ();
+ super.init();
}
@Override
@@ -109,6 +102,7 @@ public class JetBrainsAccountDialog extends DialogWrapper {
super.doOKAction();
}
+ @Override
protected JComponent createCenterPanel() {
return myMainPanel;
}
diff --git a/platform/platform-impl/src/com/intellij/ide/CommandLineProcessor.java b/platform/platform-impl/src/com/intellij/ide/CommandLineProcessor.java
index 0aeb20dbda90..c288150bd7ab 100644
--- a/platform/platform-impl/src/com/intellij/ide/CommandLineProcessor.java
+++ b/platform/platform-impl/src/com/intellij/ide/CommandLineProcessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -137,7 +137,9 @@ public class CommandLineProcessor {
if (args.size() > 0) {
String command = args.get(0);
for(ApplicationStarter starter: Extensions.getExtensions(ApplicationStarter.EP_NAME)) {
- if (starter instanceof ApplicationStarterEx && command.equals(starter.getCommandName())) {
+ if (command.equals(starter.getCommandName()) &&
+ starter instanceof ApplicationStarterEx &&
+ ((ApplicationStarterEx)starter).canProcessExternalCommandLine()) {
LOG.info("Processing command with " + starter);
((ApplicationStarterEx) starter).processExternalCommandLine(ArrayUtil.toStringArray(args));
return null;
diff --git a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java
index a7d07c9fa1e8..23491c2bdd6a 100644
--- a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java
+++ b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java
@@ -130,9 +130,9 @@ public class IdeEventQueue extends EventQueue {
private final Set<EventDispatcher> myDispatchers = new LinkedHashSet<EventDispatcher>();
- private final Set<EventDispatcher> myPostprocessors = new LinkedHashSet<EventDispatcher>();
-
+ private final Set<EventDispatcher> myPostProcessors = new LinkedHashSet<EventDispatcher>();
private final Set<Runnable> myReady = new HashSet<Runnable>();
+
private boolean myKeyboardBusy;
private boolean myDispatchingFocusEvent;
@@ -148,16 +148,14 @@ public class IdeEventQueue extends EventQueue {
private IdeEventQueue() {
addIdleTimeCounterRequest();
- final KeyboardFocusManager keyboardFocusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
- //noinspection HardCodedStringLiteral
+ final KeyboardFocusManager keyboardFocusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
keyboardFocusManager.addPropertyChangeListener("permanentFocusOwner", new PropertyChangeListener() {
@Override
public void propertyChange(final PropertyChangeEvent e) {
final Application application = ApplicationManager.getApplication();
if (application == null) {
-
// We can get focus event before application is initialized
return;
}
@@ -171,6 +169,12 @@ public class IdeEventQueue extends EventQueue {
});
addDispatcher(new WindowsAltSupressor(), null);
+
+ Application app = ApplicationManager.getApplication();
+ if (app != null && app.isUnitTestMode()) {
+ //noinspection AssignmentToStaticFieldFromInstanceMethod
+ ourAppIsLoaded = true;
+ }
}
@@ -289,11 +293,11 @@ public class IdeEventQueue extends EventQueue {
}
public void addPostprocessor(EventDispatcher dispatcher, @Nullable Disposable parent) {
- _addProcessor(dispatcher, parent, myPostprocessors);
+ _addProcessor(dispatcher, parent, myPostProcessors);
}
public void removePostprocessor(EventDispatcher dispatcher) {
- myPostprocessors.remove(dispatcher);
+ myPostProcessors.remove(dispatcher);
}
private static void _addProcessor(final EventDispatcher dispatcher, Disposable parent, final Set<EventDispatcher> set) {
@@ -344,8 +348,26 @@ public class IdeEventQueue extends EventQueue {
}
}
+ private static boolean ourAppIsLoaded = false;
+
+ private static boolean appIsLoaded() {
+ if (ourAppIsLoaded) return true;
+ boolean loaded = IdeaApplication.isLoaded();
+ if (loaded) ourAppIsLoaded = true;
+ return loaded;
+ }
+
@Override
public void dispatchEvent(AWTEvent e) {
+ if (!appIsLoaded()) {
+ try {
+ super.dispatchEvent(e);
+ }
+ catch (Throwable t) {
+ processException(t);
+ }
+ return;
+ }
fixNonEnglishKeyboardLayouts(e);
@@ -362,15 +384,13 @@ public class IdeEventQueue extends EventQueue {
_dispatchEvent(e, false);
}
catch (Throwable t) {
- if (!myToolkitBugsProcessor.process(t)) {
- PluginManager.processException(t);
- }
+ processException(t);
}
finally {
myIsInInputEvent = wasInputEvent;
myCurrentEvent = oldEvent;
- for (EventDispatcher each : myPostprocessors) {
+ for (EventDispatcher each : myPostProcessors) {
each.dispatch(e);
}
@@ -380,6 +400,12 @@ public class IdeEventQueue extends EventQueue {
}
}
+ private void processException(Throwable t) {
+ if (!myToolkitBugsProcessor.process(t)) {
+ PluginManager.processException(t);
+ }
+ }
+
private static void fixNonEnglishKeyboardLayouts(AWTEvent e) {
if (!Registry.is("ide.non.english.keyboard.layout.fix")) return;
if (e instanceof KeyEvent) {
@@ -722,9 +748,7 @@ public class IdeEventQueue extends EventQueue {
super.dispatchEvent(e);
}
catch (Throwable t) {
- if (!myToolkitBugsProcessor.process(t)) {
- PluginManager.processException(t);
- }
+ processException(t);
}
finally {
myDispatchingFocusEvent = false;
@@ -760,7 +784,7 @@ public class IdeEventQueue extends EventQueue {
}
private static boolean typeAheadDispatchToFocusManager(AWTEvent e) {
- if (e instanceof KeyEvent && appIsLoaded()) {
+ if (e instanceof KeyEvent) {
final KeyEvent event = (KeyEvent)e;
if (!event.isConsumed()) {
final IdeFocusManager focusManager = IdeFocusManager.findInstanceByComponent(event.getComponent());
@@ -771,15 +795,6 @@ public class IdeEventQueue extends EventQueue {
return false;
}
- private static boolean ourAppIsLoaded = false;
-
- private static boolean appIsLoaded() {
- if (ourAppIsLoaded) return true;
- boolean loaded = IdeaApplication.isLoaded();
- if (loaded) ourAppIsLoaded = true;
- return loaded;
- }
-
public void flushQueue() {
while (true) {
AWTEvent event = peekEvent();
diff --git a/platform/platform-impl/src/com/intellij/ide/IdeRepaintManager.java b/platform/platform-impl/src/com/intellij/ide/IdeRepaintManager.java
index d7118949e5de..4a0e11bf5ff9 100644
--- a/platform/platform-impl/src/com/intellij/ide/IdeRepaintManager.java
+++ b/platform/platform-impl/src/com/intellij/ide/IdeRepaintManager.java
@@ -128,19 +128,23 @@ public class IdeRepaintManager extends RepaintManager {
final Exception exception = new Exception();
StackTraceElement[] stackTrace = exception.getStackTrace();
for (StackTraceElement st : stackTrace) {
- if (repaint && st.getClassName().startsWith("javax.swing.")) {
+ String className = st.getClassName();
+ String methodName = st.getMethodName();
+
+ if (repaint && className.startsWith("javax.swing.")) {
fromSwing = true;
}
- if (repaint && "imageUpdate".equals(st.getMethodName())) {
+ if (repaint && "imageUpdate".equals(methodName)) {
swingKnownNonAwtOperations = true;
}
- if (st.getClassName().startsWith("javax.swing.JEditorPane") && st.getMethodName().equals("read")) {
+ if ("read".equals(methodName) && className.startsWith("javax.swing.JEditorPane") ||
+ "setCharacterAttributes".equals(methodName) && className.startsWith("javax.swing.text.DefaultStyledDocument")) {
swingKnownNonAwtOperations = true;
break;
}
- if ("repaint".equals(st.getMethodName())) {
+ if ("repaint".equals(methodName)) {
repaint = true;
fromSwing = false;
}
diff --git a/platform/platform-impl/src/com/intellij/ide/UiActivityMonitorImpl.java b/platform/platform-impl/src/com/intellij/ide/UiActivityMonitorImpl.java
index c25c68b4bb2b..e9de64905415 100644
--- a/platform/platform-impl/src/com/intellij/ide/UiActivityMonitorImpl.java
+++ b/platform/platform-impl/src/com/intellij/ide/UiActivityMonitorImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
package com.intellij.ide;
import com.intellij.openapi.Disposable;
-import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.application.ModalityStateListener;
@@ -24,7 +23,6 @@ import com.intellij.openapi.application.impl.LaterInvocator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.BusyObject;
import com.intellij.openapi.util.Disposer;
-import com.intellij.openapi.util.registry.Registry;
import com.intellij.util.containers.FactoryMap;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
@@ -34,16 +32,16 @@ import javax.swing.*;
import java.util.*;
public class UiActivityMonitorImpl extends UiActivityMonitor implements ModalityStateListener, Disposable {
-
private final FactoryMap<Project, BusyContainer> myObjects = new FactoryMap<Project, BusyContainer>() {
@Override
protected BusyContainer create(Project key) {
if (isEmpty()) {
installListener();
}
- return key == null ? new BusyContainer(key) : new BusyContainer(null) {
+ return key == null ? new BusyContainer(null) : new BusyContainer(null) {
+ @NotNull
@Override
- protected BusyImpl createBusyImpl(HashSet<UiActivity> key) {
+ protected BusyImpl createBusyImpl(@NotNull Set<UiActivity> key) {
return new BusyImpl(key, this) {
@Override
public boolean isReady() {
@@ -63,7 +61,8 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
private boolean myActive;
- private BusyObject myEmptyBusy = new BusyObject.Impl() {
+ @NotNull
+ private final BusyObject myEmptyBusy = new BusyObject.Impl() {
@Override
public boolean isReady() {
return true;
@@ -84,17 +83,12 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
@Override
public void beforeModalityStateChanged(boolean entering) {
- if (isUnitTestMode()) {
- maybeReady();
- }
- else {
- SwingUtilities.invokeLater(new Runnable() {
- @Override
- public void run() {
- maybeReady();
- }
- });
- }
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ maybeReady();
+ }
+ });
}
public void maybeReady() {
@@ -103,15 +97,17 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
}
}
+ @NotNull
@Override
- public BusyObject getBusy(@NotNull Project project, UiActivity... toWatch) {
+ public BusyObject getBusy(@NotNull Project project, @NotNull UiActivity... toWatch) {
if (!isActive()) return myEmptyBusy;
return _getBusy(project, toWatch);
}
+ @NotNull
@Override
- public BusyObject getBusy(UiActivity... toWatch) {
+ public BusyObject getBusy(@NotNull UiActivity... toWatch) {
if (!isActive()) return myEmptyBusy;
return _getBusy(null, toWatch);
@@ -129,10 +125,10 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
if (!isActive()) return;
- invokeLaterIfNeeded(new MyRunnable() {
+ UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
- public void run(Throwable allocation) {
- getBusyContainer(project).addActivity(activity, allocation, effectiveModalityState);
+ public void run() {
+ getBusyContainer(project).addActivity(activity, effectiveModalityState);
}
});
}
@@ -141,9 +137,9 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
public void removeActivity(@NotNull final Project project, @NotNull final UiActivity activity) {
if (!isActive()) return;
- invokeLaterIfNeeded(new MyRunnable() {
+ UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
- public void run(Throwable allocation) {
+ public void run() {
_getBusy(project).removeActivity(activity);
}
});
@@ -162,10 +158,10 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
public void addActivity(@NotNull final UiActivity activity, @NotNull final ModalityState effectiveModalityState) {
if (!isActive()) return;
- invokeLaterIfNeeded(new MyRunnable() {
+ UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
- public void run(Throwable allocation) {
- getBusyContainer(null).addActivity(activity, allocation, effectiveModalityState);
+ public void run() {
+ getBusyContainer(null).addActivity(activity, effectiveModalityState);
}
});
}
@@ -174,15 +170,16 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
public void removeActivity(@NotNull final UiActivity activity) {
if (!isActive()) return;
- invokeLaterIfNeeded(new MyRunnable() {
+ UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
- public void run(Throwable allocation) {
+ public void run() {
_getBusy(null).removeActivity(activity);
}
});
}
- private BusyImpl _getBusy(@Nullable Project key, UiActivity... toWatch) {
+ @NotNull
+ private BusyImpl _getBusy(@Nullable Project key, @NotNull UiActivity... toWatch) {
return getBusyContainer(key).getOrCreateBusy(toWatch);
}
@@ -204,6 +201,7 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
return myObjects.get(null);
}
+ @Override
public void clear() {
final Set<Project> keys = myObjects.keySet();
for (Project each : keys) {
@@ -215,7 +213,7 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
public void setActive(boolean active) {
if (myActive == active) return;
- if (myActive && !active) {
+ if (myActive) {
clear();
}
@@ -227,25 +225,19 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
}
private static class ActivityInfo {
- private final Throwable myAllocation;
private final ModalityState myEffectiveState;
- private ActivityInfo(@Nullable Throwable allocation, @NotNull ModalityState effectiveState) {
- myAllocation = allocation;
+ private ActivityInfo(@NotNull ModalityState effectiveState) {
myEffectiveState = effectiveState;
}
- @Nullable
- public Throwable getAllocation() {
- return myAllocation;
- }
-
@NotNull
public ModalityState getEffectiveState() {
return myEffectiveState;
}
}
+ @NotNull
protected ModalityState getCurrentState() {
return ModalityState.current();
}
@@ -258,9 +250,9 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
protected final Set<UiActivity> myToWatch;
protected final UiActivity[] myToWatchArray;
- private UiActivityMonitorImpl.BusyContainer myContainer;
+ private final UiActivityMonitorImpl.BusyContainer myContainer;
- private BusyImpl(Set<UiActivity> toWatch, BusyContainer container) {
+ private BusyImpl(@NotNull Set<UiActivity> toWatch, @NotNull BusyContainer container) {
myToWatch = toWatch;
myToWatchArray = toWatch.toArray(new UiActivity[toWatch.size()]);
myContainer = container;
@@ -274,9 +266,7 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
boolean isOwnReady() {
Map<UiActivity, ActivityInfo> infoToCheck = new HashMap<UiActivity, ActivityInfo>();
- final Iterator<Set<UiActivity>> activitySets = myContainer.myActivities2Object.keySet().iterator();
- while (activitySets.hasNext()) {
- Set<UiActivity> eachActivitySet = activitySets.next();
+ for (Set<UiActivity> eachActivitySet : myContainer.myActivities2Object.keySet()) {
final BusyImpl eachBusyObject = myContainer.myActivities2Object.get(eachActivitySet);
if (eachBusyObject == this) continue;
@@ -304,19 +294,16 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
return true;
}
+ public void addActivity(@NotNull UiActivity activity, @NotNull ModalityState effectiveModalityState) {
+ if (!myToWatch.isEmpty() && !myToWatch.contains(activity)) return;
- public void addActivity(UiActivity activity, Throwable allocation, ModalityState effectiveModalityState) {
- if (!myToWatch.isEmpty()) {
- if (!myToWatch.contains(activity)) return;
- }
-
- myActivities.put(activity, new ActivityInfo(allocation, effectiveModalityState));
+ myActivities.put(activity, new ActivityInfo(effectiveModalityState));
myQueuedToRemove.remove(activity);
- myContainer.onActivityAdded(this, activity);
+ myContainer.onActivityAdded(activity);
}
- public void removeActivity(final UiActivity activity) {
+ public void removeActivity(@NotNull final UiActivity activity) {
if (!myActivities.containsKey(activity)) return;
myQueuedToRemove.add(activity);
@@ -333,87 +320,48 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
onReady();
}
};
- if (isUnitTestMode()) {
- runnable.run();
- }
- else {
- SwingUtilities.invokeLater(runnable);
- }
+ SwingUtilities.invokeLater(runnable);
}
-
- public void clear() {
- UiActivity[] activities = myActivities.keySet().toArray(new UiActivity[myActivities.size()]);
- for (UiActivity each : activities) {
- removeActivity(each);
- }
- }
- }
-
- private static void invokeLaterIfNeeded(final MyRunnable runnable) {
- final Throwable allocation = Registry.is("ide.debugMode") ? new Exception() : null;
-
- if (isUnitTestMode()) {
- runnable.run(allocation);
- }
- else {
- UIUtil.invokeLaterIfNeeded(new Runnable() {
- @Override
- public void run() {
- runnable.run(allocation);
- }
- });
- }
- }
-
- private interface MyRunnable {
- void run(Throwable allocation);
- }
-
- private static boolean isUnitTestMode() {
- Application app = ApplicationManager.getApplication();
- return app == null || app.isUnitTestMode();
}
public class BusyContainer implements Disposable {
+ private final Map<Set<UiActivity>, BusyImpl> myActivities2Object = new HashMap<Set<UiActivity>, BusyImpl>();
+ private final Map<BusyImpl, Set<UiActivity>> myObject2Activities = new HashMap<BusyImpl, Set<UiActivity>>();
- private Map<Set<UiActivity>, BusyImpl> myActivities2Object = new HashMap<Set<UiActivity>, BusyImpl>();
- private Map<BusyImpl, Set<UiActivity>> myObject2Activities = new HashMap<BusyImpl, Set<UiActivity>>();
-
- private Set<UiActivity> myActivities = new HashSet<UiActivity>();
-
- private BusyImpl myDefault;
+ private final Set<UiActivity> myActivities = new HashSet<UiActivity>();
private boolean myRemovingActivityNow;
@Nullable private final Project myProject;
public BusyContainer(@Nullable Project project) {
myProject = project;
- myDefault = registerBusyObject(new HashSet<UiActivity>());
+ registerBusyObject(new HashSet<UiActivity>());
if (project != null) {
Disposer.register(project, this);
}
}
- public BusyImpl getOrCreateBusy(UiActivity... activities) {
- final HashSet<UiActivity> key = new HashSet<UiActivity>();
+ @NotNull
+ public BusyImpl getOrCreateBusy(@NotNull UiActivity... activities) {
+ Set<UiActivity> key = new HashSet<UiActivity>();
key.addAll(Arrays.asList(activities));
if (myActivities2Object.containsKey(key)) {
return myActivities2Object.get(key);
}
- else {
- return registerBusyObject(key);
- }
+ return registerBusyObject(key);
}
- private BusyImpl registerBusyObject(HashSet<UiActivity> key) {
+ @NotNull
+ private BusyImpl registerBusyObject(@NotNull Set<UiActivity> key) {
final BusyImpl busy = createBusyImpl(key);
myActivities2Object.put(key, busy);
myObject2Activities.put(busy, key);
return busy;
}
- protected BusyImpl createBusyImpl(HashSet<UiActivity> key) {
+ @NotNull
+ protected BusyImpl createBusyImpl(@NotNull Set<UiActivity> key) {
return new BusyImpl(key, this);
}
@@ -437,11 +385,11 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
}
}
- public void onActivityAdded(BusyImpl busy, UiActivity activity) {
+ public void onActivityAdded(@NotNull UiActivity activity) {
myActivities.add(activity);
}
- public void onActivityRemoved(BusyImpl busy, UiActivity activity) {
+ public void onActivityRemoved(@NotNull BusyImpl busy, @NotNull UiActivity activity) {
if (myRemovingActivityNow) return;
final Map<BusyImpl, Set<UiActivity>> toRemove = new HashMap<BusyImpl, Set<UiActivity>>();
@@ -450,9 +398,7 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
myRemovingActivityNow = true;
myActivities.remove(activity);
- final Iterator<BusyImpl> objects = myObject2Activities.keySet().iterator();
- while (objects.hasNext()) {
- BusyImpl each = objects.next();
+ for (BusyImpl each : myObject2Activities.keySet()) {
if (each != busy) {
each.removeActivity(activity);
}
@@ -472,11 +418,11 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
}
}
- public void addActivity(UiActivity activity, Throwable allocation, ModalityState state) {
+ public void addActivity(@NotNull UiActivity activity, @NotNull ModalityState state) {
getOrCreateBusy(activity);
final Set<BusyImpl> busies = myObject2Activities.keySet();
for (BusyImpl each : busies) {
- each.addActivity(activity, allocation, state);
+ each.addActivity(activity, state);
}
}
diff --git a/platform/platform-impl/src/com/intellij/ide/actionMacro/actions/EditMacrosAction.java b/platform/platform-impl/src/com/intellij/ide/actionMacro/actions/EditMacrosAction.java
index cb0d0ffd4619..c46241d1c4d9 100644
--- a/platform/platform-impl/src/com/intellij/ide/actionMacro/actions/EditMacrosAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actionMacro/actions/EditMacrosAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,29 +16,22 @@
package com.intellij.ide.actionMacro.actions;
import com.intellij.ide.actionMacro.ActionMacro;
+import com.intellij.ide.actionMacro.ActionMacroConfigurable;
import com.intellij.ide.actionMacro.ActionMacroManager;
-import com.intellij.ide.actionMacro.EditMacrosDialog;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.project.DumbAware;
-/**
- * Created by IntelliJ IDEA.
- * User: max
- * Date: Jul 22, 2003
- * Time: 3:33:04 PM
- * To change this template use Options | File Templates.
- */
public class EditMacrosAction extends AnAction implements DumbAware {
+ @Override
public void actionPerformed(AnActionEvent e) {
- EditMacrosDialog dialog = new EditMacrosDialog(CommonDataKeys.PROJECT.getData(e.getDataContext()));
- dialog.show();
+ ShowSettingsUtil.getInstance().editConfigurable(e.getProject(), "#com.intellij.ide.actionMacro.EditMacrosDialog", new ActionMacroConfigurable());
}
+ @Override
public void update(AnActionEvent e) {
- final ActionMacroManager manager = ActionMacroManager.getInstance();
- ActionMacro[] macros = manager.getAllMacros();
+ ActionMacro[] macros = ActionMacroManager.getInstance().getAllMacros();
e.getPresentation().setEnabled(macros != null && macros.length > 0);
}
}
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/BaseNavigateToSourceAction.java b/platform/platform-impl/src/com/intellij/ide/actions/BaseNavigateToSourceAction.java
index 1c7855d2eedb..709c3b458112 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/BaseNavigateToSourceAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/BaseNavigateToSourceAction.java
@@ -19,7 +19,9 @@ import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.project.DumbAware;
import com.intellij.pom.Navigatable;
import com.intellij.pom.NavigatableWithText;
+import com.intellij.pom.PomTargetPsiElement;
import com.intellij.util.OpenSourceUtil;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public abstract class BaseNavigateToSourceAction extends AnAction implements DumbAware {
@@ -37,7 +39,7 @@ public abstract class BaseNavigateToSourceAction extends AnAction implements Dum
public void update(AnActionEvent event) {
DataContext dataContext = event.getDataContext();
- final Navigatable target = getTarget(dataContext);
+ final Navigatable target = findTargetForUpdate(dataContext);
boolean enabled = target != null;
if (ActionPlaces.isPopupPlace(event.getPlace())) {
event.getPresentation().setVisible(enabled);
@@ -49,36 +51,21 @@ public abstract class BaseNavigateToSourceAction extends AnAction implements Dum
else {
event.getPresentation().setEnabled(enabled);
}
- if (target != null && target instanceof NavigatableWithText) {
- //as myFocusEditor is always ignored - Main Menu|View always contains 2 actions with the same name and actually same behaviour
- if (!myFocusEditor) {
- event.getPresentation().setVisible(false);
- return;
- }
- final String navigateActionText = ((NavigatableWithText)target).getNavigateActionText(myFocusEditor);
- if (navigateActionText != null) {
- event.getPresentation().setText(navigateActionText);
- }
- else {
- event.getPresentation().setText(getTemplatePresentation().getText());
- }
- }
- else {
- event.getPresentation().setText(getTemplatePresentation().getText());
- }
+ //as myFocusEditor is always ignored - Main Menu|View always contains 2 actions with the same name and actually same behaviour
+ event.getPresentation().setVisible(target == null || myFocusEditor);
+ String navigateActionText = myFocusEditor && target instanceof NavigatableWithText?
+ ((NavigatableWithText)target).getNavigateActionText(true) : null;
+ event.getPresentation().setText(navigateActionText == null ? getTemplatePresentation().getText() : navigateActionText);
}
@Nullable
- private Navigatable getTarget(final DataContext dataContext) {
- if (!myFocusEditor && CommonDataKeys.EDITOR.getData(dataContext) != null) {
- // makes no sense in editor and conflicts with another action there (ctrl+enter)
- return null;
- }
-
+ private Navigatable findTargetForUpdate(@NotNull DataContext dataContext) {
Navigatable[] navigatables = getNavigatables(dataContext);
- if (navigatables != null) {
- for (Navigatable navigatable : navigatables) {
- if (navigatable.canNavigate()) return navigatable;
+ if (navigatables == null) return null;
+
+ for (Navigatable navigatable : navigatables) {
+ if (navigatable.canNavigate()) {
+ return navigatable instanceof PomTargetPsiElement ? ((PomTargetPsiElement)navigatable).getTarget() : navigatable;
}
}
return null;
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java b/platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java
index 9bdc5948cffe..136f4b166e1a 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java
@@ -23,6 +23,7 @@ import com.intellij.notification.Notifications;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.application.ApplicationBundle;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.diagnostic.Logger;
@@ -104,11 +105,15 @@ public class CreateDesktopEntryAction extends DumbAwareAction {
final String message = ApplicationBundle.message("desktop.entry.success",
ApplicationNamesInfo.getInstance().getProductName());
- Notifications.Bus.notify(
- new Notification(Notifications.SYSTEM_MESSAGES_GROUP_ID, "Desktop entry created", message, NotificationType.INFORMATION)
- );
+ if (ApplicationManager.getApplication() != null) {
+ Notifications.Bus
+ .notify(new Notification(Notifications.SYSTEM_MESSAGES_GROUP_ID, "Desktop entry created", message, NotificationType.INFORMATION));
+ }
}
catch (Exception e) {
+ if (ApplicationManager.getApplication() == null) {
+ throw new RuntimeException(e);
+ }
final String message = e.getMessage();
if (!StringUtil.isEmptyOrSpaces(message)) {
LOG.warn(e);
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/OpenFileAction.java b/platform/platform-impl/src/com/intellij/ide/actions/OpenFileAction.java
index 4cabfe9b5fe9..37b09394dd89 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/OpenFileAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/OpenFileAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,14 +19,14 @@ import com.intellij.ide.IdeBundle;
import com.intellij.ide.impl.ProjectUtil;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.fileChooser.FileChooser;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
-import com.intellij.openapi.fileChooser.FileElement;
+import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.fileChooser.PathChooserDialog;
import com.intellij.openapi.fileChooser.impl.FileChooserUtil;
import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.fileEditor.FileEditorProvider;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.fileEditor.ex.FileEditorProviderManager;
import com.intellij.openapi.fileTypes.FileType;
@@ -34,7 +34,6 @@ import com.intellij.openapi.fileTypes.ex.FileTypeChooser;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
-import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
@@ -47,54 +46,20 @@ import org.jetbrains.annotations.Nullable;
import java.util.List;
public class OpenFileAction extends AnAction implements DumbAware {
+ @Override
public void actionPerformed(AnActionEvent e) {
- @Nullable final Project project = CommonDataKeys.PROJECT.getData(e.getDataContext());
+ final Project project = e.getProject();
final boolean showFiles = project != null || PlatformProjectOpenProcessor.getInstanceIfItExists() != null;
+ final FileChooserDescriptor descriptor = showFiles ? new ProjectOrFileChooserDescriptor() : new ProjectOnlyFileChooserDescriptor();
+ descriptor.putUserData(PathChooserDialog.PREFER_LAST_OVER_EXPLICIT, showFiles);
- final FileChooserDescriptor descriptor = new OpenProjectFileChooserDescriptor(true) {
- @Override
- public boolean isFileSelectable(VirtualFile file) {
- if (super.isFileSelectable(file)) {
- return true;
- }
- if (file.isDirectory()) {
- return false;
- }
- return showFiles && !FileElement.isArchive(file);
- }
-
- @Override
- public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) {
- if (!file.isDirectory() && isFileSelectable(file)) {
- if (!showHiddenFiles && FileElement.isFileHidden(file)) return false;
- return true;
- }
- return super.isFileVisible(file, showHiddenFiles);
- }
-
- @Override
- public boolean isChooseMultiple() {
- return showFiles;
- }
- };
- descriptor.setTitle(showFiles ? "Open File or Project" : "Open Project");
-
- VirtualFile userHomeDir = null;
- if (SystemInfo.isUnix) {
- userHomeDir = VfsUtil.getUserHomeDir();
- }
-
- descriptor.putUserData(PathChooserDialog.PREFER_LAST_OVER_EXPLICIT, Boolean.TRUE);
-
- FileChooser.chooseFiles(descriptor, project, userHomeDir, new Consumer<List<VirtualFile>>() {
+ FileChooser.chooseFiles(descriptor, project, VfsUtil.getUserHomeDir(), new Consumer<List<VirtualFile>>() {
@Override
public void consume(final List<VirtualFile> files) {
for (VirtualFile file : files) {
- if (!descriptor.isFileSelectable(file)) { // on Mac, it could be selected anyway
- Messages.showInfoMessage(project,
- file.getPresentableUrl() + " contains no " +
- ApplicationNamesInfo.getInstance().getFullProductName() + " project",
- "Cannot Open Project");
+ if (!descriptor.isFileSelectable(file)) {
+ String message = IdeBundle.message("error.dir.contains.no.project", file.getPresentableUrl());
+ Messages.showInfoMessage(project, message, IdeBundle.message("title.cannot.open.project"));
return;
}
}
@@ -103,9 +68,8 @@ public class OpenFileAction extends AnAction implements DumbAware {
});
}
- private static void doOpenFile(@Nullable final Project project,
- @NotNull final List<VirtualFile> result) {
- for (final VirtualFile file : result) {
+ private static void doOpenFile(@Nullable Project project, @NotNull List<VirtualFile> result) {
+ for (VirtualFile file : result) {
if (file.isDirectory()) {
Project openedProject;
if (ProjectAttachProcessor.canAttachToProject()) {
@@ -118,9 +82,8 @@ public class OpenFileAction extends AnAction implements DumbAware {
return;
}
- if (OpenProjectFileChooserDescriptor.isProjectFile(file) &&
- // if the ipr-based project is already open, just open the ipr file
- (project == null || !file.equals(project.getProjectFile()))) {
+ // try to open as a project - unless the file is an .ipr of the current one
+ if ((project == null || !file.equals(project.getProjectFile())) && OpenProjectFileChooserDescriptor.isProjectFile(file)) {
Project openedProject = ProjectUtil.openOrImport(file.getPath(), project, false);
if (openedProject != null) {
FileChooserUtil.setLastOpenedFile(openedProject, file);
@@ -143,26 +106,54 @@ public class OpenFileAction extends AnAction implements DumbAware {
}
}
- public static void openFile(final String filePath, final Project project) {
- final VirtualFile file = LocalFileSystem.getInstance().findFileByPath(filePath);
+ public static void openFile(String filePath, @NotNull Project project) {
+ VirtualFile file = LocalFileSystem.getInstance().findFileByPath(filePath);
if (file != null && file.isValid()) {
openFile(file, project);
}
}
- public static void openFile(final VirtualFile virtualFile, final Project project) {
- FileEditorProviderManager editorProviderManager = FileEditorProviderManager.getInstance();
- if (editorProviderManager.getProviders(project, virtualFile).length == 0) {
- Messages.showMessageDialog(project,
- IdeBundle.message("error.files.of.this.type.cannot.be.opened",
- ApplicationNamesInfo.getInstance().getProductName()),
- IdeBundle.message("title.cannot.open.file"),
- Messages.getErrorIcon());
+ public static void openFile(VirtualFile file, @NotNull Project project) {
+ FileEditorProvider[] providers = FileEditorProviderManager.getInstance().getProviders(project, file);
+ if (providers.length == 0) {
+ String message = IdeBundle.message("error.files.of.this.type.cannot.be.opened", ApplicationNamesInfo.getInstance().getProductName());
+ Messages.showErrorDialog(project, message, IdeBundle.message("title.cannot.open.file"));
return;
}
- OpenFileDescriptor descriptor = new OpenFileDescriptor(project, virtualFile);
+ OpenFileDescriptor descriptor = new OpenFileDescriptor(project, file);
FileEditorManager.getInstance(project).openTextEditor(descriptor, true);
}
+ private static class ProjectOnlyFileChooserDescriptor extends OpenProjectFileChooserDescriptor {
+ public ProjectOnlyFileChooserDescriptor() {
+ super(true);
+ setTitle(IdeBundle.message("title.open.project"));
+ }
+ }
+
+ // vanilla OpenProjectFileChooserDescriptor only accepts project files; this on is overridden to accept any files
+ private static class ProjectOrFileChooserDescriptor extends OpenProjectFileChooserDescriptor {
+ private final FileChooserDescriptor myStandardDescriptor = FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor();
+
+ public ProjectOrFileChooserDescriptor() {
+ super(true);
+ setTitle(IdeBundle.message("title.open.file.or.project"));
+ }
+
+ @Override
+ public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) {
+ return file.isDirectory() ? super.isFileVisible(file, showHiddenFiles) : myStandardDescriptor.isFileVisible(file, showHiddenFiles);
+ }
+
+ @Override
+ public boolean isFileSelectable(VirtualFile file) {
+ return file.isDirectory() ? super.isFileSelectable(file) : myStandardDescriptor.isFileSelectable(file);
+ }
+
+ @Override
+ public boolean isChooseMultiple() {
+ return true;
+ }
+ }
}
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/OpenProjectFileChooserDescriptor.java b/platform/platform-impl/src/com/intellij/ide/actions/OpenProjectFileChooserDescriptor.java
index 51d6362b36d8..b462fcbc11ad 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/OpenProjectFileChooserDescriptor.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/OpenProjectFileChooserDescriptor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,74 +15,91 @@
*/
package com.intellij.ide.actions;
-import com.intellij.icons.AllIcons;
import com.intellij.ide.highlighter.ProjectFileType;
import com.intellij.openapi.application.ex.ApplicationInfoEx;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
-import com.intellij.openapi.fileChooser.FileElement;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.IconLoader;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.projectImport.ProjectOpenProcessor;
-import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.NotNull;
import javax.swing.*;
+/**
+ * Intended for use in actions related to opening or importing existing projects.
+ * <strong>Due to a high I/O impact SHOULD NOT be used in any other cases.</strong>
+ */
public class OpenProjectFileChooserDescriptor extends FileChooserDescriptor {
private static final Icon ourProjectIcon = IconLoader.getIcon(ApplicationInfoEx.getInstanceEx().getSmallIconUrl());
- public OpenProjectFileChooserDescriptor(final boolean chooseFiles) {
+ public OpenProjectFileChooserDescriptor(boolean chooseFiles) {
super(chooseFiles, true, chooseFiles, chooseFiles, false, false);
}
- public boolean isFileSelectable(final VirtualFile file) {
- if (file == null) return false;
+ @Override
+ public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) {
+ return super.isFileVisible(file, showHiddenFiles) && (file.isDirectory() || isProjectFile(file));
+ }
+
+ @Override
+ public boolean isFileSelectable(VirtualFile file) {
return isProjectDirectory(file) || isProjectFile(file);
}
- public Icon getIcon(final VirtualFile file) {
- if (isProjectDirectory(file)) {
- return dressIcon(file, ourProjectIcon);
- }
- final Icon icon = getImporterIcon(file);
- if (icon != null) {
- return dressIcon(file, icon);
+ @Override
+ public Icon getIcon(VirtualFile file) {
+ if (canInspectDirectory(file)) {
+ if (isIprFile(file) || isIdeaDirectory(file)) {
+ return dressIcon(file, ourProjectIcon);
+ }
+ Icon icon = getImporterIcon(file);
+ if (icon != null) {
+ return dressIcon(file, icon);
+ }
}
return super.getIcon(file);
}
- @Nullable
- private static Icon getImporterIcon(final VirtualFile virtualFile) {
- final ProjectOpenProcessor provider = ProjectOpenProcessor.getImportProvider(virtualFile);
+ private static boolean canInspectDirectory(VirtualFile file) {
+ if (file.getParent() == null) return false;
+
+ VirtualFile home = VfsUtil.getUserHomeDir();
+ if (home == null) return false; // unnatural situation
+ VirtualFile homes = home.getParent();
+ if (homes == null) return false; // another one
+ if (homes.equals(file.getParent()) || VfsUtilCore.isAncestor(file, homes, false)) return false;
+
+ return true;
+ }
+
+ private static Icon getImporterIcon(VirtualFile file) {
+ ProjectOpenProcessor provider = ProjectOpenProcessor.getImportProvider(file);
if (provider != null) {
- return virtualFile.isDirectory() && provider.lookForProjectsInDirectory() ? AllIcons.Nodes.IdeaModule : provider.getIcon(virtualFile);
+ return file.isDirectory() && provider.lookForProjectsInDirectory() ? ourProjectIcon : provider.getIcon(file);
}
return null;
}
- public boolean isFileVisible(final VirtualFile file, final boolean showHiddenFiles) {
- if (!showHiddenFiles && FileElement.isFileHidden(file)) return false;
- return isProjectFile(file) || super.isFileVisible(file, showHiddenFiles) && file.isDirectory();
+ public static boolean isProjectFile(@NotNull VirtualFile file) {
+ return !file.isDirectory() && file.isValid() && (isIprFile(file) || hasImportProvider(file));
}
- public static boolean isProjectFile(final VirtualFile file) {
- if (isIprFile(file)) return true;
- final ProjectOpenProcessor importProvider = ProjectOpenProcessor.getImportProvider(file);
- return importProvider != null;
+ private static boolean isProjectDirectory(@NotNull VirtualFile file) {
+ return file.isDirectory() && file.isValid() && (isIdeaDirectory(file) || hasImportProvider(file));
}
private static boolean isIprFile(VirtualFile file) {
- if ((!file.isDirectory() && file.getName().toLowerCase().endsWith(ProjectFileType.DOT_DEFAULT_EXTENSION))) {
- return true;
- }
- return false;
+ return ProjectFileType.DEFAULT_EXTENSION.equalsIgnoreCase(file.getExtension());
+ }
+
+ private static boolean isIdeaDirectory(VirtualFile file) {
+ return file.findChild(Project.DIRECTORY_STORE_FOLDER) != null;
}
- private static boolean isProjectDirectory(final VirtualFile virtualFile) {
- // the root directory of any drive is never an IDEA project
- if (virtualFile.getParent() == null) return false;
- // NOTE: For performance reasons, it's very important not to iterate through all of the children here.
- if (virtualFile.isDirectory() && virtualFile.isValid() && virtualFile.findChild(Project.DIRECTORY_STORE_FOLDER) != null) return true;
- return false;
+ private static boolean hasImportProvider(VirtualFile file) {
+ return ProjectOpenProcessor.getImportProvider(file) != null;
}
}
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsUtilImpl.java b/platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsUtilImpl.java
index 4df11f7261ca..2c5cc5b02282 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsUtilImpl.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsUtilImpl.java
@@ -15,23 +15,20 @@
*/
package com.intellij.ide.actions;
+import com.intellij.ide.ui.search.SearchUtil;
+import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.options.Configurable;
-import com.intellij.openapi.options.ConfigurableGroup;
-import com.intellij.openapi.options.SearchableConfigurable;
-import com.intellij.openapi.options.ShowSettingsUtil;
-import com.intellij.openapi.options.ex.ConfigurableExtensionPointUtil;
-import com.intellij.openapi.options.ex.IdeConfigurablesGroup;
-import com.intellij.openapi.options.ex.MixedConfigurableGroup;
-import com.intellij.openapi.options.ex.ProjectConfigurablesGroup;
-import com.intellij.openapi.options.ex.SingleConfigurableEditor;
+import com.intellij.openapi.options.*;
+import com.intellij.openapi.options.ex.*;
+import com.intellij.openapi.options.newEditor.IdeSettingsDialog;
import com.intellij.openapi.options.newEditor.OptionsEditor;
import com.intellij.openapi.options.newEditor.OptionsEditorDialog;
-import com.intellij.openapi.options.newEditor.PreferencesDialog;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.registry.Registry;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.ui.navigation.Place;
import com.intellij.util.ui.update.Activatable;
import com.intellij.util.ui.update.UiNotifyConnector;
import org.jetbrains.annotations.NotNull;
@@ -47,7 +44,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
*/
public class ShowSettingsUtilImpl extends ShowSettingsUtil {
private static final Logger LOG = Logger.getInstance("#com.intellij.ide.actions.ShowSettingsUtilImpl");
- private AtomicBoolean myShown = new AtomicBoolean(false);
+ private final AtomicBoolean myShown = new AtomicBoolean(false);
@NotNull
private static Project getProject(@Nullable Project project) {
@@ -55,12 +52,16 @@ public class ShowSettingsUtilImpl extends ShowSettingsUtil {
}
@NotNull
- private static DialogWrapper getDialog(@Nullable Project project, @NotNull ConfigurableGroup[] groups, @Nullable Configurable toSelect) {
+ public static DialogWrapper getDialog(@Nullable Project project, @NotNull ConfigurableGroup[] groups, @Nullable Configurable toSelect) {
+ project = getProject(project);
+ final ConfigurableGroup[] filteredGroups = filterEmptyGroups(groups);
+ if (Registry.is("ide.new.settings.dialog")) {
+ return new IdeSettingsDialog(project, filteredGroups, toSelect);
+ }
+ //noinspection deprecation
return Registry.is("ide.perProjectModality")
- ? new OptionsEditorDialog(getProject(project), filterEmptyGroups(groups), toSelect, true)
- : Registry.is("ide.new.preferences")
- ? new PreferencesDialog(getProject(project), filterEmptyGroups(groups))
- : new OptionsEditorDialog(getProject(project), filterEmptyGroups(groups), toSelect);
+ ? new OptionsEditorDialog(project, filteredGroups, toSelect, true)
+ : new OptionsEditorDialog(project, filteredGroups, toSelect);
}
@NotNull
@@ -73,7 +74,7 @@ public class ShowSettingsUtilImpl extends ShowSettingsUtil {
new ProjectConfigurablesGroup(project),
new IdeConfigurablesGroup()};
- return Registry.is("ide.file.settings.order.new")
+ return Registry.is("ide.new.settings.dialog")
? MixedConfigurableGroup.getGroups(getConfigurables(groups, true))
: groups;
}
@@ -139,41 +140,34 @@ public class ShowSettingsUtilImpl extends ShowSettingsUtil {
@Override
public void showSettingsDialog(@Nullable final Project project, @NotNull final String nameToSelect) {
- ConfigurableGroup[] group = getConfigurableGroups(project, true);
-
+ ConfigurableGroup[] groups = getConfigurableGroups(project, true);
Project actualProject = getProject(project);
- group = filterEmptyGroups(group);
+ groups = filterEmptyGroups(groups);
+ getDialog(actualProject, groups, findPreselectedByDisplayName(nameToSelect, groups)).show();
+ }
- OptionsEditorDialog dialog;
- if (Registry.is("ide.perProjectModality")) {
- dialog = new OptionsEditorDialog(actualProject, group, nameToSelect, true);
- }
- else {
- dialog = new OptionsEditorDialog(actualProject, group, nameToSelect);
+ @Nullable
+ private static Configurable findPreselectedByDisplayName(final String preselectedConfigurableDisplayName, ConfigurableGroup[] groups) {
+ final List<Configurable> all = SearchUtil.expand(groups);
+ for (Configurable each : all) {
+ if (preselectedConfigurableDisplayName.equals(each.getDisplayName())) return each;
}
- dialog.show();
+ return null;
}
public static void showSettingsDialog(@Nullable Project project, final String id2Select, final String filter) {
ConfigurableGroup[] group = getConfigurableGroups(project, true);
- Project actualProject = getProject(project);
-
group = filterEmptyGroups(group);
final Configurable configurable2Select = findConfigurable2Select(id2Select, group);
- final OptionsEditorDialog dialog;
- if (Registry.is("ide.perProjectModality")) {
- dialog = new OptionsEditorDialog(actualProject, group, configurable2Select, true);
- } else {
- dialog = new OptionsEditorDialog(actualProject, group, configurable2Select);
- }
+ final DialogWrapper dialog = getDialog(project, group, configurable2Select);
new UiNotifyConnector.Once(dialog.getContentPane(), new Activatable.Adapter() {
@Override
public void showNotify() {
- final OptionsEditor editor = (OptionsEditor)dialog.getData(OptionsEditor.KEY.getName());
+ final OptionsEditor editor = (OptionsEditor)((DataProvider)dialog).getData(OptionsEditor.KEY.getName());
LOG.assertTrue(editor != null);
editor.select(configurable2Select, filter);
}
@@ -234,37 +228,53 @@ public class ShowSettingsUtilImpl extends ShowSettingsUtil {
@Override
public <T extends Configurable> T findProjectConfigurable(final Project project, final Class<T> confClass) {
+ //noinspection deprecation
return ConfigurableExtensionPointUtil.findProjectConfigurable(project, confClass);
}
@Override
public boolean editConfigurable(Project project, String dimensionServiceKey, @NotNull Configurable configurable) {
- return editConfigurable(null, project, configurable, dimensionServiceKey, null);
+ return editConfigurable(project, dimensionServiceKey, configurable, isWorthToShowApplyButton(configurable));
+ }
+
+ private static boolean isWorthToShowApplyButton(@NotNull Configurable configurable) {
+ return configurable instanceof Place.Navigator ||
+ configurable instanceof Composite ||
+ configurable instanceof TabbedConfigurable;
+ }
+
+ @Override
+ public boolean editConfigurable(Project project, String dimensionServiceKey, @NotNull Configurable configurable, boolean showApplyButton) {
+ return editConfigurable(null, project, configurable, dimensionServiceKey, null, showApplyButton);
}
@Override
public boolean editConfigurable(Project project, Configurable configurable, Runnable advancedInitialization) {
- return editConfigurable(null, project, configurable, createDimensionKey(configurable), advancedInitialization);
+ return editConfigurable(null, project, configurable, createDimensionKey(configurable), advancedInitialization, isWorthToShowApplyButton(configurable));
}
@Override
- public boolean editConfigurable(Component parent, Configurable configurable) {
+ public boolean editConfigurable(@Nullable Component parent, @NotNull Configurable configurable) {
return editConfigurable(parent, configurable, null);
}
@Override
- public boolean editConfigurable(final Component parent, final Configurable configurable, @Nullable final Runnable advancedInitialization) {
- return editConfigurable(parent, null, configurable, createDimensionKey(configurable), advancedInitialization);
+ public boolean editConfigurable(@Nullable Component parent, @NotNull Configurable configurable, @Nullable Runnable advancedInitialization) {
+ return editConfigurable(parent, null, configurable, createDimensionKey(configurable), advancedInitialization, isWorthToShowApplyButton(configurable));
}
- private static boolean editConfigurable(final @Nullable Component parent, @Nullable Project project, final Configurable configurable, final String dimensionKey,
- @Nullable final Runnable advancedInitialization) {
- SingleConfigurableEditor editor;
- if (parent != null) {
- editor = new SingleConfigurableEditor(parent, configurable, dimensionKey);
+ private static boolean editConfigurable(@Nullable Component parent,
+ @Nullable Project project,
+ @NotNull Configurable configurable,
+ String dimensionKey,
+ @Nullable final Runnable advancedInitialization,
+ boolean showApplyButton) {
+ final SingleConfigurableEditor editor;
+ if (parent == null) {
+ editor = new SingleConfigurableEditor(project, configurable, dimensionKey, showApplyButton);
}
else {
- editor = new SingleConfigurableEditor(project, configurable, dimensionKey);
+ editor = new SingleConfigurableEditor(parent, configurable, dimensionKey, showApplyButton);
}
if (advancedInitialization != null) {
new UiNotifyConnector.Once(editor.getContentPane(), new Activatable.Adapter() {
@@ -278,15 +288,14 @@ public class ShowSettingsUtilImpl extends ShowSettingsUtil {
return editor.isOK();
}
- public static String createDimensionKey(Configurable configurable) {
- String displayName = configurable.getDisplayName();
- displayName = displayName.replaceAll("\n", "_").replaceAll(" ", "_");
- return "#" + displayName;
+ @NotNull
+ public static String createDimensionKey(@NotNull Configurable configurable) {
+ return '#' + StringUtil.replaceChar(StringUtil.replaceChar(configurable.getDisplayName(), '\n', '_'), ' ', '_');
}
@Override
- public boolean editConfigurable(Component parent, String dimensionServiceKey,Configurable configurable) {
- return editConfigurable(parent, null, configurable, dimensionServiceKey, null);
+ public boolean editConfigurable(Component parent, String dimensionServiceKey, Configurable configurable) {
+ return editConfigurable(parent, null, configurable, dimensionServiceKey, null, isWorthToShowApplyButton(configurable));
}
public boolean isAlreadyShown() {
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ViewSourceAction.java b/platform/platform-impl/src/com/intellij/ide/actions/ViewSourceAction.java
index a9461422f747..825db992b218 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/ViewSourceAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/ViewSourceAction.java
@@ -17,9 +17,21 @@
package com.intellij.ide.actions;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
public class ViewSourceAction extends BaseNavigateToSourceAction {
public ViewSourceAction() {
super(false);
}
+
+ @Override
+ public void update(AnActionEvent e) {
+ if (CommonDataKeys.EDITOR.getData(e.getDataContext()) != null) {
+ e.getPresentation().setEnabledAndVisible(false);
+ }
+ else {
+ super.update(e);
+ }
+ }
}
diff --git a/platform/platform-impl/src/com/intellij/ide/customize/AbstractCustomizeWizardStep.java b/platform/platform-impl/src/com/intellij/ide/customize/AbstractCustomizeWizardStep.java
index 6844ed5bab25..798247e16186 100644
--- a/platform/platform-impl/src/com/intellij/ide/customize/AbstractCustomizeWizardStep.java
+++ b/platform/platform-impl/src/com/intellij/ide/customize/AbstractCustomizeWizardStep.java
@@ -21,12 +21,14 @@ import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
+import javax.swing.border.Border;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
public abstract class AbstractCustomizeWizardStep extends JPanel {
+ protected static final int SMALL_GAP = 10;
protected static final int GAP = 20;
protected abstract String getTitle();
@@ -40,6 +42,14 @@ public abstract class AbstractCustomizeWizardStep extends JPanel {
return ColorUtil.mix(UIUtil.getListSelectionBackground(), UIUtil.getLabelBackground(), UIUtil.isUnderDarcula() ? .5 : .75);
}
+ public static Border createSmallEmptyBorder() {
+ return BorderFactory.createEmptyBorder(SMALL_GAP, SMALL_GAP, SMALL_GAP, SMALL_GAP);
+ }
+
+ public static BorderLayout createSmallBorderLayout() {
+ return new BorderLayout(SMALL_GAP, SMALL_GAP);
+ }
+
protected static JPanel createBigButtonPanel(LayoutManager layout, final JToggleButton anchorButton, final Runnable action) {
final JPanel panel = new JPanel(layout) {
@Override
diff --git a/platform/platform-impl/src/com/intellij/ide/customize/CustomizeDesktopEntryStep.java b/platform/platform-impl/src/com/intellij/ide/customize/CustomizeDesktopEntryStep.java
new file mode 100644
index 000000000000..57b68232b797
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/ide/customize/CustomizeDesktopEntryStep.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ide.customize;
+
+import com.intellij.ide.actions.CreateDesktopEntryAction;
+import com.intellij.idea.ActionsBundle;
+import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.progress.EmptyProgressIndicator;
+import com.intellij.openapi.util.EmptyRunnable;
+import com.intellij.openapi.util.IconLoader;
+import com.intellij.util.ui.GridBag;
+import com.intellij.util.ui.UIUtil;
+
+import javax.swing.*;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import java.awt.*;
+
+/**
+ * @author Alexander Lobas
+ */
+public class CustomizeDesktopEntryStep extends AbstractCustomizeWizardStep {
+ private final JCheckBox myCreateEntryCheckBox = new JCheckBox(ActionsBundle.message("action.CreateDesktopEntry.description"));
+ private final JCheckBox myGlobalEntryCheckBox = new JCheckBox("For all users");
+
+ public CustomizeDesktopEntryStep(String iconPath) {
+ setLayout(new BorderLayout());
+
+ JPanel panel = createBigButtonPanel(createSmallBorderLayout(), myCreateEntryCheckBox, EmptyRunnable.INSTANCE);
+ panel.setBorder(createSmallEmptyBorder());
+
+ JPanel buttonPanel = new JPanel(new GridBagLayout());
+ buttonPanel.setOpaque(false);
+
+ GridBag gbc =
+ new GridBag().setDefaultAnchor(GridBagConstraints.WEST).setDefaultFill(GridBagConstraints.HORIZONTAL).setDefaultWeightX(1);
+
+ myCreateEntryCheckBox.setOpaque(false);
+ buttonPanel.add(myCreateEntryCheckBox, gbc.nextLine());
+
+ myGlobalEntryCheckBox.setOpaque(false);
+ gbc.nextLine().insets.left = UIUtil.PANEL_REGULAR_INSETS.left;
+ buttonPanel.add(myGlobalEntryCheckBox, gbc);
+
+ panel.add(buttonPanel, BorderLayout.NORTH);
+
+ JLabel label = new JLabel(IconLoader.getIcon(iconPath));
+ label.setVerticalAlignment(JLabel.TOP);
+ panel.add(label, BorderLayout.CENTER);
+
+ add(panel, BorderLayout.CENTER);
+
+ myCreateEntryCheckBox.addChangeListener(new ChangeListener() {
+ @Override
+ public void stateChanged(ChangeEvent e) {
+ myGlobalEntryCheckBox.setEnabled(myCreateEntryCheckBox.isSelected());
+ myGlobalEntryCheckBox.setSelected(myCreateEntryCheckBox.isSelected() && !PathManager.getHomePath().startsWith("/home"));
+ }
+ });
+
+ myCreateEntryCheckBox.setSelected(true);
+ }
+
+ public static boolean isAvailable() {
+ return CreateDesktopEntryAction.isAvailable();
+ }
+
+ @Override
+ public boolean beforeOkAction() {
+ if (myCreateEntryCheckBox.isSelected()) {
+ try {
+ CreateDesktopEntryAction.createDesktopEntry(null, new EmptyProgressIndicator(), myGlobalEntryCheckBox.isSelected());
+ }
+ catch (Throwable e) {
+ // ignored
+ }
+ }
+ return true;
+ }
+
+ @Override
+ protected String getTitle() {
+ return "Desktop Entry";
+ }
+
+ @Override
+ protected String getHTMLHeader() {
+ return "<html><body><h2>Create Desktop Entry</h2>&nbsp;</body></html>";
+ }
+
+ @Override
+ protected String getHTMLFooter() {
+ return "Desktop entry can be created later in Tools | Create Desktop Entry...";
+ }
+} \ No newline at end of file
diff --git a/platform/platform-impl/src/com/intellij/ide/customize/CustomizeFeaturedPluginsStepPanel.java b/platform/platform-impl/src/com/intellij/ide/customize/CustomizeFeaturedPluginsStepPanel.java
index 786a5825e783..498391b8e971 100644
--- a/platform/platform-impl/src/com/intellij/ide/customize/CustomizeFeaturedPluginsStepPanel.java
+++ b/platform/platform-impl/src/com/intellij/ide/customize/CustomizeFeaturedPluginsStepPanel.java
@@ -18,7 +18,9 @@ package com.intellij.ide.customize;
import com.intellij.CommonBundle;
import com.intellij.icons.AllIcons;
import com.intellij.ide.plugins.IdeaPluginDescriptor;
+import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.ide.plugins.PluginNode;
+import com.intellij.openapi.options.OptionsBundle;
import com.intellij.openapi.progress.util.ProgressIndicatorBase;
import com.intellij.openapi.ui.VerticalFlowLayout;
import com.intellij.openapi.updateSettings.impl.PluginDownloader;
@@ -78,7 +80,7 @@ public class CustomizeFeaturedPluginsStepPanel extends AbstractCustomizeWizardSt
final String pluginId = s.substring(j + 1);
IdeaPluginDescriptor foundDescriptor = null;
for (IdeaPluginDescriptor descriptor : pluginsFromRepository) {
- if (descriptor.getPluginId().getIdString().equals(pluginId)) {
+ if (descriptor.getPluginId().getIdString().equals(pluginId) && !PluginManagerCore.isBrokenPlugin(descriptor)) {
foundDescriptor = descriptor;
isEmptyOrOffline = false;
break;
@@ -107,11 +109,11 @@ public class CustomizeFeaturedPluginsStepPanel extends AbstractCustomizeWizardSt
JPanel progressPanel = new JPanel(new VerticalFlowLayout(true, false));
progressPanel.add(progressBar);
final LinkLabel cancelLink = new LinkLabel("Cancel", AllIcons.Actions.Cancel);
- JPanel linkWrapper = new JPanel(new FlowLayout(FlowLayout.CENTER));
+ JPanel linkWrapper = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
linkWrapper.add(cancelLink);
progressPanel.add(linkWrapper);
- JPanel buttonPanel = new JPanel(new VerticalFlowLayout());
+ JPanel buttonPanel = new JPanel(new VerticalFlowLayout(0, 0));
buttonPanel.add(installButton);
buttonWrapper.add(buttonPanel, "button");
@@ -218,7 +220,7 @@ public class CustomizeFeaturedPluginsStepPanel extends AbstractCustomizeWizardSt
}, null);
gbc.insets.bottom = -5;
groupPanel.add(titleLabel, gbc);
- gbc.insets.bottom = 10;
+ gbc.insets.bottom = SMALL_GAP;
groupPanel.add(topicLabel, gbc);
groupPanel.add(descriptionLabel, gbc);
gbc.weighty = 1;
@@ -238,7 +240,7 @@ public class CustomizeFeaturedPluginsStepPanel extends AbstractCustomizeWizardSt
protected Color getColor() {
return ColorUtil.withAlpha(JBColor.foreground(), .2);
}
- }, BorderFactory.createEmptyBorder(GAP, GAP, 0, GAP)));
+ }, BorderFactory.createEmptyBorder(0, SMALL_GAP, 0, SMALL_GAP)));
cursor++;
}
@@ -260,7 +262,10 @@ public class CustomizeFeaturedPluginsStepPanel extends AbstractCustomizeWizardSt
@Override
public String getHTMLFooter() {
- return "New plugins can also be downloaded in " + CommonBundle.settingsTitle() + " | Plugins";
+ return "New plugins can also be downloaded in "
+ + CommonBundle.settingsTitle()
+ + " | " + OptionsBundle.message("configurable.group.appearance.settings.display.name")
+ + " | " + "Plugins";
}
public static class OfflineException extends Exception {};
diff --git a/platform/platform-impl/src/com/intellij/ide/customize/CustomizeIDEWizardDialog.java b/platform/platform-impl/src/com/intellij/ide/customize/CustomizeIDEWizardDialog.java
index be37f9d9d7f6..af3c193ca9d9 100644
--- a/platform/platform-impl/src/com/intellij/ide/customize/CustomizeIDEWizardDialog.java
+++ b/platform/platform-impl/src/com/intellij/ide/customize/CustomizeIDEWizardDialog.java
@@ -21,7 +21,7 @@ import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.ui.JBCardLayout;
-import org.jetbrains.annotations.NotNull;
+import com.intellij.util.PlatformUtils;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -51,6 +51,7 @@ public class CustomizeIDEWizardDialog extends DialogWrapper implements ActionLis
public CustomizeIDEWizardDialog() {
super(null, true, true);
setTitle("Customize " + ApplicationNamesInfo.getInstance().getProductName());
+ getPeer().setAppIcons();
initSteps();
mySkipButton.addActionListener(this);
myBackButton.addActionListener(this);
@@ -119,7 +120,7 @@ public class CustomizeIDEWizardDialog extends DialogWrapper implements ActionLis
result.add(myContentPanel, BorderLayout.CENTER);
result.add(myFooterLabel, BorderLayout.SOUTH);
result.setPreferredSize(new Dimension(700, 600));
- result.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
+ result.setBorder(AbstractCustomizeWizardStep.createSmallEmptyBorder());
return result;
}
@@ -131,8 +132,10 @@ public class CustomizeIDEWizardDialog extends DialogWrapper implements ActionLis
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 0;
gbc.gridy = 0;
- buttonPanel.add(mySkipButton, gbc);
- gbc.gridx++;
+ if (!PlatformUtils.isCLion()) {
+ buttonPanel.add(mySkipButton, gbc);
+ gbc.gridx++;
+ }
buttonPanel.add(myBackButton, gbc);
gbc.gridx++;
gbc.weightx = 1;
@@ -219,15 +222,4 @@ public class CustomizeIDEWizardDialog extends DialogWrapper implements ActionLis
}
myNavigationLabel.setText(navHTML.toString());
}
-
-
- private static <T extends Component> void getChildren(@NotNull Component c, Class<? extends T> cls, List<T> accumulator) {
- if (cls.isAssignableFrom(c.getClass())) accumulator.add((T)c);
- if (c instanceof Container) {
- Component[] components = ((Container)c).getComponents();
- for (Component component : components) {
- getChildren(component, cls, accumulator);
- }
- }
- }
}
diff --git a/platform/platform-impl/src/com/intellij/ide/customize/CustomizePluginsStepPanel.java b/platform/platform-impl/src/com/intellij/ide/customize/CustomizePluginsStepPanel.java
index 8924c09780dd..de12269b5887 100644
--- a/platform/platform-impl/src/com/intellij/ide/customize/CustomizePluginsStepPanel.java
+++ b/platform/platform-impl/src/com/intellij/ide/customize/CustomizePluginsStepPanel.java
@@ -115,7 +115,7 @@ public class CustomizePluginsStepPanel extends AbstractCustomizeWizardStep imple
gbc.weighty = 1;
groupPanel.add(Box.createVerticalGlue(), gbc);
gbc.weighty = 0;
- JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 5));
+ JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, SMALL_GAP, SMALL_GAP / 2));
buttonsPanel.setOpaque(false);
if (pluginGroups.getSets(group).size() == 1) {
buttonsPanel.add(createLink(SWITCH_COMMAND + ":" + group, getGroupSwitchTextProvider(group)));
@@ -139,7 +139,7 @@ public class CustomizePluginsStepPanel extends AbstractCustomizeWizardStep imple
protected Color getColor() {
return ColorUtil.withAlpha(JBColor.foreground(), .2);
}
- }, BorderFactory.createEmptyBorder(GAP / 2, GAP, GAP / 2, GAP)));
+ }, BorderFactory.createEmptyBorder(SMALL_GAP, GAP, SMALL_GAP, GAP)));
cursor++;
}
}
diff --git a/platform/platform-impl/src/com/intellij/ide/customize/CustomizeUIThemeStepPanel.java b/platform/platform-impl/src/com/intellij/ide/customize/CustomizeUIThemeStepPanel.java
index b369e49f8bca..c7b29ef53827 100644
--- a/platform/platform-impl/src/com/intellij/ide/customize/CustomizeUIThemeStepPanel.java
+++ b/platform/platform-impl/src/com/intellij/ide/customize/CustomizeUIThemeStepPanel.java
@@ -22,6 +22,7 @@ import com.intellij.ide.ui.laf.darcula.DarculaLaf;
import com.intellij.ide.ui.laf.darcula.DarculaLookAndFeelInfo;
import com.intellij.idea.StartupUtil;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.options.OptionsBundle;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.util.IconUtil;
@@ -46,7 +47,7 @@ public class CustomizeUIThemeStepPanel extends AbstractCustomizeWizardStep {
private Map<String, Icon> myLafNames = new LinkedHashMap<String, Icon>();
public CustomizeUIThemeStepPanel() {
- setLayout(new BorderLayout(10, 10));
+ setLayout(createSmallBorderLayout());
IconLoader.activate();
initLafs();
@@ -65,13 +66,13 @@ public class CustomizeUIThemeStepPanel extends AbstractCustomizeWizardStep {
radioButton.setSelected(true);
myDefaultLafName = lafName;
}
- final JPanel panel = createBigButtonPanel(new BorderLayout(10, 10), radioButton, new Runnable() {
+ final JPanel panel = createBigButtonPanel(createSmallBorderLayout(), radioButton, new Runnable() {
@Override
public void run() {
applyLaf(lafName, CustomizeUIThemeStepPanel.this);
}
});
- panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
+ panel.setBorder(createSmallEmptyBorder());
panel.add(radioButton, myColumnMode ? BorderLayout.WEST : BorderLayout.NORTH);
final JLabel label = new JLabel(myColumnMode ? IconUtil.scale(IconUtil.cropIcon(icon, icon.getIconWidth() * 2 / 3, icon.getIconHeight() * 2 / 3), .5) : icon);
label.setVerticalAlignment(SwingConstants.TOP);
@@ -139,7 +140,10 @@ public class CustomizeUIThemeStepPanel extends AbstractCustomizeWizardStep {
@Override
public String getHTMLFooter() {
- return "UI theme can be changed later in " + CommonBundle.settingsTitle() + " | Appearance";
+ return "UI theme can be changed later in " +
+ CommonBundle.settingsTitle()
+ + " | " + OptionsBundle.message("configurable.group.appearance.settings.display.name")
+ + " | " + "Appearance";
}
private void applyLaf(String lafName, Component component) {
diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/MasterKeyPasswordSafe.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/MasterKeyPasswordSafe.java
index 6b0b9814698b..de5d67b5e2d8 100644
--- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/MasterKeyPasswordSafe.java
+++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/MasterKeyPasswordSafe.java
@@ -15,6 +15,8 @@
*/
package com.intellij.ide.passwordSafe.impl.providers.masterKey;
+import com.intellij.concurrency.AsyncFutureFactory;
+import com.intellij.concurrency.AsyncFutureResult;
import com.intellij.ide.passwordSafe.MasterPasswordUnavailableException;
import com.intellij.ide.passwordSafe.PasswordSafeException;
import com.intellij.ide.passwordSafe.impl.PasswordSafeTimed;
@@ -23,14 +25,11 @@ import com.intellij.ide.passwordSafe.impl.providers.ByteArrayWrapper;
import com.intellij.ide.passwordSafe.impl.providers.EncryptionUtil;
import com.intellij.ide.passwordSafe.impl.providers.masterKey.windows.WindowsCryptUtils;
import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Condition;
-import com.intellij.openapi.util.Ref;
-import com.intellij.openapi.util.SystemInfo;
-import com.intellij.openapi.util.ThrowableComputable;
+import com.intellij.openapi.util.*;
import com.intellij.openapi.util.registry.Registry;
+import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -38,6 +37,7 @@ import org.jetbrains.annotations.Nullable;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.ExecutionException;
/**
* The password safe that stores information in configuration file encrypted by master password
@@ -170,12 +170,6 @@ public class MasterKeyPasswordSafe extends BasePasswordSafeProvider {
throw new MasterPasswordUnavailableException("The provider is not available in headless environment");
}
- if (myDatabase.isEmpty()) {
- if (!MasterPasswordDialog.resetMasterPasswordDialog(project, this, requestor).showAndGet()) {
- throw new MasterPasswordUnavailableException("Master password is required to store passwords in the database.");
- }
- }
-
key = invokeAndWait(new ThrowableComputable<Object, PasswordSafeException>() {
@Override
public Object compute() throws PasswordSafeException {
@@ -184,7 +178,14 @@ public class MasterKeyPasswordSafe extends BasePasswordSafeProvider {
return key;
}
try {
- MasterPasswordDialog.askPassword(project, MasterKeyPasswordSafe.this, requestor);
+ if (myDatabase.isEmpty()) {
+ if (!MasterPasswordDialog.resetMasterPasswordDialog(project, MasterKeyPasswordSafe.this, requestor).showAndGet()) {
+ throw new MasterPasswordUnavailableException("Master password is required to store passwords in the database.");
+ }
+ }
+ else {
+ MasterPasswordDialog.askPassword(project, MasterKeyPasswordSafe.this, requestor);
+ }
}
catch (PasswordSafeException e) {
myKey.get().set(e);
@@ -200,35 +201,41 @@ public class MasterKeyPasswordSafe extends BasePasswordSafeProvider {
}
private static final Object ourEDTLock = new Object();
- public <T, E extends Throwable> T invokeAndWait(@NotNull final ThrowableComputable<T, E> computable, @NotNull final Condition expired) throws E {
+ public <T, E extends Throwable> T invokeAndWait(@NotNull final ThrowableComputable<T, E> computable, @NotNull final Condition<?> expired) throws E {
if (ApplicationManager.getApplication().isDispatchThread()) {
return computable.compute();
}
- final Ref<Throwable> exRef = Ref.create();
- final Ref<T> ref = Ref.create();
+
+ final AsyncFutureResult<Object> future = AsyncFutureFactory.getInstance().createAsyncFutureResult();
synchronized (ourEDTLock) {
- if (expired.value(null)) {
- throw new ProcessCanceledException();
- }
- ApplicationManager.getApplication().invokeAndWait(new Runnable() {
+ IdeFocusManager.getGlobalInstance().doWhenFocusSettlesDown(new ExpirableRunnable() {
@Override
- public void run() {
- if (expired.value(null)) {
- exRef.set(new ProcessCanceledException());
- return;
- }
+ public boolean isExpired() {
+ boolean b = expired.value(null);
+ if (b) future.setException(new ProcessCanceledException());
+ return b;
+ }
+ @Override
+ public void run() {
try {
- ref.set(computable.compute());
+ future.set(computable.compute());
}
catch (Throwable e) {
- exRef.set(e);
+ future.setException(e);
}
}
- }, ModalityState.any());
+ });
+ }
+ try {
+ return (T)future.get();
+ }
+ catch (InterruptedException e) {
+ throw new ProcessCanceledException(e);
+ }
+ catch (ExecutionException e) {
+ throw (E) e.getCause();
}
- if (!exRef.isNull()) throw (E)exRef.get();
- return ref.get();
}
@Override
diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java b/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java
index 62609d9ba5fc..0ae246d41715 100644
--- a/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java
+++ b/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java
@@ -29,7 +29,7 @@ import com.intellij.openapi.updateSettings.impl.UpdateSettings;
import com.intellij.ui.DoubleClickListener;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.TableUtil;
-import com.intellij.util.net.HTTPProxySettingsDialog;
+import com.intellij.util.net.HttpConfigurable;
import com.intellij.util.ui.update.UiNotifyConnector;
import org.jetbrains.annotations.NotNull;
@@ -41,6 +41,7 @@ import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
+import java.util.Locale;
import java.util.TreeSet;
/**
@@ -50,7 +51,7 @@ public class AvailablePluginsManagerMain extends PluginManagerMain {
public static final String MANAGE_REPOSITORIES = "Manage repositories...";
public static final String N_A = "N/A";
- private PluginManagerMain installed;
+ private final PluginManagerMain installed;
private final String myVendorFilter;
public AvailablePluginsManagerMain(PluginManagerMain installed, PluginManagerUISettings uiSettings, String vendorFilter) {
@@ -63,11 +64,11 @@ public class AvailablePluginsManagerMain extends PluginManagerMain {
manageRepositoriesBtn.setMnemonic('m');
manageRepositoriesBtn.addActionListener(new ActionListener() {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
if (ShowSettingsUtil.getInstance().editConfigurable(myActionsPanel, new PluginHostsConfigurable())) {
final ArrayList<String> pluginHosts = UpdateSettings.getInstance().myPluginHosts;
if (!pluginHosts.contains(((AvailablePluginsTableModel)pluginsModel).getRepository())) {
- ((AvailablePluginsTableModel)pluginsModel).setRepository(AvailablePluginsTableModel.ALL, myFilter.getFilter().toLowerCase());
+ ((AvailablePluginsTableModel)pluginsModel).setRepository(AvailablePluginsTableModel.ALL, myFilter.getFilter().toLowerCase(Locale.ENGLISH));
}
loadAvailablePlugins();
}
@@ -78,11 +79,9 @@ public class AvailablePluginsManagerMain extends PluginManagerMain {
final JButton httpProxySettingsButton = new JButton(IdeBundle.message("button.http.proxy.settings"));
httpProxySettingsButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- HTTPProxySettingsDialog settingsDialog = new HTTPProxySettingsDialog();
- settingsDialog.pack();
- settingsDialog.show();
- if (settingsDialog.isOK()) {
+ @Override
+ public void actionPerformed(@NotNull ActionEvent e) {
+ if (HttpConfigurable.editConfigurable(getMainPanel())) {
loadAvailablePlugins();
}
}
@@ -114,7 +113,8 @@ public class AvailablePluginsManagerMain extends PluginManagerMain {
pluginTable.registerKeyboardAction(
new ActionListener() {
- public void actionPerformed(ActionEvent e) {
+ @Override
+ public void actionPerformed(@NotNull ActionEvent e) {
installSelected(pluginTable);
}
},
@@ -235,7 +235,7 @@ public class AvailablePluginsManagerMain extends PluginManagerMain {
return new AnAction(availableCategory) {
@Override
public void actionPerformed(AnActionEvent e) {
- final String filter = myFilter.getFilter().toLowerCase();
+ final String filter = myFilter.getFilter().toLowerCase(Locale.ENGLISH);
((AvailablePluginsTableModel)pluginsModel).setCategory(availableCategory, filter);
}
};
@@ -277,7 +277,7 @@ public class AvailablePluginsManagerMain extends PluginManagerMain {
return new AnAction(host) {
@Override
public void actionPerformed(AnActionEvent e) {
- final String filter = myFilter.getFilter().toLowerCase();
+ final String filter = myFilter.getFilter().toLowerCase(Locale.ENGLISH);
((AvailablePluginsTableModel)pluginsModel).setRepository(host, filter);
TableUtil.ensureSelectionExists(getPluginTable());
}
diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java
index a1ea238835cd..57329fb8fe9d 100644
--- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java
+++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java
@@ -15,6 +15,7 @@
*/
package com.intellij.ide.plugins;
+import com.intellij.diagnostic.PluginException;
import com.intellij.ide.ClassUtilCore;
import com.intellij.ide.IdeBundle;
import com.intellij.idea.IdeaApplication;
@@ -100,31 +101,44 @@ public class PluginManager extends PluginManagerCore {
public static void processException(Throwable t) {
if (!IdeaApplication.isLoaded()) {
- @SuppressWarnings("ThrowableResultOfMethodCallIgnored") StartupAbortedException se = findCause(t);
+ @SuppressWarnings("ThrowableResultOfMethodCallIgnored") StartupAbortedException se = findCause(t, StartupAbortedException.class);
if (se == null) se = new StartupAbortedException(t);
+ @SuppressWarnings("ThrowableResultOfMethodCallIgnored") PluginException pe = findCause(t, PluginException.class);
+ PluginId pluginId = pe != null ? pe.getPluginId() : null;
- if (se.logError()) {
+ if (Logger.isInitialized() && !(t instanceof ProcessCanceledException)) {
try {
- if (Logger.isInitialized() && !(t instanceof ProcessCanceledException)) {
- getLogger().error(t);
- }
+ getLogger().error(t);
}
catch (Throwable ignore) { }
+ }
+
+ if (pluginId != null && !CORE_PLUGIN_ID.equals(pluginId.getIdString())) {
+ disablePlugin(pluginId.getIdString());
+
+ StringWriter message = new StringWriter();
+ message.append("Plugin '").append(pluginId.getIdString()).append("' failed to initialize and will be disabled. ");
+ message.append(" Please restart ").append(ApplicationNamesInfo.getInstance().getFullProductName()).append('.');
+ message.append("\n\n");
+ pe.getCause().printStackTrace(new PrintWriter(message));
+ Main.showMessage("Plugin Error", message.toString(), false);
+ System.exit(Main.PLUGIN_ERROR);
+ }
+ else {
Main.showMessage("Start Failed", t);
+ System.exit(se.exitCode());
}
-
- System.exit(se.exitCode());
}
else if (!(t instanceof ProcessCanceledException)) {
getLogger().error(t);
}
}
- private static StartupAbortedException findCause(Throwable t) {
+ private static <T extends Throwable> T findCause(Throwable t, Class<T> clazz) {
while (t != null) {
- if (t instanceof StartupAbortedException) {
- return (StartupAbortedException)t;
+ if (clazz.isInstance(t)) {
+ return clazz.cast(t);
}
t = t.getCause();
}
@@ -229,18 +243,7 @@ public class PluginManager extends PluginManagerCore {
}
if (pluginId != null && !CORE_PLUGIN_ID.equals(pluginId.getIdString())) {
- getLogger().warn(t);
-
- disablePlugin(pluginId.getIdString());
-
- StringWriter message = new StringWriter();
- message.append("Plugin '").append(pluginId.getIdString()).append("' failed to initialize and will be disabled. ");
- message.append(" Please restart ").append(ApplicationNamesInfo.getInstance().getFullProductName()).append('.');
- message.append("\n\n");
- t.printStackTrace(new PrintWriter(message));
- Main.showMessage("Plugin Error", message.toString(), false);
-
- throw new StartupAbortedException(t).exitCode(Main.PLUGIN_ERROR).logError(false);
+ throw new StartupAbortedException(new PluginException(t, pluginId));
}
else {
throw new StartupAbortedException("Fatal error initializing '" + componentClassName + "'", t);
@@ -249,7 +252,6 @@ public class PluginManager extends PluginManagerCore {
private static class StartupAbortedException extends RuntimeException {
private int exitCode = Main.STARTUP_EXCEPTION;
- private boolean logError = true;
public StartupAbortedException(Throwable cause) {
super(cause);
@@ -267,14 +269,5 @@ public class PluginManager extends PluginManagerCore {
this.exitCode = exitCode;
return this;
}
-
- public boolean logError() {
- return logError;
- }
-
- public StartupAbortedException logError(boolean logError) {
- this.logError = logError;
- return this;
- }
}
}
diff --git a/platform/platform-impl/src/com/intellij/ide/ui/AppearancePanel.form b/platform/platform-impl/src/com/intellij/ide/ui/AppearancePanel.form
index 59197a00e70b..550e8e2482e1 100644
--- a/platform/platform-impl/src/com/intellij/ide/ui/AppearancePanel.form
+++ b/platform/platform-impl/src/com/intellij/ide/ui/AppearancePanel.form
@@ -74,7 +74,7 @@
</component>
</children>
</grid>
- <grid id="d9fb" layout-manager="GridLayoutManager" row-count="2" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="d9fb" layout-manager="GridLayoutManager" row-count="1" column-count="5" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="7" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
@@ -82,17 +82,6 @@
<properties/>
<border type="none"/>
<children>
- <component id="5ea1e" class="javax.swing.JComboBox" binding="myFontSizeCombo" custom-create="true">
- <constraints>
- <grid row="1" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false">
- <minimum-size width="140" height="-1"/>
- <preferred-size width="140" height="-1"/>
- </grid>
- </constraints>
- <properties>
- <editable value="true"/>
- </properties>
- </component>
<component id="76cd" class="javax.swing.JComboBox" binding="myFontCombo">
<constraints>
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
@@ -107,15 +96,6 @@
<requestFocusEnabled value="true"/>
</properties>
</component>
- <component id="4eb1b" class="javax.swing.JLabel" binding="myFontSizeLabel">
- <constraints>
- <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties>
- <horizontalAlignment value="10"/>
- <text resource-bundle="messages/IdeBundle" key="label.font.size"/>
- </properties>
- </component>
<component id="23221" class="javax.swing.JLabel" binding="myFontNameLabel">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
@@ -127,11 +107,30 @@
</component>
<hspacer id="53ae4">
<constraints>
- <grid row="0" column="0" row-span="2" col-span="1" vsize-policy="1" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false">
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false">
<minimum-size width="20" height="-1"/>
</grid>
</constraints>
</hspacer>
+ <component id="4eb1b" class="javax.swing.JLabel" binding="myFontSizeLabel">
+ <constraints>
+ <grid row="0" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <horizontalAlignment value="10"/>
+ <text resource-bundle="messages/IdeBundle" key="label.font.size"/>
+ </properties>
+ </component>
+ <component id="5ea1e" class="javax.swing.JComboBox" binding="myFontSizeCombo" custom-create="true">
+ <constraints>
+ <grid row="0" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false">
+ <preferred-size width="40" height="-1"/>
+ </grid>
+ </constraints>
+ <properties>
+ <editable value="true"/>
+ </properties>
+ </component>
</children>
</grid>
<grid id="ce348" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
diff --git a/platform/platform-impl/src/com/intellij/ide/util/TipUIUtil.java b/platform/platform-impl/src/com/intellij/ide/util/TipUIUtil.java
index bbd52139bd51..7ebf2a57a998 100644
--- a/platform/platform-impl/src/com/intellij/ide/util/TipUIUtil.java
+++ b/platform/platform-impl/src/com/intellij/ide/util/TipUIUtil.java
@@ -15,6 +15,7 @@
*/
package com.intellij.ide.util;
+import com.intellij.CommonBundle;
import com.intellij.ide.BrowserUtil;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.plugins.IdeaPluginDescriptor;
@@ -97,6 +98,7 @@ public class TipUIUtil {
String minor = ApplicationInfo.getInstance().getMinorVersion();
replaced = replaced.replace("&minorVersion;", minor);
replaced = replaced.replace("&majorMinorVersion;", major + ("0".equals(minor) ? "" : ("." + minor)));
+ replaced = replaced.replace("&settingsPath;", CommonBundle.settingsActionPath());
if (UIUtil.isUnderDarcula()) {
replaced = replaced.replace("css/tips.css", "css/tips_darcula.css");
}
diff --git a/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java b/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java
index 94b25a1b3c94..b32729dd7328 100644
--- a/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java
+++ b/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java
@@ -24,10 +24,7 @@ import com.intellij.ide.IdeRepaintManager;
import com.intellij.ide.plugins.PluginManager;
import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.internal.statistic.UsageTrigger;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.application.ApplicationStarter;
-import com.intellij.openapi.application.ModalityState;
-import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.application.*;
import com.intellij.openapi.application.ex.ApplicationEx;
import com.intellij.openapi.application.ex.ApplicationInfoEx;
import com.intellij.openapi.application.ex.ApplicationManagerEx;
@@ -107,6 +104,12 @@ public class IdeaApplication {
if (myStarter == null) {
myStarter = getStarter();
}
+
+ if (headless && myStarter instanceof ApplicationStarterEx && !((ApplicationStarterEx)myStarter).isHeadless()) {
+ Main.showMessage("Startup Error", "Application cannot start in headless mode", true);
+ System.exit(Main.STARTUP_IMPOSSIBLE);
+ }
+
myStarter.premain(args);
}
@@ -178,10 +181,15 @@ public class IdeaApplication {
catch (ClassNotFoundException ignored) { }
}
- protected class IdeStarter implements ApplicationStarter {
+ protected class IdeStarter extends ApplicationStarterEx {
private Splash mySplash;
@Override
+ public boolean isHeadless() {
+ return false;
+ }
+
+ @Override
public String getCommandName() {
return null;
}
diff --git a/platform/platform-impl/src/com/intellij/notification/impl/actions/ShowDelayedMessageInternalAction.java b/platform/platform-impl/src/com/intellij/notification/impl/actions/ShowDelayedMessageInternalAction.java
new file mode 100644
index 000000000000..ad133f1c7574
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/notification/impl/actions/ShowDelayedMessageInternalAction.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.notification.impl.actions;
+
+import com.intellij.CommonBundle;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.application.ApplicationBundle;
+import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.ui.MessageDialogBuilder;
+
+import javax.swing.*;
+
+/**
+ * @author Denis Fokin
+ */
+public class ShowDelayedMessageInternalAction extends AnAction implements DumbAware{
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+
+ new Thread() {
+ @Override
+ public void run() {
+ super.run();
+
+ //noinspection EmptyCatchBlock
+ try {
+ Thread.sleep(3000);
+ }
+ catch (InterruptedException e1) {} // does not matter for an internal action
+
+ //noinspection SSBasedInspection
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ MessageDialogBuilder.yesNo("Nothing happens after that", "Some message goes here").yesText(
+ ApplicationBundle.message("command.exit")).noText(
+ CommonBundle.message("button.cancel")).show();
+ }
+ });
+ }
+ }.start();
+
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/ex/QuickListsManager.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/ex/QuickListsManager.java
index a17370e73266..bf7c79695c94 100644
--- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/ex/QuickListsManager.java
+++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/ex/QuickListsManager.java
@@ -24,6 +24,7 @@ import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.application.ex.DecodeDefaultsUtil;
import com.intellij.openapi.components.ExportableApplicationComponent;
import com.intellij.openapi.components.RoamingType;
+import com.intellij.openapi.components.StoragePathMacros;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.options.BaseSchemeProcessor;
import com.intellij.openapi.options.SchemesManager;
@@ -63,7 +64,7 @@ public class QuickListsManager implements ExportableApplicationComponent, NamedJ
public QuickListsManager(ActionManagerEx actionManagerEx, SchemesManagerFactory schemesManagerFactory) {
myActionManager = actionManagerEx;
mySchemesManager = schemesManagerFactory.createSchemesManager(
- "$ROOT_CONFIG$/quicklists",
+ StoragePathMacros.ROOT_CONFIG + "/quicklists",
new BaseSchemeProcessor<QuickList>(){
public QuickList readScheme(@NotNull final Document schemeContent) throws InvalidDataException, IOException, JDOMException {
return loadListFromDocument(schemeContent);
diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java
index 723956ef9daa..c5a9b01c4d21 100644
--- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java
@@ -39,6 +39,7 @@ import com.intellij.openapi.keymap.KeymapManager;
import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.openapi.keymap.ex.KeymapManagerEx;
import com.intellij.openapi.progress.ProcessCanceledException;
+import com.intellij.openapi.project.ProjectType;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Disposer;
@@ -71,28 +72,6 @@ import java.util.*;
import java.util.List;
public final class ActionManagerImpl extends ActionManagerEx implements ApplicationComponent {
- private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.actionSystem.impl.ActionManagerImpl");
- private static final int DEACTIVATED_TIMER_DELAY = 5000;
- private static final int TIMER_DELAY = 500;
- private static final int UPDATE_DELAY_AFTER_TYPING = 500;
-
- private final Object myLock = new Object();
- private final Map<String,Object> myId2Action = new THashMap<String, Object>();
- private final Map<PluginId, THashSet<String>> myPlugin2Id = new THashMap<PluginId, THashSet<String>>();
- private final TObjectIntHashMap<String> myId2Index = new TObjectIntHashMap<String>();
- private final Map<Object,String> myAction2Id = new THashMap<Object, String>();
- private final MultiMap<String,String> myId2GroupId = new MultiMap<String, String>();
- private final List<String> myNotRegisteredInternalActionIds = new ArrayList<String>();
- private MyTimer myTimer;
-
- private int myRegisteredActionsCount;
- private final List<AnActionListener> myActionListeners = ContainerUtil.createLockFreeCopyOnWriteList();
- private String myLastPreformedActionId;
- private final KeymapManager myKeymapManager;
- private final DataManager myDataManager;
- private String myPrevPerformedActionId;
- private long myLastTimeEditorWasTypedIn = 0;
-
@NonNls public static final String ACTION_ELEMENT_NAME = "action";
@NonNls public static final String GROUP_ELEMENT_NAME = "group";
@NonNls public static final String ACTIONS_ELEMENT_NAME = "actions";
@@ -130,14 +109,32 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
@NonNls public static final String USE_SHORTCUT_OF_ATTR_NAME = "use-shortcut-of";
@NonNls public static final String OVERRIDES_ATTR_NAME = "overrides";
@NonNls public static final String KEEP_CONTENT_ATTR_NAME = "keep-content";
-
+ @NonNls public static final String PROJECT_TYPE = "project-type";
+ private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.actionSystem.impl.ActionManagerImpl");
+ private static final int DEACTIVATED_TIMER_DELAY = 5000;
+ private static final int TIMER_DELAY = 500;
+ private static final int UPDATE_DELAY_AFTER_TYPING = 500;
+ private final Object myLock = new Object();
+ private final Map<String,AnAction> myId2Action = new THashMap<String, AnAction>();
+ private final Map<PluginId, THashSet<String>> myPlugin2Id = new THashMap<PluginId, THashSet<String>>();
+ private final TObjectIntHashMap<String> myId2Index = new TObjectIntHashMap<String>();
+ private final Map<Object,String> myAction2Id = new THashMap<Object, String>();
+ private final MultiMap<String,String> myId2GroupId = new MultiMap<String, String>();
+ private final List<String> myNotRegisteredInternalActionIds = new ArrayList<String>();
+ private final List<AnActionListener> myActionListeners = ContainerUtil.createLockFreeCopyOnWriteList();
+ private final KeymapManager myKeymapManager;
+ private final DataManager myDataManager;
private final List<ActionPopupMenuImpl> myPopups = new ArrayList<ActionPopupMenuImpl>();
-
private final Map<AnAction, DataContext> myQueuedNotifications = new LinkedHashMap<AnAction, DataContext>();
private final Map<AnAction, AnActionEvent> myQueuedNotificationsEvents = new LinkedHashMap<AnAction, AnActionEvent>();
-
+ private MyTimer myTimer;
+ private int myRegisteredActionsCount;
+ private String myLastPreformedActionId;
+ private String myPrevPerformedActionId;
+ private long myLastTimeEditorWasTypedIn = 0;
private Runnable myPreloadActionsRunnable;
private boolean myTransparentOnlyUpdate;
+ private int myActionsPreloaded = 0;
ActionManagerImpl(KeymapManager keymapManager, DataManager dataManager) {
myKeymapManager = keymapManager;
@@ -146,6 +143,257 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
registerPluginActions();
}
+ static AnAction convertStub(ActionStub stub) {
+ Object obj;
+ String className = stub.getClassName();
+ try {
+ Class<?> aClass = Class.forName(className, true, stub.getLoader());
+ obj = ReflectionUtil.newInstance(aClass);
+ }
+ catch (ClassNotFoundException e) {
+ PluginId pluginId = stub.getPluginId();
+ if (pluginId != null) {
+ throw new PluginException("class with name \"" + className + "\" not found", e, pluginId);
+ }
+ else {
+ throw new IllegalStateException("class with name \"" + className + "\" not found");
+ }
+ }
+ catch(UnsupportedClassVersionError e) {
+ PluginId pluginId = stub.getPluginId();
+ if (pluginId != null) {
+ throw new PluginException(e, pluginId);
+ }
+ else {
+ throw new IllegalStateException(e);
+ }
+ }
+ catch (Exception e) {
+ PluginId pluginId = stub.getPluginId();
+ if (pluginId != null) {
+ throw new PluginException("cannot create class \"" + className + "\"", e, pluginId);
+ }
+ else {
+ throw new IllegalStateException("cannot create class \"" + className + "\"", e);
+ }
+ }
+
+ if (!(obj instanceof AnAction)) {
+ throw new IllegalStateException("class with name '" + className + "' must be an instance of '" + AnAction.class.getName()+"'; got "+obj);
+ }
+
+ AnAction anAction = (AnAction)obj;
+ stub.initAction(anAction);
+ if (StringUtil.isNotEmpty(stub.getText())) {
+ anAction.getTemplatePresentation().setText(stub.getText());
+ }
+ String iconPath = stub.getIconPath();
+ if (iconPath != null) {
+ Class<? extends AnAction> actionClass = anAction.getClass();
+ setIconFromClass(actionClass, actionClass.getClassLoader(), iconPath, anAction.getTemplatePresentation(), stub.getPluginId());
+ }
+ return anAction;
+ }
+
+ private static void processAbbreviationNode(Element e, String id) {
+ final String abbr = e.getAttributeValue(VALUE_ATTR_NAME);
+ if (!StringUtil.isEmpty(abbr)) {
+ final AbbreviationManagerImpl abbreviationManager = ((AbbreviationManagerImpl)AbbreviationManager.getInstance());
+ abbreviationManager.register(abbr, id, true);
+ }
+ }
+
+ @Nullable
+ private static ResourceBundle getActionsResourceBundle(ClassLoader loader, IdeaPluginDescriptor plugin) {
+ @NonNls final String resBundleName = plugin != null && !"com.intellij".equals(plugin.getPluginId().getIdString())
+ ? plugin.getResourceBundleBaseName() : ACTIONS_BUNDLE;
+ ResourceBundle bundle = null;
+ if (resBundleName != null) {
+ bundle = AbstractBundle.getResourceBundle(resBundleName, loader);
+ }
+ return bundle;
+ }
+
+ private static boolean isSecondary(Element element) {
+ return "true".equalsIgnoreCase(element.getAttributeValue(SECONDARY));
+ }
+
+ private static void setIcon(@Nullable final String iconPath,
+ @NotNull String className,
+ @NotNull ClassLoader loader,
+ @NotNull Presentation presentation,
+ final PluginId pluginId) {
+ if (iconPath == null) return;
+
+ try {
+ final Class actionClass = Class.forName(className, true, loader);
+ setIconFromClass(actionClass, loader, iconPath, presentation, pluginId);
+ }
+ catch (ClassNotFoundException e) {
+ LOG.error(e);
+ reportActionError(pluginId, "class with name \"" + className + "\" not found");
+ }
+ catch (NoClassDefFoundError e) {
+ LOG.error(e);
+ reportActionError(pluginId, "class with name \"" + className + "\" not found");
+ }
+ }
+
+ private static void setIconFromClass(@NotNull final Class actionClass,
+ @NotNull final ClassLoader classLoader,
+ @NotNull final String iconPath,
+ @NotNull Presentation presentation,
+ final PluginId pluginId) {
+ final IconLoader.LazyIcon lazyIcon = new IconLoader.LazyIcon() {
+ @Override
+ protected Icon compute() {
+ //try to find icon in idea class path
+ Icon icon = IconLoader.findIcon(iconPath, actionClass, true);
+ if (icon == null) {
+ icon = IconLoader.findIcon(iconPath, classLoader);
+ }
+
+ if (icon == null) {
+ reportActionError(pluginId, "Icon cannot be found in '" + iconPath + "', action '" + actionClass + "'");
+ }
+
+ return icon;
+ }
+
+ @Override
+ public String toString() {
+ return "LazyIcon@ActionManagerImpl (path: " + iconPath + ", action class: " + actionClass + ")";
+ }
+ };
+
+ if (!Registry.is("ide.lazyIconLoading")) {
+ lazyIcon.load();
+ }
+
+ presentation.setIcon(lazyIcon);
+ }
+
+ private static String loadDescriptionForElement(final Element element, final ResourceBundle bundle, final String id, String elementType) {
+ final String value = element.getAttributeValue(DESCRIPTION);
+ if (bundle != null) {
+ @NonNls final String key = elementType + "." + id + ".description";
+ return CommonBundle.messageOrDefault(bundle, key, value == null ? "" : value);
+ } else {
+ return value;
+ }
+ }
+
+ private static String loadTextForElement(final Element element, final ResourceBundle bundle, final String id, String elementType) {
+ final String value = element.getAttributeValue(TEXT_ATTR_NAME);
+ return CommonBundle.messageOrDefault(bundle, elementType + "." + id + "." + TEXT_ATTR_NAME, value == null ? "" : value);
+ }
+
+ public static boolean checkRelativeToAction(final String relativeToActionId,
+ @NotNull final Anchor anchor,
+ @NotNull final String actionName,
+ @Nullable final PluginId pluginId) {
+ if ((Anchor.BEFORE == anchor || Anchor.AFTER == anchor) && relativeToActionId == null) {
+ reportActionError(pluginId, actionName + ": \"relative-to-action\" cannot be null if anchor is \"after\" or \"before\"");
+ return false;
+ }
+ return true;
+ }
+
+ @Nullable
+ public static Anchor parseAnchor(final String anchorStr,
+ @Nullable final String actionName,
+ @Nullable final PluginId pluginId) {
+ if (anchorStr == null) {
+ return Anchor.LAST;
+ }
+
+ if (FIRST.equalsIgnoreCase(anchorStr)) {
+ return Anchor.FIRST;
+ }
+ else if (LAST.equalsIgnoreCase(anchorStr)) {
+ return Anchor.LAST;
+ }
+ else if (BEFORE.equalsIgnoreCase(anchorStr)) {
+ return Anchor.BEFORE;
+ }
+ else if (AFTER.equalsIgnoreCase(anchorStr)) {
+ return Anchor.AFTER;
+ }
+ else {
+ reportActionError(pluginId, actionName + ": anchor should be one of the following constants: \"first\", \"last\", \"before\" or \"after\"");
+ return null;
+ }
+ }
+
+ private static void processMouseShortcutNode(Element element, String actionId, PluginId pluginId) {
+ String keystrokeString = element.getAttributeValue(KEYSTROKE_ATTR_NAME);
+ if (keystrokeString == null || keystrokeString.trim().isEmpty()) {
+ reportActionError(pluginId, "\"keystroke\" attribute must be specified for action with id=" + actionId);
+ return;
+ }
+ MouseShortcut shortcut;
+ try {
+ shortcut = KeymapUtil.parseMouseShortcut(keystrokeString);
+ }
+ catch (Exception ex) {
+ reportActionError(pluginId, "\"keystroke\" attribute has invalid value for action with id=" + actionId);
+ return;
+ }
+
+ String keymapName = element.getAttributeValue(KEYMAP_ATTR_NAME);
+ if (keymapName == null || keymapName.isEmpty()) {
+ reportActionError(pluginId, "attribute \"keymap\" should be defined");
+ return;
+ }
+ Keymap keymap = KeymapManager.getInstance().getKeymap(keymapName);
+ if (keymap == null) {
+ reportActionError(pluginId, "keymap \"" + keymapName + "\" not found");
+ return;
+ }
+
+ final String removeOption = element.getAttributeValue(REMOVE_SHORTCUT_ATTR_NAME);
+ if (Boolean.valueOf(removeOption)) {
+ keymap.removeShortcut(actionId, shortcut);
+ } else {
+ keymap.addShortcut(actionId, shortcut);
+ }
+ }
+
+ private static void assertActionIsGroupOrStub(final AnAction action) {
+ if (!(action instanceof ActionGroup || action instanceof ActionStub)) {
+ LOG.error("Action : " + action + "; class: " + action.getClass());
+ }
+ }
+
+ private static void reportActionError(final PluginId pluginId, @NonNls @NotNull String message) {
+ if (pluginId == null) {
+ LOG.error(message);
+ }
+ else {
+ LOG.error(new PluginException(message, null, pluginId));
+ }
+ }
+
+ @NonNls
+ private static String getPluginInfo(@Nullable PluginId id) {
+ if (id != null) {
+ final IdeaPluginDescriptor plugin = PluginManager.getPlugin(id);
+ if (plugin != null) {
+ String name = plugin.getName();
+ if (name == null) {
+ name = id.getIdString();
+ }
+ return " Plugin: " + name;
+ }
+ }
+ return "";
+ }
+
+ private static DataContext getContextBy(Component contextComponent) {
+ final DataManager dataManager = DataManager.getInstance();
+ return contextComponent != null ? dataManager.getDataContext(contextComponent) : dataManager.getDataContext();
+ }
+
@Override
public void initComponent() {}
@@ -213,7 +461,6 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
return new ActionToolbarImpl(place, group, horizontal, decorateButtons, myDataManager, this, (KeymapManagerEx)myKeymapManager);
}
-
private void registerPluginActions() {
final IdeaPluginDescriptor[] plugins = PluginManagerCore.getPlugins();
for (IdeaPluginDescriptor plugin : plugins) {
@@ -229,12 +476,28 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
@Override
public AnAction getAction(@NotNull String id) {
- return getActionImpl(id, false);
+ return getActionImpl(id, false, null);
}
- private AnAction getActionImpl(String id, boolean canReturnStub) {
+ @Override
+ public AnAction getAction(@NonNls @NotNull String actionId, @Nullable ProjectType projectType) {
+ return getActionImpl(actionId, false, projectType);
+ }
+
+ private AnAction getActionImpl(String id, boolean canReturnStub, ProjectType projectType) {
synchronized (myLock) {
- AnAction action = (AnAction)myId2Action.get(id);
+ AnAction action;
+ Object o = myId2Action.get(id);
+ if (o == null) {
+ return null;
+ }
+ if (o instanceof AnAction) {
+ action = (AnAction)o;
+ }
+ else {
+ //noinspection unchecked
+ action = ((Map<ProjectType, AnAction>)o).get(projectType);
+ }
if (!canReturnStub && action instanceof ActionStub) {
action = convert((ActionStub)action);
}
@@ -252,61 +515,14 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
LOG.assertTrue(myId2Action.containsKey(stub.getId()));
- AnAction action = (AnAction)myId2Action.remove(stub.getId());
+ AnAction action = myId2Action.remove(stub.getId());
LOG.assertTrue(action != null);
LOG.assertTrue(action.equals(stub));
- Object obj;
- String className = stub.getClassName();
- try {
- Class<?> aClass = Class.forName(className, true, stub.getLoader());
- obj = ReflectionUtil.newInstance(aClass);
- }
- catch (ClassNotFoundException e) {
- PluginId pluginId = stub.getPluginId();
- if (pluginId != null) {
- throw new PluginException("class with name \"" + className + "\" not found", e, pluginId);
- }
- else {
- throw new IllegalStateException("class with name \"" + className + "\" not found");
- }
- }
- catch(UnsupportedClassVersionError e) {
- PluginId pluginId = stub.getPluginId();
- if (pluginId != null) {
- throw new PluginException(e, pluginId);
- }
- else {
- throw new IllegalStateException(e);
- }
- }
- catch (Exception e) {
- PluginId pluginId = stub.getPluginId();
- if (pluginId != null) {
- throw new PluginException("cannot create class \"" + className + "\"", e, pluginId);
- }
- else {
- throw new IllegalStateException("cannot create class \"" + className + "\"", e);
- }
- }
-
- if (!(obj instanceof AnAction)) {
- throw new IllegalStateException("class with name '" + className + "' must be an instance of '" + AnAction.class.getName()+"'; got "+obj);
- }
+ AnAction anAction = convertStub(stub);
- AnAction anAction = (AnAction)obj;
- stub.initAction(anAction);
- if (StringUtil.isNotEmpty(stub.getText())) {
- anAction.getTemplatePresentation().setText(stub.getText());
- }
- String iconPath = stub.getIconPath();
- if (iconPath != null) {
- Class<? extends AnAction> actionClass = anAction.getClass();
- setIconFromClass(actionClass, actionClass.getClassLoader(), iconPath, anAction.getTemplatePresentation(), stub.getPluginId());
- }
-
- myId2Action.put(stub.getId(), obj);
- myAction2Id.put(obj, stub.getId());
+ addToMap(stub.getId(), anAction, stub.getPluginId(), stub.getProjectType() == null ? null : new ProjectType(stub.getProjectType()));
+ myAction2Id.put(anAction, stub.getId());
return anAction;
}
@@ -334,7 +550,7 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
@Override
public boolean isGroup(@NotNull String actionId) {
- return getActionImpl(actionId, true) instanceof ActionGroup;
+ return getActionImpl(actionId, true, null) instanceof ActionGroup;
}
@Override
@@ -344,7 +560,7 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
@Override
public AnAction getActionOrStub(String id) {
- return getActionImpl(id, true);
+ return getActionImpl(id, true, null);
}
/**
@@ -386,7 +602,8 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
return null;
}
- ActionStub stub = new ActionStub(className, id, text, loader, pluginId, iconPath);
+ String projectType = element.getAttributeValue(PROJECT_TYPE);
+ ActionStub stub = new ActionStub(className, id, text, loader, pluginId, iconPath, projectType);
Presentation presentation = stub.getTemplatePresentation();
presentation.setText(text);
@@ -441,99 +658,6 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
}
}
- private static void processAbbreviationNode(Element e, String id) {
- final String abbr = e.getAttributeValue(VALUE_ATTR_NAME);
- if (!StringUtil.isEmpty(abbr)) {
- final AbbreviationManagerImpl abbreviationManager = ((AbbreviationManagerImpl)AbbreviationManager.getInstance());
- abbreviationManager.register(abbr, id, true);
- }
- }
-
- @Nullable
- private static ResourceBundle getActionsResourceBundle(ClassLoader loader, IdeaPluginDescriptor plugin) {
- @NonNls final String resBundleName = plugin != null && !"com.intellij".equals(plugin.getPluginId().getIdString())
- ? plugin.getResourceBundleBaseName() : ACTIONS_BUNDLE;
- ResourceBundle bundle = null;
- if (resBundleName != null) {
- bundle = AbstractBundle.getResourceBundle(resBundleName, loader);
- }
- return bundle;
- }
-
- private static boolean isSecondary(Element element) {
- return "true".equalsIgnoreCase(element.getAttributeValue(SECONDARY));
- }
-
- private static void setIcon(@Nullable final String iconPath,
- @NotNull String className,
- @NotNull ClassLoader loader,
- @NotNull Presentation presentation,
- final PluginId pluginId) {
- if (iconPath == null) return;
-
- try {
- final Class actionClass = Class.forName(className, true, loader);
- setIconFromClass(actionClass, loader, iconPath, presentation, pluginId);
- }
- catch (ClassNotFoundException e) {
- LOG.error(e);
- reportActionError(pluginId, "class with name \"" + className + "\" not found");
- }
- catch (NoClassDefFoundError e) {
- LOG.error(e);
- reportActionError(pluginId, "class with name \"" + className + "\" not found");
- }
- }
-
- private static void setIconFromClass(@NotNull final Class actionClass,
- @NotNull final ClassLoader classLoader,
- @NotNull final String iconPath,
- @NotNull Presentation presentation,
- final PluginId pluginId) {
- final IconLoader.LazyIcon lazyIcon = new IconLoader.LazyIcon() {
- @Override
- protected Icon compute() {
- //try to find icon in idea class path
- Icon icon = IconLoader.findIcon(iconPath, actionClass, true);
- if (icon == null) {
- icon = IconLoader.findIcon(iconPath, classLoader);
- }
-
- if (icon == null) {
- reportActionError(pluginId, "Icon cannot be found in '" + iconPath + "', action '" + actionClass + "'");
- }
-
- return icon;
- }
-
- @Override
- public String toString() {
- return "LazyIcon@ActionManagerImpl (path: " + iconPath + ", action class: " + actionClass + ")";
- }
- };
-
- if (!Registry.is("ide.lazyIconLoading")) {
- lazyIcon.load();
- }
-
- presentation.setIcon(lazyIcon);
- }
-
- private static String loadDescriptionForElement(final Element element, final ResourceBundle bundle, final String id, String elementType) {
- final String value = element.getAttributeValue(DESCRIPTION);
- if (bundle != null) {
- @NonNls final String key = elementType + "." + id + ".description";
- return CommonBundle.messageOrDefault(bundle, key, value == null ? "" : value);
- } else {
- return value;
- }
- }
-
- private static String loadTextForElement(final Element element, final ResourceBundle bundle, final String id, String elementType) {
- final String value = element.getAttributeValue(TEXT_ATTR_NAME);
- return CommonBundle.messageOrDefault(bundle, elementType + "." + id + "." + TEXT_ATTR_NAME, value == null ? "" : value);
- }
-
private AnAction processGroupElement(Element element, final ClassLoader loader, PluginId pluginId) {
final IdeaPluginDescriptor plugin = PluginManager.getPlugin(pluginId);
ResourceBundle bundle = getActionsResourceBundle(loader, plugin);
@@ -723,43 +847,6 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
myId2GroupId.putValue(myAction2Id.get(action), myAction2Id.get(group));
}
- public static boolean checkRelativeToAction(final String relativeToActionId,
- @NotNull final Anchor anchor,
- @NotNull final String actionName,
- @Nullable final PluginId pluginId) {
- if ((Anchor.BEFORE == anchor || Anchor.AFTER == anchor) && relativeToActionId == null) {
- reportActionError(pluginId, actionName + ": \"relative-to-action\" cannot be null if anchor is \"after\" or \"before\"");
- return false;
- }
- return true;
- }
-
- @Nullable
- public static Anchor parseAnchor(final String anchorStr,
- @Nullable final String actionName,
- @Nullable final PluginId pluginId) {
- if (anchorStr == null) {
- return Anchor.LAST;
- }
-
- if (FIRST.equalsIgnoreCase(anchorStr)) {
- return Anchor.FIRST;
- }
- else if (LAST.equalsIgnoreCase(anchorStr)) {
- return Anchor.LAST;
- }
- else if (BEFORE.equalsIgnoreCase(anchorStr)) {
- return Anchor.BEFORE;
- }
- else if (AFTER.equalsIgnoreCase(anchorStr)) {
- return Anchor.AFTER;
- }
- else {
- reportActionError(pluginId, actionName + ": anchor should be one of the following constants: \"first\", \"last\", \"before\" or \"after\"");
- return null;
- }
- }
-
@Nullable
public AnAction getParentGroup(final String groupId,
@Nullable final String actionName,
@@ -768,10 +855,10 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
reportActionError(pluginId, actionName + ": attribute \"group-id\" should be defined");
return null;
}
- AnAction parentGroup = getActionImpl(groupId, true);
+ AnAction parentGroup = getActionImpl(groupId, true, null);
if (parentGroup == null) {
reportActionError(pluginId, actionName + ": group with id \"" + groupId + "\" isn't registered; action will be added to the \"Other\" group");
- parentGroup = getActionImpl(IdeActions.GROUP_OTHER_MENU, true);
+ parentGroup = getActionImpl(IdeActions.GROUP_OTHER_MENU, true, null);
}
if (!(parentGroup instanceof DefaultActionGroup)) {
reportActionError(pluginId, actionName + ": group with id \"" + groupId + "\" should be instance of " + DefaultActionGroup.class.getName() +
@@ -850,40 +937,6 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
}
}
- private static void processMouseShortcutNode(Element element, String actionId, PluginId pluginId) {
- String keystrokeString = element.getAttributeValue(KEYSTROKE_ATTR_NAME);
- if (keystrokeString == null || keystrokeString.trim().isEmpty()) {
- reportActionError(pluginId, "\"keystroke\" attribute must be specified for action with id=" + actionId);
- return;
- }
- MouseShortcut shortcut;
- try {
- shortcut = KeymapUtil.parseMouseShortcut(keystrokeString);
- }
- catch (Exception ex) {
- reportActionError(pluginId, "\"keystroke\" attribute has invalid value for action with id=" + actionId);
- return;
- }
-
- String keymapName = element.getAttributeValue(KEYMAP_ATTR_NAME);
- if (keymapName == null || keymapName.isEmpty()) {
- reportActionError(pluginId, "attribute \"keymap\" should be defined");
- return;
- }
- Keymap keymap = KeymapManager.getInstance().getKeymap(keymapName);
- if (keymap == null) {
- reportActionError(pluginId, "keymap \"" + keymapName + "\" not found");
- return;
- }
-
- final String removeOption = element.getAttributeValue(REMOVE_SHORTCUT_ATTR_NAME);
- if (Boolean.valueOf(removeOption)) {
- keymap.removeShortcut(actionId, shortcut);
- } else {
- keymap.addShortcut(actionId, shortcut);
- }
- }
-
@Nullable
private AnAction processReferenceElement(Element element, PluginId pluginId) {
if (!REFERENCE_ELEMENT_NAME.equals(element.getName())) {
@@ -902,7 +955,7 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
return null;
}
- AnAction action = getActionImpl(ref, true);
+ AnAction action = getActionImpl(ref, true, null);
if (action == null) {
if (!myNotRegisteredInternalActionIds.contains(ref)) {
@@ -936,27 +989,15 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
}
}
- private static void assertActionIsGroupOrStub(final AnAction action) {
- if (!(action instanceof ActionGroup || action instanceof ActionStub)) {
- LOG.error("Action : " + action + "; class: " + action.getClass());
- }
- }
-
@Override
public void registerAction(@NotNull String actionId, @NotNull AnAction action, @Nullable PluginId pluginId) {
synchronized (myLock) {
- if (myId2Action.containsKey(actionId)) {
- reportActionError(pluginId, "action with the ID \"" + actionId + "\" was already registered. Action being registered is " + action +
- "; Registered action is " +
- myId2Action.get(actionId) + getPluginInfo(pluginId));
- return;
- }
+ if (!addToMap(actionId, action, pluginId, null)) return;
if (myAction2Id.containsKey(action)) {
reportActionError(pluginId, "action was already registered for another ID. ID is " + myAction2Id.get(action) +
getPluginInfo(pluginId));
return;
}
- myId2Action.put(actionId, action);
myId2Index.put(actionId, myRegisteredActionsCount++);
myAction2Id.put(action, actionId);
if (pluginId != null && !(action instanceof ActionGroup)){
@@ -971,28 +1012,31 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
}
}
- private static void reportActionError(final PluginId pluginId, @NonNls @NotNull String message) {
- if (pluginId == null) {
- LOG.error(message);
+ public boolean addToMap(String actionId, AnAction action, PluginId pluginId, ProjectType projectType) {
+ if (myId2Action.containsKey(actionId)) {
+ // make sure id+projectType is unique
+ AnAction o = myId2Action.get(actionId);
+ ChameleonAction chameleonAction;
+ if (o instanceof ChameleonAction) {
+ chameleonAction = (ChameleonAction)o;
+ }
+ else {
+ chameleonAction = new ChameleonAction(o, projectType);
+ myId2Action.put(actionId, chameleonAction);
+ }
+ AnAction old = chameleonAction.addAction(action, projectType);
+ if (old != null) {
+ reportActionError(pluginId,
+ "action with the ID \"" + actionId + "\" was already registered. Action being registered is " + action +
+ "; Registered action is " +
+ myId2Action.get(actionId) + getPluginInfo(pluginId));
+ return false;
+ }
}
else {
- LOG.error(new PluginException(message, null, pluginId));
- }
- }
-
- @NonNls
- private static String getPluginInfo(@Nullable PluginId id) {
- if (id != null) {
- final IdeaPluginDescriptor plugin = PluginManager.getPlugin(id);
- if (plugin != null) {
- String name = plugin.getName();
- if (name == null) {
- name = id.getIdString();
- }
- return " Plugin: " + name;
- }
+ myId2Action.put(actionId, action);
}
- return "";
+ return true;
}
@Override
@@ -1067,6 +1111,12 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
}
}
+ //@Override
+ //public AnAction replaceAction(String actionId, @NotNull AnAction newAction) {
+ // synchronized (myLock) {
+ // return replaceAction(actionId, newAction, null);
+ // }
+ //}
@Override
public boolean isActionPopupStackEmpty() {
@@ -1078,13 +1128,6 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
return myTransparentOnlyUpdate;
}
- //@Override
- //public AnAction replaceAction(String actionId, @NotNull AnAction newAction) {
- // synchronized (myLock) {
- // return replaceAction(actionId, newAction, null);
- // }
- //}
-
private AnAction replaceAction(@NotNull String actionId, @NotNull AnAction newAction, @Nullable PluginId pluginId) {
AnAction oldAction = getActionOrStub(actionId);
if (oldAction != null) {
@@ -1208,8 +1251,6 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
}
}
- private int myActionsPreloaded = 0;
-
public void preloadActions() {
if (myPreloadActionsRunnable == null) {
myPreloadActionsRunnable = new Runnable() {
@@ -1281,6 +1322,85 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
}
}
+ @Override
+ public ActionCallback tryToExecute(@NotNull final AnAction action, @NotNull final InputEvent inputEvent, @Nullable final Component contextComponent, @Nullable final String place,
+ boolean now) {
+
+ final Application app = ApplicationManager.getApplication();
+ assert app.isDispatchThread();
+
+ final ActionCallback result = new ActionCallback();
+ final Runnable doRunnable = new Runnable() {
+ @Override
+ public void run() {
+ tryToExecuteNow(action, inputEvent, contextComponent, place, result);
+ }
+ };
+
+ if (now) {
+ doRunnable.run();
+ } else {
+ //noinspection SSBasedInspection
+ SwingUtilities.invokeLater(doRunnable);
+ }
+
+ return result;
+ }
+
+ private void tryToExecuteNow(final AnAction action, final InputEvent inputEvent, final Component contextComponent, final String place, final ActionCallback result) {
+ final Presentation presentation = action.getTemplatePresentation().clone();
+
+ IdeFocusManager.findInstanceByContext(getContextBy(contextComponent)).doWhenFocusSettlesDown(new Runnable() {
+ @Override
+ public void run() {
+ final DataContext context = getContextBy(contextComponent);
+
+ AnActionEvent event = new AnActionEvent(
+ inputEvent, context,
+ place != null ? place : ActionPlaces.UNKNOWN,
+ presentation, ActionManagerImpl.this,
+ inputEvent.getModifiersEx()
+ );
+
+ ActionUtil.performDumbAwareUpdate(action, event, false);
+ if (!event.getPresentation().isEnabled()) {
+ result.setRejected();
+ return;
+ }
+
+ ActionUtil.lastUpdateAndCheckDumb(action, event, false);
+ if (!event.getPresentation().isEnabled()) {
+ result.setRejected();
+ return;
+ }
+
+ Component component = PlatformDataKeys.CONTEXT_COMPONENT.getData(context);
+ if (component != null && !component.isShowing()) {
+ result.setRejected();
+ return;
+ }
+
+ fireBeforeActionPerformed(action, context, event);
+
+ UIUtil.addAwtListener(new AWTEventListener() {
+ @Override
+ public void eventDispatched(AWTEvent event) {
+ if (event.getID() == WindowEvent.WINDOW_OPENED ||event.getID() == WindowEvent.WINDOW_ACTIVATED) {
+ if (!result.isProcessed()) {
+ final WindowEvent we = (WindowEvent)event;
+ IdeFocusManager.findInstanceByComponent(we.getWindow()).doWhenFocusSettlesDown(result.createSetDoneRunnable());
+ }
+ }
+ }
+ }, AWTEvent.WINDOW_EVENT_MASK, result);
+
+ ActionUtil.performActionDumbAware(action, event);
+ result.setDone();
+ queueActionPerformedEvent(action, context, event);
+ }
+ });
+ }
+
private class MyTimer extends Timer implements ActionListener {
private final List<TimerListener> myTimerListeners = ContainerUtil.createLockFreeCopyOnWriteList();
private final List<TimerListener> myTransparentTimerListeners = ContainerUtil.createLockFreeCopyOnWriteList();
@@ -1371,88 +1491,4 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
}
}
}
-
- @Override
- public ActionCallback tryToExecute(@NotNull final AnAction action, @NotNull final InputEvent inputEvent, @Nullable final Component contextComponent, @Nullable final String place,
- boolean now) {
-
- final Application app = ApplicationManager.getApplication();
- assert app.isDispatchThread();
-
- final ActionCallback result = new ActionCallback();
- final Runnable doRunnable = new Runnable() {
- @Override
- public void run() {
- tryToExecuteNow(action, inputEvent, contextComponent, place, result);
- }
- };
-
- if (now) {
- doRunnable.run();
- } else {
- //noinspection SSBasedInspection
- SwingUtilities.invokeLater(doRunnable);
- }
-
- return result;
- }
-
- private void tryToExecuteNow(final AnAction action, final InputEvent inputEvent, final Component contextComponent, final String place, final ActionCallback result) {
- final Presentation presentation = action.getTemplatePresentation().clone();
-
- IdeFocusManager.findInstanceByContext(getContextBy(contextComponent)).doWhenFocusSettlesDown(new Runnable() {
- @Override
- public void run() {
- final DataContext context = getContextBy(contextComponent);
-
- AnActionEvent event = new AnActionEvent(
- inputEvent, context,
- place != null ? place : ActionPlaces.UNKNOWN,
- presentation, ActionManagerImpl.this,
- inputEvent.getModifiersEx()
- );
-
- ActionUtil.performDumbAwareUpdate(action, event, false);
- if (!event.getPresentation().isEnabled()) {
- result.setRejected();
- return;
- }
-
- ActionUtil.lastUpdateAndCheckDumb(action, event, false);
- if (!event.getPresentation().isEnabled()) {
- result.setRejected();
- return;
- }
-
- Component component = PlatformDataKeys.CONTEXT_COMPONENT.getData(context);
- if (component != null && !component.isShowing()) {
- result.setRejected();
- return;
- }
-
- fireBeforeActionPerformed(action, context, event);
-
- UIUtil.addAwtListener(new AWTEventListener() {
- @Override
- public void eventDispatched(AWTEvent event) {
- if (event.getID() == WindowEvent.WINDOW_OPENED ||event.getID() == WindowEvent.WINDOW_ACTIVATED) {
- if (!result.isProcessed()) {
- final WindowEvent we = (WindowEvent)event;
- IdeFocusManager.findInstanceByComponent(we.getWindow()).doWhenFocusSettlesDown(result.createSetDoneRunnable());
- }
- }
- }
- }, AWTEvent.WINDOW_EVENT_MASK, result);
-
- ActionUtil.performActionDumbAware(action, event);
- result.setDone();
- queueActionPerformedEvent(action, context, event);
- }
- });
- }
-
- private static DataContext getContextBy(Component contextComponent) {
- final DataManager dataManager = DataManager.getInstance();
- return contextComponent != null ? dataManager.getDataContext(contextComponent) : dataManager.getDataContext();
- }
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ChameleonAction.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ChameleonAction.java
new file mode 100644
index 000000000000..4b46dc191c0c
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ChameleonAction.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.actionSystem.impl;
+
+import com.intellij.openapi.actionSystem.ActionStub;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectType;
+import com.intellij.openapi.project.ProjectTypeService;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Dmitry Avdeev
+ */
+public class ChameleonAction extends AnAction {
+
+ private final Map<ProjectType, AnAction> myActions = new HashMap<ProjectType, AnAction>();
+
+ public ChameleonAction(@NotNull AnAction first, ProjectType projectType) {
+ addAction(first, projectType);
+ }
+
+ public AnAction addAction(AnAction action, ProjectType projectType) {
+ if (action instanceof ActionStub) {
+ String type = ((ActionStub)action).getProjectType();
+ action = ActionManagerImpl.convertStub((ActionStub)action);
+ projectType = type == null ? null : new ProjectType(type);
+ }
+ return myActions.put(projectType, action);
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ getAction(e).actionPerformed(e);
+ }
+
+ @Override
+ public void update(AnActionEvent e) {
+ super.update(e);
+ }
+
+ private AnAction getAction(AnActionEvent e) {
+ Project project = CommonDataKeys.PROJECT.getData(e.getDataContext());
+ ProjectType projectType = ProjectTypeService.getProjectType(project);
+ AnAction action = myActions.get(projectType);
+ if (action == null) action = myActions.get(null);
+ if (action == null) action = myActions.values().iterator().next();
+ return action;
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/config/ActionBean.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/config/ActionBean.java
index 01aa0ff4c49e..4de847213103 100644
--- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/config/ActionBean.java
+++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/config/ActionBean.java
@@ -40,7 +40,6 @@ public class ActionBean {
@Attribute(ActionManagerImpl.ICON_ATTR_NAME)
public String icon;
-
@Attribute(ActionManagerImpl.POPUP_ATTR_NAME)
public String isPopup;
@@ -58,4 +57,7 @@ public class ActionBean {
@Attribute(ActionManagerImpl.OVERRIDES_ATTR_NAME)
public boolean overrides;
+
+ @Attribute(ActionManagerImpl.PROJECT_TYPE)
+ public String projectType;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java
index 46fae517170d..e3a36a2e59ab 100644
--- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java
@@ -336,25 +336,26 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
}
private boolean disposeSelf(final boolean checkCanCloseProject) {
- final CommandProcessor commandProcessor = CommandProcessor.getInstance();
- final boolean[] canClose = {true};
- for (final Project project : ProjectManagerEx.getInstanceEx().getOpenProjects()) {
- try {
- commandProcessor.executeCommand(project, new Runnable() {
- @Override
- public void run() {
- final ProjectManagerImpl manager = (ProjectManagerImpl)ProjectManagerEx.getInstanceEx();
- if (!manager.closeProject(project, true, true, checkCanCloseProject)) {
- canClose[0] = false;
+ final ProjectManagerImpl manager = (ProjectManagerImpl)ProjectManagerEx.getInstanceEx();
+ if (manager != null) {
+ final boolean[] canClose = {true};
+ for (final Project project : manager.getOpenProjects()) {
+ try {
+ CommandProcessor.getInstance().executeCommand(project, new Runnable() {
+ @Override
+ public void run() {
+ if (!manager.closeProject(project, true, true, checkCanCloseProject)) {
+ canClose[0] = false;
+ }
}
- }
- }, ApplicationBundle.message("command.exit"), null);
- }
- catch (Throwable e) {
- LOG.error(e);
- }
- if (!canClose[0]) {
- return false;
+ }, ApplicationBundle.message("command.exit"), null);
+ }
+ catch (Throwable e) {
+ LOG.error(e);
+ }
+ if (!canClose[0]) {
+ return false;
+ }
}
}
runWriteAction(new Runnable() {
@@ -529,9 +530,13 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
}
@Override
- public void load(String path) throws IOException, InvalidDataException {
- getStateStore().setOptionsPath(path);
- getStateStore().setConfigPath(PathManager.getConfigPath());
+ public void load(@Nullable String optionsPath) throws IOException {
+ load(PathManager.getConfigPath(), optionsPath);
+ }
+
+ public void load(@NotNull String configPath, @Nullable String optionsPath) throws IOException {
+ getStateStore().setOptionsPath(optionsPath);
+ getStateStore().setConfigPath(configPath);
myIsFiringLoadingEvent = true;
try {
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ApplicationStoreImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ApplicationStoreImpl.java
index 41942960ab04..a00533d3244b 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ApplicationStoreImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ApplicationStoreImpl.java
@@ -24,6 +24,7 @@ import com.intellij.openapi.util.NamedJDOMExternalizable;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.util.Collection;
@@ -36,13 +37,14 @@ class ApplicationStoreImpl extends ComponentStoreImpl implements IApplicationSto
private static final String XML_EXTENSION = ".xml";
private static final String DEFAULT_STORAGE_SPEC = StoragePathMacros.APP_CONFIG + "/" + PathManager.DEFAULT_OPTIONS_FILE_NAME + XML_EXTENSION;
private static final String OPTIONS_MACRO = "OPTIONS";
- private static final String CONFIG_MACRO = "ROOT_CONFIG";
private static final String ROOT_ELEMENT_NAME = "application";
private final ApplicationImpl myApplication;
private final StateStorageManager myStateStorageManager;
private final DefaultsStateStorage myDefaultsStateStorage;
+ private String myConfigPath;
+
// created from PicoContainer
@SuppressWarnings({"UnusedDeclaration"})
public ApplicationStoreImpl(final ApplicationImpl application, PathMacroManager pathMacroManager) {
@@ -53,23 +55,24 @@ class ApplicationStoreImpl extends ComponentStoreImpl implements IApplicationSto
return new FileBasedStorage.FileStorageData(ROOT_ELEMENT_NAME);
}
+ @Nullable
@Override
protected String getOldStorageSpec(Object component, final String componentName, final StateStorageOperation operation) {
- final String fileName;
-
if (component instanceof NamedJDOMExternalizable) {
- fileName = StoragePathMacros.APP_CONFIG + "/" + ((NamedJDOMExternalizable)component).getExternalFileName() + XML_EXTENSION;
+ return StoragePathMacros.APP_CONFIG + "/" + ((NamedJDOMExternalizable)component).getExternalFileName() + XML_EXTENSION;
}
else {
- fileName = DEFAULT_STORAGE_SPEC;
+ return DEFAULT_STORAGE_SPEC;
}
-
- return fileName;
}
@Override
protected String getVersionsFilePath() {
- return PathManager.getConfigPath() + "/options/appComponentVersions.xml";
+ String configPath = myConfigPath;
+ if (configPath == null) {
+ configPath = PathManager.getConfigPath();
+ }
+ return configPath + "/options/appComponentVersions.xml";
}
@Override
@@ -97,7 +100,8 @@ class ApplicationStoreImpl extends ComponentStoreImpl implements IApplicationSto
@Override
public void setConfigPath(@NotNull final String configPath) {
- myStateStorageManager.addMacro(CONFIG_MACRO, configPath);
+ myStateStorageManager.addMacro(StoragePathMacros.getMacroName(StoragePathMacros.ROOT_CONFIG), configPath);
+ myConfigPath = configPath;
}
@Override
@@ -150,6 +154,7 @@ class ApplicationStoreImpl extends ComponentStoreImpl implements IApplicationSto
return myStateStorageManager;
}
+ @Nullable
@Override
protected StateStorage getDefaultsStorage() {
return myDefaultsStateStorage;
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/BaseFileConfigurableStoreImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/BaseFileConfigurableStoreImpl.java
index 01cc0fb987b9..25dd8a05cab3 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/BaseFileConfigurableStoreImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/BaseFileConfigurableStoreImpl.java
@@ -16,7 +16,6 @@
package com.intellij.openapi.components.impl.stores;
import com.intellij.openapi.components.*;
-import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.impl.ProjectManagerImpl;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
@@ -28,8 +27,6 @@ import java.util.ArrayList;
import java.util.Set;
abstract class BaseFileConfigurableStoreImpl extends ComponentStoreImpl {
- private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.components.impl.stores.BaseFileConfigurableStoreImpl");
-
@NonNls protected static final String VERSION_OPTION = "version";
@NonNls public static final String ATTRIBUTE_NAME = "name";
private final ComponentManager myComponentManager;
@@ -119,6 +116,7 @@ abstract class BaseFileConfigurableStoreImpl extends ComponentStoreImpl {
return (BaseStorageData) getMainStorage().getStorageData(false);
}
+ @Nullable
@Override
protected StateStorage getDefaultsStorage() {
return myDefaultsStateStorage;
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java
index 575717f455f7..fc2017b57a4a 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java
@@ -41,8 +41,7 @@ import java.util.*;
@SuppressWarnings({"deprecation"})
public abstract class ComponentStoreImpl implements IComponentStore {
-
- private static final Logger LOG = Logger.getInstance("#com.intellij.components.ComponentStoreImpl");
+ private static final Logger LOG = Logger.getInstance(ComponentStoreImpl.class);
private final Map<String, Object> myComponents = Collections.synchronizedMap(new THashMap<String, Object>());
private final List<SettingsSavingComponent> mySettingsSavingComponents = Collections.synchronizedList(new ArrayList<SettingsSavingComponent>());
@Nullable private SaveSessionImpl mySession;
@@ -53,9 +52,8 @@ public abstract class ComponentStoreImpl implements IComponentStore {
return getStateStorageManager().getStateStorage(storageSpec);
}
- protected StateStorage getDefaultsStorage() {
- throw new UnsupportedOperationException("Method getDefaultsStorage is not supported in " + getClass());
- }
+ @Nullable
+ protected abstract StateStorage getDefaultsStorage();
@Override
public void initComponent(@NotNull final Object component, final boolean service) {
@@ -143,12 +141,10 @@ public abstract class ComponentStoreImpl implements IComponentStore {
private <T> void commitPersistentComponent(@NotNull final PersistentStateComponent<T> persistentStateComponent,
@NotNull StateStorageManager.ExternalizationSession session) {
- Storage[] storageSpecs = getComponentStorageSpecs(persistentStateComponent, StateStorageOperation.WRITE);
-
T state = persistentStateComponent.getState();
if (state != null) {
- session
- .setState(storageSpecs, persistentStateComponent, getComponentName(persistentStateComponent), state);
+ Storage[] storageSpecs = getComponentStorageSpecs(persistentStateComponent, StateStorageOperation.WRITE);
+ session.setState(storageSpecs, persistentStateComponent, getComponentName(persistentStateComponent), state);
}
}
@@ -276,13 +272,12 @@ public abstract class ComponentStoreImpl implements IComponentStore {
@NotNull
private static <T> Class<T> getComponentStateClass(@NotNull final PersistentStateComponent<T> persistentStateComponent) {
final Class persistentStateComponentClass = PersistentStateComponent.class;
+
Class componentClass = persistentStateComponent.getClass();
nextSuperClass:
while (true) {
- final Class[] interfaces = componentClass.getInterfaces();
-
- for (Class anInterface : interfaces) {
+ for (Class anInterface : componentClass.getInterfaces()) {
if (anInterface.equals(persistentStateComponentClass)) {
break nextSuperClass;
}
@@ -292,7 +287,7 @@ public abstract class ComponentStoreImpl implements IComponentStore {
}
final Type type = ReflectionUtil.resolveVariable(persistentStateComponentClass.getTypeParameters()[0], componentClass);
-
+ assert type != null;
//noinspection unchecked
return (Class<T>)ReflectionUtil.getRawType(type);
}
@@ -319,14 +314,12 @@ public abstract class ComponentStoreImpl implements IComponentStore {
protected <T> Storage[] getComponentStorageSpecs(@NotNull final PersistentStateComponent<T> persistentStateComponent,
final StateStorageOperation operation) throws StateStorageException {
final State stateSpec = getStateSpec(persistentStateComponent);
-
final Storage[] storages = stateSpec.storages();
-
- if (storages.length == 1) return storages;
-
+ if (storages.length == 1) {
+ return storages;
+ }
assert storages.length > 0;
-
final Class<StorageAnnotationsDefaultValues.NullStateStorageChooser> defaultClass =
StorageAnnotationsDefaultValues.NullStateStorageChooser.class;
@@ -340,14 +333,11 @@ public abstract class ComponentStoreImpl implements IComponentStore {
}
else {
try {
- //noinspection unchecked
- final StateStorageChooser<PersistentStateComponent<T>> storageChooser = storageChooserClass.newInstance();
+ @SuppressWarnings("unchecked")
+ StateStorageChooser<PersistentStateComponent<T>> storageChooser = ReflectionUtil.newInstance(storageChooserClass);
return storageChooser.selectStorages(storages, persistentStateComponent, operation);
}
- catch (InstantiationException e) {
- throw new StateStorageException(e);
- }
- catch (IllegalAccessException e) {
+ catch (RuntimeException e) {
throw new StateStorageException(e);
}
}
@@ -404,7 +394,7 @@ public abstract class ComponentStoreImpl implements IComponentStore {
}
catch (StateStorageException e) {
LOG.info(e);
- throw new IOException(e.getMessage());
+ throw new IOException(e.getMessage(), e);
}
return this;
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DefaultProjectStoreImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DefaultProjectStoreImpl.java
index 48247b2de866..6f0c3b8122cf 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DefaultProjectStoreImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DefaultProjectStoreImpl.java
@@ -159,8 +159,8 @@ public class DefaultProjectStoreImpl extends ProjectStoreImpl {
}
@Override
- public String expandMacros(final String file) {
- throw new UnsupportedOperationException("Method expandMacroses not implemented in " + getClass());
+ public String expandMacros(@NotNull String file) {
+ throw new UnsupportedOperationException("Method expandMacros not implemented in " + getClass());
}
@Override
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/OldStreamProviderAdapter.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/OldStreamProviderAdapter.java
index 574823767d9b..2120030db2c1 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/OldStreamProviderAdapter.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/OldStreamProviderAdapter.java
@@ -55,7 +55,7 @@ final class OldStreamProviderAdapter extends StreamProvider implements CurrentUs
}
@Override
- public void deleteFile(@NotNull String fileSpec, @NotNull RoamingType roamingType) {
+ public void delete(@NotNull String fileSpec, @NotNull RoamingType roamingType) {
if (myRoamingType == roamingType) {
myProvider.deleteFile(fileSpec, roamingType);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStateStorageManager.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStateStorageManager.java
index f6a4e11e5aa5..0eed50a65131 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStateStorageManager.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStateStorageManager.java
@@ -20,6 +20,7 @@ import com.intellij.openapi.components.*;
import com.intellij.openapi.project.impl.ProjectImpl;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
import java.util.Map;
@@ -47,6 +48,7 @@ class ProjectStateStorageManager extends StateStorageManagerImpl {
return new ProjectStoreImpl.IprStorageData(ROOT_TAG_NAME, myProject);
}
+ @Nullable
@Override
protected String getOldStorageSpec(Object component, final String componentName, final StateStorageOperation operation) throws
StateStorageException {
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManager.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManager.java
index 0e2828e988a3..68d882d2b204 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManager.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManager.java
@@ -58,7 +58,7 @@ public interface StateStorageManager {
StateStorage getOldStorage(Object component, String componentName, StateStorageOperation operation) throws StateStorageException;
@Nullable
- String expandMacros(String file);
+ String expandMacros(@NotNull String file);
@Deprecated
void registerStreamProvider(@SuppressWarnings("deprecation") StreamProvider streamProvider, final RoamingType type);
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java
index 1b7da8fc2144..431c9a97820c 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java
@@ -331,7 +331,7 @@ public abstract class StateStorageManagerImpl implements StateStorageManager, Di
@Override
@Nullable
- public synchronized String expandMacros(final String file) {
+ public synchronized String expandMacros(@NotNull String file) {
final Matcher matcher = MACRO_PATTERN.matcher(file);
while (matcher.find()) {
String m = matcher.group(1);
@@ -427,6 +427,7 @@ public abstract class StateStorageManagerImpl implements StateStorageManager, Di
return getFileStateStorage(getOldStorageSpec(component, componentName, operation));
}
+ @Nullable
protected abstract String getOldStorageSpec(Object component, final String componentName, final StateStorageOperation operation)
throws StateStorageException;
@@ -615,11 +616,11 @@ public abstract class StateStorageManagerImpl implements StateStorageManager, Di
}
@Override
- public void deleteFile(@NotNull String fileSpec, @NotNull RoamingType roamingType) {
+ public void delete(@NotNull String fileSpec, @NotNull RoamingType roamingType) {
for (StreamProvider streamProvider : myStreamProviders) {
try {
if (streamProvider.isEnabled() && streamProvider.isApplicable(fileSpec, roamingType)) {
- streamProvider.deleteFile(fileSpec, roamingType);
+ streamProvider.delete(fileSpec, roamingType);
}
}
catch (Exception e) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StorageUtil.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StorageUtil.java
index 73aea37d6444..bd732705446a 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StorageUtil.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StorageUtil.java
@@ -113,19 +113,25 @@ public class StorageUtil {
@Nullable
static VirtualFile save(@NotNull IFile file, Parent element, Object requestor) throws StateStorageException {
try {
- VirtualFile vFile = LocalFileSystem.getInstance().findFileByIoFile(file);
- Couple<String> pair = loadFile(vFile);
- String text = JDOMUtil.writeParent(element, pair.second);
-
+ String lineSeparator;
+ String oldText;
if (file.exists()) {
- if (text.equals(pair.first)) {
- return null;
- }
+ VirtualFile vFile = LocalFileSystem.getInstance().findFileByIoFile(file);
+ Couple<String> pair = loadFile(vFile);
+ lineSeparator = pair.second;
+ oldText = pair.first;
}
else {
+ oldText = null;
+ lineSeparator = SystemProperties.getLineSeparator();
file.createParentDirs();
}
+ String text = JDOMUtil.writeParent(element, lineSeparator);
+ if (text.equals(oldText)) {
+ return null;
+ }
+
// mark this action as modifying the file which daemon analyzer should ignore
AccessToken token = ApplicationManager.getApplication().acquireWriteActionLock(DocumentRunnable.IgnoreDocumentRunnable.class);
try {
@@ -245,6 +251,7 @@ public class StorageUtil {
}
}
+ @NotNull
public static BufferExposingByteArrayOutputStream documentToBytes(@NotNull Document document, boolean useSystemLineSeparator) throws IOException {
BufferExposingByteArrayOutputStream out = new BufferExposingByteArrayOutputStream(512);
OutputStreamWriter writer = new OutputStreamWriter(out, CharsetToolkit.UTF8_CHARSET);
@@ -271,9 +278,9 @@ public class StorageUtil {
}
}
- public static void deleteContent(@NotNull StreamProvider provider, @NotNull String fileSpec, @NotNull RoamingType type) {
+ public static void delete(@NotNull StreamProvider provider, @NotNull String fileSpec, @NotNull RoamingType type) {
if (provider.isApplicable(fileSpec, type)) {
- provider.deleteFile(fileSpec, type);
+ provider.delete(fileSpec, type);
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.java
index cf77ee377cf1..ec57d8c63601 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.java
@@ -47,5 +47,8 @@ public abstract class StreamProvider {
return Collections.emptyList();
}
- public abstract void deleteFile(@NotNull String fileSpec, @NotNull RoamingType roamingType);
+ /**
+ * Delete file or directory
+ */
+ public abstract void delete(@NotNull String fileSpec, @NotNull RoamingType roamingType);
} \ No newline at end of file
diff --git a/platform/platform-api/src/com/intellij/openapi/diff/ApplicationStarterBase.java b/platform/platform-impl/src/com/intellij/openapi/diff/ApplicationStarterBase.java
index 21e9f7595082..b508686ade00 100644
--- a/platform/platform-api/src/com/intellij/openapi/diff/ApplicationStarterBase.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/ApplicationStarterBase.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,7 +37,7 @@ import java.util.Arrays;
* @author Konstantin Bulenkov
*/
@SuppressWarnings({"UseOfSystemOutOrSystemErr", "CallToPrintStackTrace"})
-public abstract class ApplicationStarterBase implements ApplicationStarterEx {
+public abstract class ApplicationStarterBase extends ApplicationStarterEx {
private final String myCommandName;
private final int[] myArgsCount;
@@ -52,6 +52,11 @@ public abstract class ApplicationStarterBase implements ApplicationStarterEx {
}
@Override
+ public boolean isHeadless() {
+ return false;
+ }
+
+ @Override
public void processExternalCommandLine(String[] args) {
if (!checkArguments(args)) {
Messages.showMessageDialog(getUsageMessage(), StringUtil.toTitleCase(getCommandName()), Messages.getInformationIcon());
@@ -174,4 +179,9 @@ public abstract class ApplicationStarterBase implements ApplicationStarterEx {
}
return file;
}
+
+ @Override
+ public boolean canProcessExternalCommandLine() {
+ return true;
+ }
}
diff --git a/platform/platform-api/src/com/intellij/openapi/diff/DiffApplication.java b/platform/platform-impl/src/com/intellij/openapi/diff/DiffApplication.java
index ceb075a17095..742a405f350e 100644
--- a/platform/platform-api/src/com/intellij/openapi/diff/DiffApplication.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/DiffApplication.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/platform/platform-api/src/com/intellij/openapi/diff/MergeApplication.java b/platform/platform-impl/src/com/intellij/openapi/diff/MergeApplication.java
index b2e29f1bc88d..0c088929ea49 100644
--- a/platform/platform-api/src/com/intellij/openapi/diff/MergeApplication.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/MergeApplication.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/ex/DiffPanelOptions.java b/platform/platform-impl/src/com/intellij/openapi/diff/ex/DiffPanelOptions.java
index ec7a316357e2..3ad1a58a6732 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/ex/DiffPanelOptions.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/ex/DiffPanelOptions.java
@@ -93,7 +93,7 @@ public class DiffPanelOptions {
while (window instanceof DialogWrapperDialog) {
DialogWrapperDialog dlg = (DialogWrapperDialog)window;
window = window.getParent();
- dlg.getDialogWrapper().close(DialogWrapper.CLOSE_EXIT_CODE);
+ dlg.getDialogWrapper().doCancelAction();
}
return true;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffUtil.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffUtil.java
index 2a5a01b43ca5..a67a6ad5af71 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffUtil.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffUtil.java
@@ -15,6 +15,7 @@
*/
package com.intellij.openapi.diff.impl;
+import com.intellij.codeStyle.CodeStyleFacade;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.diff.DiffContent;
import com.intellij.openapi.diff.DiffContentUtil;
@@ -84,11 +85,22 @@ public class DiffUtil {
}
public static EditorEx createEditor(Document document, Project project, boolean isViewer) {
+ return createEditor(document, project, isViewer, null);
+ }
+
+ public static EditorEx createEditor(Document document, Project project, boolean isViewer, @Nullable FileType fileType) {
EditorFactory factory = EditorFactory.getInstance();
EditorEx editor = (EditorEx)(isViewer ? factory.createViewer(document, project) : factory.createEditor(document, project));
editor.putUserData(DiffManagerImpl.EDITOR_IS_DIFF_KEY, Boolean.TRUE);
editor.setSoftWrapAppliancePlace(SoftWrapAppliancePlaces.VCS_DIFF);
editor.getGutterComponentEx().revalidateMarkup();
+
+ if (fileType != null && project != null && !project.isDisposed()) {
+ CodeStyleFacade codeStyleFacade = CodeStyleFacade.getInstance(project);
+ editor.getSettings().setTabSize(codeStyleFacade.getTabSize(fileType));
+ editor.getSettings().setUseTabCharacter(codeStyleFacade.useTabCharacter(fileType));
+ }
+
return editor;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/BaseExternalTool.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/BaseExternalTool.java
index 9ae17ec50df0..d4fbf23aa6c4 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/BaseExternalTool.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/BaseExternalTool.java
@@ -46,7 +46,7 @@ abstract class BaseExternalTool implements DiffTool {
myToolProperty = toolProperty;
}
- public final boolean canShow(DiffRequest request) {
+ public final boolean canShow(@NotNull DiffRequest request) {
if (!isEnabled() || StringUtil.isEmpty(getToolPath())) return false;
return isAvailable(request);
}
@@ -56,10 +56,10 @@ abstract class BaseExternalTool implements DiffTool {
return null;
}
- public abstract boolean isAvailable(DiffRequest request);
+ public abstract boolean isAvailable(@NotNull DiffRequest request);
@Nullable
- protected ContentExternalizer externalize(final DiffRequest request, final int index) {
+ protected ContentExternalizer externalize(@NotNull DiffRequest request, final int index) {
final VirtualFile file = getLocalFile(request.getContents()[index].getFile());
if (LocalFileExternalizer.canExternalizeAsFile(file)) {
@@ -81,7 +81,8 @@ abstract class BaseExternalTool implements DiffTool {
return myEnableProperty.value(getProperties());
}
- protected List<String> getParameters(DiffRequest request) throws Exception {
+ @NotNull
+ protected List<String> getParameters(@NotNull DiffRequest request) throws Exception {
final String p1 = convertToPath(request, 0);
final String p2 = convertToPath(request, 1);
final List<String> params = new ArrayList<String>();
@@ -91,12 +92,8 @@ abstract class BaseExternalTool implements DiffTool {
}
public void show(DiffRequest request) {
- for (DiffContent diffContent : request.getContents()) {
- Document document = diffContent.getDocument();
- if (document != null) {
- FileDocumentManager.getInstance().saveDocument(document);
- }
- }
+ saveContents(request);
+
GeneralCommandLine commandLine = new GeneralCommandLine();
commandLine.setExePath(getToolPath());
try {
@@ -109,6 +106,15 @@ abstract class BaseExternalTool implements DiffTool {
}
}
+ protected void saveContents(DiffRequest request) {
+ for (DiffContent diffContent : request.getContents()) {
+ Document document = diffContent.getDocument();
+ if (document != null) {
+ FileDocumentManager.getInstance().saveDocument(document);
+ }
+ }
+ }
+
@Nullable
protected String convertToPath(DiffRequest request, int index) throws Exception {
final ContentExternalizer externalize = externalize(request, index);
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/ExtCompareFiles.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/ExtCompareFiles.java
index 0594ab09c0c5..6f661acf9463 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/ExtCompareFiles.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/ExtCompareFiles.java
@@ -19,6 +19,7 @@ import com.intellij.openapi.diff.DiffContent;
import com.intellij.openapi.diff.DiffRequest;
import com.intellij.openapi.diff.impl.DiffUtil;
import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
/**
* @author Konstantin Bulenkov
@@ -30,7 +31,7 @@ class ExtCompareFiles extends BaseExternalTool {
super(DiffManagerImpl.ENABLE_FILES, DiffManagerImpl.FILES_TOOL);
}
- public boolean isAvailable(DiffRequest request) {
+ public boolean isAvailable(@NotNull DiffRequest request) {
final DiffContent[] contents = request.getContents();
for (DiffContent content : contents) {
final VirtualFile file = getLocalFile(content.getFile());
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/ExtCompareFolders.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/ExtCompareFolders.java
index 14c0a9607293..6260176d3e26 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/ExtCompareFolders.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/ExtCompareFolders.java
@@ -18,6 +18,7 @@ package com.intellij.openapi.diff.impl.external;
import com.intellij.openapi.diff.DiffContent;
import com.intellij.openapi.diff.DiffRequest;
import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
@@ -31,7 +32,7 @@ class ExtCompareFolders extends BaseExternalTool {
}
@Override
- public boolean isAvailable(DiffRequest request) {
+ public boolean isAvailable(@NotNull DiffRequest request) {
final DiffContent[] contents = request.getContents();
if (contents.length != 2) return false;
if (externalize(request, 0) == null) return false;
@@ -40,7 +41,7 @@ class ExtCompareFolders extends BaseExternalTool {
}
@Nullable
- protected ContentExternalizer externalize(DiffRequest request, int index) {
+ protected ContentExternalizer externalize(@NotNull DiffRequest request, int index) {
final VirtualFile file = request.getContents()[index].getFile();
if (!isLocalDirectory(file)) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/ExtMergeFiles.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/ExtMergeFiles.java
index 82313a5c9c35..cfee691a1f1f 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/ExtMergeFiles.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/ExtMergeFiles.java
@@ -15,10 +15,21 @@
*/
package com.intellij.openapi.diff.impl.external;
+import com.intellij.execution.ExecutionException;
+import com.intellij.execution.configurations.GeneralCommandLine;
+import com.intellij.execution.util.ExecutionErrorDialog;
+import com.intellij.openapi.diff.DiffBundle;
import com.intellij.openapi.diff.DiffContent;
import com.intellij.openapi.diff.DiffRequest;
import com.intellij.openapi.diff.impl.mergeTool.MergeRequestImpl;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.progress.Task;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.TimeoutUtil;
+import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
@@ -34,7 +45,8 @@ public class ExtMergeFiles extends BaseExternalTool {
}
@Override
- public boolean isAvailable(DiffRequest request) {
+ public boolean isAvailable(@NotNull DiffRequest request) {
+ if (!(request instanceof MergeRequestImpl)) return false;
DiffContent[] contents = request.getContents();
if (contents.length != 3) return false;
if (externalize(request, 0) == null) return false;
@@ -45,7 +57,8 @@ public class ExtMergeFiles extends BaseExternalTool {
}
@Override
- protected List<String> getParameters(DiffRequest request) throws Exception {
+ @NotNull
+ protected List<String> getParameters(@NotNull DiffRequest request) throws Exception {
final List<String> params = new ArrayList<String>();
String result = ((MergeRequestImpl)request).getResultContent().getFile().getPath();
String left = externalize(request, 0).getContentFile().getPath();
@@ -60,4 +73,41 @@ public class ExtMergeFiles extends BaseExternalTool {
}
return params;
}
+
+ @Override
+ public void show(@NotNull DiffRequest request) {
+ saveContents(request);
+
+ int result = DialogWrapper.CANCEL_EXIT_CODE;
+
+ GeneralCommandLine commandLine = new GeneralCommandLine();
+ commandLine.setExePath(getToolPath());
+ try {
+ commandLine.addParameters(getParameters(request));
+ commandLine.createProcess();
+
+ ProgressManager.getInstance().run(new Task.Modal(request.getProject(), "Launching external tool", false) {
+ @Override
+ public void run(@NotNull ProgressIndicator indicator) {
+ indicator.setIndeterminate(true);
+ TimeoutUtil.sleep(1000);
+ }
+ });
+
+ if (Messages.YES == Messages.showYesNoDialog(request.getProject(),
+ "Press \"Mark as Resolved\" when you finish resolving conflicts in the external tool",
+ "Merge In External Tool", "Mark as Resolved", "Revert", null)) {
+ result = DialogWrapper.OK_EXIT_CODE;
+ }
+ ((MergeRequestImpl)request).getResultContent().getFile().refresh(false, false);
+ // We can actually check exit code of external tool, but some of them could work with tabs -> do not close at all
+ }
+ catch (Exception e) {
+ ExecutionErrorDialog
+ .show(new ExecutionException(e.getMessage()), DiffBundle.message("cant.launch.diff.tool.error.message"), request.getProject());
+ }
+ finally {
+ ((MergeRequestImpl)request).setResult(result);
+ }
+ }
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/EditorPlaceHolder.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/EditorPlaceHolder.java
index 0632b56d0f0e..dabaf5f1f030 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/EditorPlaceHolder.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/EditorPlaceHolder.java
@@ -93,7 +93,7 @@ class EditorPlaceHolder extends DiffMarkup implements DiffVersionComponent {
} else {
document = new DocumentImpl("Can not show", true);
final EditorFactory editorFactory = EditorFactory.getInstance();
- myEditor = DiffUtil.createEditor(document, getProject(), true);
+ myEditor = DiffUtil.createEditor(document, getProject(), true, content.getContentType());
addDisposable(new Disposable() {
public void dispose() {
editorFactory.releaseEditor(myEditor);
@@ -105,7 +105,7 @@ class EditorPlaceHolder extends DiffMarkup implements DiffVersionComponent {
}
else {
final EditorFactory editorFactory = EditorFactory.getInstance();
- myEditor = DiffUtil.createEditor(document, getProject(), false);
+ myEditor = DiffUtil.createEditor(document, getProject(), false, content.getContentType());
addDisposable(new Disposable() {
public void dispose() {
editorFactory.releaseEditor(myEditor);
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/SyncScrollSupport.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/SyncScrollSupport.java
index f6cd904c9503..3bc3e90b81b3 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/SyncScrollSupport.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/SyncScrollSupport.java
@@ -136,16 +136,13 @@ public class SyncScrollSupport implements Disposable {
Editor slaveEditor = sidesContainer.getEditor(masterSide.otherSide());
if (slaveEditor == null) return;
- ScrollingModel scrollingModel = slaveEditor.getScrollingModel();
- scrollingModel.disableAnimation();
- scrollingModel.scrollHorizontally(newScrollOffset);
- scrollingModel.enableAnimation();
+ doScrollHorizontally(slaveEditor.getScrollingModel(), newScrollOffset);
}
private static void syncVerticalScroll(@NotNull ScrollingContext context,
@NotNull Rectangle newRectangle,
@NotNull Rectangle oldRectangle) {
- if (newRectangle.y == oldRectangle.y && newRectangle.height == oldRectangle.height) return;
+ if (newRectangle.y == oldRectangle.y) return;
EditingSides sidesContainer = context.getSidesContainer();
FragmentSide masterSide = context.getMasterSide();
FragmentSide masterDiffSide = context.getMasterDiffSide();
@@ -155,42 +152,55 @@ public class SyncScrollSupport implements Disposable {
if (master == null || slave == null) return;
+ int masterVerticalScrollOffset = master.getScrollingModel().getVerticalScrollOffset();
+ int slaveVerticalScrollOffset = slave.getScrollingModel().getVerticalScrollOffset();
+
Rectangle viewRect = master.getScrollingModel().getVisibleArea();
int middleY = viewRect.height / 3;
- int masterVerticalScrollOffset = getScrollOffset(master);
- int slaveVerticalScrollOffset = getScrollOffset(slave);
+ if (master.getDocument().getTextLength() == 0) return;
LogicalPosition masterPos = master.xyToLogicalPosition(new Point(viewRect.x, masterVerticalScrollOffset + middleY));
int masterCenterLine = masterPos.line;
- if (masterCenterLine > master.getDocument().getLineCount()) {
- masterCenterLine = master.getDocument().getLineCount();
+ int scrollToLine = sidesContainer.getLineBlocks().transform(masterDiffSide, masterCenterLine);
+
+ int offset;
+ if (scrollToLine < 0) {
+ offset = slaveVerticalScrollOffset + newRectangle.y - oldRectangle.y;
}
- int scrollToLine = sidesContainer.getLineBlocks().transform(masterDiffSide, masterCenterLine) + 1;
- int actualLine = scrollToLine - 1;
+ else {
+ int correction = (masterVerticalScrollOffset + middleY) % master.getLineHeight();
+ Point point = slave.logicalPositionToXY(new LogicalPosition(scrollToLine, masterPos.column));
+ offset = point.y - middleY + correction;
+ }
+
+ int deltaHeaderOffset = getHeaderOffset(slave) - getHeaderOffset(master);
+ doScrollVertically(slave.getScrollingModel(), offset + deltaHeaderOffset);
+ }
+ private static int getHeaderOffset(@NotNull final Editor editor) {
+ final JComponent header = editor.getHeaderComponent();
+ return header == null ? 0 : header.getHeight();
+ }
- slave.getScrollingModel().disableAnimation();
+ private static void doScrollVertically(@NotNull ScrollingModel model, int offset) {
+ model.disableAnimation();
try {
- if (scrollToLine <= 0) {
- int offset = newRectangle.y - oldRectangle.y;
- slave.getScrollingModel().scrollVertically(slaveVerticalScrollOffset + offset);
- }
- else {
- int correction = (masterVerticalScrollOffset + middleY) % master.getLineHeight();
- Point point = slave.logicalPositionToXY(new LogicalPosition(actualLine, masterPos.column));
- slave.getScrollingModel().scrollVertically(point.y - middleY + correction);
- }
- } finally {
- slave.getScrollingModel().enableAnimation();
+ model.scrollVertically(offset);
+ }
+ finally {
+ model.enableAnimation();
}
}
- private static int getScrollOffset(@NotNull final Editor editor) {
- final JComponent header = editor.getHeaderComponent();
- int headerOffset = header == null ? 0 : header.getHeight();
-
- return editor.getScrollingModel().getVerticalScrollOffset() - headerOffset;
+ private static void doScrollHorizontally(@NotNull ScrollingModel model, int offset) {
+ model.disableAnimation();
+ try {
+ model.scrollHorizontally(offset);
+ }
+ finally {
+ model.enableAnimation();
+ }
}
public static void scrollEditor(@NotNull Editor editor, int logicalLine) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/colors/impl/EditorColorsManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/colors/impl/EditorColorsManagerImpl.java
index 452d7e144356..cf3c196a9d78 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/colors/impl/EditorColorsManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/colors/impl/EditorColorsManagerImpl.java
@@ -26,6 +26,7 @@ import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.components.ExportableComponent;
import com.intellij.openapi.components.NamedComponent;
import com.intellij.openapi.components.RoamingType;
+import com.intellij.openapi.components.StoragePathMacros;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.editor.colors.EditorColorsListener;
@@ -67,7 +68,7 @@ public class EditorColorsManagerImpl extends EditorColorsManager implements Name
private final DefaultColorSchemesManager myDefaultColorSchemesManager;
private final SchemesManager<EditorColorsScheme, EditorColorsSchemeImpl> mySchemesManager;
@NonNls private static final String NAME_ATTR = "name";
- private static final String FILE_SPEC = "$ROOT_CONFIG$/colors";
+ private static final String FILE_SPEC = StoragePathMacros.ROOT_CONFIG + "/colors";
private static final String FILE_EXT = ".icls";
public EditorColorsManagerImpl(DefaultColorSchemesManager defaultColorSchemesManager, SchemesManagerFactory schemesManagerFactory) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java b/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java
index 216429557cea..7d9973fed2d3 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java
@@ -407,7 +407,7 @@ public final class EditorUtil {
IterationState state = new IterationState(editorImpl, start, end, false);
int fontType = state.getMergedAttributes().getFontType();
int column = currentColumn[0];
- int spaceSize = getSpaceWidth(fontType, editorImpl);
+ int plainSpaceSize = getSpaceWidth(Font.PLAIN, editorImpl);
for (; column < columnNumber && offset < end; offset++) {
if (offset >= state.getEndOffset()) {
state.advance();
@@ -417,7 +417,7 @@ public final class EditorUtil {
char c = text.charAt(offset);
if (c == '\t') {
final int newX = nextTabStop(x, editorImpl);
- final int columns = columnsNumber(newX - x, spaceSize);
+ final int columns = columnsNumber(newX - x, plainSpaceSize);
if (debugBuffer != null) {
debugBuffer.append(String.format(
"Processing tabulation at the offset %d. Current X: %d, new X: %d, current column: %d, new column: %d%n",
@@ -556,11 +556,11 @@ public final class EditorUtil {
return nextTabStop(x, getSpaceWidth(Font.PLAIN, editor), tabSize);
}
- public static int nextTabStop(int x, int spaceWidth, int tabSize) {
+ public static int nextTabStop(int x, int plainSpaceWidth, int tabSize) {
if (tabSize <= 0) {
- return x + spaceWidth;
+ return x + plainSpaceWidth;
}
- tabSize *= spaceWidth;
+ tabSize *= plainSpaceWidth;
int nTabs = x / tabSize;
return (nTabs + 1) * tabSize;
@@ -617,15 +617,15 @@ public final class EditorUtil {
* @param c target char
* @param x <code>'x'</code> coordinate of the line where given char is represented that indicates char end location
* @param prevX <code>'x'</code> coordinate of the line where given char is represented that indicates char start location
- * @param spaceSize <code>'space'</code> symbol width
+ * @param plainSpaceSize <code>'space'</code> symbol width (in plain font style)
* @return number of columns necessary for representation of the given char on a screen.
*/
- public static int columnsNumber(char c, int x, int prevX, int spaceSize) {
+ public static int columnsNumber(char c, int x, int prevX, int plainSpaceSize) {
if (c != '\t') {
return 1;
}
- int result = (x - prevX) / spaceSize;
- if ((x - prevX) % spaceSize > 0) {
+ int result = (x - prevX) / plainSpaceSize;
+ if ((x - prevX) % plainSpaceSize > 0) {
result++;
}
return result;
@@ -635,12 +635,12 @@ public final class EditorUtil {
* Allows to answer how many visual columns are occupied by the given width.
*
* @param width target width
- * @param spaceSize width of the single space symbol within the target editor
+ * @param plainSpaceSize width of the single space symbol within the target editor (in plain font style)
* @return number of visual columns are occupied by the given width
*/
- public static int columnsNumber(int width, int spaceSize) {
- int result = width / spaceSize;
- if (width % spaceSize > 0) {
+ public static int columnsNumber(int width, int plainSpaceSize) {
+ int result = width / plainSpaceSize;
+ if (width % plainSpaceSize > 0) {
result++;
}
return result;
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java
index c769f92fff78..e2693b2c835f 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java
@@ -1156,7 +1156,13 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
@Override
public void setSelection(int startOffset, int endOffset) {
- doSetSelection(myEditor.offsetToVisualPosition(startOffset), startOffset, myEditor.offsetToVisualPosition(endOffset), endOffset, false);
+ setSelection(startOffset, endOffset, true);
+ }
+
+ @Override
+ public void setSelection(int startOffset, int endOffset, boolean updateSystemSelection) {
+ doSetSelection(myEditor.offsetToVisualPosition(startOffset), startOffset, myEditor.offsetToVisualPosition(endOffset), endOffset, false,
+ updateSystemSelection);
}
@Override
@@ -1173,16 +1179,22 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
@Override
public void setSelection(@Nullable VisualPosition startPosition, int startOffset, @Nullable VisualPosition endPosition, int endOffset) {
+ setSelection(startPosition, startOffset, endPosition, endOffset, true);
+ }
+
+ @Override
+ public void setSelection(@Nullable VisualPosition startPosition, int startOffset, @Nullable VisualPosition endPosition, int endOffset, boolean updateSystemSelection) {
VisualPosition startPositionToUse = startPosition == null ? myEditor.offsetToVisualPosition(startOffset) : startPosition;
VisualPosition endPositionToUse = endPosition == null ? myEditor.offsetToVisualPosition(endOffset) : endPosition;
- doSetSelection(startPositionToUse, startOffset, endPositionToUse, endOffset, true);
+ doSetSelection(startPositionToUse, startOffset, endPositionToUse, endOffset, true, updateSystemSelection);
}
private void doSetSelection(@NotNull final VisualPosition startPosition,
final int _startOffset,
@NotNull final VisualPosition endPosition,
final int _endOffset,
- final boolean visualPositionAware)
+ final boolean visualPositionAware,
+ final boolean updateSystemSelection)
{
myEditor.getCaretModel().doWithCaretMerging(new Runnable() {
public void run() {
@@ -1278,7 +1290,9 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
myEditor.getSelectionModel().fireSelectionChanged(oldSelectionStart, oldSelectionEnd, startOffset, endOffset);
- updateSystemSelection();
+ if (updateSystemSelection) {
+ updateSystemSelection();
+ }
}
});
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java
index 8d6608e63dd9..15a907e826e4 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java
@@ -443,6 +443,11 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener,
@Override
public void setCaretsAndSelections(@NotNull final List<CaretState> caretStates) {
+ setCaretsAndSelections(caretStates, true);
+ }
+
+ @Override
+ public void setCaretsAndSelections(@NotNull final List<CaretState> caretStates, final boolean updateSystemSelection) {
myEditor.assertIsDispatchThread();
if (caretStates.isEmpty()) {
throw new IllegalArgumentException("At least one caret should exist");
@@ -474,9 +479,11 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener,
caret.moveToLogicalPosition(caretState.getCaretPosition());
}
if (caretState != null && caretState.getSelectionStart() != null && caretState.getSelectionEnd() != null) {
- caret.setSelection(myEditor.logicalToVisualPosition(caretState.getSelectionStart()), myEditor.logicalPositionToOffset(caretState.getSelectionStart()),
- myEditor.logicalToVisualPosition(caretState.getSelectionEnd()), myEditor.logicalPositionToOffset(
- caretState.getSelectionEnd()));
+ caret.setSelection(myEditor.logicalToVisualPosition(caretState.getSelectionStart()),
+ myEditor.logicalPositionToOffset(caretState.getSelectionStart()),
+ myEditor.logicalToVisualPosition(caretState.getSelectionEnd()),
+ myEditor.logicalPositionToOffset(caretState.getSelectionEnd()),
+ updateSystemSelection);
}
}
int caretsToRemove = myCarets.size() - caretStates.size();
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/ContextMenuImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/ContextMenuImpl.java
index 28a7c2204265..cbe6da5379cf 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/ContextMenuImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/ContextMenuImpl.java
@@ -46,16 +46,15 @@ import java.awt.event.ActionListener;
public class ContextMenuImpl extends JPanel implements Disposable {
@NonNls
public static final String ACTION_GROUP = "EditorContextBarMenu";
-
- private ActionGroup myActionGroup;
private final JComponent myComponent;
+ private final JLayeredPane myLayeredPane;
+ private ActionGroup myActionGroup;
private boolean myVisible = false;
private boolean myShow = false;
private int myCurrentOpacity;
private Timer myTimer;
private EditorImpl myEditor;
private boolean myDisposed;
- private final JLayeredPane myLayeredPane;
private ActionToolbar myActionToolbar;
public ContextMenuImpl(JLayeredPane layeredPane, @NotNull final JScrollPane container, @NotNull final EditorImpl editor) {
@@ -81,7 +80,7 @@ public class ContextMenuImpl extends JPanel implements Disposable {
}
});
- AnAction action = actionManager.getAction("EditorContextBarMenu");
+ AnAction action = actionManager.getAction(ACTION_GROUP);
if (action == null) {
action = new DefaultActionGroup();
actionManager.registerAction(ACTION_GROUP, action);
@@ -107,6 +106,15 @@ public class ContextMenuImpl extends JPanel implements Disposable {
return activationArea.contains(p.x, p.y - viewPosition.y);
}
+ public static boolean mayShowToolbar(@Nullable final Document document) {
+ if (document == null) {
+ return false;
+ }
+
+ final VirtualFile file = FileDocumentManager.getInstance().getFile(document);
+ return file != null && file.isValid() && (file.isInLocalFileSystem() || file instanceof HttpVirtualFile);
+ }
+
private void toggleContextToolbar(final boolean show) {
final Component toolbar = myComponent.getComponent(0);
final int count = ((Container)toolbar).getComponentCount();
@@ -201,15 +209,6 @@ public class ContextMenuImpl extends JPanel implements Disposable {
}
}
- public static boolean mayShowToolbar(@Nullable final Document document) {
- if (document == null) {
- return false;
- }
-
- final VirtualFile file = FileDocumentManager.getInstance().getFile(document);
- return file != null && file.isValid() && (file.isInLocalFileSystem() || file instanceof HttpVirtualFile);
- }
-
private void scheduleHide() {
if (myTimer != null && myTimer.isRunning()) {
myTimer.stop();
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorFactoryImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorFactoryImpl.java
index ec0cef4e76d5..d0313e04cf9f 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorFactoryImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorFactoryImpl.java
@@ -203,14 +203,17 @@ public class EditorFactoryImpl extends EditorFactory implements ApplicationCompo
@Override
public void releaseEditor(@NotNull Editor editor) {
try {
- ((EditorImpl)editor).release();
+ myEditorFactoryEventDispatcher.getMulticaster().editorReleased(new EditorFactoryEvent(this, editor));
}
finally {
- myEditors.remove(editor);
- myEditorFactoryEventDispatcher.getMulticaster().editorReleased(new EditorFactoryEvent(this, editor));
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("number of Editor's:" + myEditors.size());
+ try {
+ ((EditorImpl)editor).release();
+ }
+ finally {
+ myEditors.remove(editor);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("number of Editor's:" + myEditors.size());
+ }
}
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java
index 39706f016adc..f773f842f323 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java
@@ -1236,7 +1236,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
GutterIconRenderer renderer = getGutterRenderer(e);
AnAction clickAction = null;
- if (renderer != null) {
+ if (renderer != null && e.getButton() < 4) {
clickAction = (InputEvent.BUTTON2_MASK & e.getModifiers()) > 0
? renderer.getMiddleButtonClickAction()
: renderer.getClickAction();
@@ -1447,8 +1447,8 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
public void process(int x, int y, GutterMark renderer) {
final int ex = convertX((int)p.getX());
Icon icon = renderer.getIcon();
- if (x <= ex && ex <= x + icon.getIconWidth() &&
- y <= p.getY() && p.getY() <= y + icon.getIconHeight()) {
+ // Do not check y to extend the area where users could click
+ if (x <= ex && ex <= x + icon.getIconWidth()) {
result[0] = renderer;
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
index 6160ea58dcdf..51f6ec4a8cdb 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
@@ -743,12 +743,9 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
myGutterComponent.repaint(0, y, myGutterComponent.getWidth(), myGutterComponent.getHeight() - y);
}
// make sure carets won't appear at invalid positions (e.g. on Tab width change)
- getCaretModel().runForEachCaret(new CaretAction() {
- @Override
- public void perform(Caret caret) {
- caret.moveToOffset(caret.getOffset());
- }
- });
+ for (Caret caret : getCaretModel().getAllCarets()) {
+ caret.moveToOffset(caret.getOffset());
+ }
}
private void initTabPainter() {
@@ -1153,8 +1150,9 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
int textLength = myDocument.getTextLength();
LogicalPosition logicalPosition = visualToLogicalPosition(new VisualPosition(line, 0));
int offset = logicalPositionToOffset(logicalPosition);
+ int plainSpaceSize = EditorUtil.getSpaceWidth(Font.PLAIN, this);
- if (offset >= textLength) return new VisualPosition(line, EditorUtil.columnsNumber(p.x, EditorUtil.getSpaceWidth(Font.PLAIN, this)));
+ if (offset >= textLength) return new VisualPosition(line, EditorUtil.columnsNumber(p.x, plainSpaceSize));
// There is a possible case that starting logical line is split by soft-wraps and it's part after the split should be drawn.
// We mark that we're under such circumstances then.
@@ -1172,12 +1170,11 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
+ "to offset %d (end offset). State: %s",
p, line, line, 0, logicalPosition, offset, line + 1, 0, endLogicalPosition, endOffset, dumpState()
));
- return new VisualPosition(line, EditorUtil.columnsNumber(p.x, EditorUtil.getSpaceWidth(Font.PLAIN, this)));
+ return new VisualPosition(line, EditorUtil.columnsNumber(p.x, plainSpaceSize));
}
IterationState state = new IterationState(this, offset, endOffset, false);
int fontType = state.getMergedAttributes().getFontType();
- int spaceSize = EditorUtil.getSpaceWidth(fontType, this);
int x = 0;
int charWidth;
@@ -1221,7 +1218,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
if (x >= px) {
break outer;
}
- column += EditorUtil.columnsNumber(c, x, prevX, spaceSize);
+ column += EditorUtil.columnsNumber(c, x, prevX, plainSpaceSize);
}
// Process 'after soft wrap' sign.
@@ -1261,7 +1258,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
if (x >= px) {
break;
}
- column += EditorUtil.columnsNumber(c, x, prevX, spaceSize);
+ column += EditorUtil.columnsNumber(c, x, prevX, plainSpaceSize);
offset++;
}
@@ -1272,16 +1269,16 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
}
if (charWidth < 0) {
- charWidth = spaceSize;
+ charWidth = plainSpaceSize;
}
if (x >= px && c == '\t' && !onSoftWrapDrawing) {
if (mySettings.isCaretInsideTabs()) {
- column += (px - prevX) / spaceSize;
- if ((px - prevX) % spaceSize > spaceSize / 2) column++;
+ column += (px - prevX) / plainSpaceSize;
+ if ((px - prevX) % plainSpaceSize > plainSpaceSize / 2) column++;
}
else if ((x - px) * 2 < x - prevX) {
- column += EditorUtil.columnsNumber(c, x, prevX, spaceSize);
+ column += EditorUtil.columnsNumber(c, x, prevX, plainSpaceSize);
}
}
else {
@@ -1290,8 +1287,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
}
else {
int diff = px - x;
- column += diff / spaceSize;
- if (diff % spaceSize * 2 >= spaceSize) {
+ column += diff / plainSpaceSize;
+ if (diff % plainSpaceSize * 2 >= plainSpaceSize) {
column++;
}
}
@@ -1549,7 +1546,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
// so, we can't just use 'startOffset + targetColumn' as a max end offset.
IterationState state = new IterationState(this, startOffset, calcEndOffset(startOffset, targetColumn), false);
int fontType = state.getMergedAttributes().getFontType();
- int spaceSize = EditorUtil.getSpaceWidth(fontType, this);
+ int plainSpaceSize = EditorUtil.getSpaceWidth(Font.PLAIN, this);
int column = 0;
outer:
@@ -1588,8 +1585,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
if (c == '\t') {
int prevX = x;
x = EditorUtil.nextTabStop(x, this);
- int columnDiff = (x - prevX) / spaceSize;
- if ((x - prevX) % spaceSize > 0) {
+ int columnDiff = (x - prevX) / plainSpaceSize;
+ if ((x - prevX) % plainSpaceSize > 0) {
// There is a possible case that tabulation symbol takes more than one visual column to represent and it's shown at
// soft-wrapped line. Soft wrap sign width may be not divisible by space size, hence, part of tabulation symbol represented
// as a separate visual column may take less space than space width.
@@ -2895,7 +2892,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
+ ", soft wraps: " + (mySoftWrapModel.isSoftWrappingEnabled() ? "on" : "off")
+ ", soft wraps data: " + getSoftWrapModel().dumpState()
+ "\n\nfolding data: " + getFoldingModel().dumpState()
- + (myDocument instanceof DocumentImpl ? "\n\ndocument info: " + ((DocumentImpl)myDocument).dumpState() : "");
+ + (myDocument instanceof DocumentImpl ? "\n\ndocument info: " + ((DocumentImpl)myDocument).dumpState() : "")
+ + "\nfont preferences: " + myScheme.getFontPreferences();
}
private class CachedFontContent {
@@ -4824,22 +4822,21 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
int getDecScrollButtonHeight() {
ScrollBarUI barUI = getUI();
Insets insets = getInsets();
+ int top = Math.max(0, insets.top);
if (barUI instanceof ButtonlessScrollBarUI) {
- return insets.top + ((ButtonlessScrollBarUI)barUI).getDecrementButtonHeight();
+ return top + ((ButtonlessScrollBarUI)barUI).getDecrementButtonHeight();
}
- else if (barUI instanceof BasicScrollBarUI) {
+ if (barUI instanceof BasicScrollBarUI) {
try {
JButton decrButtonValue = (JButton)decrButtonField.get(barUI);
LOG.assertTrue(decrButtonValue != null);
- return insets.top + decrButtonValue.getHeight();
+ return top + decrButtonValue.getHeight();
}
catch (Exception exc) {
throw new IllegalStateException(exc);
}
}
- else {
- return insets.top + 15;
- }
+ return top + 15;
}
/**
@@ -6623,7 +6620,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
int fontType = state.getMergedAttributes().getFontType();
int column = 0;
int x = 0;
- int spaceSize = EditorUtil.getSpaceWidth(fontType, this);
+ int plainSpaceSize = EditorUtil.getSpaceWidth(Font.PLAIN, this);
for (int i = start; i < offset; i++) {
if (i >= state.getEndOffset()) {
state.advance();
@@ -6639,7 +6636,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
if (c == '\t') {
int prevX = x;
x = EditorUtil.nextTabStop(x, this);
- column += EditorUtil.columnsNumber(c, x, prevX, spaceSize);
+ column += EditorUtil.columnsNumber(c, x, prevX, plainSpaceSize);
}
else {
x += EditorUtil.charWidth(c, fontType, this);
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java
index 20c08ec4ec99..032573521b56 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java
@@ -42,6 +42,7 @@ import com.intellij.openapi.editor.ex.*;
import com.intellij.openapi.editor.markup.ErrorStripeRenderer;
import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.fileEditor.impl.EditorWindowHolder;
+import com.intellij.openapi.ui.GraphicsConfig;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.util.Disposer;
@@ -127,9 +128,10 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
void recalcEditorDimensions() {
EditorImpl.MyScrollBar scrollBar = myEditor.getVerticalScrollBar();
- int scrollBarHeight = scrollBar.getSize().height;
+ int scrollBarHeight = Math.max(0, scrollBar.getSize().height);
myEditorScrollbarTop = scrollBar.getDecScrollButtonHeight()/* + 1*/;
+ assert myEditorScrollbarTop>=0;
int editorScrollbarBottom = scrollBar.getIncScrollButtonHeight();
myEditorTargetHeight = scrollBarHeight - myEditorScrollbarTop - editorScrollbarBottom;
myEditorSourceHeight = myEditor.getPreferredHeight();
@@ -758,20 +760,32 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
Color color,
boolean drawTopDecoration,
boolean drawBottomDecoration) {
+ GraphicsConfig config = GraphicsUtil.setupAAPainting(g);
int x = isMirrored() ? 3 : 5;
int paintWidth = width;
boolean flatStyle = Registry.is("ide.new.markup.markers");
if (thinErrorStripeMark) {
paintWidth /= 2;
- paintWidth += flatStyle ? 0 : 1;
+ paintWidth += flatStyle ? -2 : 1;
x = isMirrored() ? width + 2 : 0;
+ if (yEnd - yStart < 6) {
+ yStart -= 1;
+ yEnd += yEnd-yStart - 1;
+ }
}
if (color == null) return;
- Color darker = UIUtil.isUnderDarcula()? color : ColorUtil.shift(color, 0.75);
+ Color darker = color;
+ if (!UIUtil.isUnderDarcula()) {
+ float[] hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null);
+ hsb[2] = Math.min(1f, hsb[2] * 0.85f);
+ //noinspection UseJBColor
+ darker = new Color(Color.HSBtoRGB(hsb[0], hsb[1], hsb[2]));
+ }
if (flatStyle) {
g.setColor(darker);
- g.fillRect(x, yStart, paintWidth, yEnd - yStart + 1);
+ g.fillRoundRect(x, yStart, paintWidth, yEnd - yStart, 3,3);
+ config.restore();
return;
}
@@ -794,6 +808,7 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
}
//right decoration
UIUtil.drawLine(g, x + paintWidth - 2, yStart, x + paintWidth - 2, yEnd/* - 1*/);
+ config.restore();
}
// mouse events
@@ -1056,29 +1071,30 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
int startLineNumber = end == -1 ? 0 : offsetToLine(start, document);
int startY;
int lineCount;
- if (myEditorSourceHeight < myEditorTargetHeight) {
+ int editorTargetHeight = Math.max(0, myEditorTargetHeight);
+ if (myEditorSourceHeight < editorTargetHeight) {
lineCount = 0;
startY = myEditorScrollbarTop + startLineNumber * myEditor.getLineHeight();
}
else {
lineCount = myEditorSourceHeight / myEditor.getLineHeight();
- startY = myEditorScrollbarTop + (int)((float)startLineNumber / lineCount * myEditorTargetHeight);
+ startY = myEditorScrollbarTop + (int)((float)startLineNumber / lineCount * editorTargetHeight);
}
int endY;
int endLineNumber = offsetToLine(end, document);
if (end == -1 || start == -1) {
- endY = Math.min(myEditorSourceHeight, myEditorTargetHeight);
+ endY = Math.min(myEditorSourceHeight, editorTargetHeight);
}
else if (start == end || offsetToLine(start, document) == endLineNumber) {
endY = startY; // both offsets are on the same line, no need to recalc Y position
}
else {
- if (myEditorSourceHeight < myEditorTargetHeight) {
+ if (myEditorSourceHeight < editorTargetHeight) {
endY = myEditorScrollbarTop + endLineNumber * myEditor.getLineHeight();
}
else {
- endY = myEditorScrollbarTop + (int)((float)endLineNumber / lineCount * myEditorTargetHeight);
+ endY = myEditorScrollbarTop + (int)((float)endLineNumber / lineCount * editorTargetHeight);
}
}
if (endY < startY) endY = startY;
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceManager.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceManager.java
index 3a819d88a370..881dc4100204 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceManager.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceManager.java
@@ -270,8 +270,9 @@ public class SoftWrapApplianceManager implements DocumentListener, Dumpable {
EditorPosition position = new EditorPosition(logical, start, myEditor);
position.x = point.x;
int spaceWidth = EditorUtil.getSpaceWidth(myContext.fontType, myEditor);
+ int plainSpaceWidth = EditorUtil.getSpaceWidth(Font.PLAIN, myEditor);
- myContext.logicalLineData.update(logical.line, spaceWidth, myEditor);
+ myContext.logicalLineData.update(logical.line, spaceWidth, plainSpaceWidth);
myContext.currentPosition = position;
myContext.lineStartPosition = position.clone();
@@ -363,8 +364,7 @@ public class SoftWrapApplianceManager implements DocumentListener, Dumpable {
revertListeners(softWrap.getStart(), myContext.currentPosition.visualLine);
for (int j = foldRegion.getStartOffset() - 1; j >= softWrap.getStart(); j--) {
int pixelsDiff = myOffset2widthInPixels.data[j - myOffset2widthInPixels.anchor];
- int tmpFontType = myOffset2fontType.get(j);
- int columnsDiff = calculateWidthInColumns(myContext.text.charAt(j), pixelsDiff, myContext.getSpaceWidth(tmpFontType));
+ int columnsDiff = calculateWidthInColumns(myContext.text.charAt(j), pixelsDiff, myContext.getPlainSpaceWidth());
myContext.currentPosition.offset--;
myContext.currentPosition.logicalColumn -= columnsDiff;
myContext.currentPosition.visualColumn -= columnsDiff;
@@ -582,8 +582,7 @@ public class SoftWrapApplianceManager implements DocumentListener, Dumpable {
revertListeners(actualSoftWrapOffset, myContext.currentPosition.visualLine);
for (int j = offset - 1; j >= actualSoftWrapOffset; j--) {
int pixelsDiff = myOffset2widthInPixels.data[j - myOffset2widthInPixels.anchor];
- int tmpFontType = myOffset2fontType.get(j);
- int columnsDiff = calculateWidthInColumns(myContext.text.charAt(j), pixelsDiff, myContext.getSpaceWidth(tmpFontType));
+ int columnsDiff = calculateWidthInColumns(myContext.text.charAt(j), pixelsDiff, myContext.getPlainSpaceWidth());
myContext.currentPosition.offset--;
myContext.currentPosition.logicalColumn -= columnsDiff;
myContext.currentPosition.visualColumn -= columnsDiff;
@@ -630,12 +629,12 @@ public class SoftWrapApplianceManager implements DocumentListener, Dumpable {
return Math.max(start, end);
}
- private static int calculateWidthInColumns(char c, int widthInPixels, int spaceWithInPixels) {
+ private static int calculateWidthInColumns(char c, int widthInPixels, int plainSpaceWithInPixels) {
if (c != '\t') {
return 1;
}
- int result = widthInPixels / spaceWithInPixels;
- if (widthInPixels % spaceWithInPixels > 0) {
+ int result = widthInPixels / plainSpaceWithInPixels;
+ if (widthInPixels % plainSpaceWithInPixels > 0) {
result++;
}
return result;
@@ -869,7 +868,7 @@ public class SoftWrapApplianceManager implements DocumentListener, Dumpable {
}
}
updateLastTopLeftCornerOffset();
- return result;
+ return true;
}
private void updateLastTopLeftCornerOffset() {
@@ -1035,7 +1034,7 @@ public class SoftWrapApplianceManager implements DocumentListener, Dumpable {
public int endLineOffset;
public int nonWhiteSpaceSymbolOffset;
- public void update(int logicalLine, int spaceWidth, Editor editor) {
+ public void update(int logicalLine, int spaceWidth, int plainSpaceWidth) {
Document document = myEditor.getDocument();
int startLineOffset;
if (logicalLine >= document.getLineCount()) {
@@ -1055,8 +1054,8 @@ public class SoftWrapApplianceManager implements DocumentListener, Dumpable {
switch (c) {
case ' ': indentInColumns += 1; indentInPixels += spaceWidth; break;
case '\t':
- int x = EditorUtil.nextTabStop(indentInPixels, editor);
- indentInColumns += calculateWidthInColumns(c, x - indentInPixels, spaceWidth);
+ int x = EditorUtil.nextTabStop(indentInPixels, myEditor);
+ indentInColumns += calculateWidthInColumns(c, x - indentInPixels, plainSpaceWidth);
indentInPixels = x;
break;
default: nonWhiteSpaceSymbolOffset = i; return;
@@ -1270,8 +1269,12 @@ public class SoftWrapApplianceManager implements DocumentListener, Dumpable {
public int getSpaceWidth() {
return getSpaceWidth(fontType);
}
-
- public int getSpaceWidth(@JdkConstants.FontStyle int fontType) {
+
+ public int getPlainSpaceWidth() {
+ return getSpaceWidth(Font.PLAIN);
+ }
+
+ private int getSpaceWidth(@JdkConstants.FontStyle int fontType) {
int result = fontType2spaceWidth.get(fontType);
if (result <= 0) {
result = EditorUtil.getSpaceWidth(fontType, myEditor);
@@ -1280,7 +1283,7 @@ public class SoftWrapApplianceManager implements DocumentListener, Dumpable {
assert result > 0;
return result;
}
-
+
/**
* Asks current context to update its state assuming that it begins to point to the line next to its current position.
*/
@@ -1293,7 +1296,7 @@ public class SoftWrapApplianceManager implements DocumentListener, Dumpable {
lastFoldEndPosition = null;
lastFold = null;
lineStartPosition.from(currentPosition);
- logicalLineData.update(currentPosition.logicalLine, getSpaceWidth(), myEditor);
+ logicalLineData.update(currentPosition.logicalLine, getSpaceWidth(), getPlainSpaceWidth());
fontType = myOffset2fontType.get(currentPosition.offset);
myOffset2fontType.clear();
@@ -1330,7 +1333,7 @@ public class SoftWrapApplianceManager implements DocumentListener, Dumpable {
myOffset2widthInPixels.data[currentPosition.offset - myOffset2widthInPixels.anchor] = widthInPixels;
myOffset2widthInPixels.end++;
- int widthInColumns = calculateWidthInColumns(c, widthInPixels, myContext.getSpaceWidth());
+ int widthInColumns = calculateWidthInColumns(c, widthInPixels, myContext.getPlainSpaceWidth());
if (c == '\t') {
notifyListenersOnVisualLineStart(myContext.lineStartPosition);
notifyListenersOnTabulation(widthInColumns);
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentCaret.java b/platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentCaret.java
index 92ef12c46558..48ba57e150cf 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentCaret.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentCaret.java
@@ -151,6 +151,12 @@ public class TextComponentCaret extends UserDataHolderBase implements Caret {
}
@Override
+ public void setSelection(int startOffset, int endOffset, boolean updateSystemSelection) {
+ // updating system selection is not supported currently for TextComponentEditor
+ setSelection(startOffset, endOffset);
+ }
+
+ @Override
public void setSelection(int startOffset, @Nullable VisualPosition endPosition, int endOffset) {
getSelectionModel().setSelection(startOffset, endPosition, endOffset);
}
@@ -161,6 +167,13 @@ public class TextComponentCaret extends UserDataHolderBase implements Caret {
}
@Override
+ public void setSelection(@Nullable VisualPosition startPosition, int startOffset, @Nullable VisualPosition endPosition, int endOffset,
+ boolean updateSystemSelection) {
+ // updating system selection is not supported currently for TextComponentEditor
+ setSelection(startPosition, startOffset, endPosition, endOffset);
+ }
+
+ @Override
public void removeSelection() {
getSelectionModel().removeSelection();
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentCaretModel.java b/platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentCaretModel.java
index ac415f5f9409..341c8ace3598 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentCaretModel.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentCaretModel.java
@@ -187,6 +187,11 @@ public class TextComponentCaretModel implements CaretModel {
throw new UnsupportedOperationException("Multiple carets are not supported");
}
+ @Override
+ public void setCaretsAndSelections(@NotNull List<CaretState> caretStates, boolean updateSystemSelection) {
+ throw new UnsupportedOperationException("Multiple carets are not supported");
+ }
+
@NotNull
@Override
public List<CaretState> getCaretsAndSelections() {
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java
index b1f9ec0c2b93..b9e38809faab 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java
@@ -148,7 +148,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener
}
- private boolean showEmptyText() {
+ protected boolean showEmptyText() {
return myCurrentWindow == null || myCurrentWindow.getFiles().length == 0;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java
index cce6de27545d..ec2559fc06ba 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java
@@ -550,14 +550,18 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Virt
if (document != null) {
// a file is linked to a document - chances are it is an "unknown text file" now
if (isBinaryWithoutDecompiler(file)) {
- myDocuments.remove(file);
- file.putUserData(HARD_REF_TO_DOCUMENT_KEY, null);
- document.putUserData(FILE_KEY, null);
+ unbindFileFromDocument(file, document);
}
}
}
}
+ private void unbindFileFromDocument(@NotNull VirtualFile file, @NotNull Document document) {
+ myDocuments.remove(file);
+ file.putUserData(HARD_REF_TO_DOCUMENT_KEY, null);
+ document.putUserData(FILE_KEY, null);
+ }
+
private static boolean isBinaryWithDecompiler(@NotNull VirtualFile file) {
final FileType ft = file.getFileType();
return ft.isBinary() && BinaryFileTypeDecompilers.INSTANCE.forFileType(ft) != null;
@@ -609,6 +613,13 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Virt
return;
}
+ if (file.getLength() > FileUtilRt.LARGE_FOR_CONTENT_LOADING) {
+ unbindFileFromDocument(file, document);
+ myUnsavedDocuments.remove(document);
+ myMultiCaster.fileWithNoDocumentChanged(file);
+ return;
+ }
+
final Project project = ProjectLocator.getInstance().guessProjectForFile(file);
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
@Override
@@ -640,7 +651,7 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Virt
public boolean process(final VirtualFile file, final Document document) {
String message = UIBundle.message("file.cache.conflict.message.text", file.getPresentableUrl());
- final DialogBuilder builder = new DialogBuilder((Project)null);
+ final DialogBuilder builder = new DialogBuilder();
builder.setCenterPanel(new JLabel(message, Messages.getQuestionIcon(), SwingConstants.CENTER));
builder.addOkAction().setText(UIBundle.message("file.cache.conflict.load.fs.changes.button"));
builder.addCancelAction().setText(UIBundle.message("file.cache.conflict.keep.memory.changes.button"));
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java
index bab6d2b2fa4f..65adf52041b9 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java
@@ -58,6 +58,7 @@ import com.intellij.openapi.vcs.FileStatusListener;
import com.intellij.openapi.vcs.FileStatusManager;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.wm.IdeFocusManager;
+import com.intellij.openapi.wm.ToolWindowId;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.openapi.wm.ex.StatusBarEx;
@@ -90,6 +91,7 @@ import java.beans.PropertyChangeListener;
import java.lang.ref.WeakReference;
import java.util.*;
import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
/**
* @author Anton Katilin
@@ -106,10 +108,12 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
public static final String FILE_EDITOR_MANAGER = "FileEditorManager";
private volatile JPanel myPanels;
+ private PreviewPanel myPreviewPanel;
private EditorsSplitters mySplitters;
private final Project myProject;
private final List<Pair<VirtualFile, EditorWindow>> mySelectionHistory = new ArrayList<Pair<VirtualFile, EditorWindow>>();
private WeakReference<EditorComposite> myLastSelectedComposite = new WeakReference<EditorComposite>(null);
+ private final AtomicBoolean myPreviewBlocker = new AtomicBoolean(false);
private final MergingUpdateQueue myQueue = new MergingUpdateQueue("FileEditorManagerUpdateQueue", 50, true, null);
@@ -174,7 +178,11 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
}
public Set<EditorsSplitters> getAllSplitters() {
- HashSet<EditorsSplitters> all = new HashSet<EditorsSplitters>();
+ HashSet<EditorsSplitters> all = new LinkedHashSet<EditorsSplitters>();
+ if (Registry.is("editor.use.preview")) {
+ initUI();
+ all.add(myPreviewPanel.getWindow().getOwner());
+ }
all.add(getMainSplitters());
Set<DockContainer> dockContainers = myDockManager.getContainers();
for (DockContainer each : dockContainers) {
@@ -247,6 +255,11 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
}
}
}
+ if (myPreviewPanel == null && Registry.is("editor.use.preview")) {
+ synchronized (myInitLock) {
+ myPreviewPanel = new PreviewPanel(myProject, this, myDockManager);
+ }
+ }
}
private static class MyBorder implements Border {
@@ -595,7 +608,7 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
@NotNull
public Pair<FileEditor[], FileEditorProvider[]> openFileWithProviders(@NotNull final VirtualFile file,
final boolean focusEditor,
- boolean searchForSplitter) {
+ final boolean searchForSplitter) {
if (!file.isValid()) {
throw new IllegalArgumentException("file is not valid: " + file);
}
@@ -628,6 +641,13 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
wndToOpenIn = getSplitters().getCurrentWindow();
}
+ if (wndToOpenIn == null || !wndToOpenIn.isFileOpen(file)) {
+ EditorWindow previewWindow = getPreviewWindow(file, focusEditor, searchForSplitter);
+ if (previewWindow != null) {
+ wndToOpenIn = previewWindow;
+ }
+ }
+
EditorsSplitters splitters = getSplitters();
if (wndToOpenIn == null) {
@@ -638,6 +658,31 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
return openFileImpl2(wndToOpenIn, file, focusEditor);
}
+ @Nullable
+ private EditorWindow getPreviewWindow(@NotNull VirtualFile virtualFile, final boolean focusEditor, final boolean searchForSplitter) {
+ EditorWindow wndToOpenIn = null;
+ if (Registry.is("editor.use.preview") && !myPreviewBlocker.get()) {
+ wndToOpenIn = myPreviewPanel.getWindow();
+ if (virtualFile.equals(myPreviewPanel.getCurrentFile())) return wndToOpenIn;
+ final VirtualFile modifiedFile = myPreviewPanel.closeCurrentFile();
+ ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.PREVIEW).activate(null, false);
+ if (modifiedFile != null) {
+ CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
+ @Override
+ public void run() {
+ myPreviewBlocker.set(true);
+ try {
+ openFileWithProviders(modifiedFile, focusEditor, searchForSplitter);
+ } finally {
+ myPreviewBlocker.set(false);
+ }
+ }
+ }, "", null);
+ }
+ }
+ return wndToOpenIn;
+ }
+
public Pair<FileEditor[], FileEditorProvider[]> openFileInNewWindow(@NotNull VirtualFile file) {
return ((DockManagerImpl)DockManager.getInstance(getProject())).createNewDockContainerFor(file, this);
}
@@ -1610,7 +1655,10 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
return null;
}
- public void runChange(FileEditorManagerChange change, EditorsSplitters splitters) {
+ /**
+ * @param splitters - taken getAllSplitters() value if parameter is null
+ */
+ public void runChange(@NotNull FileEditorManagerChange change, @Nullable EditorsSplitters splitters) {
Set<EditorsSplitters> target = new HashSet<EditorsSplitters>();
if (splitters == null) {
target.addAll(getAllSplitters());
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/PreviewPanel.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/PreviewPanel.java
new file mode 100644
index 000000000000..a9634d5a335a
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/PreviewPanel.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.fileEditor.impl;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.ui.UISettings;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.event.DocumentEvent;
+import com.intellij.openapi.editor.event.DocumentListener;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.fileEditor.FileEditorManagerListener;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.wm.ToolWindowAnchor;
+import com.intellij.openapi.wm.ToolWindowId;
+import com.intellij.openapi.wm.ToolWindowManager;
+import com.intellij.openapi.wm.impl.ToolWindowImpl;
+import com.intellij.ui.JBColor;
+import com.intellij.ui.docking.DockManager;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.ArrayList;
+
+class PreviewPanel extends JPanel implements DocumentListener, FileEditorManagerListener.Before {
+ private static final int HISTORY_LIMIT = 10;
+
+ private final Project myProject;
+ private final FileEditorManagerImpl myManager;
+ private final DockManager myDockManager;
+ private EditorWindow myWindow;
+ private boolean myInitialized = false;
+ private EditorsSplitters myEditorsSplitters;
+ private ArrayList<VirtualFile> myHistory = new ArrayList<VirtualFile>();
+ private VirtualFile myModifiedFile = null;
+ private ToolWindowImpl myToolWindow;
+ private VirtualFile myAwaitingForOpen = null;
+
+ public PreviewPanel(Project project, FileEditorManagerImpl manager, DockManager dockManager) {
+ myProject = project;
+ myManager = manager;
+ myDockManager = dockManager;
+ setOpaque(true);
+ setBackground(JBColor.DARK_GRAY);
+ }
+
+ private void initToolWindowIfNeed() {
+ if (myInitialized) return;
+
+ myToolWindow = (ToolWindowImpl)ToolWindowManager.getInstance(myProject)
+ .registerToolWindow(ToolWindowId.PREVIEW, this, ToolWindowAnchor.RIGHT, myProject, false);
+ myToolWindow.setIcon(AllIcons.Actions.PreviewDetails);
+
+ myEditorsSplitters = new EditorsSplitters(myManager, myDockManager, false) {
+ @Override
+ public void updateFileName(VirtualFile updatedFile) {
+ super.updateFileName(updatedFile);
+ if (updatedFile != null && updatedFile.equals(getCurrentFile())) {
+ updateWindowTitle(updatedFile);
+ }
+ }
+
+ @Override
+ protected void afterFileOpen(VirtualFile file) {
+ if (file.equals(myAwaitingForOpen)) {
+ updateWindowTitle(file);
+ Document document = FileDocumentManager.getInstance().getDocument(file);
+ if (document != null) {
+ myModifiedFile = null;
+ document.addDocumentListener(PreviewPanel.this, myProject);
+ }
+ }
+ myAwaitingForOpen = null;
+ }
+
+ @Override
+ public void setTabsPlacement(int tabPlacement) {
+ super.setTabsPlacement(UISettings.TABS_NONE);
+ }
+
+ @Override
+ protected boolean showEmptyText() {
+ return false;
+ }
+ };
+
+ myProject.getMessageBus().connect().subscribe(FileEditorManagerListener.Before.FILE_EDITOR_MANAGER, this);
+ myEditorsSplitters.createCurrentWindow();
+
+ myWindow = myEditorsSplitters.getCurrentWindow();
+ myWindow.setTabsPlacement(UISettings.TABS_NONE);
+
+ setLayout(new GridLayout(1, 1));
+ add(myEditorsSplitters);
+
+ myToolWindow.setTitleActions(new MoveToEditorTabsAction(), new CloseFileAction());
+
+ myInitialized = true;
+ }
+
+ private void updateWindowTitle(VirtualFile file) {
+ if (myToolWindow == null) return;
+ if (file == null) {
+ myToolWindow.setTitle(": (empty)");
+ }
+ else {
+ myToolWindow.setTitle(": " +
+ StringUtil.getShortened(EditorTabbedContainer.calcTabTitle(myProject, file),
+ UISettings.getInstance().EDITOR_TAB_TITLE_LIMIT));
+ }
+ }
+
+ @Override
+ public void beforeFileOpened(@NotNull FileEditorManager source, @NotNull VirtualFile file) {
+ myAwaitingForOpen = file;
+ }
+
+ @Override
+ public void beforeFileClosed(@NotNull FileEditorManager source, @NotNull VirtualFile file) {
+ if (file.equals(getCurrentFile())) {
+ updateWindowTitle(null);
+ Document document = FileDocumentManager.getInstance().getDocument(file);
+ if (document != null) {
+ document.removeDocumentListener(this);
+ }
+ }
+ }
+
+
+ @Override
+ public void beforeDocumentChange(DocumentEvent event) {
+
+ }
+
+ @Override
+ public void documentChanged(DocumentEvent event) {
+ VirtualFile file = FileDocumentManager.getInstance().getFile(event.getDocument());
+ if (file != null) {
+ myModifiedFile = file;
+ }
+ }
+
+ EditorWindow getWindow() {
+ initToolWindowIfNeed();
+ return myWindow;
+ }
+
+ @Nullable
+ VirtualFile getCurrentFile() {
+ VirtualFile[] files = myWindow.getFiles();
+ return files.length == 1 ? files[0] : null;
+ }
+
+ private class MoveToEditorTabsAction extends AnAction {
+ public MoveToEditorTabsAction() {
+ super(null, "Move to main tabs", AllIcons.Duplicates.SendToTheLeftGrayed);
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ VirtualFile virtualFile = getCurrentFile();
+ if (virtualFile == null) {
+ return;
+ }
+
+ myManager.openFileWithProviders(virtualFile, false, myManager.getCurrentWindow());
+ closeCurrentFile();
+ }
+
+ @Override
+ public void update(AnActionEvent e) {
+ super.update(e);
+ VirtualFile currentFile = getCurrentFile();
+ e.getPresentation().setEnabled(currentFile != null);
+ if (currentFile == null) return;
+
+ if (isModified(currentFile)) {
+ e.getPresentation().setIcon(AllIcons.Duplicates.SendToTheLeft);
+ }
+ else {
+ e.getPresentation().setIcon(AllIcons.Duplicates.SendToTheLeftGrayed);
+ }
+ }
+ }
+
+ private boolean isModified(@NotNull VirtualFile file) {
+ return file.equals(myModifiedFile);
+ }
+
+ //returns last open file if it has "modified" status
+ @Nullable
+ VirtualFile closeCurrentFile() {
+ VirtualFile virtualFile = getCurrentFile();
+ if (virtualFile == null) return null;
+ if (!myHistory.contains(virtualFile)) {
+ myHistory.add(virtualFile);
+ while (myHistory.size() > HISTORY_LIMIT) {
+ myHistory.remove(0);
+ }
+ }
+ myWindow.closeFile(virtualFile);
+ this.revalidate();
+ this.repaint();
+ return isModified(virtualFile) ? virtualFile : null;
+ }
+
+ private class CloseFileAction extends AnAction {
+ public CloseFileAction() {
+ super(null, "Close", AllIcons.Actions.Close);
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ if (getCurrentFile() == null) return;
+ closeCurrentFile();
+ ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.PREVIEW).hide(null);
+ }
+
+ @Override
+ public void update(AnActionEvent e) {
+ super.update(e);
+ e.getPresentation().setEnabled(getCurrentFile() != null);
+ }
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/RemoteFilePanel.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/RemoteFilePanel.java
index b24927b70726..076d29e64bbe 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/RemoteFilePanel.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/RemoteFilePanel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,7 +32,7 @@ import com.intellij.openapi.vfs.impl.http.HttpVirtualFile;
import com.intellij.openapi.vfs.impl.http.RemoteFileInfo;
import com.intellij.openapi.vfs.impl.http.RemoteFileState;
import com.intellij.ui.AppUIUtil;
-import com.intellij.util.net.HTTPProxySettingsDialog;
+import com.intellij.util.net.HttpConfigurable;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.update.MergingUpdateQueue;
import com.intellij.util.ui.update.Update;
@@ -86,22 +86,22 @@ public class RemoteFilePanel {
remoteFileInfo.addDownloadingListener(myDownloadingListener);
myCancelButton.addActionListener(new ActionListener() {
@Override
- public void actionPerformed(final ActionEvent e) {
+ public void actionPerformed(@NotNull final ActionEvent e) {
remoteFileInfo.cancelDownloading();
}
});
myTryAgainButton.addActionListener(new ActionListener() {
@Override
- public void actionPerformed(final ActionEvent e) {
+ public void actionPerformed(@NotNull final ActionEvent e) {
showCard(DOWNLOADING_CARD);
remoteFileInfo.restartDownloading();
}
});
myChangeProxySettingsButton.addActionListener(new ActionListener() {
@Override
- public void actionPerformed(final ActionEvent e) {
- new HTTPProxySettingsDialog().show();
+ public void actionPerformed(@NotNull ActionEvent e) {
+ HttpConfigurable.editConfigurable(myMainPanel);
}
});
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorProvider.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorProvider.java
index 690e7c7d2820..14f0c95ec31b 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorProvider.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorProvider.java
@@ -287,7 +287,7 @@ public class TextEditorProvider implements FileEditorProvider, DumbAware {
new LogicalPosition(caretState.SELECTION_START_LINE, caretState.SELECTION_START_COLUMN),
new LogicalPosition(caretState.SELECTION_END_LINE, caretState.SELECTION_END_COLUMN)));
}
- caretModel.setCaretsAndSelections(states);
+ caretModel.setCaretsAndSelections(states, false);
}
else {
LogicalPosition pos = new LogicalPosition(state.CARETS[0].LINE, state.CARETS[0].COLUMN);
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java
index 198ed907a8d9..837626b53246 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java
@@ -24,6 +24,7 @@ import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.application.impl.TransferToPooledThreadQueue;
import com.intellij.openapi.components.ExportableApplicationComponent;
import com.intellij.openapi.components.RoamingType;
+import com.intellij.openapi.components.StoragePathMacros;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileEditor.impl.LoadTextUtil;
@@ -120,7 +121,7 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements NamedJDOME
private static final String[] FILE_TYPES_WITH_PREDEFINED_EXTENSIONS = {"JSP", "JSPX", "DTD", "HTML", "Properties", "XHTML"};
private final SchemesManager<FileType, AbstractFileType> mySchemesManager;
@NonNls
- private static final String FILE_SPEC = "$ROOT_CONFIG$/filetypes";
+ private static final String FILE_SPEC = StoragePathMacros.ROOT_CONFIG + "/filetypes";
private final ConcurrentBitSet autoDetectWasRun = new ConcurrentBitSet();
private final ConcurrentBitSet autoDetectedAsText = new ConcurrentBitSet();
private final ConcurrentBitSet autoDetectedAsBinary = new ConcurrentBitSet();
diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/KeymapManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/KeymapManagerImpl.java
index 7c65a805ee6c..7c30e4faedec 100644
--- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/KeymapManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/KeymapManagerImpl.java
@@ -67,7 +67,7 @@ public class KeymapManagerImpl extends KeymapManagerEx implements PersistentStat
KeymapManagerImpl(DefaultKeymap defaultKeymap, SchemesManagerFactory factory) {
mySchemesManager = factory.createSchemesManager(
- "$ROOT_CONFIG$/keymaps",
+ StoragePathMacros.ROOT_CONFIG + "/keymaps",
new BaseSchemeProcessor<KeymapImpl>() {
@Override
public KeymapImpl readScheme(@NotNull final Document schemeContent) throws InvalidDataException, IOException, JDOMException {
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/CompositeConfigurable.java b/platform/platform-impl/src/com/intellij/openapi/options/CompositeConfigurable.java
index 0b9e5ade8d29..aaba0fdbaf6b 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/CompositeConfigurable.java
+++ b/platform/platform-impl/src/com/intellij/openapi/options/CompositeConfigurable.java
@@ -20,18 +20,21 @@ import java.util.List;
public abstract class CompositeConfigurable<T extends UnnamedConfigurable> extends BaseConfigurable {
private List<T> myConfigurables;
+ @Override
public void reset() {
for (T configurable : getConfigurables()) {
configurable.reset();
}
}
+ @Override
public void apply() throws ConfigurationException {
for (T configurable : getConfigurables()) {
configurable.apply();
}
}
+ @Override
public boolean isModified() {
for (T configurable : getConfigurables()) {
if (configurable.isModified()) {
@@ -41,6 +44,7 @@ public abstract class CompositeConfigurable<T extends UnnamedConfigurable> exten
return false;
}
+ @Override
public void disposeUIResources() {
if (myConfigurables != null) {
for (final T myConfigurable : myConfigurables) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/SchemesManagerFactoryImpl.java b/platform/platform-impl/src/com/intellij/openapi/options/SchemesManagerFactoryImpl.java
index 323394ad7c94..449a2180e3c1 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/SchemesManagerFactoryImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/options/SchemesManagerFactoryImpl.java
@@ -21,6 +21,7 @@ import com.intellij.openapi.application.impl.ApplicationImpl;
import com.intellij.openapi.components.RoamingType;
import com.intellij.openapi.components.ServiceBean;
import com.intellij.openapi.components.SettingsSavingComponent;
+import com.intellij.openapi.components.impl.stores.IApplicationStore;
import com.intellij.openapi.components.impl.stores.StreamProvider;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.util.containers.ContainerUtil;
@@ -32,21 +33,22 @@ import java.util.Collections;
import java.util.List;
public class SchemesManagerFactoryImpl extends SchemesManagerFactory implements SettingsSavingComponent {
-
- private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.options.SchemesManagerFactoryImpl");
+ private static final Logger LOG = Logger.getInstance(SchemesManagerFactoryImpl.class);
private final List<SchemesManagerImpl> myRegisteredManagers = ContainerUtil.createLockFreeCopyOnWriteList();
@Override
- public <T extends Scheme, E extends ExternalizableScheme> SchemesManager<T, E> createSchemesManager(final String fileSpec,
- final SchemeProcessor<E> processor,
- final RoamingType roamingType) {
+ public <T extends Scheme, E extends ExternalizableScheme> SchemesManager<T, E> createSchemesManager(@NotNull String fileSpec,
+ @NotNull SchemeProcessor<E> processor,
+ @NotNull RoamingType roamingType) {
final Application application = ApplicationManager.getApplication();
- if (!(application instanceof ApplicationImpl)) return null;
- String baseDirPath = ((ApplicationImpl)application).getStateStore().getStateStorageManager().expandMacros(fileSpec);
-
+ if (!(application instanceof ApplicationImpl)) {
+ return null;
+ }
+ IApplicationStore applicationStore = ((ApplicationImpl)application).getStateStore();
+ String baseDirPath = applicationStore.getStateStorageManager().expandMacros(fileSpec);
if (baseDirPath != null) {
- StreamProvider provider = ((ApplicationImpl)ApplicationManager.getApplication()).getStateStore().getStateStorageManager().getStreamProvider();
+ StreamProvider provider = applicationStore.getStateStorageManager().getStreamProvider();
SchemesManagerImpl<T, E> manager = new SchemesManagerImpl<T, E>(fileSpec, processor, roamingType, provider, new File(baseDirPath));
myRegisteredManagers.add(manager);
return manager;
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/SchemesManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/options/SchemesManagerImpl.java
index 1c7e768c7d83..4ff3ebba1ee9 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/SchemesManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/options/SchemesManagerImpl.java
@@ -34,6 +34,7 @@ import com.intellij.openapi.vfs.VirtualFileAdapter;
import com.intellij.openapi.vfs.VirtualFileEvent;
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
import com.intellij.util.Alarm;
+import com.intellij.util.SmartList;
import com.intellij.util.UniqueFileNamesProvider;
import com.intellij.util.containers.HashSet;
import com.intellij.util.text.UniqueNameGenerator;
@@ -51,7 +52,7 @@ import java.io.IOException;
import java.util.*;
public class SchemesManagerImpl<T extends Scheme, E extends ExternalizableScheme> extends AbstractSchemesManager<T, E> {
- private static final Logger LOG = Logger.getInstance("#" + SchemesManagerFactoryImpl.class.getName());
+ private static final Logger LOG = Logger.getInstance(SchemesManagerFactoryImpl.class);
@NonNls private static final String DEFAULT_EXT = ".xml";
@@ -292,12 +293,13 @@ public class SchemesManagerImpl<T extends Scheme, E extends ExternalizableScheme
}
}
+ @NotNull
private Collection<E> readSchemesFromProviders() {
- Collection<E> result = new ArrayList<E>();
if (myProvider == null || !myProvider.isEnabled()) {
- return result;
+ return Collections.emptyList();
}
+ Collection<E> result = new SmartList<E>();
for (String subPath : myProvider.listSubFiles(myFileSpec, myRoamingType)) {
if (!subPath.equals(DELETED_XML)) {
try {
@@ -305,6 +307,7 @@ public class SchemesManagerImpl<T extends Scheme, E extends ExternalizableScheme
if (subDocument != null) {
E scheme = readScheme(subDocument);
boolean fileRenamed = false;
+ assert scheme != null;
T existing = findSchemeByName(scheme.getName());
if (existing != null && existing instanceof ExternalizableScheme) {
String currentFileName = ((ExternalizableScheme)existing).getExternalInfo().getCurrentFileName();
@@ -315,7 +318,6 @@ public class SchemesManagerImpl<T extends Scheme, E extends ExternalizableScheme
}
}
String fileName = checkFileNameIsFree(subPath, scheme.getName());
-
if (!fileRenamed && !fileName.equals(subPath)) {
deleteServerFiles(subPath);
}
@@ -325,7 +327,7 @@ public class SchemesManagerImpl<T extends Scheme, E extends ExternalizableScheme
}
}
catch (Exception e) {
- LOG.info("Cannot load data from IDEAServer: " + e.getLocalizedMessage());
+ LOG.info("Cannot load data from stream provider: " + e.getLocalizedMessage());
}
}
}
@@ -347,21 +349,22 @@ public class SchemesManagerImpl<T extends Scheme, E extends ExternalizableScheme
});
}
- private String checkFileNameIsFree(final String subPath, final String schemeName) {
+ @NotNull
+ private String checkFileNameIsFree(@NotNull String subPath, @NotNull String schemeName) {
for (Scheme scheme : mySchemes) {
if (scheme instanceof ExternalizableScheme) {
- ExternalInfo externalInfo = ((ExternalizableScheme)scheme).getExternalInfo();
- String name = externalInfo.getCurrentFileName();
- if (name != null) {
- String fileName = name + mySchemeExtension;
- if (fileName.equals(subPath) && !Comparing.equal(schemeName, scheme.getName())) {
- return createUniqueFileName(collectAllFileNames(), UniqueFileNamesProvider.convertName(schemeName));
+ String name = ((ExternalizableScheme)scheme).getExternalInfo().getCurrentFileName();
+ if (name != null &&
+ !schemeName.equals(scheme.getName()) &&
+ subPath.length() == (name.length() + mySchemeExtension.length()) &&
+ subPath.startsWith(name) &&
+ subPath.endsWith(mySchemeExtension)) {
+ return UniqueNameGenerator.generateUniqueName(UniqueFileNamesProvider.convertName(schemeName), collectAllFileNames());
/*VirtualFile oldFile = myVFSBaseDir.findChild(subPath);
if (oldFile != null) {
oldFile.copy(this, myVFSBaseDir, uniqueFileName + EXT);
}
externalInfo.setCurrentFileName(uniqueFileName);*/
- }
}
}
}
@@ -369,8 +372,9 @@ public class SchemesManagerImpl<T extends Scheme, E extends ExternalizableScheme
return subPath;
}
+ @NotNull
private Collection<String> collectAllFileNames() {
- HashSet<String> result = new HashSet<String>();
+ Set<String> result = new THashSet<String>();
for (T scheme : mySchemes) {
if (scheme instanceof ExternalizableScheme) {
ExternalInfo externalInfo = ((ExternalizableScheme)scheme).getExternalInfo();
@@ -382,10 +386,6 @@ public class SchemesManagerImpl<T extends Scheme, E extends ExternalizableScheme
return result;
}
- private static String createUniqueFileName(final Collection<String> strings, final String schemeName) {
- return UniqueNameGenerator.generateUniqueName(schemeName, strings);
- }
-
private void loadScheme(final E scheme, boolean forceAdd, final String name) {
if (scheme != null && (!myDeletedNames.contains(scheme.getName()) || forceAdd)) {
T existing = findSchemeByName(scheme.getName());
@@ -469,13 +469,6 @@ public class SchemesManagerImpl<T extends Scheme, E extends ExternalizableScheme
}
final E scheme = readScheme(document);
if (scheme != null) {
- if (scheme.getName() == null) {
- String suggestedName = FileUtil.getNameWithoutExtension(file.getName());
- if (!"_".equals(suggestedName)) {
- scheme.setName(suggestedName);
- }
- }
-
loadScheme(scheme, forceAdd, file.getName());
result.add(scheme);
}
@@ -653,8 +646,7 @@ public class SchemesManagerImpl<T extends Scheme, E extends ExternalizableScheme
result = new SharedSchemeData(original, name, user, description);
}
else {
- Document original = subDocument;
- result = new SharedSchemeData(original, name, null, null);
+ result = new SharedSchemeData(subDocument, name, null, null);
}
return result;
}
@@ -673,8 +665,8 @@ public class SchemesManagerImpl<T extends Scheme, E extends ExternalizableScheme
return false;
}
- private String getFileFullPath(final String subPath) {
- return myFileSpec + "/" + subPath;
+ private String getFileFullPath(@NotNull String subPath) {
+ return myFileSpec + '/' + subPath;
}
@Override
@@ -843,9 +835,9 @@ public class SchemesManagerImpl<T extends Scheme, E extends ExternalizableScheme
deleteServerFiles(fileName);
}
- private void deleteServerFiles(final String fileName) {
+ private void deleteServerFiles(@NotNull String path) {
if (myProvider != null && myProvider.isEnabled()) {
- StorageUtil.deleteContent(myProvider, getFileFullPath(fileName), myRoamingType);
+ StorageUtil.delete(myProvider, getFileFullPath(path), myRoamingType);
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableWrapper.java b/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableWrapper.java
index 5f8dc0e890df..3b67a3478368 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableWrapper.java
+++ b/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableWrapper.java
@@ -165,10 +165,6 @@ public class ConfigurableWrapper implements SearchableConfigurable {
return myEp;
}
- public String getGroupId() {
- return myEp.groupId;
- }
-
public String getParentId() {
return myEp.parentId;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ex/GlassPanel.java b/platform/platform-impl/src/com/intellij/openapi/options/ex/GlassPanel.java
index 96cc9e451185..c80a222ffd96 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/ex/GlassPanel.java
+++ b/platform/platform-impl/src/com/intellij/openapi/options/ex/GlassPanel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +17,10 @@
package com.intellij.openapi.options.ex;
import com.intellij.ide.ui.search.SearchUtil;
+import com.intellij.openapi.ui.GraphicsConfig;
+import com.intellij.ui.ColorUtil;
import com.intellij.ui.components.JBTabbedPane;
+import com.intellij.util.ui.GraphicsUtil;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.Nullable;
@@ -27,6 +30,7 @@ import java.awt.geom.Area;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.Kernel;
+import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
@@ -64,17 +68,19 @@ public class GlassPanel extends JComponent {
final Point leftPoint = SwingUtilities.convertPoint(myPanel, new Point(visibleRect.x, visibleRect.y), surfaceComponent);
Area innerPanel = new Area(new Rectangle2D.Double(leftPoint.x, leftPoint.y, visibleRect.width, visibleRect.height));
Area mask = new Area(screen);
-
+ ArrayList<JComponent> components = new ArrayList<JComponent>();
for (JComponent lightComponent : myLightComponents) {
- final Area area = getComponentArea(surfaceComponent, lightComponent);
+ final Area area = getComponentArea(surfaceComponent, lightComponent, 1);
if (area == null) continue;
+ components.add(lightComponent);
if (lightComponent instanceof JLabel) {
final JLabel label = (JLabel)lightComponent;
final Component labelFor = label.getLabelFor();
if (labelFor instanceof JComponent) {
- final Area labelForArea = getComponentArea(surfaceComponent, (JComponent)labelFor);
+ final Area labelForArea = getComponentArea(surfaceComponent, (JComponent)labelFor, 1);
if (labelForArea != null) {
+ components.add((JComponent)labelFor);
area.add(labelForArea);
}
}
@@ -86,19 +92,32 @@ public class GlassPanel extends JComponent {
Graphics2D g2 = (Graphics2D)g;
- Color shieldColor = new Color(0.0f, 0.0f, 0.0f, 0.15f);
+ Color shieldColor = new Color(0.0f, 0.0f, 0.0f, 0.20f);
Color boundsColor = Color.gray;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(shieldColor);
g2.fill(mask);
- g2.setColor(boundsColor);
- g2.draw(mask);
+ g2.setColor(ColorUtil.toAlpha(Color.orange, 25));
+ GraphicsConfig config = GraphicsUtil.setupAAPainting(g2);
+ for (int i = 2; i > 0; i--) {
+ g2.setStroke(new BasicStroke(i));
+ Area arrr = new Area();
+ for (JComponent component : components) {
+ Area area = getComponentArea(surfaceComponent, component, i-1);
+ if (area != null) {
+ arrr.add(area);
+ }
+ }
+ g2.draw(arrr);
+ }
+
+ config.restore();
}
}
@Nullable
- private Area getComponentArea(final JComponent surfaceComponent, final JComponent lightComponent) {
+ private Area getComponentArea(final JComponent surfaceComponent, final JComponent lightComponent, int offset) {
if (!lightComponent.isShowing()) return null;
final Point panelPoint = SwingUtilities.convertPoint(lightComponent, new Point(0, 0), surfaceComponent);
@@ -115,12 +134,17 @@ public class GlassPanel extends JComponent {
int hInset = isWithBorder ? 7 : isLabelFromTabbedPane ? 20 : 7;
int vInset = isWithBorder ? 1 : isLabelFromTabbedPane ? 10 : 5;
- final Area area = new Area(new RoundRectangle2D.Double(x - hInset + insetsToIgnore.left,
- y - vInset + insetsToIgnore.top,
- lightComponent.getWidth() + hInset * 2 - insetsToIgnore.right - insetsToIgnore.left,
- lightComponent.getHeight() + vInset * 2 - insetsToIgnore.top - insetsToIgnore.bottom,
- 6, 6));
- return area;
+ hInset += offset;
+ vInset += offset;
+ int xCoord = x - hInset + insetsToIgnore.left;
+ int yCoord = y - vInset + insetsToIgnore.top;
+ int width = lightComponent.getWidth() + hInset * 2 - insetsToIgnore.right - insetsToIgnore.left;
+ int height = lightComponent.getHeight() + vInset * 2 - insetsToIgnore.top - insetsToIgnore.bottom;
+ return new Area(new RoundRectangle2D.Double(xCoord,
+ yCoord,
+ width,
+ height,
+ Math.min(height, 30), Math.min(height, 30)));
}
protected static Kernel getBlurKernel(int blurSize) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ex/MixedConfigurableGroup.java b/platform/platform-impl/src/com/intellij/openapi/options/ex/MixedConfigurableGroup.java
index f1411cf3551d..e3404ec017cd 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/ex/MixedConfigurableGroup.java
+++ b/platform/platform-impl/src/com/intellij/openapi/options/ex/MixedConfigurableGroup.java
@@ -17,15 +17,21 @@ package com.intellij.openapi.options.ex;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurableGroup;
+import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.OptionsBundle;
import com.intellij.openapi.options.SearchableConfigurable;
+import com.intellij.openapi.util.text.StringUtil;
+import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
+import javax.swing.JComponent;
-public final class MixedConfigurableGroup implements ConfigurableGroup {
+public final class MixedConfigurableGroup implements SearchableConfigurable, ConfigurableGroup {
private final String myGroupId;
private Configurable[] myConfigurables;
@@ -34,6 +40,7 @@ public final class MixedConfigurableGroup implements ConfigurableGroup {
myConfigurables = (configurables != null)
? configurables.toArray(new Configurable[configurables.size()])
: new Configurable[0];
+ Arrays.sort(myConfigurables, COMPARATOR);
}
private MixedConfigurableGroup(String groupId, HashMap<String, ArrayList<Configurable>> configurables) {
@@ -41,6 +48,45 @@ public final class MixedConfigurableGroup implements ConfigurableGroup {
}
@Override
+ public JComponent createComponent() {
+ return null;
+ }
+
+ @Override
+ public boolean isModified() {
+ return false;
+ }
+
+ @Override
+ public void apply() throws ConfigurationException {
+ }
+
+ @Override
+ public void reset() {
+ }
+
+ @Override
+ public void disposeUIResources() {
+ myConfigurables = null;
+ }
+
+ @Override
+ public Runnable enableSearch(String option) {
+ return null;
+ }
+
+ @NotNull
+ @Override
+ public String getId() {
+ return "configurable.group." + myGroupId;
+ }
+
+ @Override
+ public String getHelpTopic() {
+ return "configurable.group." + myGroupId + ".help.topic";
+ }
+
+ @Override
public String getDisplayName() {
return OptionsBundle.message("configurable.group." + myGroupId + ".settings.display.name");
}
@@ -60,7 +106,7 @@ public final class MixedConfigurableGroup implements ConfigurableGroup {
for (Configurable configurable : configurables) {
String groupId = null;
if (configurable instanceof ConfigurableWrapper) {
- groupId = ((ConfigurableWrapper)configurable).getGroupId();
+ groupId = ((ConfigurableWrapper)configurable).getExtensionPoint().groupId;
}
ArrayList<Configurable> list = map.get(groupId);
if (list == null) {
@@ -70,7 +116,7 @@ public final class MixedConfigurableGroup implements ConfigurableGroup {
}
ArrayList<Configurable> buildList = map.get("build");
if (buildList != null) {
- NodeConfigurable buildTools = new NodeConfigurable("build.tools");
+ NodeConfigurable buildTools = new NodeConfigurable("build.tools", 1000);
buildTools.add(find("MavenSettings", buildList.iterator()));
buildTools.add(find("reference.settingsdialog.project.gradle", buildList.iterator()));
buildTools.add(find("reference.settingsdialog.project.gant", buildList.iterator()));
@@ -106,4 +152,27 @@ public final class MixedConfigurableGroup implements ConfigurableGroup {
}
return null;
}
+
+ public static int getGroupWeight(Configurable configurable) {
+ if (configurable instanceof NodeConfigurable) {
+ return ((NodeConfigurable)configurable).getGroupWeight();
+ }
+ if (configurable instanceof ConfigurableWrapper) {
+ return ((ConfigurableWrapper)configurable).getExtensionPoint().groupWeight;
+ }
+ return 0;
+ }
+
+ private static final Comparator<Configurable> COMPARATOR = new Comparator<Configurable>() {
+ @Override
+ public int compare(Configurable configurable1, Configurable configurable2) {
+ if (configurable1 == null || configurable2 == null) {
+ return configurable2 != null ? -1 : configurable1 != null ? 1 : 0;
+ }
+ int weight1 = getGroupWeight(configurable1);
+ int weight2 = getGroupWeight(configurable2);
+ return weight1 > weight2 ? -1 : weight1 < weight2 ? 1 : StringUtil.naturalCompare(configurable1.getDisplayName(),
+ configurable2.getDisplayName());
+ }
+ };
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ex/NodeConfigurable.java b/platform/platform-impl/src/com/intellij/openapi/options/ex/NodeConfigurable.java
index 6571c7a63746..609943d02943 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/ex/NodeConfigurable.java
+++ b/platform/platform-impl/src/com/intellij/openapi/options/ex/NodeConfigurable.java
@@ -27,9 +27,15 @@ import java.util.ArrayList;
public final class NodeConfigurable extends SearchableConfigurable.Parent.Abstract {
private final ArrayList<Configurable> myConfigurables = new ArrayList<Configurable>();
private final String myId;
+ private final int myWeight;
- public NodeConfigurable(@NotNull String id) {
+ public NodeConfigurable(@NotNull String id, int weight) {
myId = id;
+ myWeight = weight;
+ }
+
+ public int getGroupWeight() {
+ return myWeight;
}
public void add(Configurable configurable) {
@@ -48,13 +54,13 @@ public final class NodeConfigurable extends SearchableConfigurable.Parent.Abstra
@NotNull
@Override
public String getId() {
- return myId;
+ return "node.configurable." + myId;
}
@Nullable
@Override
public String getHelpTopic() {
- return myId;
+ return "node.configurable." + myId + ".help.topic";
}
@Nls
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ex/SingleConfigurableEditor.java b/platform/platform-impl/src/com/intellij/openapi/options/ex/SingleConfigurableEditor.java
index 80144d230eaf..def0dd16a2d2 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/ex/SingleConfigurableEditor.java
+++ b/platform/platform-impl/src/com/intellij/openapi/options/ex/SingleConfigurableEditor.java
@@ -46,7 +46,7 @@ public class SingleConfigurableEditor extends DialogWrapper {
private Component myParentComponent;
private Configurable myConfigurable;
private JComponent myCenterPanel;
- private String myDimensionKey;
+ private final String myDimensionKey;
private final boolean myShowApplyButton;
private boolean myChangesWereApplied;
@@ -134,6 +134,7 @@ public class SingleConfigurableEditor extends DialogWrapper {
return displayName.replaceAll("\n", " ");
}
+ @Override
protected String getDimensionServiceKey() {
if (myDimensionKey == null) {
return super.getDimensionServiceKey();
@@ -143,6 +144,7 @@ public class SingleConfigurableEditor extends DialogWrapper {
}
}
+ @Override
@NotNull
protected Action[] createActions() {
List<Action> actions = new ArrayList<Action>();
@@ -157,6 +159,7 @@ public class SingleConfigurableEditor extends DialogWrapper {
return actions.toArray(new Action[actions.size()]);
}
+ @Override
protected void doHelpAction() {
HelpManager.getInstance().invokeHelp(myConfigurable.getHelpTopic());
}
@@ -169,6 +172,7 @@ public class SingleConfigurableEditor extends DialogWrapper {
super.doCancelAction();
}
+ @Override
protected void doOKAction() {
try {
if (myConfigurable.isModified()) myConfigurable.apply();
@@ -201,10 +205,11 @@ public class SingleConfigurableEditor extends DialogWrapper {
public ApplyAction() {
super(CommonBundle.getApplyButtonText());
final Runnable updateRequest = new Runnable() {
+ @Override
public void run() {
- if (!SingleConfigurableEditor.this.isShowing()) return;
+ if (!isShowing()) return;
try {
- ApplyAction.this.setEnabled(myConfigurable != null && myConfigurable.isModified());
+ setEnabled(myConfigurable != null && myConfigurable.isModified());
}
catch (IndexNotReadyException ignored) {
}
@@ -214,6 +219,7 @@ public class SingleConfigurableEditor extends DialogWrapper {
// invokeLater necessary to make sure dialog is already shown so we calculate modality state correctly.
SwingUtilities.invokeLater(new Runnable() {
+ @Override
public void run() {
addUpdateRequest(updateRequest);
}
@@ -224,6 +230,7 @@ public class SingleConfigurableEditor extends DialogWrapper {
myUpdateAlarm.addRequest(updateRequest, 500, ModalityState.stateForComponent(getWindow()));
}
+ @Override
public void actionPerformed(ActionEvent event) {
if (myPerformAction) return;
try {
@@ -248,11 +255,13 @@ public class SingleConfigurableEditor extends DialogWrapper {
}
}
+ @Override
protected JComponent createCenterPanel() {
myCenterPanel = myConfigurable.createComponent();
return myCenterPanel;
}
+ @Override
public JComponent getPreferredFocusedComponent() {
if (myConfigurable instanceof BaseConfigurable) {
JComponent preferred = ((BaseConfigurable)myConfigurable).getPreferredFocusedComponent();
@@ -261,6 +270,7 @@ public class SingleConfigurableEditor extends DialogWrapper {
return IdeFocusTraversalPolicy.getPreferredFocusedComponent(myCenterPanel);
}
+ @Override
public void dispose() {
super.dispose();
myConfigurable.disposeUIResources();
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/IdeSettingsDialog.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/IdeSettingsDialog.java
new file mode 100644
index 000000000000..c38bf6ff2033
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/IdeSettingsDialog.java
@@ -0,0 +1,330 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.options.newEditor;
+
+import com.intellij.CommonBundle;
+import com.intellij.ide.ui.search.SearchUtil;
+import com.intellij.ide.util.PropertiesComponent;
+import com.intellij.openapi.actionSystem.DataProvider;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.help.HelpManager;
+import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.options.ConfigurableGroup;
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.options.SearchableConfigurable;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.util.ActionCallback;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.ui.Gray;
+import com.intellij.ui.IdeBorderFactory;
+import com.intellij.ui.JBColor;
+import com.intellij.ui.border.CustomLineBorder;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import javax.swing.border.Border;
+import javax.swing.border.CompoundBorder;
+import javax.swing.border.EmptyBorder;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public class IdeSettingsDialog extends DialogWrapper implements DataProvider {
+ private Project myProject;
+ private ConfigurableGroup[] myGroups;
+ private Configurable myPreselected;
+ private OptionsEditor myEditor;
+
+ private ApplyAction myApplyAction;
+ public static final String DIMENSION_KEY = "OptionsEditor";
+ @NonNls static final String LAST_SELECTED_CONFIGURABLE = "options.lastSelected";
+
+ /**
+ * This constructor should be eliminated after the new modality approach
+ * will have been checked. See a {@code Registry} key ide.perProjectModality
+ *
+ * @deprecated
+ */
+ public IdeSettingsDialog(Project project, ConfigurableGroup[] groups,
+ @Nullable Configurable preselectedConfigurable, boolean applicationModalIfPossible) {
+ super(project, true, applicationModalIfPossible);
+ init(project, groups, preselectedConfigurable != null ? preselectedConfigurable : findLastSavedConfigurable(groups, project));
+ }
+
+ /**
+ * This constructor should be eliminated after the new modality approach
+ * will have been checked. See a {@code Registry} key ide.perProjectModality
+ *
+ * @deprecated
+ */
+ public IdeSettingsDialog(Project project, ConfigurableGroup[] groups,
+ @NotNull String preselectedConfigurableDisplayName, boolean applicationModalIfPossible) {
+ super(project, true, applicationModalIfPossible);
+ init(project, groups, getPreselectedByDisplayName(groups, preselectedConfigurableDisplayName, project));
+ }
+
+ public IdeSettingsDialog(Project project, ConfigurableGroup[] groups, @Nullable Configurable preselectedConfigurable) {
+ super(project, true);
+ init(project, groups, preselectedConfigurable != null ? preselectedConfigurable : findLastSavedConfigurable(groups, project));
+ }
+
+ public IdeSettingsDialog(Project project, ConfigurableGroup[] groups, @NotNull String preselectedConfigurableDisplayName) {
+ super(project, true);
+ init(project, groups, getPreselectedByDisplayName(groups, preselectedConfigurableDisplayName, project));
+ }
+
+ @Nullable
+ @Override
+ protected Border createContentPaneBorder() {
+ return IdeBorderFactory.createEmptyBorder(0);
+ }
+
+ private void init(final Project project, final ConfigurableGroup[] groups, @Nullable final Configurable preselected) {
+ myProject = project;
+ myGroups = groups;
+ myPreselected = preselected;
+
+ setTitle(CommonBundle.settingsTitle());
+
+ init();
+ }
+
+ @Nullable
+ private static Configurable getPreselectedByDisplayName(final ConfigurableGroup[] groups, final String preselectedConfigurableDisplayName,
+ final Project project) {
+ Configurable result = findPreselectedByDisplayName(preselectedConfigurableDisplayName, groups);
+
+ return result == null ? findLastSavedConfigurable(groups, project) : result;
+ }
+
+ @Override
+ public boolean isTypeAheadEnabled() {
+ return true;
+ }
+
+ @Nullable
+ @Override
+ protected JComponent createSouthPanel() {
+ final JComponent panel = super.createSouthPanel();
+ CustomLineBorder line = new CustomLineBorder(new JBColor(Gray._153.withAlpha(128), Gray._100.withAlpha(128)), 1, 0, 0, 0);
+ panel.setBorder(new CompoundBorder(line, new EmptyBorder(8, 12, 8, 12)));
+ return panel;
+ }
+
+ protected JComponent createCenterPanel() {
+ myEditor = new OptionsEditor(myProject, myGroups, myPreselected);
+ myEditor.getContext().addColleague(new OptionsEditorColleague.Adapter() {
+ @Override
+ public ActionCallback onModifiedAdded(final Configurable configurable) {
+ updateStatus();
+ return new ActionCallback.Done();
+ }
+
+ @Override
+ public ActionCallback onModifiedRemoved(final Configurable configurable) {
+ updateStatus();
+ return new ActionCallback.Done();
+ }
+
+ @Override
+ public ActionCallback onErrorsChanged() {
+ updateStatus();
+ return new ActionCallback.Done();
+ }
+ });
+ Disposer.register(myDisposable, myEditor);
+ return myEditor;
+ }
+
+ public boolean updateStatus() {
+ myApplyAction.setEnabled(myEditor.canApply());
+
+ final Map<Configurable, ConfigurationException> errors = myEditor.getContext().getErrors();
+ if (errors.size() == 0) {
+ setErrorText(null);
+ }
+ else {
+ String text = "Changes were not applied because of an error";
+
+ final String errorMessage = getErrorMessage(errors);
+ if (errorMessage != null) {
+ text += "<br>" + errorMessage;
+ }
+
+ setErrorText(text);
+ }
+
+ return errors.size() == 0;
+ }
+
+ @Nullable
+ private static String getErrorMessage(final Map<Configurable, ConfigurationException> errors) {
+ final Collection<ConfigurationException> values = errors.values();
+ final ConfigurationException[] exceptions = values.toArray(new ConfigurationException[values.size()]);
+ if (exceptions.length > 0) {
+ return exceptions[0].getMessage();
+ }
+ return null;
+ }
+
+ @Override
+ protected String getDimensionServiceKey() {
+ return DIMENSION_KEY;
+ }
+
+ @Override
+ protected void doOKAction() {
+ myEditor.flushModifications();
+
+ if (myEditor.canApply()) {
+ myEditor.apply();
+ if (!updateStatus()) return;
+ }
+
+ saveCurrentConfigurable();
+
+ ApplicationManager.getApplication().saveAll();
+
+ super.doOKAction();
+ }
+
+
+ private void saveCurrentConfigurable() {
+ final Configurable current = myEditor.getContext().getCurrentConfigurable();
+ if (current == null) return;
+
+ final PropertiesComponent props = PropertiesComponent.getInstance(myProject);
+
+ if (current instanceof SearchableConfigurable) {
+ props.setValue(LAST_SELECTED_CONFIGURABLE, ((SearchableConfigurable)current).getId());
+ }
+ else {
+ props.setValue(LAST_SELECTED_CONFIGURABLE, current.getClass().getName());
+ }
+ }
+
+ @Nullable
+ private static Configurable findLastSavedConfigurable(ConfigurableGroup[] groups, final Project project) {
+ final String id = PropertiesComponent.getInstance(project).getValue(LAST_SELECTED_CONFIGURABLE);
+ if (id == null) return null;
+
+ return findConfigurableInGroups(id, groups);
+ }
+
+ @Nullable
+ private static Configurable findConfigurableInGroups(String id, Configurable.Composite... groups) {
+ // avoid unnecessary group expand: check top-level configurables in all groups before looking at children
+ for (Configurable.Composite group : groups) {
+ final Configurable[] configurables = group.getConfigurables();
+ for (Configurable c : configurables) {
+ if (c instanceof SearchableConfigurable && id.equals(((SearchableConfigurable)c).getId())) {
+ return c;
+ }
+ else if (id.equals(c.getClass().getName())) {
+ return c;
+ }
+ }
+ }
+ for (Configurable.Composite group : groups) {
+ final Configurable[] configurables = group.getConfigurables();
+ for (Configurable c : configurables) {
+ if (c instanceof Configurable.Composite) {
+ Configurable result = findConfigurableInGroups(id, (Configurable.Composite)c);
+ if (result != null) {
+ return result;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ @Nullable
+ private static Configurable findPreselectedByDisplayName(final String preselectedConfigurableDisplayName, ConfigurableGroup[] groups) {
+ final List<Configurable> all = SearchUtil.expand(groups);
+ for (Configurable each : all) {
+ if (preselectedConfigurableDisplayName.equals(each.getDisplayName())) return each;
+ }
+ return null;
+ }
+
+ @Override
+ public void doCancelAction(final AWTEvent source) {
+ if (source instanceof KeyEvent || source instanceof ActionEvent) {
+ if (myEditor.getContext().isHoldingFilter()) {
+ myEditor.clearFilter();
+ return;
+ }
+ }
+
+ super.doCancelAction(source);
+ }
+
+ @Override
+ public void doCancelAction() {
+ saveCurrentConfigurable();
+ super.doCancelAction();
+ }
+
+ @NotNull
+ @Override
+ protected Action[] createActions() {
+ myApplyAction = new ApplyAction();
+ return new Action[]{getOKAction(), getCancelAction(), myApplyAction, getHelpAction()};
+ }
+
+ @Override
+ protected void doHelpAction() {
+ final String topic = myEditor.getHelpTopic();
+ if (topic != null) {
+ HelpManager.getInstance().invokeHelp(topic);
+ }
+ }
+
+ @Override
+ public JComponent getPreferredFocusedComponent() {
+ return myEditor.getPreferredFocusedComponent();
+ }
+
+ public Object getData(@NonNls String dataId) {
+ if (OptionsEditor.KEY.is(dataId)) {
+ return myEditor;
+ }
+ return null;
+ }
+
+ private class ApplyAction extends AbstractAction {
+ public ApplyAction() {
+ super(CommonBundle.getApplyButtonText());
+ setEnabled(false);
+ }
+
+ public void actionPerformed(final ActionEvent e) {
+ myEditor.apply();
+ myEditor.revalidate();
+ myEditor.repaint();
+ }
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditor.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditor.java
index 271539f038a0..c2119596a06e 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditor.java
+++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditor.java
@@ -15,9 +15,12 @@
*/
package com.intellij.openapi.options.newEditor;
-import com.intellij.ide.ui.search.ConfigurableHit;
+import com.intellij.AbstractBundle;
+import com.intellij.CommonBundle;
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.ui.laf.darcula.ui.DarculaTextBorder;
+import com.intellij.ide.ui.laf.darcula.ui.DarculaTextFieldUI;
import com.intellij.ide.ui.search.SearchUtil;
-import com.intellij.ide.ui.search.SearchableOptionsRegistrar;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.internal.statistic.UsageTrigger;
import com.intellij.internal.statistic.beans.ConvertUsagesUtil;
@@ -36,18 +39,18 @@ import com.intellij.openapi.ui.*;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.EdtRunnable;
+import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.registry.Registry;
-import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.IdeGlassPaneUtil;
-import com.intellij.ui.DocumentAdapter;
import com.intellij.ui.LightColors;
+import com.intellij.ui.OnePixelSplitter;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.SearchTextField;
+import com.intellij.ui.components.labels.LinkLabel;
import com.intellij.ui.components.panels.NonOpaquePanel;
import com.intellij.ui.components.panels.Wrapper;
import com.intellij.ui.navigation.History;
import com.intellij.ui.navigation.Place;
-import com.intellij.ui.speedSearch.ElementFilter;
import com.intellij.ui.treeStructure.SimpleNode;
import com.intellij.ui.treeStructure.filtered.FilteringTreeBuilder;
import com.intellij.util.ui.UIUtil;
@@ -61,7 +64,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
-import javax.swing.event.DocumentEvent;
+import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
@@ -77,23 +80,18 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
@NonNls private static final String MAIN_SPLITTER_PROPORTION = "options.splitter.main.proportions";
@NonNls private static final String DETAILS_SPLITTER_PROPORTION = "options.splitter.details.proportions";
- @NonNls private static final String SEARCH_VISIBLE = "options.searchVisible";
-
@NonNls private static final String NOT_A_NEW_COMPONENT = "component.was.already.instantiated";
- private final Project myProject;
-
- private final OptionsEditorContext myContext;
-
private final History myHistory = new History(this);
private final OptionsTree myTree;
private final SettingsTreeView myTreeView;
- private final MySearchField mySearch;
+ private final SearchTextField mySearch;
private final Splitter myMainSplitter;
//[back/forward] JComponent myToolbarComponent;
- private final DetailsComponent myOwnDetails = new DetailsComponent().setEmptyContentText("Select configuration element in the tree to edit its settings");
+ private final DetailsComponent myOwnDetails =
+ new DetailsComponent().setEmptyContentText("Select configuration element in the tree to edit its settings");
private final ContentWrapper myContentWrapper = new ContentWrapper();
@@ -101,30 +99,54 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
private final Map<Configurable, ActionCallback> myConfigurable2LoadCallback = new HashMap<Configurable, ActionCallback>();
private final MergingUpdateQueue myModificationChecker;
- private final ConfigurableGroup[] myGroups;
private final SpotlightPainter mySpotlightPainter = new SpotlightPainter();
private final MergingUpdateQueue mySpotlightUpdate;
private final LoadingDecorator myLoadingDecorator;
- private final Filter myFilter;
+ private final SettingsFilter myFilter;
private final Wrapper mySearchWrapper = new Wrapper();
private final JPanel myLeftSide;
- private boolean myFilterDocumentWasChanged;
//[back/forward] private ActionToolbar myToolbar;
private Window myWindow;
private final PropertiesComponent myProperties;
private volatile boolean myDisposed;
+ private final KeyListener myTreeKeyListener = new KeyListener() {
+ @Override
+ public void keyPressed(KeyEvent event) {
+ keyTyped(event);
+ }
+
+ @Override
+ public void keyReleased(KeyEvent event) {
+ keyTyped(event);
+ }
+
+ @Override
+ public void keyTyped(KeyEvent event) {
+ Object source = event.getSource();
+ if (source instanceof JTree) {
+ JTree tree = (JTree)source;
+ if (tree.getInputMap().get(KeyStroke.getKeyStrokeForEvent(event)) == null) {
+ myFilter.myDocumentWasChanged = false;
+ try {
+ mySearch.keyEventToTextField(event);
+ }
+ finally {
+ if (myFilter.myDocumentWasChanged && !isFilterFieldVisible()) {
+ setFilterFieldVisible(true, false, false);
+ }
+ }
+ }
+ }
+ }
+ };
+
public OptionsEditor(Project project, ConfigurableGroup[] groups, Configurable preselectedConfigurable) {
- myProject = project;
- myGroups = groups;
myProperties = PropertiesComponent.getInstance(project);
- myFilter = new Filter();
- myContext = new OptionsEditorContext(myFilter);
-
mySearch = new MySearchField() {
@Override
protected void onTextKeyEvent(final KeyEvent e) {
@@ -137,67 +159,53 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
}
};
- mySearch.getTextEditor().addMouseListener(new MouseAdapter() {
- @Override
- public void mousePressed(MouseEvent e) {
- boolean hasText = mySearch.getText().length() > 0;
- if (!myContext.isHoldingFilter() && hasText) {
- myFilter.reenable();
- }
-
- if (!isSearchFieldFocused() && hasText) {
- mySearch.selectText();
- }
- }
- });
-
- final KeyListener listener = new KeyListener() {
+ myFilter = new SettingsFilter(project, groups, mySearch) {
@Override
- public void keyTyped(KeyEvent event) {
- myFilterDocumentWasChanged = false;
- try {
- mySearch.keyEventToTextField(event);
- }
- finally {
- if (myFilterDocumentWasChanged && !isFilterFieldVisible()) {
- setFilterFieldVisible(true, false, false);
- }
+ Configurable getConfigurable(SimpleNode node) {
+ if (node instanceof OptionsTree.EditorNode) {
+ return ((OptionsTree.EditorNode)node).getConfigurable();
}
+ return SettingsTreeView.getConfigurable(node);
}
@Override
- public void keyPressed(KeyEvent event) {
- keyTyped(event);
+ SimpleNode findNode(Configurable configurable) {
+ return myTreeView != null
+ ? myTreeView.findNode(configurable)
+ : myTree.findNodeFor(configurable);
}
@Override
- public void keyReleased(KeyEvent event) {
- keyTyped(event);
+ void updateSpotlight(boolean now) {
+ if (!now) {
+ mySpotlightUpdate.queue(new Update(this) {
+ @Override
+ public void run() {
+ if (!mySpotlightPainter.updateForCurrentConfigurable()) {
+ updateSpotlight(false);
+ }
+ }
+ });
+ }
+ else if (!mySpotlightPainter.updateForCurrentConfigurable()) {
+ updateSpotlight(false);
+ }
}
};
- if (Registry.is("ide.file.settings.tree.new")) {
- myTreeView = new SettingsTreeView(listener, getContext(), groups);
+
+ if (Registry.is("ide.new.settings.dialog")) {
+ myTreeView = new SettingsTreeView(myFilter, groups);
+ myTreeView.myTree.addKeyListener(myTreeKeyListener);
myTree = null;
}
else {
myTreeView = null;
- myTree = new OptionsTree(myProject, groups, getContext()) {
- @Override
- protected void onTreeKeyEvent(final KeyEvent e) {
- listener.keyTyped(e);
- }
- };
+ myTree = new OptionsTree(myFilter, groups);
+ myTree.addKeyListener(myTreeKeyListener);
}
getContext().addColleague(myTreeView != null ? myTreeView : myTree);
Disposer.register(this, myTreeView != null ? myTreeView : myTree);
- mySearch.addDocumentListener(new DocumentAdapter() {
- @Override
- protected void textChanged(DocumentEvent e) {
- myFilter.update(e.getType(), true, false);
- }
- });
-
/* [back/forward]
final DefaultActionGroup toolbarActions = new DefaultActionGroup();
@@ -246,7 +254,7 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
setLayout(new BorderLayout());
- myMainSplitter = new Splitter(false);
+ myMainSplitter = Registry.is("ide.new.settings.dialog") ? new OnePixelSplitter(false) : new Splitter(false);
myMainSplitter.setFirstComponent(myLeftSide);
myLoadingDecorator = new LoadingDecorator(myOwnDetails.getComponent(), this, 150);
@@ -264,13 +272,9 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
mySpotlightUpdate = new MergingUpdateQueue("OptionsSpotlight", 200, false, this, this, this);
if (preselectedConfigurable != null) {
- if (myTreeView != null) {
- myTreeView.select(preselectedConfigurable);
- }
- else {
- myTree.select(preselectedConfigurable);
- }
- } else {
+ selectInTree(preselectedConfigurable);
+ }
+ else {
if (myTreeView != null) {
myTreeView.selectFirst();
}
@@ -322,6 +326,12 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
});
}
+ private ActionCallback selectInTree(Configurable configurable) {
+ return myTreeView != null
+ ? myTreeView.select(configurable)
+ : myTree.select(configurable);
+ }
+
/** @see #select(com.intellij.openapi.options.Configurable) */
@Deprecated
public ActionCallback select(Class<? extends Configurable> configurableClass) {
@@ -354,18 +364,17 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
}
public ActionCallback select(Configurable configurable) {
- if (StringUtil.isEmpty(mySearch.getText())) {
+ if (myFilter.getFilterText().isEmpty()) {
return select(configurable, "");
- } else {
- return myFilter.refilterFor(mySearch.getText(), true, true);
+ }
+ else {
+ return myFilter.update(true, true);
}
}
public ActionCallback select(Configurable configurable, final String text) {
- myFilter.refilterFor(text, false, true);
- return myTreeView != null
- ? myTreeView.select(configurable)
- : myTree.select(configurable);
+ myFilter.update(text, false, true);
+ return selectInTree(configurable);
}
private float readProportion(final float defaultValue, final String propertyName) {
@@ -390,7 +399,7 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
if (configurable == null) {
myOwnDetails.setContent(null);
- updateSpotlight(true);
+ myFilter.updateSpotlight(true);
checkModified(oldConfigurable);
result.setDone();
@@ -417,7 +426,7 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
if (myTreeView != null) {
myOwnDetails.forProject(myTreeView.findConfigurableProject(configurable));
}
- else if (Registry.is("ide.file.settings.order.new")) {
+ else if (Registry.is("ide.new.settings.dialog")) {
myOwnDetails.forProject(myTree.getConfigurableProject(configurable));
}
@@ -430,7 +439,7 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
myLoadingDecorator.stopLoading();
- updateSpotlight(false);
+ myFilter.updateSpotlight(false);
checkModified(oldConfigurable);
checkModified(configurable);
@@ -480,7 +489,7 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
((ApplicationEx)app).runEdtSafeAction(new Runnable() {
@Override
public void run() {
- if (myProject.isDisposed()) {
+ if (myFilter.myProject.isDisposed()) {
result.setRejected();
}
else {
@@ -537,26 +546,6 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
return result;
}
-
- private void updateSpotlight(boolean now) {
- if (now) {
- final boolean success = mySpotlightPainter.updateForCurrentConfigurable();
- if (!success) {
- updateSpotlight(false);
- }
- } else {
- mySpotlightUpdate.queue(new Update(this) {
- @Override
- public void run() {
- final boolean success = mySpotlightPainter.updateForCurrentConfigurable();
- if (!success) {
- updateSpotlight(false);
- }
- }
- });
- }
- }
-
private String[] getBannerText(Configurable configurable) {
if (myTreeView != null) {
return myTreeView.getPathNames(configurable);
@@ -712,7 +701,7 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
@Override
public boolean isEnabled() {
- return myContext.isModified(myConfigurable) || getContext().getErrors().containsKey(myConfigurable);
+ return myFilter.myContext.isModified(myConfigurable) || getContext().getErrors().containsKey(myConfigurable);
}
}
@@ -849,12 +838,7 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
getContext().fireErrorsChanged(errors, null);
if (!errors.isEmpty()) {
- if (myTreeView != null) {
- myTreeView.select(errors.keySet().iterator().next());
- }
- else {
- myTree.select(errors.keySet().iterator().next());
- }
+ selectInTree(errors.keySet().iterator().next());
}
}
@@ -868,7 +852,7 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
}
public JComponent getPreferredFocusedComponent() {
- return mySearch;//myTree.getTree();
+ return myTreeView != null ? myTreeView.myTree : mySearch;//myTree.getTree();
}
@Override
@@ -876,145 +860,6 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
return new Dimension(1200, 768);
}
- private class Filter extends ElementFilter.Active.Impl<SimpleNode> {
-
- SearchableOptionsRegistrar myIndex = SearchableOptionsRegistrar.getInstance();
- Set<Configurable> myFiltered = null;
- ConfigurableHit myHits;
-
- boolean myUpdateEnabled = true;
- private Configurable myLastSelected;
-
- @Override
- public boolean shouldBeShowing(final SimpleNode value) {
- if (myFiltered == null) return true;
-
- if (value instanceof OptionsTree.EditorNode) {
- final OptionsTree.EditorNode node = (OptionsTree.EditorNode)value;
- return myFiltered.contains(node.getConfigurable()) || isChildOfNameHit(node);
- }
-
- return SettingsTreeView.isFiltered(myFiltered, myHits, value);
- }
-
- private boolean isChildOfNameHit(OptionsTree.EditorNode node) {
- if (myHits != null) {
- OptionsTree.Base eachParent = node;
- while (eachParent != null) {
- if (eachParent instanceof OptionsTree.EditorNode) {
- final OptionsTree.EditorNode eachEditorNode = (OptionsTree.EditorNode)eachParent;
- if (myHits.getNameFullHits().contains(eachEditorNode.myConfigurable)) return true;
- }
- eachParent = (OptionsTree.Base)eachParent.getParent();
- }
-
- return false;
- }
-
- return false;
- }
-
- public ActionCallback refilterFor(String text, boolean adjustSelection, final boolean now) {
- try {
- myUpdateEnabled = false;
- mySearch.setText(text);
- }
- finally {
- myUpdateEnabled = true;
- }
-
- return update(DocumentEvent.EventType.CHANGE, adjustSelection, now);
- }
-
- public void clearTemporary() {
- myContext.setHoldingFilter(false);
- updateSpotlight(false);
- }
-
- public void reenable() {
- myContext.setHoldingFilter(true);
- updateSpotlight(false);
- }
-
- public ActionCallback update(DocumentEvent.EventType type, boolean adjustSelection, boolean now) {
- if (!myUpdateEnabled) return new ActionCallback.Rejected();
-
- final String text = mySearch.getText();
- if (getFilterText().length() == 0) {
- myContext.setHoldingFilter(false);
- myFiltered = null;
- } else {
- myContext.setHoldingFilter(true);
- myHits = myIndex.getConfigurables(myGroups, type, myFiltered, text, myProject);
- myFiltered = myHits.getAll();
- }
-
- if (myFiltered != null && myFiltered.isEmpty()) {
- mySearch.getTextEditor().setBackground(LightColors.RED);
- } else {
- mySearch.getTextEditor().setBackground(UIUtil.getTextFieldBackground());
- }
-
-
- final Configurable current = getContext().getCurrentConfigurable();
-
- boolean shouldMoveSelection = true;
-
- if (myHits != null && (myHits.getNameFullHits().contains(current) || myHits.getContentHits().contains(current))) {
- shouldMoveSelection = false;
- }
-
- if (shouldMoveSelection && type != DocumentEvent.EventType.INSERT && (myFiltered == null || myFiltered.contains(current))) {
- shouldMoveSelection = false;
- }
-
- Configurable toSelect = adjustSelection ? current : null;
- if (shouldMoveSelection && myHits != null) {
- if (!myHits.getNameHits().isEmpty()) {
- toSelect = suggestToSelect(myHits.getNameHits(), myHits.getNameFullHits());
- } else if (!myHits.getContentHits().isEmpty()) {
- toSelect = suggestToSelect(myHits.getContentHits(), null);
- }
- }
-
- updateSpotlight(false);
-
- if ((myFiltered == null || !myFiltered.isEmpty()) && toSelect == null && myLastSelected != null) {
- toSelect = myLastSelected;
- myLastSelected = null;
- }
-
- if (toSelect == null && current != null) {
- myLastSelected = current;
- }
-
- SimpleNode node = !adjustSelection ? null : myTreeView != null ? myTreeView.findNode(toSelect) : myTree.findNodeFor(toSelect);
- final ActionCallback callback = fireUpdate(node, adjustSelection, now);
-
- myFilterDocumentWasChanged = true;
-
- return callback;
- }
-
- private boolean isEmptyParent(Configurable configurable) {
- return configurable instanceof SearchableConfigurable.Parent && !((SearchableConfigurable.Parent)configurable).hasOwnContent();
- }
-
- @Nullable
- private Configurable suggestToSelect(Set<Configurable> set, Set<Configurable> fullHits) {
- Configurable candidate = null;
- for (Configurable each : set) {
- if (fullHits != null && fullHits.contains(each)) return each;
- if (!isEmptyParent(each) && candidate == null) {
- candidate = each;
- }
- }
-
- return candidate;
- }
-
- }
-
@Override
public ActionCallback navigateTo(@Nullable final Place place, final boolean requestFocus) {
final Configurable config = (Configurable)place.getPath("configurable");
@@ -1022,15 +867,10 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
final ActionCallback result = new ActionCallback();
- myFilter.refilterFor(filter, false, true).doWhenDone(new Runnable() {
+ myFilter.update(filter, false, true).doWhenDone(new Runnable() {
@Override
public void run() {
- if (myTreeView != null) {
- myTreeView.select(config).notifyWhenDone(result);
- }
- else {
- myTree.select(config).notifyWhenDone(result);
- }
+ selectInTree(config).notifyWhenDone(result);
}
});
@@ -1041,7 +881,7 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
public void queryPlace(@NotNull final Place place) {
final Configurable current = getContext().getCurrentConfigurable();
place.putPath("configurable", current);
- place.putPath("filter", getFilterText());
+ place.putPath("filter", myFilter.getFilterText());
if (current instanceof Place.Navigator) {
((Place.Navigator)current).queryPlace(place);
@@ -1060,7 +900,6 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
myProperties.setValue(MAIN_SPLITTER_PROPORTION, String.valueOf(myMainSplitter.getProportion()));
myProperties.setValue(DETAILS_SPLITTER_PROPORTION, String.valueOf(myContentWrapper.myLastSplitterProportion));
- myProperties.setValue(SEARCH_VISIBLE, Boolean.valueOf(isFilterFieldVisible()).toString());
Toolkit.getDefaultToolkit().removeAWTEventListener(this);
@@ -1087,7 +926,7 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
}
public OptionsEditorContext getContext() {
- return myContext;
+ return myFilter.myContext;
}
private class MyColleague extends OptionsEditorColleague.Adapter {
@@ -1137,7 +976,7 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
final MouseEvent me = (MouseEvent)event;
if (SwingUtilities.isDescendingFrom(me.getComponent(), SwingUtilities.getWindowAncestor(myContentWrapper)) || isPopupOverEditor(me.getComponent())) {
queueModificationCheck();
- myFilter.clearTemporary();
+ myFilter.setHoldingFilter(false);
}
}
else if (event.getID() == KeyEvent.KEY_PRESSED || event.getID() == KeyEvent.KEY_RELEASED) {
@@ -1175,6 +1014,23 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
private MySearchField() {
super(false);
addKeyListener(new KeyAdapter() {});
+ if (Registry.is("ide.new.settings.dialog")) {
+ final JTextField editor = getTextEditor();
+ if (!SystemInfo.isMac) {
+ editor.putClientProperty("JTextField.variant", "search");
+ if (!(editor.getUI() instanceof DarculaTextFieldUI)) {
+ editor.setUI((DarculaTextFieldUI)DarculaTextFieldUI.createUI(editor));
+ editor.setBorder(new DarculaTextBorder());
+ }
+ }
+ setBackground(UIUtil.getSidePanelColor());
+ setBorder(new EmptyBorder(5, 10, 2, 10));
+ }
+ }
+
+ @Override
+ protected boolean isSearchControlUISupported() {
+ return true;
}
@Override
@@ -1236,7 +1092,7 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
return ApplicationManager.getApplication().isUnitTestMode();
}
- String text = getFilterText();
+ String text = myFilter.getFilterText();
try {
final boolean sameText =
@@ -1263,14 +1119,7 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
myVisible = true;//myContext.isHoldingFilter();
runnable.run();
- boolean pushFilteringFurther = true;
- if (sameText) {
- pushFilteringFurther = false;
- } else {
- if (myFilter.myHits != null) {
- pushFilteringFurther = !myFilter.myHits.getNameHits().contains(current);
- }
- }
+ boolean pushFilteringFurther = !sameText && !myFilter.contains(current);
final Runnable ownSearch = searchable.enableSearch(text);
if (pushFilteringFurther && ownSearch != null) {
@@ -1295,10 +1144,6 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
}
}
- private String getFilterText() {
- return mySearch.getText() != null ? mySearch.getText().trim() : "";
- }
-
private static class SearachableWrappper implements SearchableConfigurable {
private final Configurable myConfigurable;
@@ -1366,6 +1211,49 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
abstract void setText(final String[] bannerText);
}
+ /**
+ * Returns default view for the specified configurable.
+ * It uses the configurable identifier to retrieve description.
+ *
+ * @param searchable the configurable that does not have any view
+ * @return default view for the specified configurable
+ */
+ private JComponent createDefaultComponent(SearchableConfigurable searchable) {
+ JPanel box = new JPanel();
+ box.setLayout(new BoxLayout(box, BoxLayout.Y_AXIS));
+ try {
+ box.add(new JLabel(getDefaultDescription(searchable)));
+ }
+ catch (AssertionError error) {
+ return null; // description is not set
+ }
+ if (searchable instanceof Configurable.Composite) {
+ box.add(Box.createVerticalStrut(10));
+ Configurable.Composite composite = (Configurable.Composite)searchable;
+ for (final Configurable configurable : composite.getConfigurables()) {
+ box.add(new LinkLabel(configurable.getDisplayName(), AllIcons.Ide.Link) {
+ @Override
+ public void doClick() {
+ select(configurable, null);
+ }
+ });
+ }
+ }
+ return box;
+ }
+
+ @NotNull
+ private static String getDefaultDescription(SearchableConfigurable configurable) {
+ String key = configurable.getId() + ".settings.description";
+ if (configurable instanceof ConfigurableWrapper) {
+ ConfigurableWrapper wrapper = (ConfigurableWrapper) configurable;
+ ConfigurableEP ep = wrapper.getExtensionPoint();
+ ResourceBundle resourceBundle = AbstractBundle.getResourceBundle(ep.bundle, ep.getPluginDescriptor().getPluginClassLoader());
+ return CommonBundle.message(resourceBundle, key);
+ }
+ return OptionsBundle.message(key);
+ }
+
private class Simple extends ConfigurableContent {
JComponent myComponent;
Configurable myConfigurable;
@@ -1373,7 +1261,9 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
Simple(final Configurable configurable) {
myConfigurable = configurable;
myComponent = configurable.createComponent();
-
+ if (myComponent == null && configurable instanceof SearchableConfigurable) {
+ myComponent = createDefaultComponent((SearchableConfigurable)configurable);
+ }
if (myComponent != null) {
final Object clientProperty = myComponent.getClientProperty(NOT_A_NEW_COMPONENT);
if (clientProperty != null && ApplicationManager.getApplication().isInternal()) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java
index 175b994122ef..aee9e889fdf1 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java
+++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java
@@ -37,6 +37,7 @@ import com.intellij.ui.treeStructure.filtered.FilteringTreeStructure;
import com.intellij.util.ui.GraphicsUtil;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.tree.TreeUtil;
+import com.intellij.util.ui.tree.WideSelectionTreeUI;
import com.intellij.util.ui.update.MergingUpdateQueue;
import com.intellij.util.ui.update.Update;
import org.jetbrains.annotations.NotNull;
@@ -49,33 +50,32 @@ import javax.swing.event.TreeExpansionListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.plaf.TreeUI;
-import javax.swing.plaf.basic.BasicTreeUI;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import java.awt.*;
-import java.awt.event.*;
+import java.awt.event.ComponentAdapter;
+import java.awt.event.ComponentEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
import java.util.*;
import java.util.List;
public class OptionsTree extends JPanel implements Disposable, OptionsEditorColleague {
- Project myProject;
+ private final SettingsFilter myFilter;
final SimpleTree myTree;
List<ConfigurableGroup> myGroups;
FilteringTreeBuilder myBuilder;
Root myRoot;
- OptionsEditorContext myContext;
Map<Configurable, EditorNode> myConfigurable2Node = new HashMap<Configurable, EditorNode>();
MergingUpdateQueue mySelection;
private final OptionsTree.Renderer myRenderer;
- public OptionsTree(Project project, ConfigurableGroup[] groups, OptionsEditorContext context) {
- myProject = project;
+ public OptionsTree(SettingsFilter filter, ConfigurableGroup... groups) {
+ myFilter = filter;
myGroups = Arrays.asList(groups);
- myContext = context;
-
myRoot = new Root();
final SimpleTreeStructure structure = new SimpleTreeStructure() {
@@ -132,35 +132,8 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
}
}
});
- myTree.addKeyListener(new KeyListener() {
- public void keyTyped(final KeyEvent e) {
- _onTreeKeyEvent(e);
- }
-
- public void keyPressed(final KeyEvent e) {
- _onTreeKeyEvent(e);
- }
-
- public void keyReleased(final KeyEvent e) {
- _onTreeKeyEvent(e);
- }
- });
- }
-
- protected void _onTreeKeyEvent(KeyEvent e) {
- final KeyStroke stroke = KeyStroke.getKeyStrokeForEvent(e);
-
- final Object action = myTree.getInputMap().get(stroke);
- if (action == null) {
- onTreeKeyEvent(e);
- }
- }
-
- protected void onTreeKeyEvent(KeyEvent e) {
-
}
-
ActionCallback select(@Nullable Configurable configurable) {
return queueSelection(configurable);
}
@@ -191,7 +164,7 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
if (configurable == null) {
myTree.getSelectionModel().clearSelection();
- myContext.fireSelected(null, OptionsTree.this);
+ myFilter.myContext.fireSelected(null, OptionsTree.this);
}
else {
myBuilder.getReady(this).doWhenDone(new Runnable() {
@@ -232,7 +205,7 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
}
private void fireSelected(Configurable configurable, final ActionCallback callback) {
- myContext.fireSelected(configurable, this).doWhenProcessed(callback.createSetDoneRunnable());
+ myFilter.myContext.fireSelected(configurable, this).doWhenProcessed(callback.createSetDoneRunnable());
}
@@ -297,7 +270,7 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
myRendererComponent.setOpaqueActive(false);
mySeparator = new GroupSeparator();
- myRendererComponent.add(Registry.is("ide.file.settings.order.new") ? mySeparator : mySeparatorComponent, BorderLayout.NORTH);
+ myRendererComponent.add(Registry.is("ide.new.settings.dialog") ? mySeparator : mySeparatorComponent, BorderLayout.NORTH);
final NonOpaquePanel content = new NonOpaquePanel(new BorderLayout());
myHandle = new JLabel("", SwingConstants.CENTER);
@@ -401,12 +374,12 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
myTextLabel.setForeground(selected ? UIUtil.getTreeSelectionForeground() : fg);
myTextLabel.setOpaque(selected);
- if (Registry.is("ide.file.settings.order.new")) {
+ if (Registry.is("ide.new.settings.dialog")) {
myTextLabel.setBorder(new EmptyBorder(1,2,1,0));
}
Project project = null;
- if (base != null && Registry.is("ide.file.settings.order.new")) {
+ if (base != null && Registry.is("ide.new.settings.dialog")) {
SimpleNode parent = base.getParent();
if (parent == myRoot) {
project = getConfigurableProject(base); // show icon for top-level nodes
@@ -433,6 +406,9 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
} else {
myProjectIcon.setVisible(false);
}
+ if (Registry.is("ide.new.settings.dialog")) {
+ result.setBackground(selected ? UIUtil.getTreeSelectionBackground() : UIUtil.getSidePanelColor());
+ }
return result;
}
@@ -538,7 +514,7 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
final List<EditorNode> result = new ArrayList<EditorNode>(kids.length);
for (Configurable child : kids) {
result.add(new EditorNode(parent, child, group));
- myContext.registerKid(configurable, child);
+ myFilter.myContext.registerKid(configurable, child);
}
return result; // TODO: DECIDE IF INNERS SHOULD BE SORTED: sort(result);
}
@@ -602,12 +578,12 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
@Override
boolean isModified() {
- return myContext.getModified().contains(myConfigurable);
+ return myFilter.myContext.getModified().contains(myConfigurable);
}
@Override
boolean isError() {
- return myContext.getErrors().containsKey(myConfigurable);
+ return myFilter.myContext.getErrors().containsKey(myConfigurable);
}
}
@@ -757,7 +733,7 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
super.processMouseEvent(e);
}
- private class MyTreeUi extends BasicTreeUI {
+ private class MyTreeUi extends WideSelectionTreeUI {
@Override
public void toggleExpandState(final TreePath path) {
@@ -810,7 +786,7 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
boolean myWasHoldingFilter;
public MyBuilder(SimpleTreeStructure structure) {
- super(OptionsTree.this.myTree, myContext.getFilter(), structure, new WeightBasedComparator(false));
+ super(myTree, myFilter, structure, new WeightBasedComparator(false));
myTree.addTreeExpansionListener(new TreeExpansionListener() {
public void treeExpanded(TreeExpansionEvent event) {
invalidateExpansions();
@@ -835,7 +811,7 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
@Override
public boolean isAutoExpandNode(final NodeDescriptor nodeDescriptor) {
- return myContext.isHoldingFilter();
+ return myFilter.myContext.isHoldingFilter();
}
@Override
@@ -846,21 +822,21 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
@Override
protected ActionCallback refilterNow(Object preferredSelection, boolean adjustSelection) {
final List<Object> toRestore = new ArrayList<Object>();
- if (myContext.isHoldingFilter() && !myWasHoldingFilter && myToExpandOnResetFilter == null) {
+ if (myFilter.myContext.isHoldingFilter() && !myWasHoldingFilter && myToExpandOnResetFilter == null) {
myToExpandOnResetFilter = myBuilder.getUi().getExpandedElements();
- } else if (!myContext.isHoldingFilter() && myWasHoldingFilter && myToExpandOnResetFilter != null) {
+ } else if (!myFilter.myContext.isHoldingFilter() && myWasHoldingFilter && myToExpandOnResetFilter != null) {
toRestore.addAll(myToExpandOnResetFilter);
myToExpandOnResetFilter = null;
}
- myWasHoldingFilter = myContext.isHoldingFilter();
+ myWasHoldingFilter = myFilter.myContext.isHoldingFilter();
ActionCallback result = super.refilterNow(preferredSelection, adjustSelection);
myRefilteringNow = true;
return result.doWhenDone(new Runnable() {
public void run() {
myRefilteringNow = false;
- if (!myContext.isHoldingFilter() && getSelectedElements().isEmpty()) {
+ if (!myFilter.myContext.isHoldingFilter() && getSelectedElements().isEmpty()) {
restoreExpandedState(toRestore);
}
}
@@ -968,7 +944,7 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
public void paint(Graphics g) {
super.paint(g);
- if (Registry.is("ide.file.settings.order.new")) {
+ if (Registry.is("ide.new.settings.dialog")) {
ConfigurableGroup group = getGroup(GroupSeparator.SPACE + mySeparator.getFont().getSize());
if (group != null && group == getGroup(-GroupSeparator.SPACE)) {
mySeparator.configure(group, false);
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/PreferencesDialog.form b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/PreferencesDialog.form
deleted file mode 100644
index bfd8e1f0e416..000000000000
--- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/PreferencesDialog.form
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.openapi.options.newEditor.PreferencesDialog">
- <grid id="27dc6" binding="myRoot" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
- <margin top="0" left="0" bottom="0" right="0"/>
- <constraints>
- <xy x="20" y="20" width="500" height="400"/>
- </constraints>
- <properties/>
- <border type="none"/>
- <children>
- <grid id="81fb6" binding="myTopPanel" custom-create="true" layout-manager="BorderLayout" hgap="0" vgap="0">
- <constraints>
- <grid row="0" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
- <preferred-size width="-1" height="50"/>
- </grid>
- </constraints>
- <properties/>
- <border type="none"/>
- <children/>
- </grid>
- <vspacer id="420b1">
- <constraints>
- <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
- </constraints>
- </vspacer>
- <grid id="b87b5" binding="myCenterPanel" layout-manager="BorderLayout" hgap="0" vgap="0">
- <constraints>
- <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties/>
- <border type="none"/>
- <children/>
- </grid>
- <hspacer id="e2eff">
- <constraints>
- <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
- </constraints>
- </hspacer>
- </children>
- </grid>
-</form>
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/PreferencesDialog.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/PreferencesDialog.java
deleted file mode 100644
index 8ed3527e090a..000000000000
--- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/PreferencesDialog.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright 2000-2013 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.openapi.options.newEditor;
-
-import com.intellij.icons.AllIcons;
-import com.intellij.openapi.options.ConfigurableGroup;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.DialogWrapper;
-import com.intellij.openapi.util.SystemInfo;
-import com.intellij.ui.Gray;
-import com.intellij.ui.SearchTextField;
-import com.intellij.ui.border.CustomLineBorder;
-import com.intellij.util.ui.UIUtil;
-import org.jetbrains.annotations.Nullable;
-
-import javax.swing.*;
-import javax.swing.border.EmptyBorder;
-import javax.swing.border.LineBorder;
-import java.awt.*;
-
-/**
- * @author Konstantin Bulenkov
- */
-public class PreferencesDialog extends DialogWrapper {
- private JPanel myRoot;
- private JPanel myTopPanel;
- private JPanel myCenterPanel;
- private SearchTextField mySearchTextField;
-
- public PreferencesDialog(@Nullable Project project, ConfigurableGroup[] groups) {
- super(project);
- init();
- ((JDialog)getPeer().getWindow()).setUndecorated(true);
- if (SystemInfo.isMac) {
- ((JComponent)((JDialog)getPeer().getWindow()).getContentPane()).setBorder(new EmptyBorder(0, 0, 0, 0));
- }
- else {
- ((JComponent)((JDialog)getPeer().getWindow()).getContentPane()).setBorder(new LineBorder(Gray._140, 1));
- }
-
- setTitle("Preferences");
- }
-
- @Nullable
- @Override
- protected JComponent createCenterPanel() {
- final JPanel panel = new JPanel();
- panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
- panel.setBorder(null);
- panel.add(createApplicationSettings());
- panel.add(createProjectSettings());
- panel.add(createEditorSettings());
- panel.add(createOtherSettings());
- panel.setPreferredSize(new Dimension(700, 370));
- myCenterPanel.add(panel, BorderLayout.CENTER);
- return myRoot;
- }
-
- @Nullable
- @Override
- public JComponent getPreferredFocusedComponent() {
- return mySearchTextField.getTextEditor();
- }
-
- private static JComponent createEditorSettings() {
- final LabeledButtonsPanel panel = new LabeledButtonsPanel("Editor");
- panel.addButton(new PreferenceButton("Editor", AllIcons.Preferences.Editor));
- panel.addButton(new PreferenceButton("Code Style", AllIcons.Preferences.CodeStyle));
- panel.setBackground(Gray._229);
- panel.setBorder(new CustomLineBorder(Gray._223, 0, 0, 1, 0));
- return panel;
- }
-
- private static JComponent createProjectSettings() {
- final LabeledButtonsPanel panel = new LabeledButtonsPanel("Project");
- panel.addButton(new PreferenceButton("Compiler", AllIcons.Preferences.Compiler));
- panel.addButton(new PreferenceButton("Version Control", AllIcons.Preferences.VersionControl));
- panel.addButton(new PreferenceButton("File Colors", AllIcons.Preferences.FileColors));
- panel.addButton(new PreferenceButton("Scopes", AllIcons.Preferences.Editor));
- panel.setBackground(Gray._236);
- panel.setBorder(new CustomLineBorder(Gray._223, 0, 0, 1, 0));
- return panel;
- }
-
- private static JComponent createApplicationSettings() {
- final LabeledButtonsPanel panel = new LabeledButtonsPanel("IDE");
- panel.addButton(new PreferenceButton("Appearance", AllIcons.Preferences.Appearance));
- panel.addButton(new PreferenceButton("General", AllIcons.Preferences.General));
- panel.addButton(new PreferenceButton("Keymap", AllIcons.Preferences.Keymap));
- panel.addButton(new PreferenceButton("File Types", AllIcons.Preferences.FileTypes));
- panel.setBackground(Gray._229);
- panel.setBorder(new CustomLineBorder(Gray._223, 0, 0, 1, 0));
- return panel;
- }
-
- private static JComponent createOtherSettings() {
- final LabeledButtonsPanel panel = new LabeledButtonsPanel("Other");
- panel.addButton(new PreferenceButton("Plugins", AllIcons.Preferences.Plugins));
- panel.addButton(new PreferenceButton("Updates", AllIcons.Preferences.Updates));
- panel.setBackground(Gray._236);
- panel.setBorder(new CustomLineBorder(Gray._223, 0, 0, 1, 0));
- return panel;
- }
-
-
- @Nullable
- @Override
- protected JComponent createSouthPanel() {
- if (SystemInfo.isMac) {
- return null;
- }
- final JComponent panel = super.createSouthPanel();
- if (panel != null) {
- panel.setBorder(new EmptyBorder(5, 5, 10, 20));
- }
- return panel;
- }
-
- private void createUIComponents() {
- myTopPanel = new JPanel(new BorderLayout()) {
- @Override
- protected void paintComponent(Graphics g) {
- ((Graphics2D)g).setPaint(new GradientPaint(0, 0, Gray._206, 0, getHeight() - 1, Gray._172));
- g.fillRect(0, 0, getWidth(), getHeight());
- g.setColor(Gray._145);
- g.drawLine(0, getHeight() - 2, getWidth(), getHeight() - 2);
- g.setColor(Gray._103);
- g.drawLine(0, getHeight() - 1, getWidth(), getHeight() - 1);
- }
- };
- final JLabel title = new JLabel("Preferences");
- if (!SystemInfo.isMac) {
- title.setFont(UIUtil.getLabelFont().deriveFont(Font.BOLD, 14));
- }
- else {
- title.setFont(new Font("Lucuda Grande", Font.PLAIN, 12));
- }
- title.setHorizontalTextPosition(SwingConstants.CENTER);
- title.setHorizontalAlignment(SwingConstants.CENTER);
- title.setVerticalAlignment(SwingConstants.TOP);
- myTopPanel.add(title, BorderLayout.NORTH);
- mySearchTextField = new SearchTextField();
- mySearchTextField.setOpaque(false);
- myTopPanel.add(mySearchTextField, BorderLayout.EAST);
- }
-}
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsFilter.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsFilter.java
new file mode 100644
index 000000000000..1885a852c5da
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsFilter.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.options.newEditor;
+
+import com.intellij.ide.ui.search.ConfigurableHit;
+import com.intellij.ide.ui.search.SearchableOptionsRegistrar;
+import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.options.ConfigurableGroup;
+import com.intellij.openapi.options.SearchableConfigurable;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.ActionCallback;
+import com.intellij.ui.DocumentAdapter;
+import com.intellij.ui.LightColors;
+import com.intellij.ui.SearchTextField;
+import com.intellij.ui.speedSearch.ElementFilter;
+import com.intellij.ui.treeStructure.SimpleNode;
+import com.intellij.util.ui.UIUtil;
+
+import javax.swing.event.DocumentEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.util.Set;
+
+abstract class SettingsFilter extends ElementFilter.Active.Impl<SimpleNode> {
+ final OptionsEditorContext myContext = new OptionsEditorContext(this);
+ final Project myProject;
+
+ boolean myDocumentWasChanged;
+
+ private final SearchTextField mySearch;
+ private final ConfigurableGroup[] myGroups;
+
+ private SearchableOptionsRegistrar myRegistrar = SearchableOptionsRegistrar.getInstance();
+ private Set<Configurable> myFiltered;
+ private ConfigurableHit myHits;
+
+ private boolean myUpdateRejected;
+ private Configurable myLastSelected;
+
+ SettingsFilter(Project project, ConfigurableGroup[] groups, SearchTextField search) {
+ myProject = project;
+ myGroups = groups;
+ mySearch = search;
+ mySearch.addDocumentListener(new DocumentAdapter() {
+ @Override
+ protected void textChanged(DocumentEvent event) {
+ update(event.getType(), true, false);
+ }
+ });
+ mySearch.getTextEditor().addMouseListener(new MouseAdapter() {
+ @Override
+ public void mousePressed(MouseEvent event) {
+ if (!mySearch.getText().isEmpty()) {
+ if (!myContext.isHoldingFilter()) {
+ setHoldingFilter(true);
+ }
+ if (!mySearch.getTextEditor().isFocusOwner()) {
+ mySearch.selectText();
+ }
+ }
+ }
+ });
+ }
+
+ abstract Configurable getConfigurable(SimpleNode node);
+
+ abstract SimpleNode findNode(Configurable configurable);
+
+ abstract void updateSpotlight(boolean now);
+
+ @Override
+ public boolean shouldBeShowing(SimpleNode node) {
+ if (myFiltered != null) {
+ Configurable configurable = getConfigurable(node);
+ if (configurable != null) {
+ if (!myFiltered.contains(configurable)) {
+ if (myHits != null) {
+ Set<Configurable> configurables = myHits.getNameFullHits();
+ while (node != null) {
+ if (configurable != null) {
+ if (configurables.contains(configurable)) {
+ return true;
+ }
+ }
+ node = node.getParent();
+ configurable = getConfigurable(node);
+ }
+ }
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ String getFilterText() {
+ String text = mySearch.getText();
+ return text == null ? "" : text.trim();
+ }
+
+ void setHoldingFilter(boolean holding) {
+ myContext.setHoldingFilter(holding);
+ updateSpotlight(false);
+ }
+
+ boolean contains(Configurable configurable) {
+ return myHits != null && myHits.getNameHits().contains(configurable);
+ }
+
+ ActionCallback update(boolean adjustSelection, boolean now) {
+ return update(DocumentEvent.EventType.CHANGE, adjustSelection, now);
+ }
+
+ ActionCallback update(String text, boolean adjustSelection, boolean now) {
+ try {
+ myUpdateRejected = true;
+ mySearch.setText(text);
+ }
+ finally {
+ myUpdateRejected = false;
+ }
+ return update(adjustSelection, now);
+ }
+
+ private ActionCallback update(DocumentEvent.EventType type, boolean adjustSelection, boolean now) {
+ if (myUpdateRejected) {
+ return new ActionCallback.Rejected();
+ }
+ String text = getFilterText();
+ if (text.isEmpty()) {
+ myContext.setHoldingFilter(false);
+ myFiltered = null;
+ }
+ else {
+ myContext.setHoldingFilter(true);
+ myHits = myRegistrar.getConfigurables(myGroups, type, myFiltered, text, myProject);
+ myFiltered = myHits.getAll();
+ }
+ mySearch.getTextEditor().setBackground(myFiltered != null && myFiltered.isEmpty()
+ ? LightColors.RED
+ : UIUtil.getTextFieldBackground());
+
+
+ Configurable current = myContext.getCurrentConfigurable();
+
+ boolean shouldMoveSelection = myHits == null || (
+ !myHits.getNameFullHits().contains(current) &&
+ !myHits.getContentHits().contains(current));
+
+ if (shouldMoveSelection && type != DocumentEvent.EventType.INSERT && (myFiltered == null || myFiltered.contains(current))) {
+ shouldMoveSelection = false;
+ }
+
+ Configurable candidate = adjustSelection ? current : null;
+ if (shouldMoveSelection && myHits != null) {
+ if (!myHits.getNameHits().isEmpty()) {
+ candidate = findConfigurable(myHits.getNameHits(), myHits.getNameFullHits());
+ }
+ else if (!myHits.getContentHits().isEmpty()) {
+ candidate = findConfigurable(myHits.getContentHits(), null);
+ }
+ }
+ updateSpotlight(false);
+
+ if ((myFiltered == null || !myFiltered.isEmpty()) && candidate == null && myLastSelected != null) {
+ candidate = myLastSelected;
+ myLastSelected = null;
+ }
+ if (candidate == null && current != null) {
+ myLastSelected = current;
+ }
+ SimpleNode node = !adjustSelection ? null : findNode(candidate);
+ ActionCallback callback = fireUpdate(node, adjustSelection, now);
+ myDocumentWasChanged = true;
+ return callback;
+ }
+
+ private static Configurable findConfigurable(Set<Configurable> configurables, Set<Configurable> hits) {
+ Configurable candidate = null;
+ for (Configurable configurable : configurables) {
+ if (hits != null && hits.contains(configurable)) {
+ return configurable;
+ }
+ if (candidate == null && !isEmptyParent(configurable)) {
+ candidate = configurable;
+ }
+ }
+ return candidate;
+ }
+
+ private static boolean isEmptyParent(Configurable configurable) {
+ if (configurable instanceof SearchableConfigurable.Parent) {
+ SearchableConfigurable.Parent parent = (SearchableConfigurable.Parent)configurable;
+ return !parent.hasOwnContent();
+ }
+ return false;
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsTreeView.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsTreeView.java
index 9269da7ab967..e10367d583bf 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsTreeView.java
+++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsTreeView.java
@@ -16,7 +16,6 @@
package com.intellij.openapi.options.newEditor;
import com.intellij.icons.AllIcons;
-import com.intellij.ide.ui.search.ConfigurableHit;
import com.intellij.ide.util.treeView.NodeDescriptor;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.options.*;
@@ -26,55 +25,68 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Disposer;
import com.intellij.ui.*;
-import com.intellij.ui.treeStructure.*;
+import com.intellij.ui.treeStructure.CachingSimpleNode;
+import com.intellij.ui.treeStructure.SimpleNode;
+import com.intellij.ui.treeStructure.SimpleTree;
+import com.intellij.ui.treeStructure.SimpleTreeStructure;
import com.intellij.ui.treeStructure.filtered.FilteringTreeBuilder;
import com.intellij.ui.treeStructure.filtered.FilteringTreeStructure;
import com.intellij.util.ArrayUtil;
+import com.intellij.util.ui.ButtonlessScrollBarUI;
import com.intellij.util.ui.GraphicsUtil;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.tree.TreeUtil;
+import com.intellij.util.ui.tree.WideSelectionTreeUI;
import com.intellij.util.ui.update.MergingUpdateQueue;
import com.intellij.util.ui.update.Update;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.awt.*;
-import java.awt.event.*;
-import java.util.*;
-import java.util.List;
import javax.swing.*;
import javax.swing.event.TreeExpansionEvent;
import javax.swing.event.TreeExpansionListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.plaf.TreeUI;
-import javax.swing.plaf.basic.BasicTreeUI;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
+import java.awt.*;
+import java.awt.event.ComponentAdapter;
+import java.awt.event.ComponentEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.util.*;
+import java.util.List;
/**
* @author Sergey.Malenkov
*/
final class SettingsTreeView extends JComponent implements Disposable, OptionsEditorColleague {
+ private static final Color NORMAL_NODE = new JBColor(Gray._60, Gray._140);
+ private static final Color WRONG_CONTENT = JBColor.RED;
+ private static final Color MODIFIED_CONTENT = JBColor.BLUE;
+
final SimpleTree myTree;
final FilteringTreeBuilder myBuilder;
- private final OptionsEditorContext myContext;
+ private final SettingsFilter myFilter;
private final MyRoot myRoot;
private final JScrollPane myScroller;
private JLabel mySeparator;
private final MyRenderer myRenderer = new MyRenderer();
private final IdentityHashMap<Configurable, MyNode> myConfigurableToNodeMap = new IdentityHashMap<Configurable, MyNode>();
- private final MergingUpdateQueue myQueue = new MergingUpdateQueue("OptionsTree", 150, false, this, this, this).setRestartTimerOnAdd(true);
+ private final MergingUpdateQueue myQueue = new MergingUpdateQueue("SettingsTreeView", 150, false, this, this, this)
+ .setRestartTimerOnAdd(true);
private Configurable myQueuedConfigurable;
- SettingsTreeView(final KeyListener listener, OptionsEditorContext context, ConfigurableGroup... groups) {
- myContext = context;
+ SettingsTreeView(SettingsFilter filter, ConfigurableGroup... groups) {
+ myFilter = filter;
myRoot = new MyRoot(groups);
-
myTree = new MyTree();
+ myTree.putClientProperty(WideSelectionTreeUI.TREE_TABLE_TREE_KEY, Boolean.TRUE);
+ myTree.setBackground(UIUtil.getSidePanelColor());
myTree.getInputMap().clear();
TreeUtil.installActions(myTree);
@@ -88,8 +100,11 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
myTree.setRootVisible(false);
myTree.setShowsRootHandles(false);
- myScroller = ScrollPaneFactory.createScrollPane(myTree);
- myScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
+ myScroller = ScrollPaneFactory.createScrollPane(myTree, true);
+ myScroller.getVerticalScrollBar().setUI(ButtonlessScrollBarUI.createTransparent());
+ myScroller.setBackground(UIUtil.getSidePanelColor());
+ myScroller.getViewport().setBackground(UIUtil.getSidePanelColor());
+ myScroller.getVerticalScrollBar().setBackground(UIUtil.getSidePanelColor());
add(myScroller);
myTree.addComponentListener(new ComponentAdapter() {
@@ -116,29 +131,6 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
}
});
- myTree.addKeyListener(new KeyListener() {
- public void keyTyped(KeyEvent event) {
- if (listener != null && isValid(event)) {
- listener.keyTyped(event);
- }
- }
-
- public void keyPressed(KeyEvent event) {
- if (listener != null && isValid(event)) {
- listener.keyPressed(event);
- }
- }
-
- public void keyReleased(KeyEvent event) {
- if (listener != null && isValid(event)) {
- listener.keyReleased(event);
- }
- }
-
- private boolean isValid(KeyEvent event) {
- return null == myTree.getInputMap().get(KeyStroke.getKeyStrokeForEvent(event));
- }
- });
myBuilder = new MyBuilder(new SimpleTreeStructure.Impl(myRoot));
myBuilder.setFilteringMerge(300, null);
Disposer.register(this, myBuilder);
@@ -158,9 +150,15 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
return ArrayUtil.toStringArray(path);
}
+ static Configurable getConfigurable(SimpleNode node) {
+ return node instanceof MyNode
+ ? ((MyNode)node).myConfigurable
+ : null;
+ }
+
@Nullable
- SimpleNode findNode(Configurable toSelect) {
- return myConfigurableToNodeMap.get(toSelect);
+ SimpleNode findNode(Configurable configurable) {
+ return myConfigurableToNodeMap.get(configurable);
}
@Nullable
@@ -250,24 +248,6 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
: null;
}
- static boolean isFiltered(Set<Configurable> configurables, ConfigurableHit hits, SimpleNode value) {
- if (value instanceof MyNode && !configurables.contains(((MyNode)value).myConfigurable)) {
- if (hits != null) {
- configurables = hits.getNameFullHits();
- while (value != null) {
- if (value instanceof MyNode) {
- if (configurables.contains(((MyNode)value).myConfigurable)) {
- return true;
- }
- }
- value = value.getParent();
- }
- }
- return false;
- }
- return true;
- }
-
@Override
public void doLayout() {
myScroller.setBounds(0, 0, getWidth(), getHeight());
@@ -277,34 +257,34 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
public void paint(Graphics g) {
super.paint(g);
+ if (0 == myTree.getY()) {
+ return; // separator is not needed without scrolling
+ }
if (mySeparator == null) {
mySeparator = new JLabel();
+ mySeparator.setForeground(NORMAL_NODE);
mySeparator.setFont(UIUtil.getLabelFont());
mySeparator.setFont(getFont().deriveFont(Font.BOLD));
}
- ConfigurableGroup group = findConfigurableGroupAt(0, 5 + mySeparator.getFont().getSize());
- if (group != null && group == findConfigurableGroupAt(0, -5)) {
- int offset = UIUtil.isUnderNativeMacLookAndFeel() ? 1 : 3;
- mySeparator.setBorder(BorderFactory.createEmptyBorder(offset, 18, offset, 3));
+ int height = mySeparator.getPreferredSize().height;
+ ConfigurableGroup group = findConfigurableGroupAt(0, height);
+ if (group != null && group == findConfigurableGroupAt(0, -myRenderer.getSeparatorHeight())) {
+ mySeparator.setBorder(BorderFactory.createEmptyBorder(0, 18, 0, 0));
mySeparator.setText(group.getDisplayName());
Rectangle bounds = myScroller.getViewport().getBounds();
- int height = mySeparator.getPreferredSize().height;
if (bounds.height > height) {
bounds.height = height;
}
g.setColor(myTree.getBackground());
+ g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
if (g instanceof Graphics2D) {
- int h = bounds.height / 4;
- int y = bounds.y + bounds.height - h;
- g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height - h);
+ int h = 4; // gradient height
+ int y = bounds.y + bounds.height;
((Graphics2D)g).setPaint(UIUtil.getGradientPaint(
0, y, g.getColor(),
0, y + h, ColorUtil.toAlpha(g.getColor(), 0)));
- g.fillRect(bounds.x, y, bounds.width, h + h);
- }
- else {
- g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
+ g.fillRect(bounds.x, y, bounds.width, h);
}
mySeparator.setSize(bounds.width - 1, bounds.height);
mySeparator.paint(g.create(bounds.x + 1, bounds.y, bounds.width - 1, bounds.height));
@@ -373,7 +353,7 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
}
private void fireSelected(Configurable configurable, ActionCallback callback) {
- myContext.fireSelected(configurable, this).doWhenProcessed(callback.createSetDoneRunnable());
+ myFilter.myContext.fireSelected(configurable, this).doWhenProcessed(callback.createSetDoneRunnable());
}
@Override
@@ -435,20 +415,21 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
myConfigurable = configurable;
String name = configurable.getDisplayName();
myDisplayName = name != null ? name.replace("\n", " ") : "{ " + configurable.getClass().getSimpleName() + " }";
-
- myConfigurableToNodeMap.put(configurable, this);
}
private MyNode(CachingSimpleNode parent, ConfigurableGroup group) {
super(parent);
myComposite = group;
- myConfigurable = null;
+ myConfigurable = group instanceof Configurable ? (Configurable)group : null;
String name = group.getDisplayName();
myDisplayName = name != null ? name.replace("\n", " ") : "{ " + group.getClass().getSimpleName() + " }";
}
@Override
protected SimpleNode[] buildChildren() {
+ if (myConfigurable != null) {
+ myConfigurableToNodeMap.put(myConfigurable, this);
+ }
if (myComposite == null) {
return NO_CHILDREN;
}
@@ -460,7 +441,7 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
for (int i = 0; i < configurables.length; i++) {
result[i] = new MyNode(this, configurables[i]);
if (myConfigurable != null) {
- myContext.registerKid(myConfigurable, configurables[i]);
+ myFilter.myContext.registerKid(myConfigurable, configurables[i]);
}
}
return result;
@@ -470,11 +451,6 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
public boolean isAlwaysLeaf() {
return myComposite == null;
}
-
- @Override
- public int getWeight() {
- return WeightBasedComparator.UNDEFINED_WEIGHT;
- }
}
private final class MyRenderer extends GroupedElementsRenderer.Tree {
@@ -490,8 +466,9 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
protected void layout() {
myNodeIcon = new JLabel(" ", SwingConstants.RIGHT);
myProjectIcon = new JLabel(" ", SwingConstants.LEFT);
- myProjectIcon.setOpaque(true);
- myRendererComponent.add(BorderLayout.NORTH, mySeparatorComponent);
+ myNodeIcon.setOpaque(false);
+ myTextLabel.setOpaque(false);
+ myProjectIcon.setOpaque(false);
myRendererComponent.add(BorderLayout.CENTER, myComponent);
myRendererComponent.add(BorderLayout.WEST, myNodeIcon);
myRendererComponent.add(BorderLayout.EAST, myProjectIcon);
@@ -504,22 +481,17 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
boolean leaf,
int row,
boolean focused) {
- myTextLabel.setOpaque(selected);
myTextLabel.setFont(UIUtil.getLabelFont());
-
- String text;
- boolean hasSeparatorAbove = false;
- int preferredForcedWidth = -1;
+ myRendererComponent.setBackground(selected ? UIUtil.getTreeSelectionBackground() : myTree.getBackground());
MyNode node = extractNode(value);
if (node == null) {
- text = value.toString();
+ myTextLabel.setText(value.toString());
}
else {
- text = node.myDisplayName;
+ myTextLabel.setText(node.myDisplayName);
// show groups in bold
if (myRoot == node.getParent()) {
- hasSeparatorAbove = node != myRoot.getChildAt(0);
myTextLabel.setFont(myTextLabel.getFont().deriveFont(Font.BOLD));
}
TreePath path = tree.getPathForRow(row);
@@ -543,18 +515,18 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
forcedWidth = visibleRect.width > 0 ? visibleRect.width - indent : forcedWidth;
}
- preferredForcedWidth = forcedWidth - 4;
+ myRendererComponent.setPrefereedWidth(forcedWidth - 4);
}
- Component result = configureComponent(text, null, null, null, selected, hasSeparatorAbove, null, preferredForcedWidth);
// update font color for modified configurables
+ myTextLabel.setForeground(selected ? UIUtil.getTreeSelectionForeground() : NORMAL_NODE);
if (!selected && node != null) {
Configurable configurable = node.myConfigurable;
if (configurable != null) {
- if (myContext.getErrors().containsKey(configurable)) {
- myTextLabel.setForeground(JBColor.RED);
+ if (myFilter.myContext.getErrors().containsKey(configurable)) {
+ myTextLabel.setForeground(WRONG_CONTENT);
}
- else if (myContext.getModified().contains(configurable)) {
- myTextLabel.setForeground(JBColor.BLUE);
+ else if (myFilter.myContext.getModified().contains(configurable)) {
+ myTextLabel.setForeground(MODIFIED_CONTENT);
}
}
}
@@ -586,7 +558,6 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
myProjectIcon.setToolTipText(OptionsBundle.message(project.isDefault()
? "configurable.default.project.tooltip"
: "configurable.current.project.tooltip"));
- myProjectIcon.setBackground(myTextLabel.getBackground());
myProjectIcon.setVisible(true);
}
else {
@@ -601,9 +572,12 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
else {
myNodeIcon.setIcon(null);
}
- return result;
+ return myRendererComponent;
}
+ int getSeparatorHeight() {
+ return mySeparatorComponent.getParent() == null ? 0 : mySeparatorComponent.getPreferredSize().height;
+ }
public boolean isUnderHandle(Point point) {
Point handlePoint = SwingUtilities.convertPoint(myRendererComponent, point, myNodeIcon);
@@ -720,7 +694,7 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
super.processMouseEvent(e);
}
- private final class MyTreeUi extends BasicTreeUI {
+ private final class MyTreeUi extends WideSelectionTreeUI {
@Override
public void toggleExpandState(TreePath path) {
@@ -773,7 +747,7 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
boolean myWasHoldingFilter;
public MyBuilder(SimpleTreeStructure structure) {
- super(myTree, myContext.getFilter(), structure, new WeightBasedComparator(false));
+ super(myTree, myFilter, structure, null);
myTree.addTreeExpansionListener(new TreeExpansionListener() {
public void treeExpanded(TreeExpansionEvent event) {
invalidateExpansions();
@@ -798,7 +772,7 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
@Override
public boolean isAutoExpandNode(NodeDescriptor nodeDescriptor) {
- return myContext.isHoldingFilter();
+ return myFilter.myContext.isHoldingFilter();
}
@Override
@@ -809,22 +783,22 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
@Override
protected ActionCallback refilterNow(Object preferredSelection, boolean adjustSelection) {
final List<Object> toRestore = new ArrayList<Object>();
- if (myContext.isHoldingFilter() && !myWasHoldingFilter && myToExpandOnResetFilter == null) {
+ if (myFilter.myContext.isHoldingFilter() && !myWasHoldingFilter && myToExpandOnResetFilter == null) {
myToExpandOnResetFilter = myBuilder.getUi().getExpandedElements();
}
- else if (!myContext.isHoldingFilter() && myWasHoldingFilter && myToExpandOnResetFilter != null) {
+ else if (!myFilter.myContext.isHoldingFilter() && myWasHoldingFilter && myToExpandOnResetFilter != null) {
toRestore.addAll(myToExpandOnResetFilter);
myToExpandOnResetFilter = null;
}
- myWasHoldingFilter = myContext.isHoldingFilter();
+ myWasHoldingFilter = myFilter.myContext.isHoldingFilter();
ActionCallback result = super.refilterNow(preferredSelection, adjustSelection);
myRefilteringNow = true;
return result.doWhenDone(new Runnable() {
public void run() {
myRefilteringNow = false;
- if (!myContext.isHoldingFilter() && getSelectedElements().isEmpty()) {
+ if (!myFilter.myContext.isHoldingFilter() && getSelectedElements().isEmpty()) {
restoreExpandedState(toRestore);
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java
index 6a37bb2fb69e..3d478f2b7084 100644
--- a/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java
@@ -47,6 +47,7 @@ import java.util.concurrent.atomic.AtomicInteger;
public class ProgressManagerImpl extends ProgressManager implements Disposable {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.progress.impl.ProgressManagerImpl");
+ public static final int CHECK_CANCELED_DELAY_MILLIS = 10;
private final AtomicInteger myCurrentUnsafeProgressCount = new AtomicInteger(0);
private final AtomicInteger myCurrentModalProgressCount = new AtomicInteger(0);
@@ -64,7 +65,7 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable {
public void run() {
ourNeedToCheckCancel = true;
}
- }, 0, 10, TimeUnit.MILLISECONDS);
+ }, 0, CHECK_CANCELED_DELAY_MILLIS, TimeUnit.MILLISECONDS);
}
}
@@ -83,7 +84,7 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable {
ourLockedCheckCounter++;
if (ourLockedCheckCounter > 10) {
ourLockedCheckCounter = 0;
- ourNeedToCheckCancel = true;
+ canceled();
}
}
else {
@@ -94,10 +95,6 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable {
}
}
- public static void canceled() {
- ourNeedToCheckCancel = true;
- }
-
private static class NonCancelableIndicator extends EmptyProgressIndicator implements NonCancelableSection {
private final ProgressIndicator myOld;
diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorBase.java b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorBase.java
index 2d9a7b3a88e6..b4821f52fddb 100644
--- a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorBase.java
+++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorBase.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,7 +19,6 @@ import com.intellij.openapi.application.impl.LaterInvocator;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.TaskInfo;
-import com.intellij.openapi.progress.impl.ProgressManagerImpl;
import com.intellij.openapi.wm.ex.ProgressIndicatorEx;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.WeakList;
@@ -151,9 +150,6 @@ public class ProgressIndicatorBase extends AbstractProgressIndicatorBase impleme
@Override
public void cancel() {
super.cancel();
-
- ProgressManagerImpl.canceled();
-
delegateRunningChange(CANCEL_ACTION);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorUtils.java b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorUtils.java
index 0c18cb7706d9..368200492cae 100644
--- a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorUtils.java
+++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorUtils.java
@@ -22,7 +22,11 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.ui.AppUIUtil;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.ide.PooledThreadExecutor;
+
+import java.util.concurrent.Executor;
/**
* @author gregsh
@@ -44,96 +48,76 @@ public class ProgressIndicatorUtils {
return progress;
}
- public static void runWithWriteActionPriority(@NotNull final Runnable action) {
- runWithWriteActionPriority(new ReadTask() {
- @Override
- public void computeInReadAction(@NotNull ProgressIndicator indicator) {
- action.run();
- }
-
- @Override
- public void onCanceled(@NotNull ProgressIndicator indicator) {
- }
- });
- }
-
- public static void runWithWriteActionPriority(@NotNull final ReadTask task) {
- runWithWriteActionPriority(new ProgressIndicatorBase(), task);
+ public static void scheduleWithWriteActionPriority(@NotNull ReadTask task) {
+ scheduleWithWriteActionPriority(new ProgressIndicatorBase(), task);
}
- private static void surroundWithListener(@NotNull final ProgressIndicator progressIndicator, @NotNull Runnable runnable) {
- final ApplicationAdapter listener = new ApplicationAdapter() {
- @Override
- public void beforeWriteActionStart(Object action) {
- progressIndicator.cancel();
- }
- };
- final Application application = ApplicationManager.getApplication();
- application.addApplicationListener(listener);
- try {
- runnable.run();
- }
- finally {
- application.removeApplicationListener(listener);
- }
+ public static void scheduleWithWriteActionPriority(@NotNull ProgressIndicator progressIndicator, @NotNull ReadTask readTask) {
+ scheduleWithWriteActionPriority(progressIndicator, PooledThreadExecutor.INSTANCE, readTask);
}
-
- public static void runWithWriteActionPriority(@NotNull final ProgressIndicator progressIndicator, @NotNull final ReadTask task) {
- surroundWithListener(progressIndicator, new Runnable() {
+ public static void scheduleWithWriteActionPriority(@NotNull final ProgressIndicator progressIndicator,
+ @NotNull final Executor executor,
+ @NotNull final ReadTask readTask) {
+ AppUIUtil.invokeOnEdt(new Runnable() {
@Override
public void run() {
- runUnderProgress(progressIndicator, task);
+ final Application application = ApplicationManager.getApplication();
+ application.assertIsDispatchThread();
+ final ApplicationAdapter listener = new ApplicationAdapter() {
+ @Override
+ public void beforeWriteActionStart(Object action) {
+ progressIndicator.cancel();
+ }
+ };
+ application.addApplicationListener(listener);
+ try {
+ executor.execute(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ runUnderProgress(progressIndicator, readTask);
+ }
+ finally {
+ application.removeApplicationListener(listener);
+ }
+ }
+ });
+ }
+ catch (RuntimeException e) {
+ application.removeApplicationListener(listener);
+ throw e;
+ }
+ catch (Error e) {
+ application.removeApplicationListener(listener);
+ throw e;
+ }
}
});
}
private static void runUnderProgress(@NotNull final ProgressIndicator progressIndicator, @NotNull final ReadTask task) {
ProgressManager.getInstance().runProcess(new Runnable() {
- @Override
- public void run() {
- // This read action can possible last for a long time, we want it to stop immediately on the first write access.
- // For this purpose we launch it under empty progress and invoke progressIndicator#cancel on write access to avoid possible write lock delays.
- try {
- ApplicationManager.getApplication().runReadAction(new Runnable() {
- @Override
- public void run() {
- task.computeInReadAction(progressIndicator);
- }
- });
- }
- catch (ProcessCanceledException ignore) {
- }
- finally {
- if (progressIndicator.isCanceled()) {
- task.onCanceled(progressIndicator);
- }
- }
- }
- }, progressIndicator);
- }
-
- public static void scheduleWithWriteActionPriority(@NotNull final ReadTask task) {
- scheduleWithWriteActionPriority(new ProgressIndicatorBase(), task);
- }
-
- public static void scheduleWithWriteActionPriority(@NotNull final ProgressIndicator indicator, @NotNull final ReadTask task) {
- // we have to attach listeners in EDT to avoid "fire write action started while attach listeners from another thread" race condition
- ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
- surroundWithListener(indicator, new Runnable() {
- @Override
- public void run() {
- ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
- @Override
- public void run() {
- runUnderProgress(indicator, task);
- }
- });
+ // This read action can possible last for a long time, we want it to stop immediately on the first write access.
+ // For this purpose we launch it under empty progress and invoke progressIndicator#cancel on write access to avoid possible write lock delays.
+ try {
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ @Override
+ public void run() {
+ task.computeInReadAction(progressIndicator);
+ }
+ });
+ }
+ catch (ProcessCanceledException ignore) {
+ }
+ finally {
+ if (progressIndicator.isCanceled()) {
+ task.onCanceled(progressIndicator);
}
- });
+ }
}
- });
+ }, progressIndicator);
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectMacrosUtil.java b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectMacrosUtil.java
index 77baf2a6b98c..1f3b9d149ccc 100644
--- a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectMacrosUtil.java
+++ b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectMacrosUtil.java
@@ -25,17 +25,13 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.application.PathMacros;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.options.ex.SingleConfigurableEditor;
-import com.intellij.openapi.progress.ProgressIndicator;
-import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.WaitForProgressToShow;
import org.jetbrains.annotations.NonNls;
-import javax.swing.*;
-import java.lang.reflect.InvocationTargetException;
import java.util.*;
public class ProjectMacrosUtil {
@@ -50,11 +46,7 @@ public class ProjectMacrosUtil {
if (application.isHeadlessEnvironment() || application.isUnitTestMode()) {
throw new RuntimeException(text + ": " + StringUtil.join(undefinedMacros, ", "));
}
- final UndefinedMacrosConfigurable configurable =
- new UndefinedMacrosConfigurable(text, undefinedMacros);
- final SingleConfigurableEditor editor = new SingleConfigurableEditor(project, configurable);
- editor.show();
- return editor.isOK();
+ return ShowSettingsUtil.getInstance().editConfigurable(project, new UndefinedMacrosConfigurable(text, undefinedMacros));
}
public static boolean checkNonIgnoredMacros(final Project project, final Set<String> usedMacros){
diff --git a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java
index 2f95c21cb558..e7b20959369e 100644
--- a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java
@@ -21,6 +21,7 @@ import com.intellij.conversion.ConversionService;
import com.intellij.ide.AppLifecycleListener;
import com.intellij.ide.RecentProjectsManagerBase;
import com.intellij.ide.impl.ProjectUtil;
+import com.intellij.ide.plugins.PluginManager;
import com.intellij.ide.startup.impl.StartupManagerImpl;
import com.intellij.notification.NotificationsManager;
import com.intellij.openapi.Disposable;
@@ -354,7 +355,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
myDefaultProjectRootElement = null;
}
catch (Throwable t) {
- LOG.error(t);
+ PluginManager.processException(t);
}
}
});
@@ -362,6 +363,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
return myDefaultProject;
}
+ @Nullable
public Element getDefaultProjectRootElement() {
return myDefaultProjectRootElement;
}
@@ -1126,33 +1128,27 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
}
@Override
- public void writeExternal(Element parentNode) throws WriteExternalException {
+ public void writeExternal(Element parentNode) {
if (myDefaultProject != null) {
myDefaultProject.save();
}
- if (myDefaultProjectRootElement == null) { //read external isn't called if config folder is absent
- myDefaultProjectRootElement = new Element(ELEMENT_DEFAULT_PROJECT);
+ if (myDefaultProjectRootElement != null) {
+ myDefaultProjectRootElement.detach();
+ parentNode.addContent(myDefaultProjectRootElement);
}
-
- myDefaultProjectRootElement.detach();
- parentNode.addContent(myDefaultProjectRootElement);
}
-
public void setDefaultProjectRootElement(final Element defaultProjectRootElement) {
myDefaultProjectRootElement = defaultProjectRootElement;
}
@Override
- public void readExternal(Element parentNode) throws InvalidDataException {
+ public void readExternal(Element parentNode) {
myDefaultProjectRootElement = parentNode.getChild(ELEMENT_DEFAULT_PROJECT);
-
- if (myDefaultProjectRootElement == null) {
- myDefaultProjectRootElement = new Element(ELEMENT_DEFAULT_PROJECT);
+ if (myDefaultProjectRootElement != null) {
+ myDefaultProjectRootElement.detach();
}
-
- myDefaultProjectRootElement.detach();
}
@Override
diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginAdvertiserEditorNotificationProvider.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginAdvertiserEditorNotificationProvider.java
index 394dec20f4ef..1160c64bbeb8 100644
--- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginAdvertiserEditorNotificationProvider.java
+++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginAdvertiserEditorNotificationProvider.java
@@ -15,7 +15,8 @@
*/
package com.intellij.openapi.updateSettings.impl.pluginsAdvertisement;
-import com.intellij.ide.plugins.*;
+import com.intellij.ide.plugins.IdeaPluginDescriptor;
+import com.intellij.ide.plugins.RepositoryHelper;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileTypes.FileTypeFactory;
@@ -24,7 +25,7 @@ import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.updateSettings.impl.*;
+import com.intellij.openapi.updateSettings.impl.PluginDownloader;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.EditorNotificationPanel;
@@ -94,7 +95,8 @@ public class PluginAdvertiserEditorNotificationProvider extends EditorNotificati
@Nullable
private EditorNotificationPanel createPanel(final String extension, final Set<PluginsAdvertiser.Plugin> plugins) {
final EditorNotificationPanel panel = new EditorNotificationPanel();
- panel.setText("Plugins supporting files with " + extension + " are found");
+
+ panel.setText("Plugins supporting " + extension + " files are found");
final IdeaPluginDescriptor disabledPlugin = PluginsAdvertiser.getDisabledPlugin(plugins);
if (disabledPlugin != null) {
panel.createActionLabel("Enable " + disabledPlugin.getName() + " plugin", new Runnable() {
@@ -143,6 +145,7 @@ public class PluginAdvertiserEditorNotificationProvider extends EditorNotificati
if (PropertiesComponent.getInstance().isTrueValue(PluginsAdvertiser.IGNORE_ULTIMATE_EDITION)) {
return null;
}
+ panel.setText(extension + " files are supported by " + PluginsAdvertiser.IDEA_ULTIMATE_EDITION);
panel.createActionLabel(PluginsAdvertiser.CHECK_ULTIMATE_EDITION_TITLE, new Runnable() {
@Override
diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiser.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiser.java
index ed6a629bff0d..4ae3caee88e1 100644
--- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiser.java
+++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiser.java
@@ -63,8 +63,9 @@ public class PluginsAdvertiser implements StartupActivity {
private static final String FEATURE_IMPLEMENTATIONS_URL = "http://plugins.jetbrains.com/feature/getImplementations?";
private static final String CASHED_EXTENSIONS = "extensions.xml";
+ public static final String IDEA_ULTIMATE_EDITION = "IntelliJ IDEA Ultimate Edition";
public static final String ULTIMATE_EDITION_SUGGESTION = "Do not suggest Ultimate Edition";
- public static final String CHECK_ULTIMATE_EDITION_TITLE = "Check IntelliJ IDEA Ultimate Edition";
+ public static final String CHECK_ULTIMATE_EDITION_TITLE = "Check " + IDEA_ULTIMATE_EDITION;
public static final String DISPLAY_ID = "Plugins Suggestion";
public static final NotificationGroup NOTIFICATION_GROUP = new NotificationGroup(DISPLAY_ID, NotificationDisplayType.STICKY_BALLOON, true);
@@ -198,7 +199,7 @@ public class PluginsAdvertiser implements StartupActivity {
}
public static void openDownloadPage() {
- BrowserUtil.open(ApplicationInfo.getInstance().getCompanyURL());
+ BrowserUtil.browse(ApplicationInfo.getInstance().getCompanyURL());
}
static void enablePlugins(Project project, final Collection<IdeaPluginDescriptor> disabledPlugins) {
@@ -325,7 +326,8 @@ public class PluginsAdvertiser implements StartupActivity {
message += "<a href=\"ignore\">Ignore All</a>";
}
else if (myBundledPlugin != null && !PropertiesComponent.getInstance().isTrueValue(IGNORE_ULTIMATE_EDITION)) {
- message = "Features covered by IntelliJ IDEA Ultimate Edition (" + StringUtil.join(myBundledPlugin, ", ") + ") are detected.<br>" +
+ message = "Features covered by " + IDEA_ULTIMATE_EDITION +
+ " (" + StringUtil.join(myBundledPlugin, ", ") + ") are detected.<br>" +
"<a href=\"open\">" + CHECK_ULTIMATE_EDITION_TITLE + "</a><br>" +
"<a href=\"ignoreUltimate\">" + ULTIMATE_EDITION_SUGGESTION + "</a>";
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/vcs/changes/issueLinks/LinkMouseListenerBase.java b/platform/platform-impl/src/com/intellij/openapi/vcs/changes/issueLinks/LinkMouseListenerBase.java
index 402d88cef38a..92eed9582fd2 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vcs/changes/issueLinks/LinkMouseListenerBase.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vcs/changes/issueLinks/LinkMouseListenerBase.java
@@ -27,18 +27,24 @@ import java.awt.event.MouseMotionListener;
public abstract class LinkMouseListenerBase<T> extends ClickListener implements MouseMotionListener {
public static void installSingleTagOn(@NotNull SimpleColoredComponent component) {
- new LinkMouseListenerBase<Consumer<MouseEvent>>() {
+ new LinkMouseListenerBase<Object>() {
@Nullable
@Override
- protected Consumer<MouseEvent> getTagAt(@NotNull MouseEvent e) {
+ protected Object getTagAt(@NotNull MouseEvent e) {
//noinspection unchecked
- return (Consumer<MouseEvent>)((SimpleColoredComponent)e.getSource()).getFragmentTagAt(e.getX());
+ return ((SimpleColoredComponent)e.getSource()).getFragmentTagAt(e.getX());
}
@Override
- protected void handleTagClick(@Nullable Consumer<MouseEvent> tag, @NotNull MouseEvent event) {
+ protected void handleTagClick(@Nullable Object tag, @NotNull MouseEvent event) {
if (tag != null) {
- tag.consume(event);
+ if (tag instanceof Consumer) {
+ //noinspection unchecked
+ ((Consumer<MouseEvent>)tag).consume(event);
+ }
+ else {
+ ((Runnable)tag).run();
+ }
}
}
}.installOn(component);
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/ex/temp/TempFileSystem.java b/platform/platform-impl/src/com/intellij/openapi/vfs/ex/temp/TempFileSystem.java
index 1c6e173b45d1..33ecf625c05d 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/ex/temp/TempFileSystem.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/ex/temp/TempFileSystem.java
@@ -136,7 +136,8 @@ public class TempFileSystem extends LocalFileSystemBase {
}
fsItem.getParent().removeChild(fsItem);
- ((FSDir)newParentItem).addChild(fsItem);
+ newDir.addChild(fsItem);
+ fsItem.myParent = newDir;
}
@Override
@@ -263,7 +264,7 @@ public class TempFileSystem extends LocalFileSystemBase {
}
private abstract static class FSItem {
- private final FSDir myParent;
+ private FSDir myParent;
private String myName;
private long myTimestamp;
private boolean myWritable;
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java
index d7b90178e7e8..db5de4258d41 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java
@@ -67,15 +67,16 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone
private final Object myInputLock = new Object();
private final AtomicBoolean myShutDown = new AtomicBoolean(false);
+ @SuppressWarnings("FieldCanBeLocal")
+ private final LowMemoryWatcher myWatcher = LowMemoryWatcher.register(new Runnable() {
+ @Override
+ public void run() {
+ clearIdCache();
+ }
+ });
public PersistentFSImpl(@NotNull MessageBus bus) {
myEventBus = bus;
- LowMemoryWatcher.register(new Runnable() {
- @Override
- public void run() {
- clearIdCache();
- }
- });
ShutDownTracker.getInstance().registerShutdownTask(new Runnable() {
@Override
public void run() {
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PresentationModeProgressPanel.form b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PresentationModeProgressPanel.form
index 2e1bb768a614..4e362a30a1ed 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PresentationModeProgressPanel.form
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PresentationModeProgressPanel.form
@@ -22,7 +22,7 @@
</constraints>
<properties>
<autoscrolls value="true"/>
- <text value="Text"/>
+ <text value=""/>
</properties>
</component>
<component id="94f42" class="javax.swing.JProgressBar" binding="myProgressBar" default-binding="true">
@@ -54,7 +54,7 @@
</grid>
</constraints>
<properties>
- <text value="Text 2"/>
+ <text value=""/>
</properties>
</component>
<vspacer id="8e674">
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PresentationModeProgressPanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PresentationModeProgressPanel.java
index d7bc7024f0ed..9f82a2f60cdf 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PresentationModeProgressPanel.java
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PresentationModeProgressPanel.java
@@ -22,6 +22,7 @@ import com.intellij.ui.InplaceButton;
import com.intellij.ui.TransparentPanel;
import com.intellij.util.ui.EmptyIcon;
import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
@@ -69,7 +70,7 @@ public class PresentationModeProgressPanel {
}
if (!myProgressBar.isIndeterminate()) {
- myProgressBar.setValue(((int)(myProgress.getFraction() * 99)) + 1);
+ myProgressBar.setValue((int)(myProgress.getFraction() * 99) + 1);
}
}
@@ -83,7 +84,7 @@ public class PresentationModeProgressPanel {
AllIcons.Process.Stop,
AllIcons.Process.StopHovered);
myCancelButton = new InplaceButton(iconButton, new ActionListener() {
- public void actionPerformed(final ActionEvent e) {
+ public void actionPerformed(@NotNull final ActionEvent e) {
myProgress.cancel();
}
}).setFillBg(false);
diff --git a/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java b/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java
index 1fc23e5f4055..d9ebeefa7acc 100644
--- a/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java
+++ b/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java
@@ -368,6 +368,7 @@ public abstract class AbstractExpandableItemsHandler<KeyType, ComponentType exte
if (!(renderer instanceof JComponent)) return null;
myKeyItemBounds = rendererAndBounds.second;
+ myKeyItemBounds.width = Math.min(myKeyItemBounds.width, myComponent.getToolkit().getScreenSize().width);
Rectangle cellBounds = myKeyItemBounds;
Rectangle visibleRect = getVisibleRect(key);
diff --git a/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java b/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java
index 2a7d44d017bd..f4bf768e92a6 100644
--- a/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java
+++ b/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java
@@ -90,19 +90,19 @@ public class AppUIUtil {
invokeOnEdt(runnable, null);
}
- public static void invokeOnEdt(Runnable runnable, @Nullable Condition condition) {
+ public static void invokeOnEdt(Runnable runnable, @Nullable Condition expired) {
Application application = ApplicationManager.getApplication();
if (application.isDispatchThread()) {
//noinspection unchecked
- if (condition == null || !condition.value(null)) {
+ if (expired == null || !expired.value(null)) {
runnable.run();
}
}
- else if (condition == null) {
+ else if (expired == null) {
application.invokeLater(runnable);
}
else {
- application.invokeLater(runnable, condition);
+ application.invokeLater(runnable, expired);
}
}
diff --git a/platform/platform-impl/src/com/intellij/ui/EditorComboBoxEditor.java b/platform/platform-impl/src/com/intellij/ui/EditorComboBoxEditor.java
index f4dfb1059651..60371365f2c3 100644
--- a/platform/platform-impl/src/com/intellij/ui/EditorComboBoxEditor.java
+++ b/platform/platform-impl/src/com/intellij/ui/EditorComboBoxEditor.java
@@ -17,6 +17,7 @@ package com.intellij.ui;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NonNls;
@@ -34,10 +35,19 @@ public class EditorComboBoxEditor implements ComboBoxEditor{
@NonNls protected static final String NAME = "ComboBox.textField";
public EditorComboBoxEditor(Project project, FileType fileType) {
- myTextField = new ComboboxEditorTextField((Document)null, project, fileType);
+ myTextField = new ComboboxEditorTextField((Document)null, project, fileType) {
+ @Override
+ protected EditorEx createEditor() {
+ EditorEx editor = super.createEditor();
+ onEditorCreate(editor);
+ return editor;
+ }
+ };
myTextField.setName(NAME);
}
+ protected void onEditorCreate(EditorEx editor) {}
+
@Override
public void selectAll() {
myTextField.selectAll();
diff --git a/platform/platform-impl/src/com/intellij/ui/EditorNotificationsImpl.java b/platform/platform-impl/src/com/intellij/ui/EditorNotificationsImpl.java
index 5721f4af4821..4b788c80ae54 100644
--- a/platform/platform-impl/src/com/intellij/ui/EditorNotificationsImpl.java
+++ b/platform/platform-impl/src/com/intellij/ui/EditorNotificationsImpl.java
@@ -102,13 +102,7 @@ public class EditorNotificationsImpl extends EditorNotifications {
task.computeInReadAction(indicator);
}
else {
- final ProgressIndicator indicator1 = indicator;
- myExecutor.execute(new Runnable() {
- @Override
- public void run() {
- ProgressIndicatorUtils.runWithWriteActionPriority(indicator1, task);
- }
- });
+ ProgressIndicatorUtils.scheduleWithWriteActionPriority(indicator, myExecutor, task);
}
}
});
@@ -165,7 +159,7 @@ public class EditorNotificationsImpl extends EditorNotifications {
}
@Override
- public void onCanceled(@NotNull ProgressIndicator _) {
+ public void onCanceled(@NotNull ProgressIndicator ignored) {
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
diff --git a/platform/platform-impl/src/com/intellij/ui/EditorTextField.java b/platform/platform-impl/src/com/intellij/ui/EditorTextField.java
index c16f5f188cdc..27b1a2be56ae 100644
--- a/platform/platform-impl/src/com/intellij/ui/EditorTextField.java
+++ b/platform/platform-impl/src/com/intellij/ui/EditorTextField.java
@@ -278,13 +278,18 @@ public class EditorTextField extends NonOpaquePanel implements DocumentListener,
public void selectAll() {
if (myEditor != null) {
- myEditor.getSelectionModel().setSelection(0, myDocument.getTextLength());
+ doSelectAll(myEditor);
}
else {
myWholeTextSelected = true;
}
}
+ private static void doSelectAll(@NotNull Editor editor) {
+ editor.getCaretModel().removeSecondaryCarets();
+ editor.getCaretModel().getPrimaryCaret().setSelection(0, editor.getDocument().getTextLength(), false);
+ }
+
public void removeSelection() {
if (myEditor != null) {
myEditor.getSelectionModel().removeSelection();
@@ -514,7 +519,8 @@ public class EditorTextField extends NonOpaquePanel implements DocumentListener,
editor.getSelectionModel().removeSelection();
}
else if (myWholeTextSelected) {
- editor.getSelectionModel().setSelection(0, myDocument.getTextLength());
+ doSelectAll(editor);
+ myWholeTextSelected = false;
}
editor.putUserData(SUPPLEMENTARY_KEY, myIsSupplementary);
diff --git a/platform/platform-impl/src/com/intellij/ui/FocusTrackback.java b/platform/platform-impl/src/com/intellij/ui/FocusTrackback.java
index 9ad0931c85b9..5c531a7b6ae8 100644
--- a/platform/platform-impl/src/com/intellij/ui/FocusTrackback.java
+++ b/platform/platform-impl/src/com/intellij/ui/FocusTrackback.java
@@ -191,10 +191,12 @@ public class FocusTrackback {
if (app == null || wrongOS() || myConsumed || isSheduledForRestore()) return;
Project project = null;
- DataContext context =
- myParentWindow == null ? DataManager.getInstance().getDataContext() : DataManager.getInstance().getDataContext(myParentWindow);
- if (context != null) {
- project = CommonDataKeys.PROJECT.getData(context);
+ DataManager dataManager = DataManager.getInstance();
+ if (dataManager != null) {
+ DataContext context = myParentWindow == null ? dataManager.getDataContext() : dataManager.getDataContext(myParentWindow);
+ if (context != null) {
+ project = CommonDataKeys.PROJECT.getData(context);
+ }
}
mySheduledForRestore = true;
diff --git a/platform/platform-impl/src/com/intellij/ui/LibNotifyWrapper.java b/platform/platform-impl/src/com/intellij/ui/LibNotifyWrapper.java
index e8c6f49f8088..7e613982a406 100644
--- a/platform/platform-impl/src/com/intellij/ui/LibNotifyWrapper.java
+++ b/platform/platform-impl/src/com/intellij/ui/LibNotifyWrapper.java
@@ -50,6 +50,8 @@ class LibNotifyWrapper implements SystemNotificationsImpl.Notifier {
private final LibNotify myLibNotify;
private final String myIcon;
+ private final Object myLock = new Object();
+ private boolean myDisposed = false;
private LibNotifyWrapper() {
myLibNotify = (LibNotify)Native.loadLibrary("libnotify.so.4", LibNotify.class);
@@ -66,14 +68,21 @@ class LibNotifyWrapper implements SystemNotificationsImpl.Notifier {
connection.subscribe(AppLifecycleListener.TOPIC, new AppLifecycleListener.Adapter() {
@Override
public void appClosing() {
- myLibNotify.notify_uninit();
+ synchronized (myLock) {
+ myDisposed = true;
+ myLibNotify.notify_uninit();
+ }
}
});
}
@Override
public void notify(@NotNull Set<String> allNames, @NotNull String name, @NotNull String title, @NotNull String description) {
- Pointer notification = myLibNotify.notify_notification_new(title, description, myIcon);
- myLibNotify.notify_notification_show(notification, null);
+ synchronized (myLock) {
+ if (!myDisposed) {
+ Pointer notification = myLibNotify.notify_notification_new(title, description, myIcon);
+ myLibNotify.notify_notification_show(notification, null);
+ }
+ }
}
}
diff --git a/platform/platform-impl/src/com/intellij/ui/SpeedSearchBase.java b/platform/platform-impl/src/com/intellij/ui/SpeedSearchBase.java
index cbcde2d36418..76985ad77362 100644
--- a/platform/platform-impl/src/com/intellij/ui/SpeedSearchBase.java
+++ b/platform/platform-impl/src/com/intellij/ui/SpeedSearchBase.java
@@ -298,6 +298,7 @@ public abstract class SpeedSearchBase<Comp extends JComponent> extends SpeedSear
protected void processKeyEvent(KeyEvent e) {
if (e.isAltDown()) return;
+ if (e.isShiftDown() && isNavigationKey(e.getKeyCode())) return;
if (mySearchPopup != null) {
mySearchPopup.processKeyEvent(e);
return;
@@ -499,6 +500,15 @@ public abstract class SpeedSearchBase<Comp extends JComponent> extends SpeedSear
return keyCode == KeyEvent.VK_HOME || keyCode == KeyEvent.VK_END || keyCode == KeyEvent.VK_UP || keyCode == KeyEvent.VK_DOWN;
}
+ private static boolean isPgUpPgDown(int keyCode) {
+ return keyCode == KeyEvent.VK_PAGE_UP || keyCode == KeyEvent.VK_PAGE_DOWN;
+ }
+
+ private static boolean isNavigationKey(int keyCode) {
+ return isPgUpPgDown(keyCode) || isUpDownHomeEnd(keyCode);
+ }
+
+
private void manageSearchPopup(@Nullable SearchPopup searchPopup) {
Project project = null;
if (ApplicationManager.getApplication() != null && !ApplicationManager.getApplication().isDisposed()) {
diff --git a/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java b/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java
index 2d76d6391ee8..bf0b37116941 100755
--- a/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java
+++ b/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java
@@ -70,6 +70,8 @@ public class SheetController {
private static int GAP_BETWEEN_BUTTONS = 5;
+ private static String SPACE_OR_LINE_SEPARATOR_PATTERN = "[\\s" + System.getProperty("line.separator") + "]+";
+
// SHEET
public int SHEET_WIDTH = 400;
@@ -289,7 +291,7 @@ public class SheetController {
int widestWordWidth = 250;
- String [] words = (message == null) ? ArrayUtil.EMPTY_STRING_ARRAY : message.split(" ");
+ String [] words = (message == null) ? ArrayUtil.EMPTY_STRING_ARRAY : message.split(SPACE_OR_LINE_SEPARATOR_PATTERN);
for (String word : words) {
widestWordWidth = Math.max(fontMetrics.stringWidth(word), widestWordWidth);
diff --git a/platform/platform-impl/src/com/intellij/ui/messages/SheetMessage.java b/platform/platform-impl/src/com/intellij/ui/messages/SheetMessage.java
index 446722c081e4..fee84330f0a2 100755
--- a/platform/platform-impl/src/com/intellij/ui/messages/SheetMessage.java
+++ b/platform/platform-impl/src/com/intellij/ui/messages/SheetMessage.java
@@ -70,6 +70,8 @@ public class SheetMessage {
final Component recentFocusOwner = activeWindow == null ? null : activeWindow.getMostRecentFocusOwner();
beforeShowFocusOwner = new WeakReference<Component>(recentFocusOwner);
+ maximizeIfNeeded(owner);
+
myWindow = new JDialog(owner, "This should not be shown", Dialog.ModalityType.APPLICATION_MODAL);
myWindow.getRootPane().putClientProperty("apple.awt.draggableWindowBackground", Boolean.FALSE);
@@ -132,6 +134,16 @@ public class SheetMessage {
}
+ private static void maximizeIfNeeded(final Window owner) {
+ if (owner == null) return;
+ if (owner instanceof Frame) {
+ Frame f = (Frame)owner;
+ if (f.getState() == Frame.ICONIFIED) {
+ f.setState(Frame.NORMAL);
+ }
+ }
+ }
+
private void setWindowOpacity(float opacity) {
try {
Method setOpacityMethod = myWindow.getClass().getMethod("setOpacity", Float.TYPE);
diff --git a/platform/platform-impl/src/com/intellij/ui/popup/WizardPopup.java b/platform/platform-impl/src/com/intellij/ui/popup/WizardPopup.java
index 04c38a6cc295..1b9190f6a740 100644
--- a/platform/platform-impl/src/com/intellij/ui/popup/WizardPopup.java
+++ b/platform/platform-impl/src/com/intellij/ui/popup/WizardPopup.java
@@ -177,15 +177,19 @@ public abstract class WizardPopup extends AbstractPopup implements ActionListene
LOG.assertTrue (!isDisposed());
Rectangle targetBounds = new Rectangle(new Point(aScreenX, aScreenY), getContent().getPreferredSize());
- ScreenUtil.moveRectangleToFitTheScreen(targetBounds);
if (getParent() != null) {
final Rectangle parentBounds = getParent().getBounds();
parentBounds.x += STEP_X_PADDING;
parentBounds.width -= STEP_X_PADDING * 2;
+ ScreenUtil.moveToFit(targetBounds, ScreenUtil.getScreenRectangle(
+ parentBounds.x + parentBounds.width / 2,
+ parentBounds.y + parentBounds.height / 2), null);
if (parentBounds.intersects(targetBounds)) {
targetBounds.x = getParent().getBounds().x - targetBounds.width - STEP_X_PADDING;
}
+ } else {
+ ScreenUtil.moveToFit(targetBounds, ScreenUtil.getScreenRectangle(aScreenX, aScreenY), null);
}
if (getParent() == null) {
diff --git a/platform/platform-impl/src/net/sf/cglib/proxy/AdvancedEnhancer.java b/platform/platform-impl/src/net/sf/cglib/proxy/AdvancedEnhancer.java
index 5b22e706508a..a2f21c3d0018 100644
--- a/platform/platform-impl/src/net/sf/cglib/proxy/AdvancedEnhancer.java
+++ b/platform/platform-impl/src/net/sf/cglib/proxy/AdvancedEnhancer.java
@@ -15,7 +15,7 @@
*/
package net.sf.cglib.proxy;
-import com.intellij.ide.plugins.PluginManager;
+import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.ide.plugins.cl.PluginClassLoader;
import com.intellij.util.ReflectionUtil;
import net.sf.cglib.core.*;
@@ -26,6 +26,7 @@ import org.objectweb.asm.Type;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
import java.util.*;
/**
@@ -61,6 +62,7 @@ import java.util.*;
* <code>java.lang.reflect.Proxy</code>, see the {@link Proxy} class.
*/
+@SuppressWarnings("StaticFieldReferencedViaSubclass")
public class AdvancedEnhancer extends AbstractClassGenerator
{
private static final CallbackFilter ALL_ZERO = new CallbackFilter(){
@@ -125,7 +127,7 @@ public class AdvancedEnhancer extends AbstractClassGenerator
/** Internal interface, only public due to ClassLoader issues. */
public interface EnhancerKey {
- public Object newInstance(String type,
+ Object newInstance(String type,
String[] interfaces,
CallbackFilter filter,
Type[] callbackTypes,
@@ -250,18 +252,6 @@ public class AdvancedEnhancer extends AbstractClassGenerator
}
/**
- * Set the single type of {@link Callback} to use.
- * This may be used instead of {@link #setCallback} when calling
- * {@link #createClass}, since it may not be possible to have
- * an array of actual callback instances.
- * @param callbackType the type of callback to use for all methods
- * @see #setCallbackTypes
- */
- public void setCallbackType(Class callbackType) {
- setCallbackTypes(new Class[]{ callbackType });
- }
-
- /**
* Set the array of callback types to use.
* This may be used instead of {@link #setCallbacks} when calling
* {@link #createClass}, since it may not be possible to have
@@ -315,27 +305,6 @@ public class AdvancedEnhancer extends AbstractClassGenerator
}
}
- /**
- * Generate a new class if necessary and return it without creating a new instance.
- * This ignores any callbacks that have been set.
- * To create a new instance you will have to use reflection, and methods
- * called during the constructor will not be intercepted. To avoid this problem,
- * use the multi-arg <code>create</code> method.
- * @see #create(Class[], Object[])
- */
- public Class createClass() {
- classOnly = true;
- return (Class)createHelper();
- }
-
- /**
- * Insert a static serialVersionUID field into the generated class.
- * @param sUID the field value, or null to avoid generating field.
- */
- public void setSerialVersionUID(Long sUID) {
- serialVersionUID = sUID;
- }
-
private void validate() {
if (classOnly ^ (callbacks == null)) {
if (classOnly) {
@@ -401,7 +370,7 @@ public class AdvancedEnhancer extends AbstractClassGenerator
for (final Class anInterface : interfaces) {
final ClassLoader loader = anInterface.getClassLoader();
if (loader instanceof PluginClassLoader) {
- final int order = PluginManager.getPluginLoadingOrder(((PluginClassLoader)loader).getPluginId());
+ final int order = PluginManagerCore.getPluginLoadingOrder(((PluginClassLoader)loader).getPluginId());
if (maxIndex < order) {
maxIndex = order;
bestLoader = loader;
@@ -413,7 +382,7 @@ public class AdvancedEnhancer extends AbstractClassGenerator
if (superclass != null) {
superLoader = superclass.getClassLoader();
if (superLoader instanceof PluginClassLoader &&
- maxIndex < PluginManager.getPluginLoadingOrder(((PluginClassLoader)superLoader).getPluginId())) {
+ maxIndex < PluginManagerCore.getPluginLoadingOrder(((PluginClassLoader)superLoader).getPluginId())) {
return superLoader;
}
}
@@ -426,24 +395,6 @@ public class AdvancedEnhancer extends AbstractClassGenerator
sig.getDescriptor());
}
- /**
- * Finds all of the methods that will be extended by an
- * Enhancer-generated class using the specified superclass and
- * interfaces. This can be useful in building a list of Callback
- * objects. The methods are added to the end of the given list. Due
- * to the subclassing nature of the classes generated by Enhancer,
- * the methods are guaranteed to be non-static, non-final, and
- * non-private. Each method signature will only occur once, even if
- * it occurs in multiple classes.
- * @param superclass the class that will be extended, or null
- * @param interfaces the list of interfaces that will be implemented, or null
- * @param methods the list into which to copy the applicable methods
- */
- public static void getMethods(Class superclass, Class[] interfaces, List<Method> methods)
- {
- getMethods(superclass, interfaces, methods, null, null);
- }
-
private static void getMethods(Class superclass, Class[] interfaces, List<Method> methods, List<Method> interfaceMethods, Set forcePublic)
{
ReflectUtils.addAllMethods(superclass, methods);
@@ -520,6 +471,9 @@ public class AdvancedEnhancer extends AbstractClassGenerator
}
final Map<Method, MethodInfo> methodInfoMap = new HashMap<Method, MethodInfo>();
for (Method method : actualMethods) {
+ if (isJdk8DefaultMethod(method)) {
+ continue;
+ }
int modifiers =
Constants.ACC_FINAL | (method.getModifiers() & ~Constants.ACC_ABSTRACT & ~Constants.ACC_NATIVE & ~Constants.ACC_SYNCHRONIZED);
if (forcePublic.contains(MethodWrapper.create(method))) {
@@ -551,6 +505,11 @@ public class AdvancedEnhancer extends AbstractClassGenerator
e.end_class();
}
+ private static boolean isJdk8DefaultMethod(Method method) {
+ return ((method.getModifiers() & (Modifier.ABSTRACT | Modifier.PUBLIC | Modifier.STATIC)) ==
+ Modifier.PUBLIC) && method.getDeclaringClass().isInterface();
+ }
+
private static void removeAllCovariantMethods(final List<Method> actualMethods, final Method method, final Map<Method, Method> covariantMethods) {
if ((method.getModifiers() & Constants.ACC_SYNTHETIC) != 0) {
return;
@@ -618,57 +577,6 @@ public class AdvancedEnhancer extends AbstractClassGenerator
}
}
- /**
- * Call this method to register the {@link Callback} array to use before
- * creating a new instance of the generated class via reflection. If you are using
- * an instance of <code>Enhancer</code> or the {@link Factory} interface to create
- * new instances, this method is unnecessary. Its primary use is for when you want to
- * cache and reuse a generated class yourself, and the generated class does
- * <i>not</i> implement the {@link Factory} interface.
- * <p>
- * Note that this method only registers the callbacks on the current thread.
- * If you want to register callbacks for instances created by multiple threads,
- * use {@link #registerStaticCallbacks}.
- * <p>
- * The registered callbacks are overwritten and subsequently cleared
- * when calling any of the <code>create</code> methods (such as
- * {@link #create}).
- * @param generatedClass a class previously created by {@link Enhancer}
- * @param callbacks the array of callbacks to use when instances of the generated
- * class are created
- * @see #setUseFactory
- */
- public static void registerCallbacks(Class generatedClass, Callback[] callbacks) {
- setThreadCallbacks(generatedClass, callbacks);
- }
-
- /**
- * Similar to {@link #registerCallbacks}, but suitable for use
- * when multiple threads will be creating instances of the generated class.
- * The thread-level callbacks will always override the static callbacks.
- * Static callbacks are never cleared.
- * @param generatedClass a class previously created by {@link Enhancer}
- * @param callbacks the array of callbacks to use when instances of the generated
- * class are created
- */
- public static void registerStaticCallbacks(Class generatedClass, Callback[] callbacks) {
- setCallbacksHelper(generatedClass, callbacks, SET_STATIC_CALLBACKS_NAME);
- }
-
- /**
- * Determine if a class was generated using <code>Enhancer</code>.
- * @param type any class
- * @return whether the class was generated using <code>Enhancer</code>
- */
- public static boolean isEnhanced(Class type) {
- try {
- getCallbacksSetter(type, SET_THREAD_CALLBACKS_NAME);
- return true;
- } catch (NoSuchMethodException e) {
- return false;
- }
- }
-
private static void setThreadCallbacks(Class type, Callback[] callbacks) {
setCallbacksHelper(type, callbacks, SET_THREAD_CALLBACKS_NAME);
}
@@ -710,54 +618,6 @@ public class AdvancedEnhancer extends AbstractClassGenerator
}
}
- /**
- * Helper method to create an intercepted object.
- * For finer control over the generated instance, use a new instance of <code>Enhancer</code>
- * instead of this static method.
- * @param type class to extend or interface to implement
- * @param callback the callback to use for all methods
- */
- public static Object create(Class type, Callback callback) {
- Enhancer e = new Enhancer();
- e.setSuperclass(type);
- e.setCallback(callback);
- return e.create();
- }
-
- /**
- * Helper method to create an intercepted object.
- * For finer control over the generated instance, use a new instance of <code>Enhancer</code>
- * instead of this static method.
- * @param type class to extend or interface to implement
- * @param interfaces array of interfaces to implement, or null
- * @param callback the callback to use for all methods
- */
- public static Object create(Class superclass, Class interfaces[], Callback callback) {
- Enhancer e = new Enhancer();
- e.setSuperclass(superclass);
- e.setInterfaces(interfaces);
- e.setCallback(callback);
- return e.create();
- }
-
- /**
- * Helper method to create an intercepted object.
- * For finer control over the generated instance, use a new instance of <code>Enhancer</code>
- * instead of this static method.
- * @param type class to extend or interface to implement
- * @param interfaces array of interfaces to implement, or null
- * @param filter the callback filter to use when generating a new class
- * @param callbacks callback implementations to use for the enhanced object
- */
- public static Object create(Class superclass, Class[] interfaces, CallbackFilter filter, Callback[] callbacks) {
- Enhancer e = new Enhancer();
- e.setSuperclass(superclass);
- e.setInterfaces(interfaces);
- e.setCallbackFilter(filter);
- e.setCallbacks(callbacks);
- return e.create();
- }
-
private void emitConstructors(ClassEmitter ce, List constructors) {
boolean seenNull = false;
for (final Object constructor1 : constructors) {
@@ -791,7 +651,7 @@ public class AdvancedEnhancer extends AbstractClassGenerator
return keys;
}
- private void emitGetCallback(ClassEmitter ce, int[] keys) {
+ private static void emitGetCallback(ClassEmitter ce, int[] keys) {
final CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, GET_CALLBACK, null);
e.load_this();
e.invoke_static_this(BIND_CALLBACKS);
@@ -866,14 +726,14 @@ public class AdvancedEnhancer extends AbstractClassGenerator
e.end_method();
}
- private void emitNewInstanceCallbacks(ClassEmitter ce) {
+ private static void emitNewInstanceCallbacks(ClassEmitter ce) {
CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, NEW_INSTANCE, null);
e.load_arg(0);
e.invoke_static_this(SET_THREAD_CALLBACKS);
emitCommonNewInstance(e);
}
- private void emitCommonNewInstance(CodeEmitter e) {
+ private static void emitCommonNewInstance(CodeEmitter e) {
e.new_instance_this();
e.dup();
e.invoke_constructor_this();
@@ -905,7 +765,7 @@ public class AdvancedEnhancer extends AbstractClassGenerator
emitCommonNewInstance(e);
}
- private void emitNewInstanceMultiarg(ClassEmitter ce, List constructors) {
+ private static void emitNewInstanceMultiarg(ClassEmitter ce, List constructors) {
final CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, MULTIARG_NEW_INSTANCE, null);
e.load_arg(2);
e.invoke_static_this(SET_THREAD_CALLBACKS);
@@ -1034,7 +894,7 @@ public class AdvancedEnhancer extends AbstractClassGenerator
se.end_method();
}
- private void emitSetThreadCallbacks(ClassEmitter ce) {
+ private static void emitSetThreadCallbacks(ClassEmitter ce) {
CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC | Constants.ACC_STATIC,
SET_THREAD_CALLBACKS,
null);
@@ -1045,7 +905,7 @@ public class AdvancedEnhancer extends AbstractClassGenerator
e.end_method();
}
- private void emitSetStaticCallbacks(ClassEmitter ce) {
+ private static void emitSetStaticCallbacks(ClassEmitter ce) {
CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC | Constants.ACC_STATIC,
SET_STATIC_CALLBACKS,
null);
@@ -1055,7 +915,7 @@ public class AdvancedEnhancer extends AbstractClassGenerator
e.end_method();
}
- private void emitCurrentCallback(CodeEmitter e, int index) {
+ private static void emitCurrentCallback(CodeEmitter e, int index) {
e.load_this();
e.getfield(getCallbackField(index));
e.dup();
diff --git a/platform/platform-impl/src/org/jetbrains/io/BuiltInServer.java b/platform/platform-impl/src/org/jetbrains/io/BuiltInServer.java
index 7310b936246d..cba4a70487b3 100644
--- a/platform/platform-impl/src/org/jetbrains/io/BuiltInServer.java
+++ b/platform/platform-impl/src/org/jetbrains/io/BuiltInServer.java
@@ -17,6 +17,7 @@ package org.jetbrains.io;
import com.intellij.ide.XmlRpcServer;
import com.intellij.openapi.Disposable;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.SystemInfo;
@@ -91,6 +92,10 @@ public class BuiltInServer implements Disposable {
}
private void bindCustomPorts(int firstPort, int port, NioEventLoopGroup eventLoopGroup) {
+ if (ApplicationManager.getApplication().isUnitTestMode()) {
+ return;
+ }
+
for (CustomPortServerManager customPortServerManager : CustomPortServerManager.EP_NAME.getExtensions()) {
try {
int customPortServerManagerPort = customPortServerManager.getPort();
diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties
index 50500e895c48..05f2cd2f8f70 100644
--- a/platform/platform-resources-en/src/messages/ActionsBundle.properties
+++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties
@@ -251,8 +251,6 @@ action.NewModule.text=New _Module...
action.NewModule.description=Create new module from scratch and add it to the project
action.ImportProject.description=Create project structure for directory with existing sources or convert existing project model
action.ImportModule.description=Import module from directory with existing sources or from existing project model
-action.OpenProject.text=Open Project...
-action.OpenProject.description=Open an existing project
action.OpenFile.text=_Open...
action.OpenFile.description=Open a project or a file in editor
group.reopen.win.text=_Reopen Project
diff --git a/platform/platform-resources-en/src/messages/IdeBundle.properties b/platform/platform-resources-en/src/messages/IdeBundle.properties
index 05e73117e044..3b3773a07e06 100644
--- a/platform/platform-resources-en/src/messages/IdeBundle.properties
+++ b/platform/platform-resources-en/src/messages/IdeBundle.properties
@@ -243,6 +243,7 @@ button.no=_No
error.project.file.does.not.exist=Cannot load {0}. The file does not exist.
error.file.does.not.exist=File {0} does not exist.
title.open.project=Open Project
+title.open.file.or.project=Open File or Project
button.cancel=&Cancel
error.cannot.load.project=Cannot load project: {0}
title.cannot.load.project=Cannot Load Project
@@ -255,7 +256,7 @@ conversion.dialog.text.2=<b> </b><a href=\"details\">Details...</a><br/><br/>Old
message.text.unlock.read.only.files=<html><body>The following files are read only. {0} will unlock them.<br>{1}</body></html>
error.message.cannot.make.files.writable=Cannot make the following files writable:\n{0}
error.cannot.convert.project=Cannot convert project: {0}
-message.files.doesn.t.exists.0.so.the.corresponding.modules.won.t.be.converted.do.you.want.to.continue=<html><body>The following files don''t exists: <br>\
+message.text.files.do.not.exist=<html><body>The following files don''t exists: <br>\
{0}The corresponding modules won''t be converted. Do you want to continue?</body></html>
select.in.project.settings=Project Structure
@@ -413,8 +414,10 @@ title.popup.new.element=New
title.popup.new.element.same.place=New in Current Directory
command.go.to.next.split=Go to next split
message.occurrence.N.of.M=Occurrence {0} of {1}
+error.dir.contains.no.project=''{0}'' does not contain a project
error.files.of.this.type.cannot.be.opened=Files of this type cannot be opened in {0}
title.cannot.open.file=Cannot Open File
+title.cannot.open.project=Cannot Open Project
filter.all.file.types=All file types
filter.project.files=Project files ({0}) or project directories (.idea)
action.unpin.tab=Unp_in Tab
@@ -556,6 +559,8 @@ action.show.modules=Show Modules
action.description.show.modules=Show/Hide Modules
action.show.libraries.contents=Show Libraries Contents
action.show.hide.library.contents=Show/Hide Library Contents
+action.show.excluded.files=Show Excluded Files
+action.show.hide.excluded.files=Show/Hide Excluded Files
action.sort.by.type=Sort by Type
action.show.structure=Show Structure
action.description.show.structure=Show structure view
diff --git a/platform/platform-resources-en/src/messages/InspectionsBundle.properties b/platform/platform-resources-en/src/messages/InspectionsBundle.properties
index a339716f031e..98e0045a31f3 100644
--- a/platform/platform-resources-en/src/messages/InspectionsBundle.properties
+++ b/platform/platform-resources-en/src/messages/InspectionsBundle.properties
@@ -167,7 +167,7 @@ inspection.parameter.can.be.local.display.name=Parameter can be local
inspection.parameter.can.be.local.problem.descriptor=Parameter can be converted to a local variable
inspection.convert.to.local.quickfix=Convert to local
-inspection.unused.return.value.display.name=Unused method return value
+inspection.unused.return.value.display.name=Method can be void
inspection.unused.return.value.problem.descriptor=Return value of the method is never used
inspection.unused.return.value.make.void.quickfix=Make Method void
diff --git a/platform/platform-resources-en/src/messages/OptionsBundle.properties b/platform/platform-resources-en/src/messages/OptionsBundle.properties
index 2a78c19bdd82..2c06b31b53f7 100644
--- a/platform/platform-resources-en/src/messages/OptionsBundle.properties
+++ b/platform/platform-resources-en/src/messages/OptionsBundle.properties
@@ -199,14 +199,30 @@ options.xml.display.name=XML
settings.panel.title=Settings
node.configurable.build.tools.display.name=Build Tools
+node.configurable.build.tools.settings.description=<html><body>\
+ Default view for Build Tools
configurable.group.appearance.settings.display.name=Appearance and Behavior
+configurable.group.appearance.settings.description=<html><body>\
+ Default view for Appearance and Behavior
configurable.group.editor.settings.display.name=Editor
+configurable.group.editor.settings.description=<html><body>\
+ Default view for Editor
configurable.group.project.settings.display.name=Current Project
+configurable.group.project.settings.description=<html><body>\
+ Default view for Current Project
configurable.group.build.settings.display.name=Build, Execution, Deployment
+configurable.group.build.settings.description=<html><body>\
+ Default view for Build, Execution, Deployment
configurable.group.language.settings.display.name=Languages and Frameworks
+configurable.group.language.settings.description=<html><body>\
+ Default view for Languages and Frameworks
configurable.group.tools.settings.display.name=Tools
+configurable.group.tools.settings.description=<html><body>\
+ Default view for Tools
configurable.group.null.settings.display.name=Other Settings
+configurable.group.null.settings.description=<html><body>\
+ Default view for Other Settings
configurable.default.project.tooltip=For default project
configurable.current.project.tooltip=For current project
diff --git a/platform/platform-resources-en/src/messages/UIBundle.properties b/platform/platform-resources-en/src/messages/UIBundle.properties
index 2a0a6ee4799d..5dd72ae735b7 100644
--- a/platform/platform-resources-en/src/messages/UIBundle.properties
+++ b/platform/platform-resources-en/src/messages/UIBundle.properties
@@ -42,6 +42,7 @@ tool.window.name.project=Project
tool.window.name.structure=Structure
tool.window.name.favorites=Favorites
tool.window.name.ant.build=Ant Build
+tool.window.name.preview=Preview
tool.window.name.debug=Debug
tool.window.name.run=Run
tool.window.name.find=Find
@@ -91,7 +92,6 @@ file.chooser.default.title=Select Path
file.chooser.save.dialog.default.title=Select File to Save
file.chooser.save.dialog.confirmation={0} already exists.\nDo you want to replace it?
file.chooser.save.dialog.confirmation.title=Confirm Save as
-file.chooser.select.object.title=Select {0}
delete.dialog.title=Delete
are.you.sure.you.want.to.delete.selected.folder.confirmation.message=Are you sure you want to delete selected folder?
are.you.sure.you.want.to.delete.selected.file.confirmation.message=Delete {0}?
diff --git a/platform/platform-resources-en/src/messages/XDebuggerBundle.properties b/platform/platform-resources-en/src/messages/XDebuggerBundle.properties
index 058e446bc896..a1300adfd1bc 100644
--- a/platform/platform-resources-en/src/messages/XDebuggerBundle.properties
+++ b/platform/platform-resources-en/src/messages/XDebuggerBundle.properties
@@ -123,3 +123,6 @@ setting.sort.alphabetically.label=Sort a&lphabetically
setting.hide.window.label=Hide debug &window on process termination
setting.focus.app.on.breakpoint.label=Focus application on breakpoint
+settings.show.window.label=Show &debug window on breakpoint
+
+showReferring.dialog.title=Referring Objects For {0}
diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml
index c338dac9848b..4aa4ef8dea94 100644
--- a/platform/platform-resources/src/META-INF/LangExtensions.xml
+++ b/platform/platform-resources/src/META-INF/LangExtensions.xml
@@ -360,25 +360,25 @@
serviceImplementation="com.intellij.codeInspection.ex.ProjectInspectionProfilesVisibleTreeState"/>
<!-- Editor -->
- <applicationConfigurable groupId="editor" instance="com.intellij.application.options.editor.EditorOptions" id="editor" key="title.editor"
+ <applicationConfigurable groupId="editor" groupWeight="190" instance="com.intellij.application.options.editor.EditorOptions" id="editor" key="title.editor"
bundle="messages.ApplicationBundle" order="after appearance"
childrenEPName="com.intellij.editorOptionsProvider"/>
<projectService serviceInterface="com.intellij.semantic.SemService" serviceImplementation="com.intellij.semantic.SemServiceImpl"/>
<!-- Global Code Style -->
- <projectConfigurable groupId="editor" dynamic="true" displayName="Code Style" instance="com.intellij.application.options.CodeStyleSchemesConfigurable" order="after colors"/>
+ <projectConfigurable groupId="editor" groupWeight="170" dynamic="true" displayName="Code Style" instance="com.intellij.application.options.CodeStyleSchemesConfigurable" order="after colors"/>
<applicationService serviceInterface="com.intellij.application.options.codeStyle.CodeStyleSchemesUIConfiguration"
serviceImplementation="com.intellij.application.options.codeStyle.CodeStyleSchemesUIConfiguration"/>
<!-- File Types -->
- <applicationConfigurable groupId="editor" instance="com.intellij.openapi.fileTypes.impl.FileTypeConfigurable" id="preferences.fileTypes"
+ <applicationConfigurable groupId="editor" groupWeight="120" instance="com.intellij.openapi.fileTypes.impl.FileTypeConfigurable" id="preferences.fileTypes"
key="filetype.settings.title" bundle="messages.FileTypesBundle"/>
<applicationConfigurable groupId="editor" key="intention.settings" bundle="messages.CodeInsightBundle" instance="com.intellij.codeInsight.intention.impl.config.IntentionSettingsConfigurable" id="intentions"/>
<!-- Live Templates -->
- <applicationConfigurable groupId="editor" instance="com.intellij.codeInsight.template.impl.LiveTemplatesConfigurable" id="editing.templates"
+ <applicationConfigurable groupId="editor" groupWeight="130" instance="com.intellij.codeInsight.template.impl.LiveTemplatesConfigurable" id="editing.templates"
key="templates.settings.page.title" bundle="messages.CodeInsightBundle"/>
<lookup.actionProvider implementation="com.intellij.codeInsight.template.impl.LiveTemplateLookupActionProvider"/>
<documentationProvider implementation="com.intellij.codeInsight.template.impl.LiveTemplateDocumentationProvider"/>
@@ -386,7 +386,7 @@
serviceImplementation="com.intellij.codeInsight.template.impl.TemplateManagerImpl"/>
<!-- File Templates-->
- <applicationConfigurable groupId="editor" instance="com.intellij.ide.fileTemplates.impl.AllFileTemplatesConfigurable" id="fileTemplates"
+ <applicationConfigurable groupId="editor" groupWeight="150" instance="com.intellij.ide.fileTemplates.impl.AllFileTemplatesConfigurable" id="fileTemplates"
key="title.file.templates" bundle="messages.IdeBundle"/>
<!-- T.O.D.O -->
@@ -394,7 +394,7 @@
bundle="messages.IdeBundle"/>
<!-- External Tools -->
- <applicationConfigurable groupId="tools" instance="com.intellij.tools.ToolConfigurable" id="preferences.externalTools" key="tools.settings.title"
+ <applicationConfigurable groupId="tools" groupWeight="140" instance="com.intellij.tools.ToolConfigurable" id="preferences.externalTools" key="tools.settings.title"
bundle="messages.ToolsBundle"/>
<stepsBeforeRunProvider implementation="com.intellij.tools.ToolBeforeRunTaskProvider"/>
<checkinHandlerFactory implementation="com.intellij.tools.ExternalToolsCheckinHandlerFactory"/>
@@ -613,7 +613,7 @@
<editorCustomization implementation="com.intellij.ui.RightMarginEditorCustomization"/>
<!-- Colors & Fonts-->
- <applicationConfigurable groupId="editor" dynamic="true" instance="com.intellij.application.options.colors.ColorAndFontOptions"
+ <applicationConfigurable groupId="editor" groupWeight="180" dynamic="true" instance="com.intellij.application.options.colors.ColorAndFontOptions"
id="reference.settingsdialog.IDE.editor.colors"/>
<editorOptionsProvider instance="com.intellij.application.options.editor.EditorTabsConfigurable" id="editor.preferences.tabs"
displayName="Editor Tabs"/>
@@ -753,7 +753,7 @@
<psi.fileReferenceHelper implementation="com.intellij.psi.impl.source.resolve.reference.impl.providers.HttpFileReferenceHelper"/>
<psi.fileReferenceHelper implementation="com.intellij.psi.impl.source.resolve.reference.impl.providers.NullFileReferenceHelper" order="last"/>
- <projectConfigurable groupId="editor" key="file.encodings.configurable" bundle="messages.IdeBundle" instance="com.intellij.openapi.vfs.encoding.FileEncodingConfigurable"/>
+ <projectConfigurable groupId="editor" groupWeight="140" key="file.encodings.configurable" bundle="messages.IdeBundle" instance="com.intellij.openapi.vfs.encoding.FileEncodingConfigurable"/>
<projectConfigurable groupId="appearance" instance="com.intellij.ui.tabs.FileColorsConfigurable" id="fileColors" displayName="File Colors"/>
<uiDebuggerExtension implementation="com.intellij.ui.debugger.extensions.PlaybackDebugger"/>
diff --git a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml
index a4dfd49a71a8..baea70a67c7a 100644
--- a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml
+++ b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml
@@ -9,6 +9,9 @@
<extensionPoint name="postStartupActivity"
interface="com.intellij.openapi.startup.StartupActivity"/>
+ <extensionPoint name="defaultProjectTypeProvider"
+ interface="com.intellij.openapi.project.DefaultProjectTypeProvider"/>
+
<extensionPoint name="errorHandler"
interface="com.intellij.openapi.diagnostic.ErrorReportSubmitter"/>
diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml
index 467ef8233919..51028d93edac 100644
--- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml
+++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml
@@ -155,6 +155,7 @@
serviceImplementation="com.intellij.openapi.vcs.readOnlyHandler.ReadonlyStatusHandlerImpl"/>
<projectService serviceInterface="com.intellij.openapi.startup.StartupManager"
serviceImplementation="com.intellij.ide.startup.impl.StartupManagerImpl"/>
+ <projectService serviceImplementation="com.intellij.openapi.project.ProjectTypeService"/>
<projectService serviceInterface="com.intellij.openapi.ui.MasterDetailsStateService" serviceImplementation="com.intellij.openapi.ui.MasterDetailsStateService"/>
<projectService serviceInterface="com.intellij.ide.SelectInManager" serviceImplementation="com.intellij.ide.SelectInManager"/>
@@ -197,14 +198,14 @@
serviceImplementation="com.intellij.openapi.editor.impl.LazyRangeMarkerFactoryImpl"/>
<!-- General -->
- <applicationConfigurable groupId="appearance" key="title.general" bundle="messages.IdeBundle" id="preferences.general" instance="com.intellij.ide.GeneralSettingsConfigurable"/>
+ <applicationConfigurable groupId="appearance" groupWeight="120" key="title.general" bundle="messages.IdeBundle" id="preferences.general" instance="com.intellij.ide.GeneralSettingsConfigurable"/>
<!-- Appearance -->
- <applicationConfigurable groupId="appearance" instance="com.intellij.ide.ui.AppearanceConfigurable" id="appearance" key="title.appearance"
+ <applicationConfigurable groupId="appearance" groupWeight="150" instance="com.intellij.ide.ui.AppearanceConfigurable" id="appearance" key="title.appearance"
bundle="messages.IdeBundle"/>
<!-- Keymap -->
- <applicationConfigurable groupId="appearance" instance="com.intellij.openapi.keymap.impl.ui.KeymapPanel" id="preferences.keymap" key="keymap.display.name"
+ <applicationConfigurable groupId="appearance" groupWeight="140" instance="com.intellij.openapi.keymap.impl.ui.KeymapPanel" id="preferences.keymap" key="keymap.display.name"
bundle="messages.KeyMapBundle"/>
<applicationConfigurable parentId="appearance" instance="com.intellij.openapi.keymap.impl.ui.QuickListsPanel" id="reference.idesettings.quicklists"
displayName="Quick Lists"/>
@@ -214,13 +215,13 @@
key="title.customizations" bundle="messages.IdeBundle"/>
<!-- Notifications -->
- <applicationConfigurable groupId="appearance" displayName="Notifications" instance="com.intellij.notification.impl.NotificationsConfigurable"/>
+ <applicationConfigurable groupId="appearance" groupWeight="110" displayName="Notifications" instance="com.intellij.notification.impl.NotificationsConfigurable"/>
<!-- Plugins -->
- <applicationConfigurable groupId="appearance" instance="com.intellij.ide.plugins.PluginManagerConfigurable" id="preferences.pluginManager"
+ <applicationConfigurable groupId="appearance" groupWeight="130" instance="com.intellij.ide.plugins.PluginManagerConfigurable" id="preferences.pluginManager"
displayName="Plugins"/>
<actionFromOptionDescriptorProvider implementation="com.intellij.ide.plugins.InstalledPluginsManagerMain$PluginsActionFromOptionDescriptorProvider"/>
- <applicationConfigurable parentId="preferences.general" instance="com.intellij.util.net.HTTPProxySettingsPanel" id="http.proxy" displayName="HTTP Proxy" />
+ <applicationConfigurable parentId="preferences.general" instance="com.intellij.util.net.HttpProxyConfigurable" id="http.proxy" displayName="HTTP Proxy"/>
<applicationConfigurable groupId="tools" displayName="Server Certificates" instance="com.intellij.util.net.ssl.CertificateConfigurable"/>
<applicationConfigurable groupId="tools" instance="com.intellij.openapi.diff.impl.external.DiffOptionsForm" id="diff" displayName="External Diff Tools" />
<!--<applicationConfigurable instance="com.intellij.ui.switcher.QuickAccessConfigurable"/>-->
@@ -250,7 +251,7 @@
<componentConfigurationMerger implementation="com.intellij.openapi.vcs.changes.shelf.ShelfManagerConfigurationMerger"/>
<editorActionHandler action="EditorEscape" implementationClass="com.intellij.codeInsight.hint.EscapeHandler" id="hide-hints"/>
- <projectConfigurable groupId="language" instance="com.intellij.javaee.ExternalResourceConfigurable" key="display.name.edit.external.resource"
+ <projectConfigurable groupId="language" groupWeight="110" instance="com.intellij.javaee.ExternalResourceConfigurable" key="display.name.edit.external.resource"
bundle="messages.XmlBundle" id="preferences.externalResources">
<configurable instance="com.intellij.javaee.XMLCatalogConfigurable" displayName="XML Catalog" id="xml.catalog"/>
</projectConfigurable>
diff --git a/platform/platform-resources/src/META-INF/PlatformLangPlugin.xml b/platform/platform-resources/src/META-INF/PlatformLangPlugin.xml
index ea14882e5ae6..b675e6491e09 100644
--- a/platform/platform-resources/src/META-INF/PlatformLangPlugin.xml
+++ b/platform/platform-resources/src/META-INF/PlatformLangPlugin.xml
@@ -81,7 +81,7 @@
<programRunner implementation="com.intellij.execution.runners.BasicProgramRunner" order="last"/>
- <projectConfigurable groupId="editor" displayName="Inspections" provider="com.intellij.profile.codeInspection.ui.ProjectInspectionToolsConfigurableProvider" order="before intentions"/>
+ <projectConfigurable groupId="editor" groupWeight="160" displayName="Inspections" provider="com.intellij.profile.codeInspection.ui.ProjectInspectionToolsConfigurableProvider" order="before intentions"/>
<projectConfigurable groupId="project" instance="com.intellij.ide.util.scopeChooser.ScopeChooserConfigurable" id="project.scopes" key="scopes.display.name" bundle="messages.IdeBundle" />
<checkoutCompletedListener implementation="com.intellij.openapi.vcs.checkout.PlatformProjectCheckoutListener" id="PlatformProjectCheckoutListener"/>
diff --git a/platform/platform-resources/src/META-INF/VcsExtensions.xml b/platform/platform-resources/src/META-INF/VcsExtensions.xml
index a05f28107034..2322381c3b89 100644
--- a/platform/platform-resources/src/META-INF/VcsExtensions.xml
+++ b/platform/platform-resources/src/META-INF/VcsExtensions.xml
@@ -25,7 +25,7 @@
<selectInTarget implementation="com.intellij.openapi.vcs.changes.SelectInChangesViewTarget"/>
- <projectConfigurable groupId="project" dynamic="true" key="version.control.main.configurable.name" bundle="messages.VcsBundle" instance="com.intellij.openapi.vcs.configurable.VcsManagerConfigurable" id="vcs"/>
+ <projectConfigurable groupId="project" groupWeight="110" dynamic="true" key="version.control.main.configurable.name" bundle="messages.VcsBundle" instance="com.intellij.openapi.vcs.configurable.VcsManagerConfigurable" id="vcs"/>
<changesViewContent tabName="Repository" className="com.intellij.openapi.vcs.changes.committed.CommittedChangesViewManager"
predicateClassName="com.intellij.openapi.vcs.changes.committed.CommittedChangesVisibilityPredicate"/>
diff --git a/platform/platform-resources/src/META-INF/XmlPlugin.xml b/platform/platform-resources/src/META-INF/XmlPlugin.xml
index 525ea3c94540..566d674d0063 100644
--- a/platform/platform-resources/src/META-INF/XmlPlugin.xml
+++ b/platform/platform-resources/src/META-INF/XmlPlugin.xml
@@ -329,6 +329,7 @@
<!--
<copyPastePreProcessor implementation="com.intellij.codeInsight.editorActions.XmlCopyPastePreProcessor"/>
+ <copyPastePreProcessor implementation="com.intellij.codeInsight.editorActions.HtmlCopyPastePreProcessor"/>
-->
<syntaxHighlighter key="IDEA_PROJECT" implementationClass="com.intellij.ide.highlighter.XmlFileHighlighter"/>
@@ -531,7 +532,7 @@
<selectInTarget implementation="com.intellij.ide.browsers.actions.SelectInDefaultBrowserTarget"/>
<xml.xmlExtension implementation="com.intellij.xml.HtmlXmlExtension"/>
- <applicationConfigurable groupId="tools" instance="com.intellij.ide.browsers.BrowserSettings" id="reference.settings.ide.settings.web.browsers"
+ <applicationConfigurable groupId="tools" groupWeight="160" instance="com.intellij.ide.browsers.BrowserSettings" id="reference.settings.ide.settings.web.browsers"
key="browsers.settings" bundle="messages.IdeBundle"/>
<lang.inspectionSuppressor language="XML" implementationClass="com.intellij.codeInspection.XmlInspectionSuppressor"/>
diff --git a/platform/platform-resources/src/META-INF/mime.types b/platform/platform-resources/src/META-INF/mime.types
index 699aa1b3058b..9338bb4957fe 100644
--- a/platform/platform-resources/src/META-INF/mime.types
+++ b/platform/platform-resources/src/META-INF/mime.types
@@ -86,4 +86,6 @@
video/x-msvideo avi
application/x-chrome-extension crx
-application/dart dart \ No newline at end of file
+application/dart dart
+
+text/xml rng \ No newline at end of file
diff --git a/platform/platform-resources/src/META-INF/xdebugger.xml b/platform/platform-resources/src/META-INF/xdebugger.xml
index 4dde33287f0c..d28921d17ba6 100644
--- a/platform/platform-resources/src/META-INF/xdebugger.xml
+++ b/platform/platform-resources/src/META-INF/xdebugger.xml
@@ -39,5 +39,7 @@
<editor.linePainter implementation="com.intellij.xdebugger.impl.evaluate.XDebuggerEditorLinePainter"/>
<executor implementation="com.intellij.execution.executors.DefaultDebugExecutor" order="first,after run"/>
+
+ <copyPastePreProcessor implementation="com.intellij.xdebugger.impl.ui.DebuggerCopyPastePreprocessor"/>
</extensions>
</idea-plugin>
diff --git a/platform/platform-resources/src/brokenPlugins.txt b/platform/platform-resources/src/brokenPlugins.txt
index 7b0830e86b02..584c3a466615 100644
--- a/platform/platform-resources/src/brokenPlugins.txt
+++ b/platform/platform-resources/src/brokenPlugins.txt
@@ -1,18 +1,18 @@
// This file contains list of broken plugins.
// Each line contains plugin ID and list of versions that are broken.
// If plugin name or version contains a space you can quote it like in command line.
-NodeJS 138.1189 138.1145 138.937 138.1013 138.921 138.447 138.172 138.317 138.21 138.35 138.96 138.85 136.1205 134.1276 134.1163 134.1145 134.1081 134.1039 134.985 134.680 134.31 134.307 134.262 134.198 134.125 136.1141
-com.jetbrains.php 138.1161 138.826 136.1768 136.1672 134.1456 133.982 133.679 133.51 133.326 131.98 131.374 131.332 131.235 131.205 130.1639 130.1481 130.1176 129.91 129.814 129.672 129.362 127.67 127.100 126.334 123.66 122.875 121.62 121.390 121.215 121.12
+NodeJS 138.1367 138.1495 138.1189 138.1145 138.937 138.1013 138.921 138.447 138.172 138.317 138.21 138.35 138.96 138.85 136.1205 134.1276 134.1163 134.1145 134.1081 134.1039 134.985 134.680 134.31 134.307 134.262 134.198 134.125 136.1141
+com.jetbrains.php 138.1505 138.1161 138.826 136.1768 136.1672 134.1456 133.982 133.679 133.51 133.326 131.98 131.374 131.332 131.235 131.205 130.1639 130.1481 130.1176 129.91 129.814 129.672 129.362 127.67 127.100 126.334 123.66 122.875 121.62 121.390 121.215 121.12
com.jetbrains.lang.ejs 131.17 131.12
com.jetbrains.twig 133.51 130.1639
-org.jetbrains.plugins.ruby 6.0.0.20140207 6.5.2.20140512 7.0.0.20140704 7.0.0.20140707 7.0.0.20140724
-Pythonid 3.1 4.0.25
-Karma 138.21 134.1163 134.1039 134.686 134.31
-org.intellij.scala 0.42.23 0.40.20 0.40.18 0.40.16 0.32.593 0.32.562 0.32.558 0.32.550 0.32.520 0.32.512
+org.jetbrains.plugins.ruby 7.0.0.20140807 6.0.0.20140207 6.5.2.20140512 7.0.0.20140704 7.0.0.20140707 7.0.0.20140724
+Pythonid 3.1 4.0.25 4.0.26
+Karma 138.317 138.21 134.1163 134.1039 134.686 134.31
+org.intellij.scala 0.42.28 0.42.23 0.40.20 0.40.18 0.40.16 0.32.593 0.32.562 0.32.558 0.32.550 0.32.520 0.32.512
org.jetbrains.kannotator 0.2.420
org.jetbrains.kotlin 0.7.1360 0.7.1376 0.8.7
SBT 1.0.0 1.1.0 1.2.0 1.3.0 1.3.1 1.4.0 1.5.0
-"JSTestDriver Plugin" 138.21 136.1141 134.1163 134.686 134.31 134.307 134.1039
+"JSTestDriver Plugin" 138.317 138.21 136.1141 134.1163 134.686 134.31 134.307 134.1039
AngularJS 134.1094 0.1.8 0.1.9
org.jetbrains.plugins.vagrant 0.1 0.2
org.intellij.clojure 0.2.1.178
diff --git a/platform/platform-resources/src/idea/LangActions.xml b/platform/platform-resources/src/idea/LangActions.xml
index 3b0289f12433..39957743629d 100644
--- a/platform/platform-resources/src/idea/LangActions.xml
+++ b/platform/platform-resources/src/idea/LangActions.xml
@@ -683,6 +683,7 @@
<action id="XDebugger.ToggleSortValues" class="com.intellij.xdebugger.impl.ui.tree.actions.SortValuesToggleAction" icon="AllIcons.ObjectBrowser.Sorted"/>
<action id="Debugger.MarkObject" class="com.intellij.xdebugger.impl.actions.MarkObjectAction"/>
<action id="Debugger.FocusOnBreakpoint" class="com.intellij.xdebugger.impl.actions.FocusOnBreakpointAction"/>
+ <action id="Debugger.ShowReferring" class="com.intellij.xdebugger.impl.ui.tree.actions.ShowReferringObjectsAction"/>
</group>
<group id="XDebugger.ToolWindow.TopToolbar">
@@ -698,7 +699,6 @@
</group>
<group id="XDebugger.ToolWindow.LeftToolbar">
- <reference ref="Rerun"/>
<reference ref="Resume"/>
<reference ref="Pause"/>
<reference ref="Stop"/>
@@ -709,6 +709,7 @@
<group id="XDebugger.ValueGroup" popup="false">
<reference ref="XDebugger.Inspect"/>
+ <reference ref="Debugger.ShowReferring"/>
<reference ref="Debugger.MarkObject"/>
<reference ref="XDebugger.SetValue"/>
<reference ref="XDebugger.CopyValue"/>
diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml
index 7773a2b00e49..0c970d8e802f 100644
--- a/platform/platform-resources/src/idea/PlatformActions.xml
+++ b/platform/platform-resources/src/idea/PlatformActions.xml
@@ -611,6 +611,8 @@
<action id="TestMessageBoxAction" internal="true" class="com.intellij.diagnostic.TestMessageBoxAction" text="Show Test Dialog"/>
<separator/>
<group id="Internal.focusAndModality" popup="true" text="Focus and modality testing">
+ <action id="ShowDelayedMessageInternalAction" internal="true" class="com.intellij.notification.impl.actions.ShowDelayedMessageInternalAction"
+ text="Show Delayed Message"/>
<action id="ManualMacMessagesTest" internal="true" class="com.intellij.internal.validation.MacMessagesTest"
text="Manual test for testing MacMessages"/>
<action id="MacMessagesSequencesTest" internal="true" class="com.intellij.internal.validation.TestMacMessagesSequencesAction"
diff --git a/platform/platform-tests/testSrc/com/intellij/codeInsight/actions/ReformatOnlyVcsChangedTextTest.java b/platform/platform-tests/testSrc/com/intellij/codeInsight/actions/ReformatOnlyVcsChangedTextTest.java
index 476bd66ddde4..d66988ab2ef5 100644
--- a/platform/platform-tests/testSrc/com/intellij/codeInsight/actions/ReformatOnlyVcsChangedTextTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/codeInsight/actions/ReformatOnlyVcsChangedTextTest.java
@@ -163,6 +163,28 @@ public class ReformatOnlyVcsChangedTextTest extends LightPlatformTestCase {
);
}
+ public void testModificationCRLF() throws IOException {
+ doTest(
+ "public class B {\r\n" +
+ " int a = 3;\r\n" +
+ " String text;\r\n" +
+ " Object last = null;\r\n" +
+ " Object first = null;\r\n" +
+ " Object second = null;\r\n" +
+ "}",
+
+ "public class B {\r\n" +
+ " int a = 33;\r\n" +
+ " String text;\r\n" +
+ " Object last = new Object();\r\n" +
+ " Object first = null;\r\n" +
+ " Object second = new Object();\r\n" +
+ "}",
+
+ line(1, 1), line(3,3), line(5,5)
+ );
+ }
+
public void testReformatFiles() throws IOException {
ChangedFilesStructure fs = new ChangedFilesStructure(myWorkingDirectory);
diff --git a/platform/platform-tests/testSrc/com/intellij/execution/process/AnsiEscapeDecoderTest.java b/platform/platform-tests/testSrc/com/intellij/execution/process/AnsiEscapeDecoderTest.java
index 32ec00d1a733..df0acc766dc7 100644
--- a/platform/platform-tests/testSrc/com/intellij/execution/process/AnsiEscapeDecoderTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/execution/process/AnsiEscapeDecoderTest.java
@@ -3,47 +3,60 @@ package com.intellij.execution.process;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.testFramework.PlatformTestCase;
-import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.junit.Assert;
+import java.util.Arrays;
import java.util.List;
public class AnsiEscapeDecoderTest extends PlatformTestCase {
public void testTextWithoutColors() throws Exception {
AnsiEscapeDecoder decoder = new AnsiEscapeDecoder();
- decoder.escapeText("", ProcessOutputTypes.STDOUT, createExpectedAcceptor(ContainerUtil.newArrayList(
+ decoder.escapeText("", ProcessOutputTypes.STDOUT, createExpectedAcceptor(
Pair.create("", ProcessOutputTypes.STDOUT)
- )));
- decoder.escapeText("simple text", ProcessOutputTypes.STDOUT, createExpectedAcceptor(ContainerUtil.newArrayList(
+ ));
+ decoder.escapeText("simple text", ProcessOutputTypes.STDOUT, createExpectedAcceptor(
Pair.create("simple text", ProcessOutputTypes.STDOUT)
- )));
+ ));
}
public void testSingleColoredChunk() throws Exception {
AnsiEscapeDecoder decoder = new AnsiEscapeDecoder();
- decoder.escapeText("Chrome 35.0.1916 (Linux): Executed 0 of 1\u001B[32m SUCCESS\u001B[39m (0 secs / 0 secs)\n", ProcessOutputTypes.STDOUT, createExpectedAcceptor(ContainerUtil.newArrayList(
+ decoder.escapeText("Chrome 35.0.1916 (Linux): Executed 0 of 1\u001B[32m SUCCESS\u001B[39m (0 secs / 0 secs)\n", ProcessOutputTypes.STDOUT, createExpectedAcceptor(
Pair.create("Chrome 35.0.1916 (Linux): Executed 0 of 1", ProcessOutputTypes.STDOUT),
Pair.create(" SUCCESS", ColoredOutputTypeRegistry.getInstance().getOutputKey("\u001B[32m")),
Pair.create(" (0 secs / 0 secs)\n", ColoredOutputTypeRegistry.getInstance().getOutputKey("\u001B[39m"))
- )));
+ ));
}
public void testCompoundEscSeq() throws Exception {
AnsiEscapeDecoder decoder = new AnsiEscapeDecoder();
- decoder.escapeText("E\u001B[41m\u001B[37mE\u001B[0mE", ProcessOutputTypes.STDOUT, createExpectedAcceptor(ContainerUtil.newArrayList(
+ decoder.escapeText("E\u001B[41m\u001B[37mE\u001B[0mE", ProcessOutputTypes.STDOUT, createExpectedAcceptor(
Pair.create("E", ProcessOutputTypes.STDOUT),
Pair.create("E", ColoredOutputTypeRegistry.getInstance().getOutputKey("\u001B[41;37m")),
Pair.create("E", ProcessOutputTypes.STDOUT)
- )));
+ ));
}
- private static AnsiEscapeDecoder.ColoredChunksAcceptor createExpectedAcceptor(@NotNull final List<Pair<String, Key>> expected) {
+ public void testOtherEscSeq() throws Exception {
+ AnsiEscapeDecoder decoder = new AnsiEscapeDecoder();
+ decoder.escapeText("Plain\u001B[32mGreen\u001B[39mNormal\u001B[1A\u001B[2K\u001B[31mRed\u001B[39m",
+ ProcessOutputTypes.STDOUT,
+ createExpectedAcceptor(
+ Pair.create("Plain", ProcessOutputTypes.STDOUT),
+ Pair.create("Green", ColoredOutputTypeRegistry.getInstance().getOutputKey("\u001B[32m")),
+ Pair.create("Normal", ColoredOutputTypeRegistry.getInstance().getOutputKey("\u001B[39m")),
+ Pair.create("Red", ColoredOutputTypeRegistry.getInstance().getOutputKey("\u001B[31m"))
+ )
+ );
+ }
+
+ private static AnsiEscapeDecoder.ColoredChunksAcceptor createExpectedAcceptor(@NotNull final Pair<String, Key>... expected) {
return new AnsiEscapeDecoder.ColoredChunksAcceptor() {
@Override
public void coloredChunksAvailable(List<Pair<String, Key>> chunks) {
- Assert.assertEquals(expected, chunks);
+ Assert.assertEquals(Arrays.asList(expected), chunks);
}
@Override
diff --git a/platform/platform-tests/testSrc/com/intellij/ide/ActivityMonitorTest.java b/platform/platform-tests/testSrc/com/intellij/ide/ActivityMonitorTest.java
index 3fad6d619b72..8e0a0b1e9aa3 100644
--- a/platform/platform-tests/testSrc/com/intellij/ide/ActivityMonitorTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/ide/ActivityMonitorTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,16 +15,15 @@
*/
package com.intellij.ide;
-import com.intellij.mock.MockApplication;
import com.intellij.mock.MockProject;
import com.intellij.mock.MockProjectEx;
-import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
+import com.intellij.openapi.application.impl.LaterInvocator;
import com.intellij.openapi.application.impl.ModalityStateEx;
-import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.BusyObject;
-import com.intellij.testFramework.UsefulTestCase;
+import com.intellij.testFramework.LightPlatformTestCase;
+import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -35,28 +34,12 @@ import org.jetbrains.annotations.Nullable;
* Time: 10:04 AM
* To change this template use File | Settings | File Templates.
*/
-public class ActivityMonitorTest extends UsefulTestCase {
+public class ActivityMonitorTest extends LightPlatformTestCase {
private UiActivityMonitorImpl myMonitor;
- private ModalityState myCurrentState;
@Override
protected void setUp() throws Exception {
super.setUp();
- myCurrentState = ModalityState.NON_MODAL;
- final ModalityStateEx any = new ModalityStateEx();
- Extensions.registerAreaClass("IDEA_PROJECT", null);
- ApplicationManager.setApplication(new MockApplication(getTestRootDisposable()) {
- @NotNull
- @Override
- public ModalityState getCurrentModalityState() {
- return myCurrentState;
- }
-
- @Override
- public ModalityState getAnyModalityState() {
- return any;
- }
- }, getTestRootDisposable());
myMonitor = new UiActivityMonitorImpl();
myMonitor.setActive(true);
disposeOnTearDown(myMonitor);
@@ -150,19 +133,23 @@ public class ActivityMonitorTest extends UsefulTestCase {
myMonitor.addActivity(new UiActivity("non_modal_1"), ModalityState.NON_MODAL);
assertBusy(null);
- myCurrentState = new ModalityStateEx(new Object[] {"dialog"});
- assertReady(null);
+ LaterInvocator.enterModal("dialog");
+ try {
+ assertReady(null);
- myMonitor.addActivity(new UiActivity("non_modal2"), ModalityState.NON_MODAL);
- assertReady(null);
+ myMonitor.addActivity(new UiActivity("non_modal2"), ModalityState.NON_MODAL);
+ assertReady(null);
- myMonitor.addActivity(new UiActivity("modal_1"), new ModalityStateEx(new Object[] {"dialog"}));
- assertBusy(null);
+ myMonitor.addActivity(new UiActivity("modal_1"), new ModalityStateEx(new Object[] {"dialog"}));
+ assertBusy(null);
- myMonitor.addActivity(new UiActivity("modal_2"), new ModalityStateEx(new Object[] {"dialog", "popup"}));
- assertBusy(null);
+ myMonitor.addActivity(new UiActivity("modal_2"), new ModalityStateEx(new Object[] {"dialog", "popup"}));
+ assertBusy(null);
+ }
+ finally {
+ LaterInvocator.leaveModal("dialog");
+ }
- myCurrentState = ModalityState.NON_MODAL;
assertBusy(null);
}
@@ -172,8 +159,13 @@ public class ActivityMonitorTest extends UsefulTestCase {
myMonitor.addActivity(new UiActivity("non_modal_1"), ModalityState.any());
assertBusy(null);
- myCurrentState = new ModalityStateEx(new Object[] {"dialog"});
- assertBusy(null);
+ try {
+ LaterInvocator.enterModal("dialog");
+ assertBusy(null);
+ }
+ finally {
+ LaterInvocator.leaveModal("dialog");
+ }
}
public void testUiActivity() throws Exception {
@@ -183,11 +175,12 @@ public class ActivityMonitorTest extends UsefulTestCase {
assertFalse(new UiActivity("root", "folder2").isSameOrGeneralFor(new UiActivity("anotherRoot")));
}
- private void assertReady(@Nullable Project key, UiActivity ... activities) {
+ private void assertReady(@Nullable Project key, @NotNull UiActivity ... activities) {
+ UIUtil.dispatchAllInvocationEvents();
BusyObject.Impl busy = (BusyObject.Impl)(key != null ? myMonitor.getBusy(key, activities) : myMonitor.getBusy(activities));
assertTrue("Must be READY, but was: BUSY", busy.isReady());
- final boolean[] done = new boolean[] {false};
+ final boolean[] done = {false};
busy.getReady(this).doWhenDone(new Runnable() {
@Override
public void run() {
@@ -198,9 +191,9 @@ public class ActivityMonitorTest extends UsefulTestCase {
assertTrue(done[0]);
}
- private void assertBusy(@Nullable Project key, UiActivity ... activities) {
+ private void assertBusy(@Nullable Project key, @NotNull UiActivity ... activities) {
+ UIUtil.dispatchAllInvocationEvents();
BusyObject.Impl busy = (BusyObject.Impl)(key != null ? myMonitor.getBusy(key, activities) : myMonitor.getBusy(activities));
assertFalse("Must be BUSY, but was: READY", busy.isReady());
}
-
}
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/components/impl/ApplicationStoreTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/components/impl/ApplicationStoreTest.java
new file mode 100644
index 000000000000..cfbd5a12f146
--- /dev/null
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/components/impl/ApplicationStoreTest.java
@@ -0,0 +1,153 @@
+package com.intellij.openapi.components.impl;
+
+import com.intellij.application.options.PathMacrosImpl;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.components.*;
+import com.intellij.openapi.components.impl.stores.*;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.testFramework.LightPlatformLangTestCase;
+import com.intellij.util.xmlb.XmlSerializerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.IOException;
+
+public class ApplicationStoreTest extends LightPlatformLangTestCase {
+ private File testAppConfig;
+ private MyComponentStore componentStore;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ String testAppConfigPath = System.getProperty("test.app.config.path");
+ if (testAppConfigPath == null) {
+ testAppConfig = FileUtil.createTempDirectory("testAppSettings", null);
+ }
+ else {
+ testAppConfig = new File(FileUtil.expandUserHome(testAppConfigPath));
+ }
+ FileUtil.delete(testAppConfig);
+
+ componentStore = new MyComponentStore(testAppConfig.getAbsolutePath());
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ try {
+ Disposer.dispose(componentStore);
+ componentStore = null;
+ }
+ finally {
+ try {
+ super.tearDown();
+ }
+ finally {
+ FileUtil.delete(testAppConfig);
+ }
+ }
+ }
+
+ public void testStreamProviderSaveIfSeveralStoragesConfigured() throws Exception {
+ SeveralStoragesConfigured component = new SeveralStoragesConfigured();
+ componentStore.initComponent(component, false);
+ StoreUtil.doSave(componentStore);
+ }
+
+ class MyComponentStore extends ComponentStoreImpl implements Disposable {
+ private final StateStorageManager stateStorageManager;
+
+ MyComponentStore(@NotNull final String testAppConfigPath) {
+ TrackingPathMacroSubstitutor macroSubstitutor = new ApplicationPathMacroManager().createTrackingSubstitutor();
+ stateStorageManager = new StateStorageManagerImpl(macroSubstitutor, "application", this, ApplicationManager.getApplication().getPicoContainer()) {
+ @Override
+ protected StorageData createStorageData(String storageSpec) {
+ return new FileBasedStorage.FileStorageData("application");
+ }
+
+ @Nullable
+ @Override
+ protected String getOldStorageSpec(Object component, final String componentName, final StateStorageOperation operation) {
+ return null;
+ }
+
+ @Override
+ protected String getVersionsFilePath() {
+ return testAppConfigPath + "/options/appComponentVersions.xml";
+ }
+
+ @Override
+ protected TrackingPathMacroSubstitutor getMacroSubstitutor(@NotNull final String fileSpec) {
+ if (fileSpec.equals(StoragePathMacros.APP_CONFIG + "/" + PathMacrosImpl.EXT_FILE_NAME + ".xml")) {
+ return null;
+ }
+ return super.getMacroSubstitutor(fileSpec);
+ }
+ };
+
+ stateStorageManager.addMacro(StoragePathMacros.getMacroName(StoragePathMacros.APP_CONFIG), testAppConfigPath);
+ }
+
+ @Override
+ public void load() throws IOException, StateStorageException {
+ }
+
+ @NotNull
+ @Override
+ public StateStorageManager getStateStorageManager() {
+ return stateStorageManager;
+ }
+
+ @Override
+ public void dispose() {
+ }
+
+ @Nullable
+ @Override
+ protected StateStorage getDefaultsStorage() {
+ return null;
+ }
+ }
+
+ static class SeveralStoragesConfiguredStorageChooser implements StateStorageChooser<SeveralStoragesConfigured> {
+ @Override
+ public Storage[] selectStorages(Storage[] storages, SeveralStoragesConfigured component, StateStorageOperation operation) {
+ if (operation == StateStorageOperation.WRITE) {
+ for (Storage storage : storages) {
+ if (storage.file().equals(StoragePathMacros.APP_CONFIG + "/proxy.settings.xml")) {
+ return new Storage[]{storage};
+ }
+ }
+ }
+ return storages;
+ }
+ }
+
+ @State(
+ name = "HttpConfigurable",
+ storages = {
+ // we use two storages due to backward compatibility, see http://crucible.labs.intellij.net/cru/CR-IC-5142
+ @Storage(file = StoragePathMacros.APP_CONFIG + "/other.xml"),
+ @Storage(file = StoragePathMacros.APP_CONFIG + "/proxy.settings.xml")
+ },
+ storageChooser = SeveralStoragesConfiguredStorageChooser.class
+ )
+ static class SeveralStoragesConfigured implements PersistentStateComponent<SeveralStoragesConfigured> {
+ public String foo = "defaultValue";
+
+ @Nullable
+ @Override
+ public SeveralStoragesConfigured getState() {
+ foo = "newValue";
+ return this;
+ }
+
+ @Override
+ public void loadState(SeveralStoragesConfigured state) {
+ XmlSerializerUtil.copyBean(state, this);
+ }
+ }
+}
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/components/impl/StateStorageManagerImplTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/components/impl/StateStorageManagerImplTest.java
index a4e3024a60d0..76c673626b26 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/components/impl/StateStorageManagerImplTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/components/impl/StateStorageManagerImplTest.java
@@ -23,6 +23,7 @@ import com.intellij.openapi.components.impl.stores.StateStorageManagerImpl;
import com.intellij.openapi.components.impl.stores.StorageData;
import com.intellij.openapi.util.Disposer;
import com.intellij.testFramework.LightPlatformLangTestCase;
+import org.jetbrains.annotations.Nullable;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
@@ -43,6 +44,7 @@ public class StateStorageManagerImplTest extends LightPlatformLangTestCase {
throw new UnsupportedOperationException("Method createStorageData not implemented in " + getClass());
}
+ @Nullable
@Override
protected String getOldStorageSpec(Object component, String componentName, StateStorageOperation operation) throws StateStorageException {
throw new UnsupportedOperationException("Method getOldStorageSpec not implemented in " + getClass());
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/HeavyFileEditorManagerTestCase.java b/platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/HeavyFileEditorManagerTestCase.java
index f494f565acf1..b128eb5d3ec2 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/HeavyFileEditorManagerTestCase.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/HeavyFileEditorManagerTestCase.java
@@ -56,6 +56,13 @@ public abstract class HeavyFileEditorManagerTestCase extends CodeInsightFixtureT
}
@Override
+ protected void tearDown() throws Exception {
+ myManager = null;
+
+ super.tearDown();
+ }
+
+ @Override
protected String getBasePath() {
return "/platform/platform-tests/testData/fileEditorManager";
}
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/keymap/impl/ModifierKeyDoubleClickHandlerTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/keymap/impl/ModifierKeyDoubleClickHandlerTest.java
index 96d85c122624..54a2865ad444 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/keymap/impl/ModifierKeyDoubleClickHandlerTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/keymap/impl/ModifierKeyDoubleClickHandlerTest.java
@@ -22,20 +22,19 @@ import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.KeyboardShortcut;
import com.intellij.openapi.keymap.KeymapManager;
import com.intellij.openapi.util.Clock;
-import com.intellij.testFramework.LightPlatformTestCase;
+import com.intellij.testFramework.LightPlatformLangTestCase;
import javax.swing.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
-public class ModifierKeyDoubleClickHandlerTest extends LightPlatformTestCase {
+public class ModifierKeyDoubleClickHandlerTest extends LightPlatformLangTestCase {
private static final String MY_SHIFT_SHIFT_ACTION = "ModifierKeyDoubleClickHandlerTest.action1";
private static final String MY_SHIFT_KEY_ACTION = "ModifierKeyDoubleClickHandlerTest.action2";
private static final String MY_SHIFT_SHIFT_KEY_ACTION = "ModifierKeyDoubleClickHandlerTest.action3";
- public static final KeyboardShortcut SHIFT_KEY_SHORTCUT = new KeyboardShortcut(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE,
- InputEvent.SHIFT_MASK),
- null);
+ private static final KeyboardShortcut SHIFT_KEY_SHORTCUT =
+ new KeyboardShortcut(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, InputEvent.SHIFT_MASK), null);
private final JComponent myComponent = new JPanel();
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java
index 66c10c26b528..1a0d9c37388e 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java
@@ -396,8 +396,8 @@ public class LocalFileSystemTest extends PlatformLangTestCase {
PersistentFS.getInstance().findRoot("", myFS);
fail("should fail by assertion in PersistentFsImpl.findRoot()");
}
- catch (AssertionError e) {
- String message = e.getMessage();
+ catch (Throwable t) {
+ String message = t.getMessage();
assertTrue(message, message.startsWith("Invalid root"));
}
}
diff --git a/platform/platform-tests/testSrc/com/intellij/psi/impl/PsiDocumentManagerImplTest.java b/platform/platform-tests/testSrc/com/intellij/psi/impl/PsiDocumentManagerImplTest.java
index b1ab5117dba9..693c23766d62 100644
--- a/platform/platform-tests/testSrc/com/intellij/psi/impl/PsiDocumentManagerImplTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/psi/impl/PsiDocumentManagerImplTest.java
@@ -25,11 +25,13 @@ import com.intellij.openapi.editor.impl.event.DocumentEventImpl;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ex.ProjectManagerEx;
+import com.intellij.openapi.util.ThrowableComputable;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.PsiDocumentManager;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.PsiManager;
+import com.intellij.psi.*;
import com.intellij.psi.impl.source.PsiFileImpl;
import com.intellij.testFramework.LeakHunter;
import com.intellij.testFramework.LightVirtualFile;
@@ -40,6 +42,7 @@ import com.intellij.util.concurrency.Semaphore;
import com.intellij.util.ui.UIUtil;
import java.io.File;
+import java.io.IOException;
import java.util.concurrent.atomic.AtomicInteger;
public class PsiDocumentManagerImplTest extends PlatformLangTestCase {
@@ -394,4 +397,63 @@ public class PsiDocumentManagerImplTest extends PlatformLangTestCase {
});
assertTrue(commitThread.isEnabled());
}
+
+ public void testFileChangesToText() throws IOException {
+ VirtualFile vFile = getVirtualFile(createTempFile("a.txt", "abc"));
+ PsiFile psiFile = getPsiManager().findFile(vFile);
+ Document document = getPsiDocumentManager().getDocument(psiFile);
+
+ rename(vFile, "a.xml");
+ assertFalse(psiFile.isValid());
+ assertNotSame(psiFile, getPsiManager().findFile(vFile));
+ psiFile = getPsiManager().findFile(vFile);
+
+ assertSame(document, FileDocumentManager.getInstance().getDocument(vFile));
+ assertSame(document, getPsiDocumentManager().getDocument(psiFile));
+ }
+
+ public void testFileChangesToBinary() throws IOException {
+ VirtualFile vFile = getVirtualFile(createTempFile("a.txt", "abc"));
+ PsiFile psiFile = getPsiManager().findFile(vFile);
+ Document document = getPsiDocumentManager().getDocument(psiFile);
+
+ rename(vFile, "a.zip");
+ assertFalse(psiFile.isValid());
+ psiFile = getPsiManager().findFile(vFile);
+ assertInstanceOf(psiFile, PsiBinaryFile.class);
+
+ assertNoFileDocumentMapping(vFile, psiFile, document);
+ assertEquals("abc", document.getText());
+ }
+
+ public void testFileBecomesTooLarge() throws Exception {
+ VirtualFile vFile = getVirtualFile(createTempFile("a.txt", "abc"));
+ PsiFile psiFile = getPsiManager().findFile(vFile);
+ Document document = getPsiDocumentManager().getDocument(psiFile);
+
+ makeFileTooLarge(vFile);
+ assertFalse(psiFile.isValid());
+ psiFile = getPsiManager().findFile(vFile);
+ assertInstanceOf(psiFile, PsiLargeFile.class);
+
+ assertNoFileDocumentMapping(vFile, psiFile, document);
+ assertEquals("abc", document.getText());
+ }
+
+ private void assertNoFileDocumentMapping(VirtualFile vFile, PsiFile psiFile, Document document) {
+ assertNull(FileDocumentManager.getInstance().getDocument(vFile));
+ assertNull(FileDocumentManager.getInstance().getFile(document));
+ assertNull(getPsiDocumentManager().getPsiFile(document));
+ assertNull(getPsiDocumentManager().getDocument(psiFile));
+ }
+
+ private void makeFileTooLarge(final VirtualFile vFile) throws Exception {
+ WriteCommandAction.runWriteCommandAction(myProject, new ThrowableComputable<Object, Exception>() {
+ @Override
+ public Object compute() throws Exception {
+ VfsUtil.saveText(vFile, StringUtil.repeat("a", FileUtil.LARGE_FOR_CONTENT_LOADING + 1));
+ return null;
+ }
+ });
+ }
}
diff --git a/platform/projectModel-api/src/com/intellij/openapi/components/StoragePathMacros.java b/platform/projectModel-api/src/com/intellij/openapi/components/StoragePathMacros.java
index 765f350309bd..374423225694 100644
--- a/platform/projectModel-api/src/com/intellij/openapi/components/StoragePathMacros.java
+++ b/platform/projectModel-api/src/com/intellij/openapi/components/StoragePathMacros.java
@@ -31,6 +31,8 @@ import org.jetbrains.annotations.NotNull;
* @since 5/2/12 12:57 PM
*/
public class StoragePathMacros {
+ @NonNls @NotNull public static final String ROOT_CONFIG = "$ROOT_CONFIG$";
+
/** Points to the application-level settings root directory. */
@NonNls @NotNull public static final String APP_CONFIG = "$APP_CONFIG$";
diff --git a/platform/projectModel-api/src/com/intellij/openapi/project/DefaultProjectTypeProvider.java b/platform/projectModel-api/src/com/intellij/openapi/project/DefaultProjectTypeProvider.java
new file mode 100644
index 000000000000..81887eba0f98
--- /dev/null
+++ b/platform/projectModel-api/src/com/intellij/openapi/project/DefaultProjectTypeProvider.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.project;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Dmitry Avdeev
+ */
+public abstract class DefaultProjectTypeProvider {
+
+ private final static ExtensionPointName<DefaultProjectTypeProvider> EXTENSION_POINT_NAME = ExtensionPointName.create("com.intellij.defaultProjectTypeProvider");
+
+ @Nullable
+ public static ProjectType getDefaultProjectType() {
+ DefaultProjectTypeProvider[] extensions = EXTENSION_POINT_NAME.getExtensions();
+ return extensions.length > 0 ? extensions[0].getProjectType() : null;
+ }
+
+ protected abstract ProjectType getProjectType();
+}
diff --git a/platform/projectModel-api/src/com/intellij/openapi/project/ProjectType.java b/platform/projectModel-api/src/com/intellij/openapi/project/ProjectType.java
new file mode 100644
index 000000000000..f096e67c0ff5
--- /dev/null
+++ b/platform/projectModel-api/src/com/intellij/openapi/project/ProjectType.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.project;
+
+/**
+ * @author Dmitry Avdeev
+ */
+public class ProjectType {
+
+ private String id;
+
+ /**
+ * For serialization.
+ */
+ public ProjectType() {
+ }
+
+ public ProjectType(String id) {
+ this.id = id;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ ProjectType type = (ProjectType)o;
+
+ if (id != null ? !id.equals(type.id) : type.id != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return id != null ? id.hashCode() : 0;
+ }
+}
diff --git a/platform/projectModel-api/src/com/intellij/openapi/project/ProjectTypeService.java b/platform/projectModel-api/src/com/intellij/openapi/project/ProjectTypeService.java
new file mode 100644
index 000000000000..e43059390b19
--- /dev/null
+++ b/platform/projectModel-api/src/com/intellij/openapi/project/ProjectTypeService.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.project;
+
+import com.intellij.openapi.components.*;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Dmitry Avdeev
+ */
+
+@State(
+ name = "ProjectType",
+ storages = {
+ @Storage(file = StoragePathMacros.PROJECT_FILE),
+ @Storage(file = StoragePathMacros.PROJECT_CONFIG_DIR + "/misc.xml", scheme = StorageScheme.DIRECTORY_BASED)
+ }
+)
+public class ProjectTypeService implements PersistentStateComponent<ProjectType> {
+
+ private ProjectType myProjectType;
+
+ @Nullable
+ public static ProjectType getProjectType(@Nullable Project project) {
+ ProjectType projectType;
+ if (project != null) {
+ projectType = getInstance(project).myProjectType;
+ if (projectType != null) return projectType;
+ }
+ return DefaultProjectTypeProvider.getDefaultProjectType();
+ }
+
+ public static ProjectTypeService getInstance(@NotNull Project project) {
+ return ServiceManager.getService(project, ProjectTypeService.class);
+ }
+
+ @Nullable
+ @Override
+ public ProjectType getState() {
+ return myProjectType;
+ }
+
+ @Override
+ public void loadState(ProjectType state) {
+ myProjectType = state;
+ }
+}
diff --git a/platform/projectModel-api/src/com/intellij/openapi/roots/OrderRootType.java b/platform/projectModel-api/src/com/intellij/openapi/roots/OrderRootType.java
index 60fccacb04c0..3230ed3ae496 100644
--- a/platform/projectModel-api/src/com/intellij/openapi/roots/OrderRootType.java
+++ b/platform/projectModel-api/src/com/intellij/openapi/roots/OrderRootType.java
@@ -18,6 +18,7 @@ package com.intellij.openapi.roots;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.Extensions;
import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
import java.util.*;
@@ -111,8 +112,8 @@ public class OrderRootType {
List<PersistentOrderRootType> allTypes = new ArrayList<PersistentOrderRootType>();
Collections.addAll(allTypes, getAllPersistentTypes());
Collections.sort(allTypes, new Comparator<PersistentOrderRootType>() {
- public int compare(final PersistentOrderRootType o1, final PersistentOrderRootType o2) {
- return o1.getSdkRootName().compareTo(o2.getSdkRootName());
+ public int compare(@NotNull final PersistentOrderRootType o1, @NotNull final PersistentOrderRootType o2) {
+ return o1.name().compareToIgnoreCase(o2.name());
}
});
return allTypes;
diff --git a/platform/projectModel-api/src/com/intellij/openapi/roots/PersistentOrderRootType.java b/platform/projectModel-api/src/com/intellij/openapi/roots/PersistentOrderRootType.java
index b799e76ad351..cb8f90e35326 100644
--- a/platform/projectModel-api/src/com/intellij/openapi/roots/PersistentOrderRootType.java
+++ b/platform/projectModel-api/src/com/intellij/openapi/roots/PersistentOrderRootType.java
@@ -18,6 +18,7 @@ package com.intellij.openapi.roots;
import org.jetbrains.annotations.NonNls;
import com.intellij.util.ArrayUtil;
+import org.jetbrains.annotations.Nullable;
/**
* @author yole
@@ -27,7 +28,7 @@ public class PersistentOrderRootType extends OrderRootType {
private final String myModulePathsName;
private final String myOldSdkRootName;
- protected PersistentOrderRootType(@NonNls String name, @NonNls String sdkRootName, @NonNls String modulePathsName, @NonNls final String oldSdkRootName) {
+ protected PersistentOrderRootType(@NonNls String name, @NonNls @Nullable String sdkRootName, @NonNls @Nullable String modulePathsName, @NonNls final @Nullable String oldSdkRootName) {
super(name);
mySdkRootName = sdkRootName;
myModulePathsName = modulePathsName;
@@ -37,12 +38,14 @@ public class PersistentOrderRootType extends OrderRootType {
}
/**
- * @return Element name used for storing roots of this type in JDK and library definitions.
+ * @return Element name used for storing roots of this type in JDK definitions.
*/
+ @Nullable
public String getSdkRootName() {
return mySdkRootName;
}
+ @Nullable
public String getOldSdkRootName() {
return myOldSdkRootName;
}
@@ -50,6 +53,7 @@ public class PersistentOrderRootType extends OrderRootType {
/**
* @return Element name used for storing roots of this type in module definitions.
*/
+ @Nullable
public String getModulePathsName() {
return myModulePathsName;
}
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/DefaultStateSerializer.java b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/DefaultStateSerializer.java
index 890d77578a81..608a350d770c 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/DefaultStateSerializer.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/DefaultStateSerializer.java
@@ -27,11 +27,11 @@ import com.intellij.util.xmlb.Accessor;
import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters;
import com.intellij.util.xmlb.XmlSerializer;
import org.jdom.Element;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.annotation.Annotation;
-
@SuppressWarnings({"deprecation"})
class DefaultStateSerializer {
@@ -40,7 +40,7 @@ class DefaultStateSerializer {
private DefaultStateSerializer() {
}
- static Element serializeState(Object state, final Storage storage) throws WriteExternalException {
+ static Element serializeState(@NotNull Object state, final Storage storage) throws WriteExternalException {
if (state instanceof Element) {
return (Element)state;
}
@@ -53,7 +53,8 @@ class DefaultStateSerializer {
}
catch (WriteExternalException e) {
throw e;
- }catch (Throwable e) {
+ }
+ catch (Throwable e) {
LOG.info("Unable to serialize component state!", e);
return new Element("empty");
}
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/projectRoots/impl/ProjectRootContainerImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/projectRoots/impl/ProjectRootContainerImpl.java
index 22800f9a4e1a..1036456dfc6b 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/projectRoots/impl/ProjectRootContainerImpl.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/projectRoots/impl/ProjectRootContainerImpl.java
@@ -23,10 +23,7 @@ import com.intellij.openapi.projectRoots.ex.ProjectRoot;
import com.intellij.openapi.projectRoots.ex.ProjectRootContainer;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.PersistentOrderRootType;
-import com.intellij.openapi.util.Comparing;
-import com.intellij.openapi.util.InvalidDataException;
-import com.intellij.openapi.util.JDOMExternalizable;
-import com.intellij.openapi.util.WriteExternalException;
+import com.intellij.openapi.util.*;
import com.intellij.openapi.vfs.*;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashMap;
@@ -223,7 +220,8 @@ public class ProjectRootContainerImpl implements JDOMExternalizable, ProjectRoot
}
private void read(Element element, PersistentOrderRootType type) throws InvalidDataException {
- Element child = element.getChild(type.getSdkRootName());
+ String sdkRootName = type.getSdkRootName();
+ Element child = sdkRootName != null ? element.getChild(sdkRootName) : null;
if (child == null) {
myRoots.put(type, new CompositeProjectRoot());
return;
@@ -236,11 +234,14 @@ public class ProjectRootContainerImpl implements JDOMExternalizable, ProjectRoot
}
private void write(Element roots, PersistentOrderRootType type) throws WriteExternalException {
- Element e = new Element(type.getSdkRootName());
- roots.addContent(e);
- final Element root = ProjectRootUtil.write(myRoots.get(type));
- if (root != null) {
- e.addContent(root);
+ String sdkRootName = type.getSdkRootName();
+ if (sdkRootName != null) {
+ Element e = new Element(sdkRootName);
+ roots.addContent(e);
+ final Element root = ProjectRootUtil.write(myRoots.get(type));
+ if (root != null) {
+ e.addContent(root);
+ }
}
}
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java
index 8e80670b1f76..c439a35d0a36 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java
@@ -134,6 +134,7 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
public ProjectRootManagerImpl(Project project) {
myProject = project;
myRootsCache = new OrderRootsCache(project);
+ myJdkTableMultiListener = new JdkTableMultiListener(project);
}
@Override
@@ -281,7 +282,6 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
@Override
public void disposeComponent() {
- myJdkTableMultiListener = null;
}
@Override
@@ -478,45 +478,52 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
void addListenerForTable(LibraryTable.Listener libraryListener,
final LibraryTable libraryTable) {
- LibraryTableMultilistener multilistener = myLibraryTableMultilisteners.get(libraryTable);
- if (multilistener == null) {
- multilistener = new LibraryTableMultilistener(libraryTable);
+ synchronized (myLibraryTableListenersLock) {
+ LibraryTableMultiListener multiListener = myLibraryTableMultiListeners.get(libraryTable);
+ if (multiListener == null) {
+ multiListener = new LibraryTableMultiListener(libraryTable);
+ libraryTable.addListener(multiListener);
+ myLibraryTableMultiListeners.put(libraryTable, multiListener);
+ }
+ multiListener.addListener(libraryListener);
}
- multilistener.addListener(libraryListener);
}
void removeListenerForTable(LibraryTable.Listener libraryListener,
final LibraryTable libraryTable) {
- LibraryTableMultilistener multilistener = myLibraryTableMultilisteners.get(libraryTable);
- if (multilistener == null) {
- multilistener = new LibraryTableMultilistener(libraryTable);
+ synchronized (myLibraryTableListenersLock) {
+ LibraryTableMultiListener multiListener = myLibraryTableMultiListeners.get(libraryTable);
+ if (multiListener != null) {
+ boolean last = multiListener.removeListener(libraryListener);
+ if (last) {
+ libraryTable.removeListener(multiListener);
+ myLibraryTableMultiListeners.remove(libraryTable);
+ }
+ }
}
- multilistener.removeListener(libraryListener);
}
- private final Map<LibraryTable, LibraryTableMultilistener> myLibraryTableMultilisteners
- = new HashMap<LibraryTable, LibraryTableMultilistener>();
+ private final Object myLibraryTableListenersLock = new Object();
+ private final Map<LibraryTable, LibraryTableMultiListener> myLibraryTableMultiListeners = new HashMap<LibraryTable, LibraryTableMultiListener>();
- private class LibraryTableMultilistener implements LibraryTable.Listener {
- final List<LibraryTable.Listener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
+ private class LibraryTableMultiListener implements LibraryTable.Listener {
+ private final Set<LibraryTable.Listener> myListeners = new LinkedHashSet<LibraryTable.Listener>();
private final LibraryTable myLibraryTable;
+ private LibraryTable.Listener[] myListenersArray;
- private LibraryTableMultilistener(LibraryTable libraryTable) {
+ private LibraryTableMultiListener(LibraryTable libraryTable) {
myLibraryTable = libraryTable;
- myLibraryTable.addListener(this);
- myLibraryTableMultilisteners.put(myLibraryTable, this);
}
- private void addListener(LibraryTable.Listener listener) {
+ private synchronized void addListener(LibraryTable.Listener listener) {
myListeners.add(listener);
+ myListenersArray = null;
}
- private void removeListener(LibraryTable.Listener listener) {
+ private synchronized boolean removeListener(LibraryTable.Listener listener) {
myListeners.remove(listener);
- if (myListeners.isEmpty()) {
- myLibraryTable.removeListener(this);
- myLibraryTableMultilisteners.remove(myLibraryTable);
- }
+ myListenersArray = null;
+ return myListeners.isEmpty();
}
@Override
@@ -525,20 +532,27 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
mergeRootsChangesDuring(new Runnable() {
@Override
public void run() {
- for (LibraryTable.Listener listener : myListeners) {
+ for (LibraryTable.Listener listener : getListeners()) {
listener.afterLibraryAdded(newLibrary);
}
}
});
}
+ private synchronized LibraryTable.Listener[] getListeners() {
+ if (myListenersArray == null) {
+ myListenersArray = myListeners.toArray(new LibraryTable.Listener[myListeners.size()]);
+ }
+ return myListenersArray;
+ }
+
@Override
public void afterLibraryRenamed(final Library library) {
incModificationCount();
mergeRootsChangesDuring(new Runnable() {
@Override
public void run() {
- for (LibraryTable.Listener listener : myListeners) {
+ for (LibraryTable.Listener listener : getListeners()) {
listener.afterLibraryRenamed(library);
}
}
@@ -551,7 +565,7 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
mergeRootsChangesDuring(new Runnable() {
@Override
public void run() {
- for (LibraryTable.Listener listener : myListeners) {
+ for (LibraryTable.Listener listener : getListeners()) {
listener.beforeLibraryRemoved(library);
}
}
@@ -564,7 +578,7 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
mergeRootsChangesDuring(new Runnable() {
@Override
public void run() {
- for (LibraryTable.Listener listener : myListeners) {
+ for (LibraryTable.Listener listener : getListeners()) {
listener.afterLibraryRemoved(library);
}
}
@@ -572,24 +586,33 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
}
}
- private JdkTableMultiListener myJdkTableMultiListener = null;
+ private final JdkTableMultiListener myJdkTableMultiListener;
private class JdkTableMultiListener implements ProjectJdkTable.Listener {
- final EventDispatcher<ProjectJdkTable.Listener> myDispatcher = EventDispatcher.create(ProjectJdkTable.Listener.class);
+ private final Set<ProjectJdkTable.Listener> myListeners = new LinkedHashSet<ProjectJdkTable.Listener>();
private MessageBusConnection listenerConnection;
+ private ProjectJdkTable.Listener[] myListenersArray;
private JdkTableMultiListener(Project project) {
listenerConnection = project.getMessageBus().connect();
listenerConnection.subscribe(ProjectJdkTable.JDK_TABLE_TOPIC, this);
}
- private void addListener(ProjectJdkTable.Listener listener) {
- myDispatcher.addListener(listener);
+ private synchronized void addListener(ProjectJdkTable.Listener listener) {
+ myListeners.add(listener);
+ myListenersArray = null;
+ }
+
+ private synchronized void removeListener(ProjectJdkTable.Listener listener) {
+ myListeners.remove(listener);
+ myListenersArray = null;
}
- private void removeListener(ProjectJdkTable.Listener listener) {
- myDispatcher.removeListener(listener);
- uninstallListener(true);
+ private synchronized ProjectJdkTable.Listener[] getListeners() {
+ if (myListenersArray == null) {
+ myListenersArray = myListeners.toArray(new ProjectJdkTable.Listener[myListeners.size()]);
+ }
+ return myListenersArray;
}
@Override
@@ -597,7 +620,9 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
mergeRootsChangesDuring(new Runnable() {
@Override
public void run() {
- myDispatcher.getMulticaster().jdkAdded(jdk);
+ for (ProjectJdkTable.Listener listener : getListeners()) {
+ listener.jdkAdded(jdk);
+ }
}
});
}
@@ -607,7 +632,9 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
mergeRootsChangesDuring(new Runnable() {
@Override
public void run() {
- myDispatcher.getMulticaster().jdkRemoved(jdk);
+ for (ProjectJdkTable.Listener listener : getListeners()) {
+ listener.jdkRemoved(jdk);
+ }
}
});
}
@@ -617,7 +644,9 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
mergeRootsChangesDuring(new Runnable() {
@Override
public void run() {
- myDispatcher.getMulticaster().jdkNameChanged(jdk, previousName);
+ for (ProjectJdkTable.Listener listener : getListeners()) {
+ listener.jdkNameChanged(jdk, previousName);
+ }
}
});
String currentName = getProjectSdkName();
@@ -627,32 +656,15 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
myProjectSdkType = jdk.getSdkType().getName();
}
}
-
- public void uninstallListener(boolean soft) {
- if (!soft || !myDispatcher.hasListeners()) {
- if (listenerConnection != null) {
- listenerConnection.disconnect();
- listenerConnection = null;
- }
- }
- }
}
private final Map<RootProvider, Set<OrderEntry>> myRegisteredRootProviders = new HashMap<RootProvider, Set<OrderEntry>>();
void addJdkTableListener(ProjectJdkTable.Listener jdkTableListener) {
- getJdkTableMultiListener().addListener(jdkTableListener);
- }
-
- private JdkTableMultiListener getJdkTableMultiListener() {
- if (myJdkTableMultiListener == null) {
- myJdkTableMultiListener = new JdkTableMultiListener(myProject);
- }
- return myJdkTableMultiListener;
+ myJdkTableMultiListener.addListener(jdkTableListener);
}
void removeJdkTableListener(ProjectJdkTable.Listener jdkTableListener) {
- if (myJdkTableMultiListener == null) return;
myJdkTableMultiListener.removeListener(jdkTableListener);
}
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootIndex.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootIndex.java
index bc85dabc9aec..bd9531a2d888 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootIndex.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootIndex.java
@@ -71,14 +71,6 @@ public class RootIndex {
private final TObjectIntHashMap<JpsModuleSourceRootType<?>> myRootTypeId = new TObjectIntHashMap<JpsModuleSourceRootType<?>>();
@NotNull private final Project myProject;
private volatile Map<VirtualFile, OrderEntry[]> myOrderEntries;
- @SuppressWarnings("UnusedDeclaration")
- private final LowMemoryWatcher myLowMemoryWatcher = LowMemoryWatcher.register(new Runnable() {
- @Override
- public void run() {
- myNonExistentPackages.clear();
- }
- });
-
// made public for Upsource
public RootIndex(@NotNull Project project, @NotNull InfoCache cache) {
@@ -98,6 +90,12 @@ public class RootIndex {
myProjectExcludedRoots.add(root);
}
}
+ LowMemoryWatcher.register(new Runnable() {
+ @Override
+ public void run() {
+ myNonExistentPackages.clear();
+ }
+ }, project);
}
@NotNull
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java
index fa901849867f..7b5de892d4da 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java
@@ -22,7 +22,6 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.OrderRootType;
-import com.intellij.openapi.roots.PersistentOrderRootType;
import com.intellij.openapi.roots.RootProvider;
import com.intellij.openapi.roots.impl.RootModelImpl;
import com.intellij.openapi.roots.impl.RootProviderBaseImpl;
@@ -320,23 +319,13 @@ public class LibraryImpl extends TraceableDisposable implements LibraryEx.Modifi
List<OrderRootType> allTypes = new ArrayList<OrderRootType>(rootTypes);
Collections.sort(allTypes, new Comparator<OrderRootType>() {
@Override
- public int compare(final OrderRootType o1, final OrderRootType o2) {
- return getSortKey(o1).compareTo(getSortKey(o2));
+ public int compare(@NotNull final OrderRootType o1, @NotNull final OrderRootType o2) {
+ return o1.name().compareToIgnoreCase(o2.name());
}
});
return allTypes;
}
- private static String getSortKey(OrderRootType orderRootType) {
- if (orderRootType instanceof PersistentOrderRootType) {
- return ((PersistentOrderRootType)orderRootType).getSdkRootName();
- }
- if (orderRootType instanceof OrderRootType.DocumentationRootType) {
- return ((OrderRootType.DocumentationRootType)orderRootType).getSdkRootName();
- }
- return "";
- }
-
@Override
public void writeExternal(Element rootElement) throws WriteExternalException {
checkDisposed();
diff --git a/platform/projectModel-impl/src/messages/ProjectBundle.properties b/platform/projectModel-impl/src/messages/ProjectBundle.properties
index 2d74782822db..a0fe65ad981a 100644
--- a/platform/projectModel-impl/src/messages/ProjectBundle.properties
+++ b/platform/projectModel-impl/src/messages/ProjectBundle.properties
@@ -128,6 +128,7 @@ button.text.attach.files=Attach &Files or Directories...
library.attach.files.action=Attach Files or Directories
library.attach.files.to.library.action=Attach Files or Directories to Library ''{0}''
library.attach.files.description=Select files or directories in which library classes, sources and documentation are located
+library.java.attach.files.description=Select files or directories in which library classes, sources, documentation or native libraries are located
library.sources.not.found=Sources not found
library.sources.not.attached=Sources not attached
@@ -318,6 +319,7 @@ external.annotations.root.chooser.description=External annotations would be save
external.annotation.prompt=External annotation prompt
external.annotations.suggestion.message=<html><body>If you do not want annotations in your code you may use external storage.<br> \
To configure external annotations please specify root directory where files with annotations would be placed</body></html>
+project.roots.native.library.node.text=Native Library Locations
sdk.configure.annotations.tab=Annotations
project.roots.path.tab.title=Paths
project.roots.external.annotations.tab.title=External Annotations
diff --git a/platform/remote-servers/impl/src/META-INF/RemoteServers.xml b/platform/remote-servers/impl/src/META-INF/RemoteServers.xml
index 41067b075460..2888727432c9 100644
--- a/platform/remote-servers/impl/src/META-INF/RemoteServers.xml
+++ b/platform/remote-servers/impl/src/META-INF/RemoteServers.xml
@@ -42,6 +42,8 @@
<action id="RemoteServers.EditServer" class="com.intellij.remoteServer.impl.runtime.ui.tree.actions.EditConfigurationAction"/>
<separator/>
<action id="RemoteServers.DeployAll" class="com.intellij.remoteServer.impl.runtime.ui.tree.actions.DeployAllAction"/>
+ <action id="Servers.Deploy" class="com.intellij.remoteServer.impl.runtime.ui.tree.actions.DeployAction"/>
+ <action id="Servers.Undeploy" class="com.intellij.remoteServer.impl.runtime.ui.tree.actions.UndeployAction"/>
</group>
</actions>
</idea-plugin> \ No newline at end of file
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudAccountSelectionEditor.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudAccountSelectionEditor.java
index 5a3d150daf57..729a1e9bc605 100644
--- a/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudAccountSelectionEditor.java
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudAccountSelectionEditor.java
@@ -127,21 +127,16 @@ public class CloudAccountSelectionEditor {
}
};
- final SingleConfigurableEditor configurableEditor
- = new SingleConfigurableEditor(myMainPanel, configurable, ShowSettingsUtilImpl.createDimensionKey(configurable), false) {
-
+ if (!new SingleConfigurableEditor(myMainPanel, configurable, ShowSettingsUtilImpl.createDimensionKey(configurable), false) {
{
errorConsumerRef.set(new Consumer<String>() {
-
@Override
public void consume(String s) {
setErrorText(s);
}
});
}
- };
-
- if (!configurableEditor.showAndGet()) {
+ }.showAndGet()) {
return;
}
diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/SourceMapDecoder.java b/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/SourceMapDecoder.java
index c033a6979f09..27bd8abfe0ce 100644
--- a/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/SourceMapDecoder.java
+++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/SourceMapDecoder.java
@@ -2,7 +2,7 @@ package org.jetbrains.debugger.sourcemap;
import com.google.gson.stream.JsonToken;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.util.Function;
+import com.intellij.openapi.util.text.StringUtilRt;
import com.intellij.util.PathUtil;
import com.intellij.util.SmartList;
import com.intellij.util.text.CharSequenceSubSequence;
@@ -24,7 +24,7 @@ public final class SourceMapDecoder {
private static final Comparator<MappingEntry> MAPPING_COMPARATOR_BY_SOURCE_POSITION = new Comparator<MappingEntry>() {
@Override
- public int compare(MappingEntry o1, MappingEntry o2) {
+ public int compare(@NotNull MappingEntry o1, @NotNull MappingEntry o2) {
if (o1.getSourceLine() == o2.getSourceLine()) {
return o1.getSourceColumn() - o2.getSourceColumn();
}
@@ -36,7 +36,7 @@ public final class SourceMapDecoder {
public static final Comparator<MappingEntry> MAPPING_COMPARATOR_BY_GENERATED_POSITION = new Comparator<MappingEntry>() {
@Override
- public int compare(MappingEntry o1, MappingEntry o2) {
+ public int compare(@NotNull MappingEntry o1, @NotNull MappingEntry o2) {
if (o1.getGeneratedLine() == o2.getGeneratedLine()) {
return o1.getGeneratedColumn() - o2.getGeneratedColumn();
}
@@ -46,7 +46,12 @@ public final class SourceMapDecoder {
}
};
- public static SourceMap decode(@NotNull String contents, @NotNull Function<List<String>, SourceResolver> sourceResolverFactory) throws IOException {
+ public interface SourceResolverFactory {
+ @NotNull
+ SourceResolver create(@NotNull List<String> sourcesUrl, @Nullable List<String> sourcesContent);
+ }
+
+ public static SourceMap decode(@NotNull String contents, @NotNull SourceResolverFactory sourceResolverFactory) throws IOException {
if (contents.isEmpty()) {
throw new IOException("source map contents cannot be empty");
}
@@ -59,7 +64,7 @@ public final class SourceMapDecoder {
}
@Nullable
- public static SourceMap decode(@NotNull CharSequence in, @NotNull Function<List<String>, SourceResolver> sourceResolverFactory) throws IOException {
+ public static SourceMap decode(@NotNull CharSequence in, @NotNull SourceResolverFactory sourceResolverFactory) throws IOException {
JsonReaderEx reader = new JsonReaderEx(in);
List<MappingEntry> mappings = new ArrayList<MappingEntry>();
return parseMap(reader, 0, 0, mappings, sourceResolverFactory);
@@ -70,7 +75,7 @@ public final class SourceMapDecoder {
int line,
int column,
List<MappingEntry> mappings,
- @NotNull Function<List<String>, SourceResolver> sourceResolverFactory) throws IOException {
+ @NotNull SourceResolverFactory sourceResolverFactory) throws IOException {
reader.beginObject();
String sourceRoot = null;
JsonReaderEx sourcesReader = null;
@@ -78,6 +83,7 @@ public final class SourceMapDecoder {
String encodedMappings = null;
String file = null;
int version = -1;
+ List<String> sourcesContent = null;
while (reader.hasNext()) {
String propertyName = reader.nextName();
if (propertyName.equals("sections")) {
@@ -98,7 +104,14 @@ public final class SourceMapDecoder {
if (reader.hasNext()) {
names = new ArrayList<String>();
do {
- names.add(reader.nextString(true));
+ if (reader.peek() == JsonToken.BEGIN_OBJECT) {
+ // polymer map
+ reader.skipValue();
+ names.add("POLYMER UNKNOWN NAME");
+ }
+ else {
+ names.add(reader.nextString(true));
+ }
}
while (reader.hasNext());
}
@@ -113,6 +126,17 @@ public final class SourceMapDecoder {
else if (propertyName.equals("file")) {
file = reader.nextString();
}
+ else if (propertyName.equals("sourcesContent")) {
+ reader.beginArray();
+ if (reader.peek() != JsonToken.END_ARRAY) {
+ sourcesContent = new SmartList<String>();
+ do {
+ sourcesContent.add(StringUtilRt.convertLineSeparators(reader.nextString()));
+ }
+ while (reader.hasNext());
+ }
+ reader.endArray();
+ }
else {
// skip file or extensions
reader.skipValue();
@@ -152,7 +176,7 @@ public final class SourceMapDecoder {
sourceToEntries[i] = new SourceMappingList(entries);
}
}
- return new SourceMap(file, new GeneratedMappingList(mappings), sourceToEntries, sourceResolverFactory.fun(sources));
+ return new SourceMap(file, new GeneratedMappingList(mappings), sourceToEntries, sourceResolverFactory.create(sources, sourcesContent));
}
@Nullable
diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/SourceResolver.java b/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/SourceResolver.java
index 38693e4ac3ae..665039507ace 100644
--- a/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/SourceResolver.java
+++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/SourceResolver.java
@@ -8,6 +8,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Url;
import com.intellij.util.UrlImpl;
import com.intellij.util.Urls;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.ObjectIntHashMap;
import com.intellij.util.io.URLUtil;
import com.intellij.util.text.CaseInsensitiveStringHashingStrategy;
@@ -20,6 +21,7 @@ import java.util.List;
public class SourceResolver {
private final List<String> rawSources;
+ @Nullable private final List<String> sourcesContent;
final Url[] canonicalizedSources;
private final ObjectIntHashMap<Url> canonicalizedSourcesMap;
@@ -28,14 +30,15 @@ public class SourceResolver {
// absoluteLocalPathToSourceIndex contains canonical paths too, but this map contains only used (specified in the source map) path
private String[] sourceIndexToAbsoluteLocalPath;
- public SourceResolver(@NotNull List<String> sources, boolean trimFileScheme, @Nullable Url baseFileUrl) {
- rawSources = sources;
- canonicalizedSources = new Url[sources.size()];
+ public SourceResolver(@NotNull List<String> sourcesUrl, boolean trimFileScheme, @Nullable Url baseFileUrl, @Nullable List<String> sourcesContent) {
+ rawSources = sourcesUrl;
+ this.sourcesContent = sourcesContent;
+ canonicalizedSources = new Url[sourcesUrl.size()];
canonicalizedSourcesMap = SystemInfo.isFileSystemCaseSensitive
? new ObjectIntHashMap<Url>(canonicalizedSources.length)
: new ObjectIntHashMap<Url>(canonicalizedSources.length, Urls.getCaseInsensitiveUrlHashingStrategy());
- for (int i = 0; i < sources.size(); i++) {
- String rawSource = sources.get(i);
+ for (int i = 0; i < sourcesUrl.size(); i++) {
+ String rawSource = sourcesUrl.get(i);
Url url = canonicalizeUrl(rawSource, baseFileUrl, trimFileScheme, i);
canonicalizedSources[i] = url;
canonicalizedSourcesMap.put(url, i);
@@ -111,6 +114,16 @@ public class SourceResolver {
}
@Nullable
+ public String getSourceContent(@NotNull MappingEntry entry) {
+ if (ContainerUtil.isEmpty(sourcesContent)) {
+ return null;
+ }
+
+ int index = entry.getSource();
+ return index < 0 || index >= sourcesContent.size() ? null : sourcesContent.get(index);
+ }
+
+ @Nullable
public String getRawSource(@NotNull MappingEntry entry) {
int index = entry.getSource();
return index < 0 ? null : rawSources.get(index);
diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerTreeStructure.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerTreeStructure.java
index b740bb6a0ccc..7d15140c8de5 100644
--- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerTreeStructure.java
+++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerTreeStructure.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -43,6 +43,11 @@ public class SMTRunnerTreeStructure extends AbstractTreeStructure
public void commit() {
}
+ @Override
+ public boolean hasSomethingToCommit() {
+ return false;
+ }
+
@NotNull
@Override
public SMTRunnerNodeDescriptor createDescriptor(final Object element,
@@ -70,17 +75,12 @@ public class SMTRunnerTreeStructure extends AbstractTreeStructure
return ((AbstractTestProxy)element).getParent();
}
+
@Override
public Object getRootElement() {
return myRootNode;
}
-
- @Override
- public boolean hasSomethingToCommit() {
- return false;
- }
-
public void setFilter(final Filter nodesFilter) {
myTestNodesFilter = nodesFilter;
}
diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/TestComparisionFailedState.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/TestComparisionFailedState.java
index 84b28a79c5e8..2d500115c038 100644
--- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/TestComparisionFailedState.java
+++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/TestComparisionFailedState.java
@@ -15,9 +15,11 @@
*/
package com.intellij.execution.testframework.sm.runner.states;
+import com.intellij.execution.process.ProcessOutputTypes;
import com.intellij.execution.testframework.AbstractTestProxy;
import com.intellij.execution.testframework.CompositePrintable;
import com.intellij.execution.testframework.Printer;
+import com.intellij.execution.testframework.sm.runner.ui.TestsPresentationUtil;
import com.intellij.execution.testframework.stacktrace.DiffHyperlink;
import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.openapi.project.Project;
@@ -41,10 +43,8 @@ public class TestComparisionFailedState extends TestFailedState implements Abstr
super(localizedMessage, stackTrace);
myHyperlink = new DiffHyperlink(expectedText, actualText, null);
- myErrorMsgPresentation = StringUtil.isEmptyOrSpaces(localizedMessage) ? ""
- : localizedMessage;
- myStacktracePresentation = StringUtil.isEmptyOrSpaces(stackTrace) ? ""
- : stackTrace;
+ myErrorMsgPresentation = StringUtil.isEmptyOrSpaces(localizedMessage) ? "" : localizedMessage;
+ myStacktracePresentation = StringUtil.isEmptyOrSpaces(stackTrace) ? "" : stackTrace;
}
@Override
@@ -53,20 +53,15 @@ public class TestComparisionFailedState extends TestFailedState implements Abstr
printer.mark();
// Error msg
- if (myErrorMsgPresentation != null) {
- printer.print(myErrorMsgPresentation, ConsoleViewContentType.ERROR_OUTPUT);
- }
+ TestsPresentationUtil.printWithAnsiColoring(printer, myErrorMsgPresentation, ProcessOutputTypes.STDERR);
// Diff link
myHyperlink.printOn(printer);
// Stacktrace
- if (myStacktracePresentation != null) {
- printer.print(CompositePrintable.NEW_LINE, ConsoleViewContentType.ERROR_OUTPUT);
-
- printer.print(myStacktracePresentation, ConsoleViewContentType.ERROR_OUTPUT);
- printer.print(CompositePrintable.NEW_LINE, ConsoleViewContentType.ERROR_OUTPUT);
- }
+ printer.print(CompositePrintable.NEW_LINE, ConsoleViewContentType.ERROR_OUTPUT);
+ TestsPresentationUtil.printWithAnsiColoring(printer, myStacktracePresentation, ProcessOutputTypes.STDERR);
+ printer.print(CompositePrintable.NEW_LINE, ConsoleViewContentType.ERROR_OUTPUT);
}
public void openDiff(final Project project) {
diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/TestFailedState.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/TestFailedState.java
index 8906bd1867a9..712f6fc35dbf 100644
--- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/TestFailedState.java
+++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/TestFailedState.java
@@ -15,8 +15,10 @@
*/
package com.intellij.execution.testframework.sm.runner.states;
+import com.intellij.execution.process.ProcessOutputTypes;
import com.intellij.execution.testframework.CompositePrintable;
import com.intellij.execution.testframework.Printer;
+import com.intellij.execution.testframework.sm.runner.ui.TestsPresentationUtil;
import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.containers.ContainerUtilRt;
@@ -75,7 +77,7 @@ public class TestFailedState extends AbstractState {
printer.mark();
addMark = false;
}
- printer.print(errorText, ConsoleViewContentType.ERROR_OUTPUT);
+ TestsPresentationUtil.printWithAnsiColoring(printer, errorText, ProcessOutputTypes.STDERR);
}
}
}
diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/TestsPresentationUtil.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/TestsPresentationUtil.java
index 7cb42773f735..d36250191b09 100644
--- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/TestsPresentationUtil.java
+++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/TestsPresentationUtil.java
@@ -15,14 +15,19 @@
*/
package com.intellij.execution.testframework.sm.runner.ui;
+import com.intellij.execution.process.AnsiEscapeDecoder;
+import com.intellij.execution.process.ProcessOutputTypes;
import com.intellij.execution.testframework.PoolOfTestIcons;
+import com.intellij.execution.testframework.Printer;
import com.intellij.execution.testframework.TestConsoleProperties;
import com.intellij.execution.testframework.TestsUIUtil;
import com.intellij.execution.testframework.sm.SMTestsRunnerBundle;
import com.intellij.execution.testframework.sm.runner.SMTestProxy;
import com.intellij.execution.testframework.sm.runner.states.TestStateInfo;
import com.intellij.execution.testframework.ui.TestsProgressAnimator;
+import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.icons.AllIcons;
+import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.ColoredTableCellRenderer;
import com.intellij.ui.SimpleTextAttributes;
@@ -448,4 +453,18 @@ public class TestsPresentationUtil {
break;
}
}
+
+ public static void printWithAnsiColoring(@NotNull final Printer printer, @NotNull String text, @NotNull final Key processOutputType) {
+ AnsiEscapeDecoder decoder = new AnsiEscapeDecoder();
+ decoder.escapeText(text, ProcessOutputTypes.STDOUT, new AnsiEscapeDecoder.ColoredTextAcceptor() {
+ @Override
+ public void coloredTextAvailable(String text, Key attributes) {
+ ConsoleViewContentType contentType = ConsoleViewContentType.getConsoleViewType(attributes);
+ if (contentType == null || contentType == ConsoleViewContentType.NORMAL_OUTPUT) {
+ contentType = ConsoleViewContentType.getConsoleViewType(processOutputType);
+ }
+ printer.print(text, contentType);
+ }
+ });
+ }
}
diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/DataProvider.java b/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/DataProvider.java
deleted file mode 100644
index e7327fad7e5e..000000000000
--- a/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/DataProvider.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.intellij.structuralsearch.impl.matcher;
-
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.project.Project;
-
-/**
- * Created by IntelliJ IDEA.
- * User: maxim
- * Date: 07.01.2004
- * Time: 1:06:51
- * To change this template use Options | File Templates.
- */
-public interface DataProvider {
- Editor getEditor();
- Project getProject();
-}
diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ui/ReplaceUsageViewContext.java b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ui/ReplaceUsageViewContext.java
index 6a0d352d3284..f5279e15026e 100644
--- a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ui/ReplaceUsageViewContext.java
+++ b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ui/ReplaceUsageViewContext.java
@@ -44,13 +44,6 @@ class ReplaceUsageViewContext extends UsageViewContext {
return command;
}
- protected String _getPresentableText() {
- return SSRBundle.message("replaceusageview.text",
- getConfiguration().getMatchOptions().getSearchPattern(),
- ((ReplaceConfiguration)getConfiguration()).getOptions().getReplacement()
- );
- }
-
public Replacer getReplacer() {
return replacer;
}
diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/DialogBase.java b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/DialogBase.java
deleted file mode 100644
index 83d93ba0d05c..000000000000
--- a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/DialogBase.java
+++ /dev/null
@@ -1,152 +0,0 @@
-package com.intellij.structuralsearch.plugin.ui;
-
-import com.intellij.openapi.MnemonicHelper;
-import com.intellij.CommonBundle;
-
-import javax.swing.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.KeyEvent;
-import java.awt.event.InputEvent;
-import java.awt.*;
-
-import org.jetbrains.annotations.NonNls;
-
-/**
- * Base dialog class
- */
-public abstract class DialogBase extends JDialog {
- private JButton ok;
- private JButton cancel;
-
- private Action okAction;
- private Action cancelAction;
- private static Rectangle virtualBounds;
-
- class OkAction extends AbstractAction {
- OkAction() {
- putValue(NAME, CommonBundle.getOkButtonText());
- }
- public void actionPerformed(ActionEvent e) {
- doOKAction();
- }
- }
-
- class CancelAction extends AbstractAction {
- CancelAction() {
- putValue(NAME,CommonBundle.getCancelButtonText());
- }
-
- public void actionPerformed(ActionEvent e) {
- doCancelAction();
- }
- }
-
- protected DialogBase() {
- this(null);
- }
-
- protected DialogBase(Frame frame) {
- this(frame,true);
- }
-
- protected DialogBase(Frame frame,boolean modal) {
- super(frame,modal);
-
- new MnemonicHelper().register(getContentPane());
-
- okAction = new OkAction();
- cancelAction = new CancelAction();
-
- ok = createJButtonForAction(okAction);
- cancel = createJButtonForAction(cancelAction);
-
- if (virtualBounds == null) {
- GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
- GraphicsDevice[] gs = ge.getScreenDevices();
- virtualBounds = new Rectangle();
-
- for (int j = 0; j < gs.length; j++) {
- GraphicsDevice gd = gs[j];
- GraphicsConfiguration[] gc = gd.getConfigurations();
-
- for (int i=0; i < gc.length; i++) {
- virtualBounds = virtualBounds.union(gc[i].getBounds());
- }
- }
- }
-
- @NonNls String cancelCommandName = "close";
- KeyStroke escKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE,0);
- ok.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(escKeyStroke, cancelCommandName);
- ok.getActionMap().put(cancelCommandName, cancelAction);
-
- @NonNls String startCommandName = "start";
- KeyStroke enterKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,InputEvent.CTRL_MASK);
- ok.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(enterKeyStroke, startCommandName);
- ok.getActionMap().put(startCommandName, okAction);
- }
-
- protected JButton getCancelButton() {
- return cancel;
- }
-
- protected JButton getOkButton() {
- return ok;
- }
-
- protected abstract JComponent createCenterPanel();
-
- protected JComponent createSouthPanel() {
- JPanel p = new JPanel( null );
- p.setLayout( new BoxLayout(p,BoxLayout.X_AXIS) );
- p.add(Box.createHorizontalGlue());
- p.add(getOkButton());
- p.add(getCancelButton());
- return p;
- }
-
- public void init() {
- getContentPane().setLayout(new BorderLayout());
- getContentPane().add(BorderLayout.CENTER,createCenterPanel());
- getContentPane().add(BorderLayout.SOUTH,createSouthPanel());
- pack();
-
- Dimension dim = getPreferredSize();
- setLocation(
- (int)(virtualBounds.getWidth()/2 - dim.getWidth()/2),
- (int)(virtualBounds.getHeight()/2 - dim.getHeight()/2)
- );
- }
-
- public void show() {
- pack();
- super.show();
- }
-
- protected void doCancelAction() {
- setVisible(false);
- }
-
- protected void doOKAction() {
- setVisible(false);
- }
-
- protected void setOKActionEnabled(boolean b) {
- okAction.setEnabled(b);
- }
-
- protected void setOKButtonText(String text) {
- okAction.putValue(Action.NAME,text);
- }
-
- protected void setCancelButtonText(String text) {
- cancelAction.putValue(Action.NAME,text);
- }
-
- protected JButton createJButtonForAction(Action _action) {
- JButton jb = new JButton( (String)_action.getValue(Action.NAME) );
- jb.setAction(_action);
-
- return jb;
- }
-}
diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/EditVarConstraintsDialog.java b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/EditVarConstraintsDialog.java
index f82ad12e5f4f..258aaf6b8ccc 100644
--- a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/EditVarConstraintsDialog.java
+++ b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/EditVarConstraintsDialog.java
@@ -30,11 +30,13 @@ import com.intellij.structuralsearch.MatchVariableConstraint;
import com.intellij.structuralsearch.NamedScriptableDefinition;
import com.intellij.structuralsearch.ReplacementVariableDefinition;
import com.intellij.structuralsearch.SSRBundle;
+import com.intellij.structuralsearch.impl.matcher.CompiledPattern;
import com.intellij.structuralsearch.impl.matcher.predicates.ScriptSupport;
import com.intellij.structuralsearch.plugin.replace.ReplaceOptions;
import com.intellij.structuralsearch.plugin.replace.ui.ReplaceConfiguration;
import com.intellij.ui.ComboboxWithBrowseButton;
import com.intellij.ui.EditorTextField;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -47,6 +49,7 @@ import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
+import java.util.Set;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
@@ -223,7 +226,10 @@ class EditVarConstraintsDialog extends DialogWrapper {
customScriptCode.getButton().addActionListener(new ActionListener() {
public void actionPerformed(@NotNull final ActionEvent e) {
- final EditScriptDialog dialog = new EditScriptDialog(project, customScriptCode.getChildComponent().getText());
+ Set<String> strings = ContainerUtil.collectSet(model.getConfig().getMatchOptions().getVariableConstraintNames());
+ strings.remove(current.getName());
+ strings.remove(CompiledPattern.ALL_CLASS_UNMATCHED_CONTENT_VAR_ARTIFICIAL_NAME);
+ EditScriptDialog dialog = new EditScriptDialog(project, customScriptCode.getChildComponent().getText(), strings);
dialog.show();
if (dialog.getExitCode() == OK_EXIT_CODE) {
customScriptCode.getChildComponent().setText(dialog.getScriptText());
@@ -585,11 +591,13 @@ class EditVarConstraintsDialog extends DialogWrapper {
private static class EditScriptDialog extends DialogWrapper {
private final Editor editor;
+ private final String title;
- public EditScriptDialog(final Project project, String text) {
+ public EditScriptDialog(Project project, String text, Set<String> names) {
super(project, true);
setTitle(SSRBundle.message("edit.groovy.script.constraint.title"));
editor = createEditor(project, text, "1.groovy");
+ title = names.size() > 0 ? "Available variables: " + StringUtil.join(names, ", ") : "";
init();
}
@@ -604,7 +612,15 @@ class EditVarConstraintsDialog extends DialogWrapper {
}
protected JComponent createCenterPanel() {
- return editor.getComponent();
+ JPanel panel = new JPanel(new BorderLayout());
+ panel.add(editor.getComponent(), BorderLayout.CENTER);
+ if (!title.isEmpty()) {
+ JTextField f=new JTextField(title);
+ f.setEditable(false);
+ f.setBorder(null);
+ panel.add(f, BorderLayout.SOUTH);
+ }
+ return panel;
}
String getScriptText() {
diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchCommand.java b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchCommand.java
index 8cb7e55ea290..80f0c7b8ce0d 100644
--- a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchCommand.java
+++ b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchCommand.java
@@ -56,6 +56,7 @@ public class SearchCommand {
}
public void matchingFinished() {
+ if (project.isDisposed()) return;
findEnded();
progress.setText(SSRBundle.message("found.progress.message", count));
}
@@ -114,7 +115,7 @@ public class SearchCommand {
new Runnable() {
@Override
public void run() {
- NotificationGroup.toolWindowGroup("Structural Search", ToolWindowId.FIND, true)
+ NotificationGroup.toolWindowGroup("Structural Search", ToolWindowId.FIND)
.createNotification(SSRBundle.message("problem", e.getMessage()), MessageType.ERROR).notify(project);
}
},
@@ -132,9 +133,7 @@ public class SearchCommand {
}
protected void findEnded() {
- if (!project.isDisposed()) {
- StructuralSearchPlugin.getInstance(project).setSearchInProgress(false);
- }
+ StructuralSearchPlugin.getInstance(project).setSearchInProgress(false);
}
protected void foundUsage(MatchResult result, Usage usage) {
diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchContext.java b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchContext.java
index 62371e7e29d1..045c2749871c 100644
--- a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchContext.java
+++ b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchContext.java
@@ -9,12 +9,11 @@ import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
-import com.intellij.structuralsearch.impl.matcher.DataProvider;
/**
* Context of the search to be done
*/
-public final class SearchContext implements DataProvider, Cloneable {
+public final class SearchContext implements Cloneable {
private final PsiFile file;
private final Project project;
diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchDialog.java b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchDialog.java
index a3bee702563e..3f89f11b9e6d 100644
--- a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchDialog.java
+++ b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchDialog.java
@@ -12,6 +12,7 @@ import com.intellij.lang.LanguageUtil;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.command.WriteCommandAction;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
@@ -90,8 +91,6 @@ public class SearchDialog extends DialogWrapper implements ConfigurationCreator
private boolean useLastConfiguration;
- private static boolean ourOpenInNewTab;
-
@NonNls private FileType ourFtSearchVariant = StructuralSearchUtil.getDefaultFileType();
private static Language ourDialect = null;
private static String ourContext = null;
@@ -184,7 +183,7 @@ public class SearchDialog extends DialogWrapper implements ConfigurationCreator
try {
new WriteAction(){
@Override
- protected void run(Result result) throws Throwable {
+ protected void run(Result result) {
if (!isValid()) {
getOKAction().setEnabled(false);
}
@@ -195,8 +194,8 @@ public class SearchDialog extends DialogWrapper implements ConfigurationCreator
}
}.execute();
}
- catch (Exception e) {
- e.printStackTrace();
+ catch (RuntimeException e) {
+ Logger.getInstance(SearchDialog.class).error(e);
}
}
}, 500);
@@ -498,7 +497,7 @@ public class SearchDialog extends DialogWrapper implements ConfigurationCreator
final UsageViewContext context = createUsageViewContext(config);
final UsageViewPresentation presentation = new UsageViewPresentation();
- presentation.setOpenInNewTab(openInNewTab.isSelected());
+ presentation.setOpenInNewTab(FindSettings.getInstance().isShowResultsInSeparateView());
presentation.setScopeText(config.getMatchOptions().getScope().getDisplayName());
context.configure(presentation);
@@ -635,7 +634,7 @@ public class SearchDialog extends DialogWrapper implements ConfigurationCreator
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 0));
openInNewTab = new JCheckBox(FindBundle.message("find.open.in.new.tab.checkbox"));
- openInNewTab.setSelected(ourOpenInNewTab);
+ openInNewTab.setSelected(FindSettings.getInstance().isShowResultsInSeparateView());
ToolWindow findWindow = ToolWindowManager.getInstance(searchContext.getProject()).getToolWindow(ToolWindowId.FIND);
openInNewTab.setEnabled(findWindow != null && findWindow.isAvailable());
panel.add(openInNewTab, BorderLayout.EAST);
@@ -868,8 +867,9 @@ public class SearchDialog extends DialogWrapper implements ConfigurationCreator
super.doOKAction();
if (!myRunFindActionOnClose) return;
- FindSettings.getInstance().setDefaultScopeName(selectedScope.getDisplayName());
- ourOpenInNewTab = openInNewTab.isSelected();
+ final FindSettings findSettings = FindSettings.getInstance();
+ findSettings.setDefaultScopeName(selectedScope.getDisplayName());
+ findSettings.setShowResultsInSeparateView(openInNewTab.isSelected());
try {
if (model.getShadowConfig() != null) {
diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/UIUtil.java b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/UIUtil.java
index e2c16bfbc355..7521b9bbc014 100644
--- a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/UIUtil.java
+++ b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/UIUtil.java
@@ -3,7 +3,6 @@ package com.intellij.structuralsearch.plugin.ui;
import com.intellij.codeInsight.hint.TooltipController;
import com.intellij.codeInsight.hint.TooltipGroup;
import com.intellij.codeInsight.template.TemplateContextType;
-import com.intellij.codeInsight.template.impl.TemplateContext;
import com.intellij.codeInsight.template.impl.TemplateEditorUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
@@ -77,12 +76,8 @@ public class UIUtil {
else {
((EditorEx)editor).setEmbeddedIntoDialogWrapper(true);
}
-
- if (contextType != null) {
- TemplateContext context = new TemplateContext();
- context.setEnabled(contextType, true);
- TemplateEditorUtil.setHighlighter(editor, context);
- }
+
+ TemplateEditorUtil.setHighlighter(editor, contextType);
if (addToolTipForVariableHandler) {
SubstitutionShortInfoHandler handler = new SubstitutionShortInfoHandler(editor);
@@ -222,11 +217,6 @@ public class UIUtil {
}
public static void updateHighlighter(Editor editor, StructuralSearchProfile profile) {
- final TemplateContextType contextType = profile.getTemplateContextType();
- if (contextType != null) {
- TemplateContext context = new TemplateContext();
- context.setEnabled(contextType, true);
- TemplateEditorUtil.setHighlighter(editor, context);
- }
+ TemplateEditorUtil.setHighlighter(editor, profile.getTemplateContextType());
}
}
diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/UsageViewContext.java b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/UsageViewContext.java
index a55a16d4c379..e492906f0d4f 100644
--- a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/UsageViewContext.java
+++ b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/UsageViewContext.java
@@ -8,9 +8,13 @@ import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
+import com.intellij.structuralsearch.MatchOptions;
import com.intellij.structuralsearch.SSRBundle;
import com.intellij.structuralsearch.plugin.replace.ui.ReplaceCommand;
-import com.intellij.usages.*;
+import com.intellij.usages.ConfigurableUsageTarget;
+import com.intellij.usages.Usage;
+import com.intellij.usages.UsageView;
+import com.intellij.usages.UsageViewPresentation;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -61,20 +65,15 @@ public class UsageViewContext {
return new SearchCommand(mySearchContext.getProject(), this);
}
- protected String _getPresentableText() {
- return myConfiguration.getMatchOptions().getSearchPattern();
- }
-
- public UsageTarget getTarget() {
- return new MyUsageTarget(_getPresentableText());
+ public ConfigurableUsageTarget getTarget() {
+ return new MyUsageTarget();
}
public void configure(@NotNull UsageViewPresentation presentation) {
- String s = _getPresentableText();
- if (s.length() > 15) s = s.substring(0,15) + "...";
- final String usagesString = SSRBundle.message("occurrences.of", s);
- presentation.setUsagesString(usagesString);
- presentation.setTabText(StringUtil.capitalize(usagesString));
+ final String pattern = myConfiguration.getMatchOptions().getSearchPattern();
+ final String usagesString = SSRBundle.message("occurrences.of", StringUtil.shortenTextWithEllipsis(pattern, 50, 0, true));
+ presentation.setUsagesString(SSRBundle.message("occurrences.of", pattern));
+ presentation.setTabText(usagesString);
presentation.setUsagesWord(SSRBundle.message("occurrence"));
presentation.setCodeUsagesString(SSRBundle.message("found.occurrences"));
}
@@ -82,15 +81,12 @@ public class UsageViewContext {
protected void configureActions() {}
private class MyUsageTarget implements ConfigurableUsageTarget,ItemPresentation {
- private final String myPresentableText;
-
- MyUsageTarget(String str) {
- myPresentableText = str;
- }
+ @NotNull
@Override
public String getPresentableText() {
- return myPresentableText;
+ final MatchOptions matchOptions = myConfiguration.getMatchOptions();
+ return SSRBundle.message("occurrences.of.0.in.1", matchOptions.getSearchPattern(), matchOptions.getScope().getDisplayName());
}
@Override
@@ -177,7 +173,7 @@ public class UsageViewContext {
@NotNull
@Override
public String getLongDescriptiveName() {
- return _getPresentableText();
+ return getPresentableText();
}
}
}
diff --git a/platform/structuralsearch/source/messages/SSRBundle.properties b/platform/structuralsearch/source/messages/SSRBundle.properties
index bfd12890ffb9..97baac9bf247 100644
--- a/platform/structuralsearch/source/messages/SSRBundle.properties
+++ b/platform/structuralsearch/source/messages/SSRBundle.properties
@@ -31,9 +31,10 @@ search.dialog.file.dialect.label=D&ialect:
#search usage view specific
looking.in.progress.message=Looking in {0}
found.progress.message=Found {0} occurrences
-occurrences.of=occurrences of {0}
+occurrences.of=Occurrences of ''{0}''
+occurrences.of.0.in.1=Occurrences of ''{0}'' in {1}
occurrence=occurrence
-found.occurrences=Found occurrence
+found.occurrences=Found occurrences
# search dialog messages
this.pattern.is.malformed.message=This pattern is malformed\n {0}
@@ -48,7 +49,6 @@ selecttemplate.template.label.please.select.template=<html><body><center>Please
# Replace Dialog specific titles/options
structural.replace.title=Structural Replace
shorten.fully.qualified.names.checkbox=Sh&orten fully qualified names
-format.according.to.style.checkbox=Fo&rmat according to style
replacement.template.label=Replacement template:
# Replace validation messages
diff --git a/platform/structure-view-impl/src/com/intellij/ide/util/treeView/smartTree/SmartTreeStructure.java b/platform/structure-view-impl/src/com/intellij/ide/util/treeView/smartTree/SmartTreeStructure.java
index 478c160b8c14..be7eb5453638 100644
--- a/platform/structure-view-impl/src/com/intellij/ide/util/treeView/smartTree/SmartTreeStructure.java
+++ b/platform/structure-view-impl/src/com/intellij/ide/util/treeView/smartTree/SmartTreeStructure.java
@@ -36,6 +36,12 @@ public class SmartTreeStructure extends AbstractTreeStructure {
@Override
public void commit() {
+ PsiDocumentManager.getInstance(myProject).commitAllDocuments();
+ }
+
+ @Override
+ public boolean hasSomethingToCommit() {
+ return PsiDocumentManager.getInstance(myProject).hasUncommitedDocuments();
}
@Override
@@ -71,11 +77,6 @@ public class SmartTreeStructure extends AbstractTreeStructure {
return ((AbstractTreeNode)element).isAlwaysLeaf();
}
- @Override
- public boolean hasSomethingToCommit() {
- return PsiDocumentManager.getInstance(myProject).hasUncommitedDocuments();
- }
-
public void rebuildTree() {
((CachingChildrenTreeNode)getRootElement()).rebuildChildren();
}
diff --git a/platform/testFramework/src/com/intellij/testFramework/MockSchemesManagerFactory.java b/platform/testFramework/src/com/intellij/testFramework/MockSchemesManagerFactory.java
index b74bb8e204b5..ab5ee3d9f7c6 100644
--- a/platform/testFramework/src/com/intellij/testFramework/MockSchemesManagerFactory.java
+++ b/platform/testFramework/src/com/intellij/testFramework/MockSchemesManagerFactory.java
@@ -2,16 +2,19 @@ package com.intellij.testFramework;
import com.intellij.openapi.components.RoamingType;
import com.intellij.openapi.options.*;
+import org.jetbrains.annotations.NotNull;
public class MockSchemesManagerFactory extends SchemesManagerFactory {
@Override
- public <T extends Scheme,E extends ExternalizableScheme> SchemesManager<T,E> createSchemesManager(final String fileSpec,
- final SchemeProcessor<E> processor, final RoamingType roamingType) {
+ public <T extends Scheme, E extends ExternalizableScheme> SchemesManager<T, E> createSchemesManager(@NotNull String fileSpec,
+ @NotNull SchemeProcessor<E> processor,
+ @NotNull RoamingType roamingType) {
+ //noinspection unchecked
return SchemesManager.EMPTY;
}
@Override
public void updateConfigFilesFromStreamProviders() {
-
+
}
}
diff --git a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java
index d9b32080f458..ea7a7c0deed1 100644
--- a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java
+++ b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java
@@ -141,7 +141,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
}
private static final String[] PREFIX_CANDIDATES = {
- "AppCode", "CppIde", "CidrCommon",
+ "AppCode", "CLion", "CidrCommon",
"Python", "PyCharmCore", "Ruby", "UltimateLangXml", "Idea" };
public static void autodetectPlatformPrefix() {
diff --git a/platform/testFramework/src/com/intellij/testFramework/PlatformTestUtil.java b/platform/testFramework/src/com/intellij/testFramework/PlatformTestUtil.java
index 307fb65e5ef1..ee6e519cb583 100644
--- a/platform/testFramework/src/com/intellij/testFramework/PlatformTestUtil.java
+++ b/platform/testFramework/src/com/intellij/testFramework/PlatformTestUtil.java
@@ -52,6 +52,7 @@ import com.intellij.util.io.ZipUtil;
import com.intellij.util.ui.UIUtil;
import junit.framework.AssertionFailedError;
import org.jdom.Element;
+import org.jdom.JDOMException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -752,6 +753,18 @@ public class PlatformTestUtil {
}
}
+ public static void assertElementEquals(final String expected, final Element actual) {
+ try {
+ assertElementsEqual(JDOMUtil.loadDocument(expected).getRootElement(), actual);
+ }
+ catch (IOException e) {
+ throw new AssertionError(e);
+ }
+ catch (JDOMException e) {
+ throw new AssertionError(e);
+ }
+ }
+
public static String printElement(final Element element) throws IOException {
final StringWriter writer = new StringWriter();
JDOMUtil.writeElement(element, writer, "\n");
diff --git a/platform/testFramework/src/com/intellij/testFramework/PlatformUltraLiteTestFixture.java b/platform/testFramework/src/com/intellij/testFramework/PlatformUltraLiteTestFixture.java
index 5b01cf414149..ee6c3bd68304 100644
--- a/platform/testFramework/src/com/intellij/testFramework/PlatformUltraLiteTestFixture.java
+++ b/platform/testFramework/src/com/intellij/testFramework/PlatformUltraLiteTestFixture.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,10 +15,10 @@
*/
package com.intellij.testFramework;
-import com.intellij.mock.MockApplication;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.impl.ApplicationImpl;
import com.intellij.openapi.util.Disposer;
import org.jetbrains.annotations.NotNull;
@@ -28,21 +28,19 @@ public class PlatformUltraLiteTestFixture {
return new PlatformUltraLiteTestFixture();
}
- private Disposable myAppDisposable = null;
+ private final Disposable myAppDisposable = Disposer.newDisposable();
private PlatformUltraLiteTestFixture() { }
public void setUp() {
final Application application = ApplicationManager.getApplication();
if (application == null) {
- myAppDisposable = Disposer.newDisposable();
- ApplicationManager.setApplication(new MockApplication(myAppDisposable), myAppDisposable);
+ ApplicationImpl testapp = new ApplicationImpl(false, true, true, true, "testapp", null);
+ ApplicationManager.setApplication(testapp, myAppDisposable);
}
}
public void tearDown() {
- if (myAppDisposable != null) {
- Disposer.dispose(myAppDisposable);
- }
+ Disposer.dispose(myAppDisposable);
}
}
diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java
index 449b1bacf8e9..8aafb17da1de 100644
--- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java
+++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java
@@ -576,6 +576,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
@Override
public void launchAction(@NotNull final IntentionAction action) {
ShowIntentionActionsHandler.chooseActionAndInvoke(getFile(), getEditor(), action, action.getText());
+ UIUtil.dispatchAllInvocationEvents();
}
@Override
@@ -1424,6 +1425,8 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
module.getMessageBus().syncPublisher(FacetManager.FACETS_TOPIC).facetConfigurationChanged(facet);
}
}
+ PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
+
if (myCaresAboutInjection) {
setupEditorForInjectedLanguage();
}
diff --git a/platform/testRunner/src/com/intellij/execution/testframework/TestTreeView.java b/platform/testRunner/src/com/intellij/execution/testframework/TestTreeView.java
index 2ecb0fca32cd..839568b4c2a9 100644
--- a/platform/testRunner/src/com/intellij/execution/testframework/TestTreeView.java
+++ b/platform/testRunner/src/com/intellij/execution/testframework/TestTreeView.java
@@ -52,6 +52,10 @@ public abstract class TestTreeView extends Tree implements DataProvider, CopyPro
public abstract AbstractTestProxy getSelectedTest(@NotNull TreePath selectionPath);
+ protected TestFrameworkRunningModel getTestFrameworkRunningModel() {
+ return myModel;
+ }
+
@Nullable
public AbstractTestProxy getSelectedTest() {
TreePath[] paths = getSelectionPaths();
diff --git a/platform/usageView/src/com/intellij/usages/impl/GroupNode.java b/platform/usageView/src/com/intellij/usages/impl/GroupNode.java
index 44e33ef3632a..ac4079d1309e 100644
--- a/platform/usageView/src/com/intellij/usages/impl/GroupNode.java
+++ b/platform/usageView/src/com/intellij/usages/impl/GroupNode.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -294,8 +294,8 @@ public class GroupNode extends Node implements Navigatable, Comparable<GroupNode
protected boolean isDataReadOnly() {
Enumeration enumeration = children();
while (enumeration.hasMoreElements()) {
- Node node = (Node)enumeration.nextElement();
- if (node.isReadOnly()) return true;
+ Object element = enumeration.nextElement();
+ if (element instanceof Node && ((Node)element).isReadOnly()) return true;
}
return false;
}
diff --git a/platform/usageView/src/com/intellij/usages/impl/SearchForUsagesRunnable.java b/platform/usageView/src/com/intellij/usages/impl/SearchForUsagesRunnable.java
index 170d1802eee4..8771ef75502b 100644
--- a/platform/usageView/src/com/intellij/usages/impl/SearchForUsagesRunnable.java
+++ b/platform/usageView/src/com/intellij/usages/impl/SearchForUsagesRunnable.java
@@ -327,7 +327,7 @@ class SearchForUsagesRunnable implements Runnable {
@Override
public void run() {
notifyByFindBalloon(null, MessageType.WARNING, myProcessPresentation, myProject,
- Collections.singletonList(UsageViewManagerImpl.getProgressTitle(myPresentation)));
+ Collections.singletonList(StringUtil.escapeXml(UsageViewManagerImpl.getProgressTitle(myPresentation))));
findStartedBalloonShown.set(true);
}
}, 300, ModalityState.NON_MODAL);
diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java b/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java
index b9fc77295d62..a33bc9e48437 100644
--- a/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java
+++ b/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java
@@ -196,8 +196,7 @@ public class UsageViewManagerImpl extends UsageViewManager {
public static String getProgressTitle(@NotNull UsageViewPresentation presentation) {
final String scopeText = presentation.getScopeText();
String usagesString = StringUtil.capitalize(presentation.getUsagesString());
- String result = UsageViewBundle.message("progress.searching.for.in", usagesString, scopeText);
- return StringUtil.escapeXml(result);
+ return UsageViewBundle.message("progress.searching.for.in", usagesString, scopeText);
}
void showToolWindow(boolean activateWindow) {
diff --git a/platform/util-rt/src/com/intellij/openapi/util/Conditions.java b/platform/util-rt/src/com/intellij/openapi/util/Conditions.java
index 791a5a9756dd..48bb06ad8b8e 100644
--- a/platform/util-rt/src/com/intellij/openapi/util/Conditions.java
+++ b/platform/util-rt/src/com/intellij/openapi/util/Conditions.java
@@ -34,10 +34,18 @@ public class Conditions {
return (Condition<T>)FALSE;
}
+ public static <T> Condition<T> instanceOf(final Class<?> clazz) {
+ return new Condition<T>() {
+ public boolean value(T t) {
+ return clazz.isInstance(t);
+ }
+ };
+ }
+
public static <T> Condition<T> is(final T option) {
return new Condition<T>() {
public boolean value(T t) {
- return t == option;
+ return Comparing.equal(t, option);
}
};
}
diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties
index e9802f2321ae..11ace8a42cad 100644
--- a/platform/util/resources/misc/registry.properties
+++ b/platform/util/resources/misc/registry.properties
@@ -58,7 +58,7 @@ ide.checkDuplicateMnemonics.description=Check for duplicate mnemonics.
ide.dnd.textHints=false
ide.max.recent.projects=25
-ide.hide.excluded.files=true
+ide.hide.excluded.files=false
ide.hide.excluded.files.restartRequired=true
ide.hide.excluded.files.description=Do not show excluded files in Project View and exclude them from VCS
@@ -122,7 +122,7 @@ editor.use.scrollable.tabs=true
editor.smarterSelectionQuoting=true
editor.skip.copy.and.cut.for.empty.selection=false
editor.distraction.free.mode=false
-
+editor.use.preview=false
editor.add.carets.on.double.control.arrows=true
ide.showIndexRebuildMessage=false
@@ -150,7 +150,6 @@ ide.perProjectModality.description=New modality approach. All dialogs are DOCUME
ide.mac.retina.disableDrawingFix=false
-ide.new.preferences=false
ide.new.license.dialog=true
debugger.valueTooltipAutoShow=true
@@ -160,6 +159,8 @@ debugger.breakpoint.message.full.trace=false
debugger.breakpoint.message.full.trace.description='Log message to console' breakpoint action will out full stacktrace\
for the thread that hit the breakpoint.
debugger.batch.evaluation=false
+debugger.compiling.evaluator=false
+debugger.watches.in.variables=false
analyze.exceptions.on.the.fly=false
analyze.exceptions.on.the.fly.description=Automatically analyze clipboard on frame activation,\
@@ -320,6 +321,7 @@ diff.status.tracker.skip.spaces=true
svn.use.terminal=false
svn.use.incoming.optimization=false
svn.executable.locale=C.UTF-8
+svn.lowest.supported.format.for.command.line=1.7.0
completion.enable.relevant.method.chain.suggestions=false
ide.mac.message.sheets.java.emulation=false
@@ -354,8 +356,10 @@ embed.scene.builder=true
dsm.retina.darcula.legend=true
dsm.retina.darcula.legend.description=Experimental DSM legend component
-ide.scratch.enabled=false
-ide.show.progress.without.status.bar=false
+ide.scratch.enabled=true
+ide.scratch.enabled.description=Disables Tools > Scratchpad: temporary editor without persistence
+ide.show.progress.without.status.bar=true
+ide.show.progress.without.status.bar.description=Disables transparent progress indicator when status bar is switched off
editor.injected.highlighting.enabled=true
editor.injected.highlighting.enabled.description=Disables injected fragments highlighting (requires project reopening)
@@ -393,8 +397,8 @@ console.too.much.text.buffer.ratio=10
console.too.much.text.buffer.ratio.description=Used for disabling of console processing(console filters for highlights, foldings...),\n\
when there is too much of text to process.\n\
The ratio is used against the console cycle buffer size (idea.cycle.buffer.size/theRatio=maxTextLength).
-ide.file.settings.order.new=false
-ide.file.settings.tree.new=false
+ide.new.settings.dialog=true
+ide.new.settings.dialog.description=New settings dialog
ide.new.project.settings=true
ide.new.project.settings.description=Temporary key for new project settings dialog UI
diff --git a/platform/util/src/com/intellij/diagnostic/ThreadDumper.java b/platform/util/src/com/intellij/diagnostic/ThreadDumper.java
index ede7cddbd5c5..a67cc6cbdc31 100644
--- a/platform/util/src/com/intellij/diagnostic/ThreadDumper.java
+++ b/platform/util/src/com/intellij/diagnostic/ThreadDumper.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,6 +24,8 @@ import java.io.Writer;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
+import java.util.Arrays;
+import java.util.Comparator;
/**
* @author yole
@@ -44,7 +46,7 @@ public class ThreadDumper {
boolean dumpSuccessful = false;
try {
- ThreadInfo[] threads = threadMXBean.dumpAllThreads(false, false);
+ ThreadInfo[] threads = sort(threadMXBean.dumpAllThreads(false, false));
for(ThreadInfo info: threads) {
if (info != null) {
if (info.getThreadName().equals("AWT-EventQueue-1")) {
@@ -61,7 +63,7 @@ public class ThreadDumper {
if (!dumpSuccessful) {
final long[] threadIds = threadMXBean.getAllThreadIds();
- final ThreadInfo[] threadInfo = threadMXBean.getThreadInfo(threadIds, Integer.MAX_VALUE);
+ final ThreadInfo[] threadInfo = sort(threadMXBean.getThreadInfo(threadIds, Integer.MAX_VALUE));
for (ThreadInfo info : threadInfo) {
if (info != null) {
if (info.getThreadName().equals("AWT-EventQueue-1")) {
@@ -75,6 +77,25 @@ public class ThreadDumper {
return edtStack;
}
+ private static ThreadInfo[] sort(ThreadInfo[] threads) {
+ Arrays.sort(threads, new Comparator<ThreadInfo>() {
+ @Override
+ public int compare(ThreadInfo o1, ThreadInfo o2) {
+ final String t1 = o1.getThreadName();
+ final String t2 = o2.getThreadName();
+ if (t1.startsWith("AWT-EventQueue")) return -1;
+ if (t2.startsWith("AWT-EventQueue")) return 1;
+ final boolean r1 = o1.getThreadState() == Thread.State.RUNNABLE;
+ final boolean r2 = o2.getThreadState() == Thread.State.RUNNABLE;
+ if (r1 && !r2) return -1;
+ if (r2 && !r1) return 1;
+ return 0;
+ }
+ });
+
+ return threads;
+ }
+
private static void dumpThreadInfo(final ThreadInfo info, final Writer f) {
dumpCallStack(info, f, info.getStackTrace());
}
diff --git a/platform/util/src/com/intellij/icons/AllIcons.java b/platform/util/src/com/intellij/icons/AllIcons.java
index 318895db57f1..a80ffccdd58e 100644
--- a/platform/util/src/com/intellij/icons/AllIcons.java
+++ b/platform/util/src/com/intellij/icons/AllIcons.java
@@ -74,9 +74,9 @@ public class AllIcons {
public static final Icon Forward = IconLoader.getIcon("/actions/forward.png"); // 16x16
public static final Icon GC = IconLoader.getIcon("/actions/gc.png"); // 16x16
public static final Icon Get = IconLoader.getIcon("/actions/get.png"); // 16x16
+ public static final Icon GroupByClass = IconLoader.getIcon("/actions/GroupByClass.png"); // 16x16
public static final Icon GroupByFile = IconLoader.getIcon("/actions/GroupByFile.png"); // 16x16
public static final Icon GroupByMethod = IconLoader.getIcon("/actions/groupByMethod.png"); // 16x16
- public static final Icon GroupByClass = IconLoader.getIcon("/actions/GroupByClass.png"); // 16x16
public static final Icon GroupByModule = IconLoader.getIcon("/actions/GroupByModule.png"); // 16x16
public static final Icon GroupByModuleGroup = IconLoader.getIcon("/actions/GroupByModuleGroup.png"); // 16x16
public static final Icon GroupByPackage = IconLoader.getIcon("/actions/GroupByPackage.png"); // 16x16
@@ -833,6 +833,7 @@ public class AllIcons {
public static final Icon Method = IconLoader.getIcon("/nodes/method.png"); // 16x16
public static final Icon Module = IconLoader.getIcon("/nodes/Module.png"); // 16x16
public static final Icon ModuleGroup = IconLoader.getIcon("/nodes/moduleGroup.png"); // 16x16
+ public static final Icon NativeLibrariesFolder = IconLoader.getIcon("/nodes/nativeLibrariesFolder.png"); // 16x16
public static final Icon NewException = IconLoader.getIcon("/nodes/newException.png"); // 14x14
public static final Icon NewFolder = IconLoader.getIcon("/nodes/newFolder.png"); // 16x16
public static final Icon NewParameter = IconLoader.getIcon("/nodes/newParameter.png"); // 14x14
diff --git a/platform/util/src/com/intellij/openapi/application/PathManager.java b/platform/util/src/com/intellij/openapi/application/PathManager.java
index 4001fd0138ef..9956959f0e22 100644
--- a/platform/util/src/com/intellij/openapi/application/PathManager.java
+++ b/platform/util/src/com/intellij/openapi/application/PathManager.java
@@ -418,7 +418,7 @@ public class PathManager {
private static String getAbsolutePath(String path) {
path = FileUtil.expandUserHome(path);
- return new File(path).getAbsolutePath();
+ return FileUtil.toCanonicalPath(new File(FileUtil.toCanonicalPath(path)).getAbsolutePath());
}
private static String trimPathQuotes(String path){
diff --git a/platform/util/src/com/intellij/openapi/diagnostic/Logger.java b/platform/util/src/com/intellij/openapi/diagnostic/Logger.java
index f3da0c22fde5..d90876fe6be9 100644
--- a/platform/util/src/com/intellij/openapi/diagnostic/Logger.java
+++ b/platform/util/src/com/intellij/openapi/diagnostic/Logger.java
@@ -69,6 +69,7 @@ public abstract class Logger {
return ourFactory.getLoggerInstance(category);
}
+ @NotNull
public static Logger getInstance(Class cl) {
return getInstance("#" + cl.getName());
}
diff --git a/platform/util/src/com/intellij/openapi/util/JDOMUtil.java b/platform/util/src/com/intellij/openapi/util/JDOMUtil.java
index 2cd5ed09bfdc..c82ee6df346b 100644
--- a/platform/util/src/com/intellij/openapi/util/JDOMUtil.java
+++ b/platform/util/src/com/intellij/openapi/util/JDOMUtil.java
@@ -204,34 +204,34 @@ public class JDOMUtil {
@NotNull
private static String intern(@NotNull final StringInterner interner, @NotNull final String s) {
- synchronized (interner) {
- return interner.intern(s);
- }
+ return interner.intern(s);
}
@NotNull
- public static String legalizeText(@NotNull final String str) {
- StringReader reader = new StringReader(str);
- StringBuilder result = new StringBuilder();
-
- while(true) {
- try {
- int each = reader.read();
- if (each == -1) break;
+ public static String legalizeText(@NotNull String str) {
+ return legalizeChars(str).toString();
+ }
- if (Verifier.isXMLCharacter(each)) {
- result.append((char)each);
- } else {
- result.append("0x").append(StringUtil.toUpperCase(Long.toHexString(each)));
- }
- }
- catch (IOException ignored) {
- }
+ @NotNull
+ public static CharSequence legalizeChars(@NotNull CharSequence str) {
+ StringBuilder result = new StringBuilder(str.length());
+ for (int i = 0, len = str.length(); i < len; i ++) {
+ appendLegalized(result, str.charAt(i));
}
-
- return result.toString().replaceAll("<", "&lt;").replaceAll(">", "&gt;");
+ return result;
}
+ public static void appendLegalized(@NotNull StringBuilder sb, char each) {
+ if (each == '<' || each == '>') {
+ sb.append(each == '<' ? "&lt;" : "&gt;");
+ }
+ else if (!Verifier.isXMLCharacter(each)) {
+ sb.append("0x").append(StringUtil.toUpperCase(Long.toHexString(each)));
+ }
+ else {
+ sb.append(each);
+ }
+ }
private static class EmptyTextFilter implements Filter {
@Override
diff --git a/platform/util/src/com/intellij/openapi/util/LowMemoryWatcher.java b/platform/util/src/com/intellij/openapi/util/LowMemoryWatcher.java
index 33bd953d422f..f6c7b924590a 100644
--- a/platform/util/src/com/intellij/openapi/util/LowMemoryWatcher.java
+++ b/platform/util/src/com/intellij/openapi/util/LowMemoryWatcher.java
@@ -15,6 +15,7 @@
*/
package com.intellij.openapi.util;
+import com.intellij.openapi.Disposable;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.util.ConcurrencyUtil;
import com.intellij.util.containers.WeakList;
@@ -93,10 +94,29 @@ public class LowMemoryWatcher {
}, null, null);
}
+ /**
+ * Registers a runnable to run on low memory events
+ * @return a LowMemoryWatcher instance holding the runnable. This instance should be kept in memory while the
+ * low memory notification functionality is needed. As soon as it's garbage-collected, the runnable won't receive any further notifications.
+ */
public static LowMemoryWatcher register(Runnable runnable) {
return new LowMemoryWatcher(runnable);
}
+ /**
+ * Registers a runnable to run on low memory events. The notifications will be issued until parentDisposable is disposed.
+ */
+ public static void register(Runnable runnable, Disposable parentDisposable) {
+ final Ref<LowMemoryWatcher> watcher = Ref.create(new LowMemoryWatcher(runnable));
+ Disposer.register(parentDisposable, new Disposable() {
+ @Override
+ public void dispose() {
+ watcher.get().stop();
+ watcher.set(null);
+ }
+ });
+ }
+
private LowMemoryWatcher(Runnable runnable) {
myRunnable = runnable;
ourInstances.add(this);
diff --git a/platform/util/src/com/intellij/openapi/util/NotNullLazyValue.java b/platform/util/src/com/intellij/openapi/util/NotNullLazyValue.java
index 96eefe8ddf78..d604d5f41ed1 100644
--- a/platform/util/src/com/intellij/openapi/util/NotNullLazyValue.java
+++ b/platform/util/src/com/intellij/openapi/util/NotNullLazyValue.java
@@ -38,6 +38,7 @@ public abstract class NotNullLazyValue<T> {
return myValue;
}
+ @NotNull
public static <T> NotNullLazyValue<T> createConstantValue(@NotNull final T value) {
return new NotNullLazyValue<T>() {
@NotNull
diff --git a/platform/util/src/com/intellij/openapi/util/Ref.java b/platform/util/src/com/intellij/openapi/util/Ref.java
index d35b39de264b..0119c5626bf7 100644
--- a/platform/util/src/com/intellij/openapi/util/Ref.java
+++ b/platform/util/src/com/intellij/openapi/util/Ref.java
@@ -15,6 +15,7 @@
*/
package com.intellij.openapi.util;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
@@ -49,6 +50,7 @@ public class Ref<T> {
return false;
}
+ @NotNull
public static <T> Ref<T> create() {
return new Ref<T>();
}
diff --git a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java
index adec13d20412..7d3d6f557249 100644
--- a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java
+++ b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java
@@ -848,9 +848,10 @@ public class FileUtil extends FileUtilRt {
}
public static boolean isFilePathAcceptable(@NotNull File root, @Nullable FileFilter fileFilter) {
+ if (fileFilter == null) return true;
File file = root;
do {
- if (fileFilter != null && !fileFilter.accept(file)) return false;
+ if (!fileFilter.accept(file)) return false;
file = file.getParentFile();
}
while (file != null);
diff --git a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java
index e364a8568fda..af2b3dd4293e 100644
--- a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java
+++ b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -96,7 +96,7 @@ public class StringUtil extends StringUtilRt {
@Nullable
@Override
public String fun(@Nullable String s) {
- return s == null ? null : s.trim();
+ return trim(s);
}
};
@@ -246,6 +246,7 @@ public class StringUtil extends StringUtilRt {
return html.replaceAll("<(.|\n)*?>", "");
}
+ @Contract("null -> null; !null -> !null")
public static String toLowerCase(@Nullable final String str) {
//noinspection ConstantConditions
return str == null ? null : str.toLowerCase();
@@ -852,6 +853,11 @@ public class StringUtil extends StringUtilRt {
return startsWithConcatenation(string, firstPrefix, secondPrefix, thirdPrefix);
}
+ @Contract("null -> null; !null -> !null")
+ public static String trim(@Nullable String s) {
+ return s == null ? null : s.trim();
+ }
+
@NotNull
public static String trimEnd(@NotNull String s, @NonNls @NotNull String suffix) {
if (s.endsWith(suffix)) {
@@ -1467,7 +1473,7 @@ public class StringUtil extends StringUtilRt {
/**
* @deprecated use #capitalize(String)
*/
- @Nullable
+ @Contract("null -> null; !null -> !null")
public static String firstLetterToUpperCase(@Nullable final String displayString) {
if (displayString == null || displayString.isEmpty()) return displayString;
char firstChar = displayString.charAt(0);
@@ -1827,11 +1833,13 @@ public class StringUtil extends StringUtilRt {
@NonNls private static final String[] REPLACES_REFS = {"&lt;", "&gt;", "&amp;", "&#39;", "&quot;"};
@NonNls private static final String[] REPLACES_DISP = {"<", ">", "&", "'", "\""};
+ @Contract("null -> null; !null -> !null")
public static String unescapeXml(@Nullable final String text) {
if (text == null) return null;
return replace(text, REPLACES_REFS, REPLACES_DISP);
}
+ @Contract("null -> null; !null -> !null")
public static String escapeXml(@Nullable final String text) {
if (text == null) return null;
return replace(text, REPLACES_DISP, REPLACES_REFS);
diff --git a/platform/util/src/com/intellij/util/ArrayUtil.java b/platform/util/src/com/intellij/util/ArrayUtil.java
index 5de68c11799b..d0419de9e820 100644
--- a/platform/util/src/com/intellij/util/ArrayUtil.java
+++ b/platform/util/src/com/intellij/util/ArrayUtil.java
@@ -190,7 +190,7 @@ public class ArrayUtil extends ArrayUtilRt {
}
@NotNull
- public static int[] toIntArray(@NotNull List<Integer> list) {
+ public static int[] toIntArray(@NotNull Collection<Integer> list) {
int[] ret = newIntArray(list.size());
int i = 0;
for (Integer e : list) {
diff --git a/platform/util/src/com/intellij/util/EnvironmentUtil.java b/platform/util/src/com/intellij/util/EnvironmentUtil.java
index 1d7016460f1e..19961bfc0b89 100644
--- a/platform/util/src/com/intellij/util/EnvironmentUtil.java
+++ b/platform/util/src/com/intellij/util/EnvironmentUtil.java
@@ -255,6 +255,24 @@ public class EnvironmentUtil {
return getEnvironmentMap();
}
+ public static void inlineParentOccurrences(@NotNull Map<String, String> envs) {
+ Map<String, String> parentParams = new HashMap<String, String>(System.getenv());
+ for (Map.Entry<String, String> entry : envs.entrySet()) {
+ String key = entry.getKey();
+ String value = entry.getValue();
+ if (value != null) {
+ String parentVal = parentParams.get(key);
+ if (parentVal != null && containsEnvKeySubstitution(key, value)) {
+ envs.put(key, value.replace("$" + key + "$", parentVal));
+ }
+ }
+ }
+ }
+
+ private static boolean containsEnvKeySubstitution(final String envKey, final String val) {
+ return ArrayUtil.find(val.split(File.pathSeparator), "$" + envKey + "$") != -1;
+ }
+
@TestOnly
static Map<String, String> testLoader() {
try {
diff --git a/platform/util/src/com/intellij/util/concurrency/BoundedTaskExecutor.java b/platform/util/src/com/intellij/util/concurrency/BoundedTaskExecutor.java
index 2ef9cfbedc61..cdc892071e01 100644
--- a/platform/util/src/com/intellij/util/concurrency/BoundedTaskExecutor.java
+++ b/platform/util/src/com/intellij/util/concurrency/BoundedTaskExecutor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -46,8 +46,9 @@ public class BoundedTaskExecutor implements Executor {
}
};
- public BoundedTaskExecutor(Executor backendExecutor, int maxSimultaneousTasks) {
+ public BoundedTaskExecutor(@NotNull Executor backendExecutor, int maxSimultaneousTasks) {
myBackendExecutor = backendExecutor;
+ assert maxSimultaneousTasks >= 1 : maxSimultaneousTasks;
myMaxTasks = Math.max(maxSimultaneousTasks, 1);
}
@@ -56,7 +57,8 @@ public class BoundedTaskExecutor implements Executor {
submit(task);
}
- public Future<?> submit(Runnable task) {
+ @NotNull
+ public Future<?> submit(@NotNull Runnable task) {
final RunnableFuture<Void> future = queueTask(new FutureTask<Void>(task, null));
if (future == null) {
throw new RuntimeException("Failed to queue task: " + task);
@@ -64,7 +66,8 @@ public class BoundedTaskExecutor implements Executor {
return future;
}
- public <T> Future<T> submit(Callable<T> task) {
+ @NotNull
+ public <T> Future<T> submit(@NotNull Callable<T> task) {
final RunnableFuture<T> future = queueTask(new FutureTask<T>(task));
if (future == null) {
throw new RuntimeException("Failed to queue task: " + task);
@@ -73,7 +76,7 @@ public class BoundedTaskExecutor implements Executor {
}
@Nullable
- private <T> RunnableFuture<T> queueTask(FutureTask<T> futureTask) {
+ private <T> RunnableFuture<T> queueTask(@NotNull FutureTask<T> futureTask) {
if (myTaskQueue.offer(futureTask)) {
processQueue();
return futureTask;
diff --git a/platform/util/src/com/intellij/util/concurrency/SequentialTaskExecutor.java b/platform/util/src/com/intellij/util/concurrency/SequentialTaskExecutor.java
index c05579c8f002..86fa72075e90 100644
--- a/platform/util/src/com/intellij/util/concurrency/SequentialTaskExecutor.java
+++ b/platform/util/src/com/intellij/util/concurrency/SequentialTaskExecutor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,11 +16,12 @@
package com.intellij.util.concurrency;
+import org.jetbrains.annotations.NotNull;
+
import java.util.concurrent.Executor;
public class SequentialTaskExecutor extends BoundedTaskExecutor {
-
- public SequentialTaskExecutor(Executor executor) {
+ public SequentialTaskExecutor(@NotNull Executor executor) {
super(executor, 1);
}
}
diff --git a/platform/util/src/com/intellij/util/containers/ConcurrentInstanceMap.java b/platform/util/src/com/intellij/util/containers/ConcurrentInstanceMap.java
index e99db9d1d2c3..4c85f15a8c7c 100644
--- a/platform/util/src/com/intellij/util/containers/ConcurrentInstanceMap.java
+++ b/platform/util/src/com/intellij/util/containers/ConcurrentInstanceMap.java
@@ -29,10 +29,10 @@ public class ConcurrentInstanceMap<T> extends ConcurrentFactoryMap<Class<? exten
return key.newInstance();
}
catch (InstantiationException e) {
- throw new RuntimeException(e);
+ throw new RuntimeException("Couldn't instantiate " + key, e);
}
catch (IllegalAccessException e) {
- throw new RuntimeException(e);
+ throw new RuntimeException("Couldn't instantiate " + key, e);
}
}
} \ No newline at end of file
diff --git a/platform/util/src/com/intellij/util/containers/ContainerUtil.java b/platform/util/src/com/intellij/util/containers/ContainerUtil.java
index dca7a0e6b30d..40bd75a2eff8 100644
--- a/platform/util/src/com/intellij/util/containers/ContainerUtil.java
+++ b/platform/util/src/com/intellij/util/containers/ContainerUtil.java
@@ -1073,7 +1073,8 @@ public class ContainerUtil extends ContainerUtilRt {
}
public static <T, U extends T> U findInstance(@NotNull Iterator<T> iterator, @NotNull Class<U> aClass) {
- @SuppressWarnings("unchecked") U u = (U)find(iterator, new FilteringIterator.InstanceOf<U>(aClass));
+ //noinspection unchecked
+ U u = (U)find(iterator, FilteringIterator.instanceOf(aClass));
return u;
}
@@ -1429,6 +1430,16 @@ public class ContainerUtil extends ContainerUtilRt {
return sorted;
}
+ @NotNull
+ public static <T extends Comparable<T>> List<T> sorted(@NotNull Collection<T> list) {
+ return sorted(list, new Comparator<T>() {
+ @Override
+ public int compare(T o1, T o2) {
+ return o1.compareTo(o2);
+ }
+ });
+ }
+
public static <T> void sort(@NotNull T[] a, @NotNull Comparator<T> comparator) {
int size = a.length;
@@ -1927,6 +1938,15 @@ public class ContainerUtil extends ContainerUtilRt {
return -1;
}
+ public static <T> int indexOf(@NotNull List<T> list, @NotNull final T object) {
+ return indexOf(list, new Condition<T>() {
+ @Override
+ public boolean value(T t) {
+ return t.equals(object);
+ }
+ });
+ }
+
@NotNull
public static <A,B> Map<B,A> reverseMap(@NotNull Map<A,B> map) {
final Map<B,A> result = newHashMap();
diff --git a/platform/util/src/com/intellij/util/containers/FilteringIterator.java b/platform/util/src/com/intellij/util/containers/FilteringIterator.java
index c6b7173b4db2..3e146441d6ab 100644
--- a/platform/util/src/com/intellij/util/containers/FilteringIterator.java
+++ b/platform/util/src/com/intellij/util/containers/FilteringIterator.java
@@ -17,7 +17,6 @@ package com.intellij.util.containers;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Conditions;
-import com.intellij.util.ReflectionUtil;
import org.jetbrains.annotations.NotNull;
import java.util.Iterator;
@@ -30,7 +29,7 @@ import java.util.NoSuchElementException;
*/
public class FilteringIterator<Dom, E extends Dom> implements Iterator<E> {
private final Iterator<Dom> myBaseIterator;
- private final Condition<Dom> myFilter;
+ private final Condition<? super Dom> myFilter;
private boolean myNextObtained = false;
private boolean myCurrentIsValid = false;
private Dom myCurrent;
@@ -42,7 +41,7 @@ public class FilteringIterator<Dom, E extends Dom> implements Iterator<E> {
}
};
- public FilteringIterator(@NotNull Iterator<Dom> baseIterator, @NotNull Condition<Dom> filter) {
+ public FilteringIterator(@NotNull Iterator<Dom> baseIterator, @NotNull Condition<? super Dom> filter) {
myBaseIterator = baseIterator;
myFilter = filter;
}
@@ -103,7 +102,7 @@ public class FilteringIterator<Dom, E extends Dom> implements Iterator<E> {
return create(iterator, NOT_NULL);
}
- public static <Dom, T extends Dom> Iterator<T> create(Iterator<Dom> iterator, Condition<Dom> condition) {
+ public static <Dom, T extends Dom> Iterator<T> create(Iterator<Dom> iterator, Condition<? super Dom> condition) {
return new FilteringIterator<Dom, T>(iterator, condition);
}
@@ -119,7 +118,7 @@ public class FilteringIterator<Dom, E extends Dom> implements Iterator<E> {
return create((Iterator<T>)iterator, instanceOf(aClass));
}
- public static class InstanceOf<T> implements Condition {
+ public static class InstanceOf<T> implements Condition<Object> {
private final Class<T> myInstancesClass;
public InstanceOf(Class<T> instancesClass) {
@@ -130,13 +129,5 @@ public class FilteringIterator<Dom, E extends Dom> implements Iterator<E> {
public boolean value(Object object) {
return myInstancesClass.isInstance(object);
}
-
- public boolean isClassAcceptable(Class hintClass) {
- return ReflectionUtil.isAssignable(myInstancesClass, hintClass);
- }
-
- public T cast(Object object) {
- return (T)object;
- }
}
}
diff --git a/platform/util/src/com/intellij/util/containers/InternalIterator.java b/platform/util/src/com/intellij/util/containers/InternalIterator.java
index 9b7d1da8f156..49c84ece6a48 100644
--- a/platform/util/src/com/intellij/util/containers/InternalIterator.java
+++ b/platform/util/src/com/intellij/util/containers/InternalIterator.java
@@ -70,10 +70,10 @@ public interface InternalIterator<T>{
}
class Filtering<T> implements InternalIterator<T> {
- private final Condition<T> myFilter;
+ private final Condition<? super T> myFilter;
private final InternalIterator<T> myIterator;
- public Filtering(InternalIterator<T> iterator, Condition<T> filter) {
+ public Filtering(InternalIterator<T> iterator, Condition<? super T> filter) {
myIterator = iterator;
myFilter = filter;
}
diff --git a/platform/util/src/com/intellij/util/io/storage/HeavyProcessLatch.java b/platform/util/src/com/intellij/util/io/storage/HeavyProcessLatch.java
index 663cd215cfbe..0f14dcb8511b 100644
--- a/platform/util/src/com/intellij/util/io/storage/HeavyProcessLatch.java
+++ b/platform/util/src/com/intellij/util/io/storage/HeavyProcessLatch.java
@@ -20,7 +20,6 @@
package com.intellij.util.io.storage;
import com.intellij.openapi.Disposable;
-import com.intellij.openapi.util.Disposer;
import com.intellij.util.EventDispatcher;
import org.jetbrains.annotations.NotNull;
@@ -56,10 +55,8 @@ public class HeavyProcessLatch {
public void processFinished();
}
- @NotNull
- public Disposable addListener(@NotNull HeavyProcessListener listener) {
- Disposable disposable = Disposer.newDisposable();
- myEventDispatcher.addListener(listener, disposable);
- return disposable;
+ public void addListener(@NotNull Disposable parentDisposable,
+ @NotNull HeavyProcessListener listener) {
+ myEventDispatcher.addListener(listener, parentDisposable);
}
} \ No newline at end of file
diff --git a/platform/util/src/com/intellij/util/xmlb/MapBinding.java b/platform/util/src/com/intellij/util/xmlb/MapBinding.java
index dbc3c0e082c3..354af5f93d7b 100644
--- a/platform/util/src/com/intellij/util/xmlb/MapBinding.java
+++ b/platform/util/src/com/intellij/util/xmlb/MapBinding.java
@@ -15,6 +15,7 @@
*/
package com.intellij.util.xmlb;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.xmlb.annotations.MapAnnotation;
@@ -34,6 +35,8 @@ import java.util.Set;
import static com.intellij.util.xmlb.Constants.*;
class MapBinding implements Binding {
+ private static final Logger LOG = Logger.getInstance(MapBinding.class);
+
private static final Comparator<Object> KEY_COMPARATOR = new Comparator<Object>() {
@SuppressWarnings("unchecked")
@Override
@@ -161,7 +164,10 @@ class MapBinding implements Binding {
Object k = null;
Object v = null;
- assert entry.getName().equals(getEntryAttributeName());
+ if (!entry.getName().equals(getEntryAttributeName())) {
+ LOG.warn("unexpected entry for serialized Map will be skipped: " + entry);
+ continue;
+ }
Attribute keyAttr = entry.getAttribute(getKeyAttributeName());
if (keyAttr != null) {
diff --git a/platform/util/src/com/intellij/util/xmlb/XmlSerializer.java b/platform/util/src/com/intellij/util/xmlb/XmlSerializer.java
index 86b7d111430f..73f216bc3749 100644
--- a/platform/util/src/com/intellij/util/xmlb/XmlSerializer.java
+++ b/platform/util/src/com/intellij/util/xmlb/XmlSerializer.java
@@ -45,6 +45,7 @@ public class XmlSerializer {
return serialize(object, TRUE_FILTER);
}
+ @NotNull
public static Element serialize(@NotNull Object object, @Nullable SerializationFilter filter) throws XmlSerializationException {
return new XmlSerializerImpl(filter == null ? TRUE_FILTER : filter).serialize(object);
}
diff --git a/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.java b/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.java
index 9a3fcb9d7066..8d0576c12405 100644
--- a/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.java
+++ b/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.java
@@ -23,6 +23,7 @@ import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.xmlb.annotations.*;
import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
+import org.intellij.lang.annotations.Language;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -1133,6 +1134,24 @@ public class XmlSerializerTest extends TestCase {
bean);
}
+ public static class BeanWithMapAtTopLevel {
+ @Property(surroundWithTag = false)
+ @MapAnnotation(surroundWithTag = false, surroundKeyWithTag = false, surroundValueWithTag = false)
+ public Map<String, String> map = new HashMap<String, String>();
+
+ public String option;
+ }
+
+ public void testMapAtTopLevel() {
+ BeanWithMapAtTopLevel bean = new BeanWithMapAtTopLevel();
+ bean.map.put("a", "b");
+ bean.option = "xxx";
+ doSerializerTest("<BeanWithMapAtTopLevel>\n" +
+ " <entry key=\"a\" value=\"b\" />\n" +
+ " <option name=\"option\" value=\"xxx\" />\n" +
+ "</BeanWithMapAtTopLevel>", bean);
+ }
+
private static class BeanWithConverter {
private static class MyConverter extends Converter<Ref<String>> {
@Nullable
@@ -1193,7 +1212,7 @@ public class XmlSerializerTest extends TestCase {
return assertSerializer(bean, expected, "Serialization failure", filter);
}
- private static Object doSerializerTest(String expectedText, Object bean) {
+ private static Object doSerializerTest(@Language("XML") String expectedText, Object bean) {
try {
Element element = assertSerializer(bean, expectedText, null);
diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsTaskHandler.java b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsTaskHandler.java
index 6f5ea05abea3..28f162908a20 100644
--- a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsTaskHandler.java
+++ b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsTaskHandler.java
@@ -17,16 +17,27 @@ package com.intellij.openapi.vcs;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Condition;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
+import java.util.List;
+
/**
* @author Dmitry Avdeev
* Date: 16.07.13
*/
public abstract class VcsTaskHandler {
- public static VcsTaskHandler[] getAllHandlers(Project project) {
- return EXTENSION_POINT_NAME.getExtensions(project);
+ public static VcsTaskHandler[] getAllHandlers(final Project project) {
+ VcsTaskHandler[] extensions = EXTENSION_POINT_NAME.getExtensions(project);
+ List<VcsTaskHandler> handlers = ContainerUtil.filter(extensions, new Condition<VcsTaskHandler>() {
+ @Override
+ public boolean value(VcsTaskHandler handler) {
+ return handler.isEnabled(project);
+ }
+ });
+ return handlers.toArray(new VcsTaskHandler[handlers.size()]);
}
public static class TaskInfo {
@@ -49,6 +60,8 @@ public abstract class VcsTaskHandler {
private static final ExtensionPointName<VcsTaskHandler> EXTENSION_POINT_NAME = ExtensionPointName.create("com.intellij.vcs.taskHandler");
+ public abstract boolean isEnabled(Project project);
+
public abstract TaskInfo startNewTask(String taskName);
public abstract void switchToTask(TaskInfo taskInfo, Runnable invokeAfter);
diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/changes/ChangeListManagerGate.java b/platform/vcs-api/src/com/intellij/openapi/vcs/changes/ChangeListManagerGate.java
index 376188e477eb..d0c28f5583fc 100644
--- a/platform/vcs-api/src/com/intellij/openapi/vcs/changes/ChangeListManagerGate.java
+++ b/platform/vcs-api/src/com/intellij/openapi/vcs/changes/ChangeListManagerGate.java
@@ -15,7 +15,6 @@
*/
package com.intellij.openapi.vcs.changes;
-import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
@@ -39,8 +38,13 @@ public interface ChangeListManagerGate {
void editComment(final String name, final String comment);
void editName(final String oldName, final String newName);
- // must be allowed only for perforce change synchronizer, not during normal update
+
+
+ /**
+ * @deprecated unused, to be removed in IDEA 15
+ */
void moveChanges(final String toList, final Collection<Change> changes);
+
void setListsToDisappear(final Collection<String> names);
FileStatus getStatus(final VirtualFile file);
FileStatus getStatus(final File file);
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/VcsNotifier.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/VcsNotifier.java
index 4b7f6baf2616..985f383ecbc6 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/VcsNotifier.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/VcsNotifier.java
@@ -26,7 +26,7 @@ import org.jetbrains.annotations.Nullable;
public class VcsNotifier {
private static final NotificationGroup NOTIFICATION_GROUP_ID = NotificationGroup.toolWindowGroup(
- "Vcs Messages", ChangesViewContentManager.TOOLWINDOW_ID, true);
+ "Vcs Messages", ChangesViewContentManager.TOOLWINDOW_ID);
private static final NotificationGroup IMPORTANT_ERROR_NOTIFICATION = new NotificationGroup(
"Vcs Important Messages", NotificationDisplayType.STICKY_BALLOON, true);
private static final NotificationGroup MINOR_NOTIFICATION = new NotificationGroup(
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/CallbackData.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/CallbackData.java
index 8ad034cfee1b..c1d2d0049edb 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/CallbackData.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/CallbackData.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,8 +24,6 @@ import com.intellij.openapi.vcs.VcsBundle;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import javax.swing.*;
-
class CallbackData {
private final static Logger LOG = Logger.getInstance("com.intellij.openapi.vcs.changes.CallbackData");
private final Runnable myCallback;
@@ -50,7 +48,7 @@ class CallbackData {
return new CallbackData(new Runnable() {
public void run() {
if (mode.isCallbackOnAwt()) {
- SwingUtilities.invokeLater(new Runnable() {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
LOG.debug("invokeAfterUpdate: silent wrapper called for project: " + project.getName());
if (project.isDisposed()) return;
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesFragmentedDiffPanel.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesFragmentedDiffPanel.java
index 731634b85080..53092e6a1369 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesFragmentedDiffPanel.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesFragmentedDiffPanel.java
@@ -15,6 +15,7 @@
*/
package com.intellij.openapi.vcs.changes;
+import com.intellij.codeStyle.CodeStyleFacade;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
@@ -55,6 +56,7 @@ import com.intellij.util.BeforeAfter;
import com.intellij.util.PlatformIcons;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
@@ -152,87 +154,87 @@ public class ChangesFragmentedDiffPanel implements Disposable {
private void createNavigateAction() {
myNavigateAction = new DumbAwareAction("Edit Source", "Edit Source", AllIcons.Actions.EditSource) {
+ @Nullable
+ private OpenFileDescriptor createDescriptor() {
+ if (myFragmentedContent == null || myFragmentedContent.getFile() == null) return null;
+
+ final DiffPanel panel = myCurrentHorizontal ? myHorizontal : myVertical;
+ final DiffSideView side = ((DiffPanelImpl)panel).getCurrentSide();
+ if (side == null || side.getEditor() == null) return null;
+
+ final boolean isAfter = FragmentSide.SIDE2.equals(side.getSide());
+ if (isAfter) {
+ final LogicalPosition position = side.getEditor().getCaretModel().getLogicalPosition();
+ final int line = position.line;
+ final int converted = myFragmentedContent.getNewConvertor().execute(line);
+ return new OpenFileDescriptor(myProject, myFragmentedContent.getFile(), converted, position.column);
+ }
+
+ if (((DiffPanelImpl)panel).getEditor1().getDocument().getTextLength() == 0) {
+ return new OpenFileDescriptor(myProject, myFragmentedContent.getFile(), 0);
+ }
+
+ final CaretModel model = side.getEditor().getCaretModel();
+ final FragmentList fragments = ((DiffPanelImpl)panel).getFragments();
+ final int line = model.getLogicalPosition().line;
+ //final int offset = side.getEditor().getDocument().getLineStartOffset(line);
+ final int offset = model.getOffset();
+
+ BeforeAfter<Integer> current = null;
+ final List<BeforeAfter<Integer>> ranges = myFragmentedContent.getLineRanges();
+ for (BeforeAfter<Integer> range : ranges) {
+ if (range.getBefore() > line) break;
+ current = range;
+ }
+ if (current == null) return null;
+ final Fragment at = fragments.getFragmentAt(offset, FragmentSide.SIDE1, Condition.TRUE);
+ if (at == null) return null;
+ final TextRange opposite = at.getRange(FragmentSide.SIDE2);
+
+ final int lineInNew = ((DiffPanelImpl)panel).getEditor2().getDocument().getLineNumber(opposite.getStartOffset());
+
+ int correctLine;
+ int column;
+ if (at.getType() == null || TextDiffTypeEnum.NONE.equals(at.getType())) {
+ column = model.getLogicalPosition().column;
+ final int startIn1 =
+ ((DiffPanelImpl)panel).getEditor1().getDocument().getLineNumber(at.getRange(FragmentSide.SIDE1).getStartOffset());
+ correctLine = lineInNew + line - startIn1;
+ }
+ else {
+ column = 0;
+ correctLine = Math.max(lineInNew, current.getAfter());
+ }
+
+ int converted = myFragmentedContent.getNewConvertor().execute(correctLine);
+ return new OpenFileDescriptor(myProject, myFragmentedContent.getFile(), converted, column);
+ }
+
@Override
public void actionPerformed(AnActionEvent e) {
- final boolean enabled = getEnabled();
- if (enabled) {
- OpenFileDescriptor descriptor = null;
- if (myFragmentedContent != null && myFragmentedContent.getFile() != null) {
- final DiffPanel panel = myCurrentHorizontal ? myHorizontal : myVertical;
-
- final DiffSideView side = ((DiffPanelImpl)panel).getCurrentSide();
- if (side == null || side.getEditor() == null) return;
-
- final boolean isAfter = FragmentSide.SIDE2.equals(side.getSide());
- if (isAfter) {
- final LogicalPosition position = side.getEditor().getCaretModel().getLogicalPosition();
- final int line = position.line;
- final int converted = myFragmentedContent.getNewConvertor().execute(line);
- descriptor = new OpenFileDescriptor(myProject, myFragmentedContent.getFile(), converted, position.column);
- } else {
- if (((DiffPanelImpl) panel).getEditor1().getDocument().getTextLength() == 0) {
- FileEditorManager.getInstance(myProject).openTextEditor(new OpenFileDescriptor(myProject, myFragmentedContent.getFile(), 0),
- true);
- return;
- }
-
- final CaretModel model = side.getEditor().getCaretModel();
- final FragmentList fragments = ((DiffPanelImpl)panel).getFragments();
- final int line = model.getLogicalPosition().line;
- //final int offset = side.getEditor().getDocument().getLineStartOffset(line);
- final int offset = model.getOffset();
-
- BeforeAfter<Integer> current = null;
- final List<BeforeAfter<Integer>> ranges = myFragmentedContent.getLineRanges();
- for (BeforeAfter<Integer> range : ranges) {
- if (range.getBefore() > line) break;
- current = range;
- }
- if (current == null) return;
- final Fragment at = fragments.getFragmentAt(offset, FragmentSide.SIDE1, Condition.TRUE);
- if (at == null) return;
- final TextRange opposite = at.getRange(FragmentSide.SIDE2);
-
- final int lineInNew = ((DiffPanelImpl)panel).getEditor2().getDocument().getLineNumber(opposite.getStartOffset());
-
- int correctLine;
- int column;
- if (at.getType() == null || TextDiffTypeEnum.NONE.equals(at.getType())) {
- column = model.getLogicalPosition().column;
- final int startIn1 =
- ((DiffPanelImpl)panel).getEditor1().getDocument().getLineNumber(at.getRange(FragmentSide.SIDE1).getStartOffset());
- correctLine = lineInNew + line - startIn1;
- }
- else {
- column = 0;
- correctLine = Math.max(lineInNew, current.getAfter());
- }
-
- int converted = myFragmentedContent.getNewConvertor().execute(correctLine);
- descriptor = new OpenFileDescriptor(myProject, myFragmentedContent.getFile(), converted, column);
- }
+ if (!getEnabled()) return;
+ final OpenFileDescriptor descriptor = createDescriptor();
+ if (descriptor == null) return;
+
+ final Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ FileEditorManager.getInstance(myProject).openTextEditor(descriptor, true);
}
- if (descriptor == null) return;
- final OpenFileDescriptor finalDescriptor = descriptor;
- final Runnable runnable = new Runnable() {
- @Override
- public void run() {
- FileEditorManager.getInstance(myProject).openTextEditor(finalDescriptor, true);
- }
- };
- if (! ModalityState.NON_MODAL.equals(ModalityState.current())) {
- final Window window = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
- if (window instanceof DialogWrapperDialog) {
- final DialogWrapper wrapper = ((DialogWrapperDialog)window).getDialogWrapper();
- if (wrapper != null) {
- Disposer.dispose(wrapper.getDisposable());
- wrapper.close(DialogWrapper.CANCEL_EXIT_CODE);
- ApplicationManager.getApplication().invokeLater(runnable, ModalityState.NON_MODAL, myProject.getDisposed());
- return;
- }
+ };
+
+ if (ModalityState.NON_MODAL.equals(ModalityState.current())) {
+ runnable.run();
+ }
+ else {
+ final Window window = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
+ if (window instanceof DialogWrapperDialog) {
+ final DialogWrapper wrapper = ((DialogWrapperDialog)window).getDialogWrapper();
+ if (wrapper != null) {
+ wrapper.doCancelAction();
+ ApplicationManager.getApplication().invokeLater(runnable, ModalityState.NON_MODAL, myProject.getDisposed());
}
}
- runnable.run();
}
}
@@ -280,15 +282,25 @@ public class ChangesFragmentedDiffPanel implements Disposable {
myTitleLabel.setText(titleText((DiffPanelImpl)currentPanel));
myLeftLines = state.getLeftLines();
+ EditorEx hEditor1 = (EditorEx)((DiffPanelImpl)myHorizontal).getEditor1();
+ EditorEx vEditor1 = (EditorEx)((DiffPanelImpl)myVertical).getEditor1();
+ EditorEx hEditor2 = (EditorEx)((DiffPanelImpl)myHorizontal).getEditor2();
+ EditorEx vEditor2 = (EditorEx)((DiffPanelImpl)myVertical).getEditor2();
+
+ assert hEditor1 != null;
+ assert vEditor1 != null;
+ assert hEditor2 != null;
+ assert vEditor2 != null;
+
FragmentedEditorHighlighter bh = fragmentedContent.getBeforeHighlighter();
if (bh != null) {
- ((EditorEx) ((DiffPanelImpl) myHorizontal).getEditor1()).setHighlighter(bh);
- ((EditorEx) ((DiffPanelImpl) myVertical).getEditor1()).setHighlighter(bh);
+ hEditor1.setHighlighter(bh);
+ vEditor1.setHighlighter(bh);
}
FragmentedEditorHighlighter ah = fragmentedContent.getAfterHighlighter();
if (ah != null) {
- ((EditorEx) ((DiffPanelImpl) myHorizontal).getEditor2()).setHighlighter(ah);
- ((EditorEx) ((DiffPanelImpl) myVertical).getEditor2()).setHighlighter(ah);
+ hEditor2.setHighlighter(ah);
+ vEditor2.setHighlighter(ah);
}
if (((DiffPanelImpl) currentPanel).getEditor1() != null) {
highlightTodo(true, fragmentedContent.getBeforeTodoRanges());
@@ -296,6 +308,19 @@ public class ChangesFragmentedDiffPanel implements Disposable {
if (((DiffPanelImpl) currentPanel).getEditor2() != null) {
highlightTodo(false, fragmentedContent.getAfterTodoRanges());
}
+ if (fragmentedContent.getFileType() != null && myProject != null && !myProject.isDisposed()) {
+ CodeStyleFacade codeStyleFacade = CodeStyleFacade.getInstance(myProject);
+ int tabSize = codeStyleFacade.getTabSize(fragmentedContent.getFileType());
+ boolean useTabCharacter = codeStyleFacade.useTabCharacter(fragmentedContent.getFileType());
+ hEditor1.getSettings().setTabSize(tabSize);
+ vEditor1.getSettings().setTabSize(tabSize);
+ hEditor2.getSettings().setTabSize(tabSize);
+ vEditor2.getSettings().setTabSize(tabSize);
+ hEditor1.getSettings().setUseTabCharacter(useTabCharacter);
+ vEditor1.getSettings().setUseTabCharacter(useTabCharacter);
+ hEditor2.getSettings().setUseTabCharacter(useTabCharacter);
+ vEditor2.getSettings().setUseTabCharacter(useTabCharacter);
+ }
ensurePresentation();
softWraps(myConfiguration.SOFT_WRAPS_IN_SHORT_DIFF);
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/PreparedFragmentedContent.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/PreparedFragmentedContent.java
index 6e8a1a04d135..2722239d33b7 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/PreparedFragmentedContent.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/PreparedFragmentedContent.java
@@ -398,4 +398,8 @@ public class PreparedFragmentedContent {
public VirtualFile getFile() {
return myFile;
}
+
+ public FileType getFileType() {
+ return myFileType;
+ }
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/CompoundShelfFileProcessor.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/CompoundShelfFileProcessor.java
index cb073e2c129b..f060cca6368f 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/CompoundShelfFileProcessor.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/CompoundShelfFileProcessor.java
@@ -19,6 +19,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.application.impl.ApplicationImpl;
import com.intellij.openapi.components.RoamingType;
+import com.intellij.openapi.components.StoragePathMacros;
import com.intellij.openapi.components.impl.stores.StorageUtil;
import com.intellij.openapi.components.impl.stores.StreamProvider;
import com.intellij.openapi.diagnostic.Logger;
@@ -36,6 +37,8 @@ import java.util.Collections;
import java.util.List;
public class CompoundShelfFileProcessor {
+ public static final String SHELF_DIR_NAME = "shelf";
+
private final String mySubdirName;
private final StreamProvider myServerStreamProvider;
private final String FILE_SPEC;
@@ -43,19 +46,20 @@ public class CompoundShelfFileProcessor {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.changes.shelf.CompoundShelfFileProcessor");
- public CompoundShelfFileProcessor(final String subdirName) {
- mySubdirName = subdirName;
- myServerStreamProvider = ((ApplicationImpl)ApplicationManager.getApplication()).getStateStore().getStateStorageManager().getStreamProvider();
+ public CompoundShelfFileProcessor() {
+ this(PathManager.getConfigPath());
+ }
- FILE_SPEC = "$ROOT_CONFIG$/" + subdirName + "/";
- myShelfPath = PathManager.getConfigPath() + File.separator + mySubdirName;
+ public CompoundShelfFileProcessor(String shelfBaseDirPath) {
+ this(((ApplicationImpl)ApplicationManager.getApplication()).getStateStore().getStateStorageManager().getStreamProvider(),
+ shelfBaseDirPath + File.separator + SHELF_DIR_NAME);
}
public CompoundShelfFileProcessor(@Nullable StreamProvider serverStreamProvider, String shelfPath) {
myServerStreamProvider = serverStreamProvider;
myShelfPath = shelfPath;
mySubdirName = new File(myShelfPath).getName();
- FILE_SPEC = "$ROOT_CONFIG$/" + mySubdirName + "/";
+ FILE_SPEC = StoragePathMacros.ROOT_CONFIG + "/" + mySubdirName + "/";
}
/*
@@ -150,7 +154,7 @@ public class CompoundShelfFileProcessor {
if (stream != null) {
File file = new File(myShelfPath + "/" + newName);
copyFileToStream(stream, file);
- serverStreamProvider.deleteFile(oldFilePath, RoamingType.PER_USER);
+ serverStreamProvider.delete(oldFilePath, RoamingType.PER_USER);
copyFileContentToProviders(newFilePath, serverStreamProvider, file);
}
}
@@ -221,7 +225,7 @@ public class CompoundShelfFileProcessor {
public void delete(final String name) {
FileUtil.delete(new File(getBaseIODir(), name));
if (myServerStreamProvider != null && myServerStreamProvider.isEnabled()) {
- StorageUtil.deleteContent(myServerStreamProvider, FILE_SPEC + name, RoamingType.PER_USER);
+ StorageUtil.delete(myServerStreamProvider, FILE_SPEC + name, RoamingType.PER_USER);
}
}
} \ No newline at end of file
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelfManagerConfigurationMerger.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelfManagerConfigurationMerger.java
index bfaead47ab3a..b05cc9067592 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelfManagerConfigurationMerger.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelfManagerConfigurationMerger.java
@@ -35,7 +35,7 @@ public class ShelfManagerConfigurationMerger implements XmlConfigurationMerger {
public ShelfManagerConfigurationMerger() {
myConfigPath = PathManager.getConfigPath()+ "/shelf";
- myFileProcessor = new CompoundShelfFileProcessor("shelf");
+ myFileProcessor = new CompoundShelfFileProcessor();
}
@TestOnly
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java
index e76ba194672e..96bb835bc086 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java
@@ -26,6 +26,7 @@ import com.intellij.lifecycle.PeriodicalTasksCloser;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.components.AbstractProjectComponent;
+import com.intellij.openapi.components.StorageScheme;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.diff.impl.patch.*;
import com.intellij.openapi.diff.impl.patch.apply.ApplyFilePatchBase;
@@ -34,6 +35,7 @@ import com.intellij.openapi.diff.impl.patch.formove.PatchApplier;
import com.intellij.openapi.progress.AsynchronousExecution;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ex.ProjectEx;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.FileUtilRt;
@@ -65,6 +67,8 @@ import javax.swing.event.ChangeListener;
import java.io.*;
import java.util.*;
+import static com.intellij.openapi.vcs.changes.shelf.CompoundShelfFileProcessor.SHELF_DIR_NAME;
+
public class ShelveChangesManager extends AbstractProjectComponent implements JDOMExternalizable {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.changes.shelf.ShelveChangesManager");
@@ -86,10 +90,16 @@ public class ShelveChangesManager extends AbstractProjectComponent implements JD
super(project);
myBus = bus;
if (project.isDefault()) {
- myFileProcessor = new CompoundShelfFileProcessor(null, PathManager.getConfigPath() + File.separator + "shelf");
+ myFileProcessor = new CompoundShelfFileProcessor(null, PathManager.getConfigPath() + File.separator + SHELF_DIR_NAME);
}
else {
- myFileProcessor = new CompoundShelfFileProcessor("shelf");
+ if (project instanceof ProjectEx && ((ProjectEx)project).getStateStore().getStorageScheme() == StorageScheme.DIRECTORY_BASED) {
+ String shelfBaseDirPath = project.getBaseDir().getPath() + File.separator + Project.DIRECTORY_STORE_FOLDER;
+ myFileProcessor = new CompoundShelfFileProcessor(shelfBaseDirPath);
+ }
+ else {
+ myFileProcessor = new CompoundShelfFileProcessor();
+ }
}
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/checkin/CodeAnalysisBeforeCheckinHandler.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/checkin/CodeAnalysisBeforeCheckinHandler.java
index 8d5463cd444b..57229c3fdf18 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/checkin/CodeAnalysisBeforeCheckinHandler.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/checkin/CodeAnalysisBeforeCheckinHandler.java
@@ -30,14 +30,12 @@ import com.intellij.openapi.vcs.VcsBundle;
import com.intellij.openapi.vcs.VcsConfiguration;
import com.intellij.openapi.vcs.changes.CommitExecutor;
import com.intellij.openapi.vcs.ui.RefreshableOnComponent;
-import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.PairConsumer;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
-import java.util.ArrayList;
import java.util.List;
/**
@@ -139,7 +137,8 @@ public class CodeAnalysisBeforeCheckinHandler extends CheckinHandler {
try {
final List<CodeSmellInfo> codeSmells =
- CodeSmellDetector.getInstance(myProject).findCodeSmells(new ArrayList<VirtualFile>(myCheckinPanel.getVirtualFiles()));
+ CodeSmellDetector.getInstance(myProject)
+ .findCodeSmells(CheckinHandlerUtil.filterOutGeneratedAndExcludedFiles(myCheckinPanel.getVirtualFiles(), myProject));
if (!codeSmells.isEmpty()) {
return processFoundCodeSmells(codeSmells, executor);
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/checkin/CodeCleanupCheckinHandlerFactory.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/checkin/CodeCleanupCheckinHandlerFactory.java
index 97e9e4d1b534..b80936aafa14 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/checkin/CodeCleanupCheckinHandlerFactory.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/checkin/CodeCleanupCheckinHandlerFactory.java
@@ -24,10 +24,12 @@ import com.intellij.openapi.vcs.CheckinProjectPanel;
import com.intellij.openapi.vcs.VcsConfiguration;
import com.intellij.openapi.vcs.changes.CommitContext;
import com.intellij.openapi.vcs.ui.RefreshableOnComponent;
+import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
+import java.util.List;
public class CodeCleanupCheckinHandlerFactory extends CheckinHandlerFactory {
@@ -75,7 +77,8 @@ public class CodeCleanupCheckinHandlerFactory extends CheckinHandlerFactory {
public void runCheckinHandlers(Runnable runnable) {
if (VcsConfiguration.getInstance(myProject).CHECK_CODE_CLEANUP_BEFORE_PROJECT_COMMIT && !DumbService.isDumb(myProject)) {
- GlobalInspectionContextBase.codeCleanup(myProject, new AnalysisScope(myProject, myPanel.getVirtualFiles()), runnable);
+ List<VirtualFile> filesToProcess = CheckinHandlerUtil.filterOutGeneratedAndExcludedFiles(myPanel.getVirtualFiles(), myProject);
+ GlobalInspectionContextBase.codeCleanup(myProject, new AnalysisScope(myProject, filesToProcess), runnable);
} else {
runnable.run();
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java
index 9d8d73a92be9..daef43857c4e 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,13 +39,11 @@ import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.EditorNotificationPanel;
-import com.intellij.util.ExceptionUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.diff.FilesTooBigForDiffException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import javax.swing.*;
import java.util.*;
/**
@@ -459,7 +457,7 @@ public class LineStatusTracker {
}
if (myRanges.isEmpty() && myVirtualFile != null) {
- SwingUtilities.invokeLater(new Runnable() {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
FileDocumentManager.getInstance().saveDocument(myDocument);
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ui/VcsBalloonProblemNotifier.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ui/VcsBalloonProblemNotifier.java
index 908a3d9f8433..82ff0bcc6e5a 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ui/VcsBalloonProblemNotifier.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ui/VcsBalloonProblemNotifier.java
@@ -37,7 +37,7 @@ import javax.swing.event.HyperlinkEvent;
*/
public class VcsBalloonProblemNotifier implements Runnable {
public static final NotificationGroup
- NOTIFICATION_GROUP = NotificationGroup.toolWindowGroup("Common Version Control Messages", ChangesViewContentManager.TOOLWINDOW_ID, true);
+ NOTIFICATION_GROUP = NotificationGroup.toolWindowGroup("Common Version Control Messages", ChangesViewContentManager.TOOLWINDOW_ID);
private final Project myProject;
private final String myMessage;
private final MessageType myMessageType;
diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogFilterCollection.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogFilterCollection.java
index 19cfbdf486eb..65b999f4c4db 100644
--- a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogFilterCollection.java
+++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogFilterCollection.java
@@ -40,6 +40,9 @@ public interface VcsLogFilterCollection {
VcsLogTextFilter getTextFilter();
@Nullable
+ VcsLogHashFilter getHashFilter();
+
+ @Nullable
VcsLogStructureFilter getStructureFilter();
/**
diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogHashFilter.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogHashFilter.java
index acd39bf51b18..71a14e1f732d 100644
--- a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogHashFilter.java
+++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogHashFilter.java
@@ -15,10 +15,13 @@
*/
package com.intellij.vcs.log;
+import org.jetbrains.annotations.NotNull;
+
import java.util.Collection;
public interface VcsLogHashFilter {
- Collection<Hash> getHashes();
+ @NotNull
+ Collection<String> getHashes();
}
diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/AbstractVisibleGraph.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/AbstractVisibleGraph.java
index 18d7222d9257..83cb53fd8c8f 100644
--- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/AbstractVisibleGraph.java
+++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/AbstractVisibleGraph.java
@@ -85,6 +85,8 @@ public abstract class AbstractVisibleGraph<CommitId> implements VisibleGraph<Com
@NotNull
@Override
public RowInfo<CommitId> getRowInfo(final int visibleRow) {
+ if (visibleRow < 0 || visibleRow >= getVisibleCommitCount())
+ throw new IndexOutOfBoundsException("VisibleCommitCount is: " + getVisibleCommitCount() + ", but visibleRow: " + visibleRow);
return new RowInfo<CommitId>() {
@NotNull
@Override
diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/AbstractPrintElementsManager.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/AbstractPrintElementsManager.java
index 8219c50a4851..8da596f026bf 100644
--- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/AbstractPrintElementsManager.java
+++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/AbstractPrintElementsManager.java
@@ -108,8 +108,8 @@ public abstract class AbstractPrintElementsManager<CommitId> implements PrintEle
if (printElement != null) {
GraphEdge graphEdge = containedCollapsedEdge(printElement.getGraphElement(), myPrintedLinearGraph);
- if (graphEdge != null) {
- mySelectedNodes = ContainerUtil.set(graphEdge.getUpNodeIndex(), graphEdge.getDownNodeIndex());
+ if (graphEdge != null && allowSelectCollapsedEdge(graphEdge)) {
+ mySelectedNodes = ContainerUtil.set(graphEdge.getUpNodeIndex(), graphEdge.getDownNodeIndex());
} else {
mySelectedNodes = getSelectedNodes(printElement.getGraphElement());
}
@@ -150,4 +150,8 @@ public abstract class AbstractPrintElementsManager<CommitId> implements PrintEle
@NotNull
protected abstract Set<Integer> getSelectedNodes(@NotNull GraphElement graphElement);
+
+ protected boolean allowSelectCollapsedEdge(@NotNull GraphEdge graphEdge) {
+ return true;
+ }
}
diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/FilterPrintElementsManager.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/FilterPrintElementsManager.java
index 517128e01f4f..12ac6af5f388 100644
--- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/FilterPrintElementsManager.java
+++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/FilterPrintElementsManager.java
@@ -18,6 +18,7 @@ package com.intellij.vcs.log.graph.impl.print;
import com.intellij.vcs.log.graph.GraphColorManager;
import com.intellij.vcs.log.graph.api.LinearGraphWithCommitInfo;
+import com.intellij.vcs.log.graph.api.elements.GraphEdge;
import com.intellij.vcs.log.graph.api.elements.GraphElement;
import org.jetbrains.annotations.NotNull;
@@ -35,4 +36,9 @@ public class FilterPrintElementsManager<CommitId> extends AbstractPrintElementsM
protected Set<Integer> getSelectedNodes(@NotNull GraphElement graphElement) {
return Collections.emptySet();
}
+
+ @Override
+ protected boolean allowSelectCollapsedEdge(@NotNull GraphEdge graphEdge) {
+ return false;
+ }
}
diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/visible/DottedEdges.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/visible/DottedEdges.java
new file mode 100644
index 000000000000..d6ff4230b4df
--- /dev/null
+++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/visible/DottedEdges.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.vcs.log.graph.impl.visible;
+
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.SmartList;
+import com.intellij.util.containers.MultiMap;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+public class DottedEdges {
+
+ @NotNull
+ public static DottedEdges newInstance(@NotNull MultiMap<Integer, Integer> delegate) {
+ int[] nodesWithEdges = ArrayUtil.toIntArray(delegate.keySet());
+ Arrays.sort(nodesWithEdges);
+
+ int[] startIndexes = new int[nodesWithEdges.length + 1];
+ int[] edges = new int[delegate.values().size()];
+
+ int start = 0;
+ for (int i = 0; i < startIndexes.length - 1; i++) {
+ startIndexes[i] = start;
+ for (int toNode : delegate.get(nodesWithEdges[i])) {
+ edges[start] = toNode;
+ start++;
+ }
+ }
+ startIndexes[startIndexes.length - 1] = start;
+
+ return new DottedEdges(nodesWithEdges, startIndexes, edges);
+ }
+
+ @NotNull private final int[] sortedStartNodes; // graph is not oriented => end nodes are there as well
+
+ @NotNull private final int[] startEdgesPosition;
+
+ @NotNull private final int[] endNodes;
+
+ public DottedEdges(@NotNull int[] sortedStartNodes, @NotNull int[] startEdgesPosition, @NotNull int[] endNodes) {
+ this.sortedStartNodes = sortedStartNodes;
+ this.startEdgesPosition = startEdgesPosition;
+ this.endNodes = endNodes;
+ }
+
+ public List<Integer> getAdjacentNodes(int nodeIndex) {
+ int smallIndex = Arrays.binarySearch(sortedStartNodes, nodeIndex);
+ if (smallIndex < 0)
+ return Collections.emptyList();
+ List<Integer> result = new SmartList<Integer>();
+
+ for (int i = startEdgesPosition[smallIndex]; i < startEdgesPosition[smallIndex + 1]; i++)
+ result.add(endNodes[i]);
+ return result;
+ }
+
+}
diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/visible/DottedEdgesComputer.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/visible/DottedEdgesComputer.java
new file mode 100644
index 000000000000..a5d9ef7cc15f
--- /dev/null
+++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/visible/DottedEdgesComputer.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.vcs.log.graph.impl.visible;
+
+import com.intellij.util.containers.MultiMap;
+import com.intellij.vcs.log.graph.api.LinearGraph;
+import com.intellij.vcs.log.graph.utils.Flags;
+import org.jetbrains.annotations.NotNull;
+
+public class DottedEdgesComputer {
+ @NotNull
+ public static MultiMap<Integer, Integer> compute(@NotNull LinearGraph delegateGraph, @NotNull Flags visibleNodes) {
+ DottedEdgesComputer dottedEdgesComputer = new DottedEdgesComputer(delegateGraph, visibleNodes);
+ dottedEdgesComputer.compute();
+ return dottedEdgesComputer.myDottedEdges;
+ }
+
+ @NotNull
+ private final LinearGraph myDelegateGraph;
+
+ @NotNull
+ private final Flags myVisibleNodes;
+
+ @NotNull
+ private final MultiMap<Integer, Integer> myDottedEdges;
+
+ @NotNull
+ private final int[] myNumbers;
+
+ private DottedEdgesComputer(@NotNull LinearGraph delegateGraph, @NotNull Flags visibleNodes) {
+ assert delegateGraph.nodesCount() == visibleNodes.size();
+ myDelegateGraph = delegateGraph;
+ myVisibleNodes = visibleNodes;
+ myDottedEdges = MultiMap.create();
+ myNumbers = new int[myDelegateGraph.nodesCount()];
+ }
+
+ private void putEdge(int node1, int node2) {
+ myDottedEdges.putValue(node1, node2);
+ myDottedEdges.putValue(node2, node1);
+ }
+
+ private void compute() {
+ downWalk();
+ upWalk();
+ }
+
+ private void downWalk() {
+ for (int i = 0; i < myDelegateGraph.nodesCount() - 1; i++) {
+ if (myVisibleNodes.get(i)) {
+ int nearlyUp = Integer.MIN_VALUE;
+ int maxAdjNumber = Integer.MIN_VALUE;
+ for (int upNode : myDelegateGraph.getUpNodes(i)) {
+ if (myVisibleNodes.get(upNode))
+ maxAdjNumber = Math.max(maxAdjNumber, myNumbers[upNode]);
+ else
+ nearlyUp = Math.max(nearlyUp, myNumbers[upNode]);
+ }
+
+ if (nearlyUp == maxAdjNumber || nearlyUp == Integer.MIN_VALUE) {
+ myNumbers[i] = maxAdjNumber;
+ } else {
+ putEdge(i, nearlyUp);
+ myNumbers[i] = nearlyUp;
+ }
+ } else {
+ // node i invisible
+
+ int nearlyUp = Integer.MIN_VALUE;
+ for (int upNode : myDelegateGraph.getUpNodes(i)) {
+ if (myVisibleNodes.get(upNode))
+ nearlyUp = Math.max(nearlyUp, upNode);
+ else
+ nearlyUp = Math.max(nearlyUp, myNumbers[upNode]);
+ }
+ myNumbers[i] = nearlyUp;
+ }
+ }
+ }
+
+ private void upWalk() {
+ for (int i = myDelegateGraph.nodesCount() - 1; i >= 0; i--) {
+ if (myVisibleNodes.get(i)) {
+ int nearlyDown = Integer.MAX_VALUE;
+ int minAdjNumber = Integer.MAX_VALUE;
+ for (int downNode : myDelegateGraph.getDownNodes(i)) {
+ if (downNode == LinearGraph.NOT_LOAD_COMMIT) continue;
+ if (myVisibleNodes.get(downNode))
+ minAdjNumber = Math.min(minAdjNumber, myNumbers[downNode]);
+ else
+ nearlyDown = Math.min(nearlyDown, myNumbers[downNode]);
+ }
+
+ if (nearlyDown == minAdjNumber || nearlyDown == Integer.MAX_VALUE) {
+ myNumbers[i] = minAdjNumber;
+ } else {
+ putEdge(i, nearlyDown);
+ myNumbers[i] = nearlyDown;
+ }
+
+ } else {
+ // node i invisible
+
+ int nearlyDown = Integer.MAX_VALUE;
+ for (int downNode : myDelegateGraph.getDownNodes(i)) {
+ if (downNode == LinearGraph.NOT_LOAD_COMMIT) continue;
+ if (myVisibleNodes.get(downNode))
+ nearlyDown = Math.min(nearlyDown, downNode);
+ else
+ nearlyDown = Math.min(nearlyDown, myNumbers[downNode]);
+ }
+ myNumbers[i] = nearlyDown;
+ }
+ }
+ }
+}
diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/visible/FilterGraphWithHiddenNodes.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/visible/FilterGraphWithHiddenNodes.java
index 72f02273d488..667b8c744fc4 100644
--- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/visible/FilterGraphWithHiddenNodes.java
+++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/visible/FilterGraphWithHiddenNodes.java
@@ -19,6 +19,7 @@ package com.intellij.vcs.log.graph.impl.visible;
import com.intellij.openapi.util.Condition;
import com.intellij.util.Consumer;
import com.intellij.util.SmartList;
+import com.intellij.util.containers.MultiMap;
import com.intellij.vcs.log.graph.api.LinearGraph;
import com.intellij.vcs.log.graph.api.LinearGraphWithHiddenNodes;
import com.intellij.vcs.log.graph.api.elements.GraphEdge;
@@ -39,6 +40,9 @@ public class FilterGraphWithHiddenNodes implements LinearGraphWithHiddenNodes {
private final Flags myVisibleNodes;
@NotNull
+ private final DottedEdges myDottedEdges;
+
+ @NotNull
private final SetListenerController<UpdateListener> myListenerController = new SetListenerController<UpdateListener>();
public FilterGraphWithHiddenNodes(@NotNull LinearGraphWithHiddenNodes delegateGraph, @NotNull Condition<Integer> isVisibleNode) {
@@ -47,6 +51,10 @@ public class FilterGraphWithHiddenNodes implements LinearGraphWithHiddenNodes {
for (int i = 0; i < delegateGraph.nodesCount(); i++) {
myVisibleNodes.set(i, delegateGraph.nodeIsVisible(i) && isVisibleNode.value(i)); // todo: think about it: may be drop myVisibleNodes
}
+
+ MultiMap<Integer, Integer> edges = DottedEdgesComputer.compute(myDelegateGraph, myVisibleNodes);
+ myDottedEdges = DottedEdges.newInstance(edges);
+
addUpdateListener();
}
@@ -78,7 +86,10 @@ public class FilterGraphWithHiddenNodes implements LinearGraphWithHiddenNodes {
@NotNull
@Override
public GraphEdge.Type getEdgeType(int upNodeIndex, int downNodeIndex) {
- return GraphEdge.Type.USUAL;
+ if (myDottedEdges.getAdjacentNodes(upNodeIndex).contains(downNodeIndex))
+ return GraphEdge.Type.HIDE;
+ else
+ return GraphEdge.Type.USUAL;
}
@NotNull
@@ -100,6 +111,10 @@ public class FilterGraphWithHiddenNodes implements LinearGraphWithHiddenNodes {
if (nodeIsVisible(upNode))
upNodes.add(upNode);
}
+ for (int adjNode : myDottedEdges.getAdjacentNodes(nodeIndex)) {
+ if (adjNode < nodeIndex)
+ upNodes.add(adjNode);
+ }
return upNodes;
}
@@ -111,6 +126,10 @@ public class FilterGraphWithHiddenNodes implements LinearGraphWithHiddenNodes {
if (downNode != LinearGraph.NOT_LOAD_COMMIT && nodeIsVisible(downNode))
downNodes.add(downNode);
}
+ for (int adjNode : myDottedEdges.getAdjacentNodes(nodeIndex)) {
+ if (adjNode > nodeIndex)
+ downNodes.add(adjNode);
+ }
return downNodes;
}
}
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogFilterer.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogFilterer.java
index 5a1766d9cb81..f0bf75c08dcf 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogFilterer.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogFilterer.java
@@ -48,11 +48,33 @@ public class VcsLogFilterer {
@NotNull
public AbstractVcsLogTableModel applyFiltersAndUpdateUi(@NotNull DataPack dataPack, @NotNull VcsLogFilterCollection filters) {
resetFilters(dataPack);
+ VcsLogHashFilter hashFilter = filters.getHashFilter();
+ if (hashFilter != null && !hashFilter.getHashes().isEmpty()) { // hashes should be shown, no matter if they match other filters or not
+ return applyHashFilter(dataPack, hashFilter.getHashes());
+ }
List<VcsLogDetailsFilter> detailsFilters = filters.getDetailsFilters();
applyGraphFilters(dataPack, filters.getBranchFilter());
return applyDetailsFilter(dataPack, detailsFilters);
}
+ private GraphTableModel applyHashFilter(@NotNull DataPack dataPack, @NotNull Collection<String> hashes) {
+ final List<Integer> indices = ContainerUtil.mapNotNull(hashes, new Function<String, Integer>() {
+ @Override
+ public Integer fun(String partOfHash) {
+ Hash hash = myLogDataHolder.findHashByString(partOfHash);
+ return hash != null ? myLogDataHolder.getCommitIndex(hash) : null;
+ }
+ });
+ dataPack.getGraphFacade().setVisibleBranches(null);
+ dataPack.getGraphFacade().setFilter(new Condition<Integer>() {
+ @Override
+ public boolean value(Integer integer) {
+ return indices.contains(integer);
+ }
+ });
+ return new GraphTableModel(dataPack, myLogDataHolder, myUI, LoadMoreStage.ALL_REQUESTED);
+ }
+
private static void resetFilters(@NotNull DataPack dataPack) {
GraphFacade facade = dataPack.getGraphFacade();
facade.setVisibleBranches(null);
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java
index 12996f91c116..c7ab5e324b3d 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java
@@ -15,12 +15,14 @@
*/
package com.intellij.vcs.log.data;
+import com.intellij.openapi.diagnostic.Attachment;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.progress.impl.ProgressManagerImpl;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Consumer;
@@ -272,22 +274,23 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
Map<VirtualFile, Collection<VcsRef>> currentRefs = myCurrentDataPack.getRefsModel().getAllRefsByRoot();
try {
if (permanentGraph != null) {
- loadLogAndRefs(roots, currentRefs, myRecentCommitCount);
- List<? extends GraphCommit<Integer>> compoundLog = compound(ContainerUtil.map(myLoadedInfos.values(),
- new Function<LogAndRefs, List<? extends GraphCommit<Integer>>>() {
- @Override
- public List<? extends GraphCommit<Integer>> fun(
- LogAndRefs refs) {
- return refs.log;
- }
- }));
- Map<VirtualFile, Collection<VcsRef>> allNewRefs = getAllNewRefs(myLoadedInfos, currentRefs);
- List<GraphCommit<Integer>> joinedFullLog = join(compoundLog, permanentGraph.getAllCommits(), currentRefs, allNewRefs);
- if (joinedFullLog != null) {
- return DataPack.build(joinedFullLog, new RefsModel(allNewRefs, myHashMap.asIndexGetter()),
- myHashMap.asIndexGetter(), myHashMap.asHashGetter(), myProviders, true);
+ int commitCount = myRecentCommitCount;
+ for (int attempt = 0; attempt <= 1; attempt++) {
+ loadLogAndRefs(roots, currentRefs, commitCount);
+ List<? extends GraphCommit<Integer>> compoundLog = compoundLoadedLogs(myLoadedInfos.values());
+ Map<VirtualFile, Collection<VcsRef>> allNewRefs = getAllNewRefs(myLoadedInfos, currentRefs);
+ List<GraphCommit<Integer>> joinedFullLog = join(compoundLog, permanentGraph.getAllCommits(), currentRefs, allNewRefs);
+ if (joinedFullLog == null) {
+ commitCount *= 5;
+ }
+ else {
+ return DataPack.build(joinedFullLog, new RefsModel(allNewRefs, myHashMap.asIndexGetter()),
+ myHashMap.asIndexGetter(), myHashMap.asHashGetter(), myProviders, true);
+ }
}
- // couldn't join => need to reload everything; this shouldn't happen often, the error is logged in join().
+ // couldn't join => need to reload everything; if 5000 commits is still not enough, it's worth reporting:
+ LOG.error("Couldn't join " + commitCount + " recent commits to the log (" + permanentGraph.getAllCommits().size() + " commits)",
+ new Attachment("recent_commits", toLogString(myLoadedInfos)));
}
Pair<PermanentGraph<Integer>, Map<VirtualFile, Collection<VcsRef>>> fullLogAndRefs = loadFullLog();
@@ -302,6 +305,38 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
}
}
+ private String toLogString(Map<VirtualFile, LogAndRefs> infos) {
+ StringBuilder sb = new StringBuilder();
+ for (Map.Entry<VirtualFile, LogAndRefs> entry : infos.entrySet()) {
+ sb.append(entry.getKey().getName());
+ sb.append(" LOG:\n");
+ sb.append(StringUtil.join(entry.getValue().log, new Function<GraphCommit<Integer>, String>() {
+ @Override
+ public String fun(GraphCommit<Integer> commit) {
+ return commit.getId() + "<-" + StringUtil.join(commit.getParents(), ",");
+ }
+ }, "\n"));
+ sb.append("\nREFS:\n");
+ sb.append(StringUtil.join(entry.getValue().refs, new Function<VcsRef, String>() {
+ @Override
+ public String fun(VcsRef ref) {
+ return ref.getName() + "(" + myHashMap.getCommitIndex(ref.getCommitHash()) + ")";
+ }
+ }, ","));
+ }
+ return sb.toString();
+ }
+
+ @NotNull
+ private List<? extends GraphCommit<Integer>> compoundLoadedLogs(@NotNull Collection<LogAndRefs> logsAndRefs) {
+ return compound(ContainerUtil.map(logsAndRefs, new Function<LogAndRefs, List<? extends GraphCommit<Integer>>>() {
+ @Override
+ public List<? extends GraphCommit<Integer>> fun(LogAndRefs refs) {
+ return refs.log;
+ }
+ }));
+ }
+
@NotNull
private Map<VirtualFile, Collection<VcsRef>> getAllNewRefs(@NotNull Map<VirtualFile, LogAndRefs> newInfo,
@NotNull Map<VirtualFile, Collection<VcsRef>> previousRefs) {
@@ -374,7 +409,7 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
return commits;
}
catch (VcsLogRefreshNotEnoughDataException e) {
- LOG.error(e); // collecting information : how often this situation happens, do we need to try to load more or can safely reload all
+ LOG.info(e);
}
catch (IllegalStateException e) {
LOG.error(e);
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogFilterCollectionImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogFilterCollectionImpl.java
index 285e3ce91079..3fbb7cb7b82f 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogFilterCollectionImpl.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogFilterCollectionImpl.java
@@ -27,17 +27,20 @@ public class VcsLogFilterCollectionImpl implements VcsLogFilterCollection {
@Nullable private final VcsLogBranchFilter myBranchFilter;
@Nullable private final VcsLogUserFilter myUserFilter;
+ @Nullable private final VcsLogHashFilter myHashFilter;
@Nullable private final VcsLogDateFilter myDateFilter;
@Nullable private final VcsLogTextFilter myTextFilter;
@Nullable private final VcsLogStructureFilter myStructureFilter;
public VcsLogFilterCollectionImpl(@Nullable VcsLogBranchFilter branchFilter,
@Nullable VcsLogUserFilter userFilter,
+ @Nullable VcsLogHashFilter hashFilter,
@Nullable VcsLogDateFilter dateFilter,
@Nullable VcsLogTextFilter textFilter,
@Nullable VcsLogStructureFilter structureFilter) {
myBranchFilter = branchFilter;
myUserFilter = userFilter;
+ myHashFilter = hashFilter;
myDateFilter = dateFilter;
myTextFilter = textFilter;
myStructureFilter = structureFilter;
@@ -49,6 +52,12 @@ public class VcsLogFilterCollectionImpl implements VcsLogFilterCollection {
return myBranchFilter;
}
+ @Override
+ @Nullable
+ public VcsLogHashFilter getHashFilter() {
+ return myHashFilter;
+ }
+
@Nullable
@Override
public VcsLogUserFilter getUserFilter() {
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogHashFilterImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogHashFilterImpl.java
new file mode 100644
index 000000000000..ff747f4f37d4
--- /dev/null
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogHashFilterImpl.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.vcs.log.impl;
+
+import com.intellij.vcs.log.VcsLogHashFilter;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+
+public class VcsLogHashFilterImpl implements VcsLogHashFilter {
+
+ @NotNull private final Collection<String> myHashes;
+
+ public VcsLogHashFilterImpl(@NotNull Collection<String> hashes) {
+ myHashes = hashes;
+ }
+
+ @NotNull
+ @Override
+ public Collection<String> getHashes() {
+ return myHashes;
+ }
+}
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogSettingsImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogSettingsImpl.java
index 88b2b449ac69..016f08451a95 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogSettingsImpl.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogSettingsImpl.java
@@ -45,9 +45,4 @@ public class VcsLogSettingsImpl implements VcsLogSettings, PersistentStateCompon
public void setShowBranchesPanel(boolean show) {
myState.SHOW_BRANCHES_PANEL = show;
}
-
- public void setRecentCommitsBlockSize(int commitCount) {
- myState.RECENT_COMMITS_COUNT = commitCount;
- }
-
}
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogClassicFilterUi.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogClassicFilterUi.java
index d18c99c4e24c..9a44f320f040 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogClassicFilterUi.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogClassicFilterUi.java
@@ -20,15 +20,20 @@ import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.actionSystem.ex.CustomComponentAction;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.DumbAwareAction;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.SearchTextField;
import com.intellij.ui.SearchTextFieldWithStoredHistory;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.UIUtil;
import com.intellij.vcs.log.*;
import com.intellij.vcs.log.data.DataPack;
import com.intellij.vcs.log.data.VcsLogDataHolder;
import com.intellij.vcs.log.data.VcsLogUiProperties;
import com.intellij.vcs.log.impl.VcsLogFilterCollectionImpl;
+import com.intellij.vcs.log.impl.VcsLogHashFilterImpl;
import com.intellij.vcs.log.ui.VcsLogUiImpl;
import org.jetbrains.annotations.NotNull;
@@ -43,6 +48,9 @@ import java.util.List;
*/
public class VcsLogClassicFilterUi implements VcsLogFilterUi {
+ private static final Logger LOG = Logger.getInstance(VcsLogClassicFilterUi.class);
+ private static final String HASH_PATTERN = "[a-fA-F0-9]{7,}";
+
@NotNull private final SearchTextField myTextFilter;
@NotNull private final VcsLogUiImpl myUi;
@NotNull private final DefaultActionGroup myActionGroup;
@@ -104,9 +112,38 @@ public class VcsLogClassicFilterUi implements VcsLogFilterUi {
@NotNull
@Override
public VcsLogFilterCollection getFilters() {
- VcsLogTextFilter textFilter = !myTextFilter.getText().isEmpty() ? new VcsLogTextFilterImpl(myTextFilter.getText().trim()) : null;
+ Pair<VcsLogTextFilter, VcsLogHashFilter> filtersFromText = getFiltersFromTextArea(myTextFilter.getText().trim());
return new VcsLogFilterCollectionImpl(myBranchFilterComponent.getFilter(), myUserFilterComponent.getFilter(),
- myDateFilterComponent.getFilter(), textFilter, myStructureFilterComponent.getFilter());
+ filtersFromText.second, myDateFilterComponent.getFilter(),
+ filtersFromText.first, myStructureFilterComponent.getFilter());
+ }
+
+ @NotNull
+ private static Pair<VcsLogTextFilter, VcsLogHashFilter> getFiltersFromTextArea(@NotNull String text) {
+ if (text.isEmpty()) {
+ return Pair.empty();
+ }
+ List<String> hashes = ContainerUtil.newArrayList();
+ for (String word : StringUtil.split(text, " ")) {
+ if (!StringUtil.isEmptyOrSpaces(word) && word.matches(HASH_PATTERN)) {
+ hashes.add(word);
+ }
+ else {
+ break;
+ }
+ }
+
+ VcsLogTextFilter textFilter;
+ VcsLogHashFilterImpl hashFilter;
+ if (!hashes.isEmpty()) { // text is ignored if there are hashes in the text
+ textFilter = null;
+ hashFilter = new VcsLogHashFilterImpl(hashes);
+ }
+ else {
+ textFilter = new VcsLogTextFilterImpl(text);
+ hashFilter = null;
+ }
+ return Pair.<VcsLogTextFilter, VcsLogHashFilter>create(textFilter, hashFilter);
}
@Override
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugSession.java b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugSession.java
index 33fa877064db..5e43a76c6c6d 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugSession.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugSession.java
@@ -61,9 +61,20 @@ public interface XDebugSession extends AbstractDebuggerSession {
XSuspendContext getSuspendContext();
+ /**
+ * Position from the current frame
+ * @return
+ */
@Nullable
XSourcePosition getCurrentPosition();
+ /**
+ * Position from the top frame
+ * @return
+ */
+ @Nullable
+ XSourcePosition getTopFramePosition();
+
void stepOver(boolean ignoreBreakpoints);
void stepInto();
@@ -80,13 +91,12 @@ public interface XDebugSession extends AbstractDebuggerSession {
void showExecutionPoint();
- void setCurrentStackFrame(@NotNull XExecutionStack executionStack, @NotNull XStackFrame frame);
+ void setCurrentStackFrame(@NotNull XExecutionStack executionStack, @NotNull XStackFrame frame, boolean isTopFrame);
/**
- * @deprecated use {@link #setCurrentStackFrame(com.intellij.xdebugger.frame.XExecutionStack, com.intellij.xdebugger.frame.XStackFrame)} instead
+ * @deprecated use {@link #setCurrentStackFrame(com.intellij.xdebugger.frame.XExecutionStack, com.intellij.xdebugger.frame.XStackFrame, boolean)} instead
*/
- @SuppressWarnings("UnusedDeclaration")
- void setCurrentStackFrame(@NotNull XStackFrame frame);
+ void setCurrentStackFrame(@NotNull XExecutionStack executionStack, @NotNull XStackFrame frame);
/**
* Call this method to setup custom icon and/or error message (it will be shown in tooltip) for breakpoint
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XNearestSourcePosition.java b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XNearestSourcePosition.java
new file mode 100644
index 000000000000..87abf3da3b21
--- /dev/null
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XNearestSourcePosition.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.xdebugger.frame;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public interface XNearestSourcePosition extends XNavigatable {
+}
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XReferrersProvider.java b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XReferrersProvider.java
new file mode 100644
index 000000000000..9f9f3a8bf407
--- /dev/null
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XReferrersProvider.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.xdebugger.frame;
+
+/**
+ * @author traff
+ */
+public interface XReferrersProvider<T extends XValue> {
+ T getReferringObjectsValue();
+}
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XValue.java b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XValue.java
index ff2b3303d4da..9cfa2fb15af4 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XValue.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XValue.java
@@ -87,4 +87,9 @@ public abstract class XValue extends XValueContainer {
public void computeTypeSourcePosition(@NotNull XNavigatable navigatable) {
navigatable.setSourcePosition(null);
}
+
+ @Nullable
+ public XReferrersProvider getReferrersProvider() {
+ return null;
+ }
} \ No newline at end of file
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java
index 8ee2f1ee587a..1b0f0ca69a59 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java
@@ -45,6 +45,7 @@ import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.ToolWindowId;
import com.intellij.ui.AppUIUtil;
@@ -96,7 +97,8 @@ public class XDebugSessionImpl implements XDebugSession {
private XSuspendContext mySuspendContext;
private XExecutionStack myCurrentExecutionStack;
private XStackFrame myCurrentStackFrame;
- private XSourcePosition myCurrentPosition;
+ private boolean myIsTopFrame;
+ private XSourcePosition myTopFramePosition;
private final AtomicBoolean myPaused = new AtomicBoolean();
private MyDependentBreakpointListener myDependentBreakpointListener;
private XValueMarkers<?, ?> myValueMarkers;
@@ -255,7 +257,13 @@ public class XDebugSessionImpl implements XDebugSession {
@Override
@Nullable
public XSourcePosition getCurrentPosition() {
- return myCurrentPosition;
+ return myCurrentStackFrame != null ? myCurrentStackFrame.getSourcePosition() : null;
+ }
+
+ @Nullable
+ @Override
+ public XSourcePosition getTopFramePosition() {
+ return myTopFramePosition;
}
public XDebugSessionTab init(@NotNull XDebugProcess process, @NotNull XDebugSessionData sessionData, @Nullable RunContentDescriptor contentToReuse) {
@@ -538,8 +546,8 @@ public class XDebugSessionImpl implements XDebugSession {
mySuspendContext = null;
myCurrentExecutionStack = null;
myCurrentStackFrame = null;
- adjustMouseTrackingCounter(myCurrentPosition, -1);
- myCurrentPosition = null;
+ adjustMouseTrackingCounter(myTopFramePosition, -1);
+ myTopFramePosition = null;
myActiveNonLineBreakpoint = null;
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
@@ -559,7 +567,7 @@ public class XDebugSessionImpl implements XDebugSession {
}
private boolean isTopFrameSelected() {
- return myCurrentExecutionStack != null && myCurrentExecutionStack.getTopFrame() == myCurrentStackFrame;
+ return myCurrentExecutionStack != null && myIsTopFrame;
}
@@ -570,7 +578,7 @@ public class XDebugSessionImpl implements XDebugSession {
if (executionStack != null) {
XStackFrame topFrame = executionStack.getTopFrame();
if (topFrame != null) {
- setCurrentStackFrame(executionStack, topFrame);
+ setCurrentStackFrame(executionStack, topFrame, true);
myDebuggerManager.showExecutionPosition();
}
}
@@ -578,17 +586,18 @@ public class XDebugSessionImpl implements XDebugSession {
}
@Override
- public void setCurrentStackFrame(@NotNull final XStackFrame frame) {
- setCurrentStackFrame(myCurrentExecutionStack, frame);
+ public void setCurrentStackFrame(@NotNull XExecutionStack executionStack, @NotNull XStackFrame frame) {
+ setCurrentStackFrame(myCurrentExecutionStack, frame, frame == executionStack.getTopFrame());
}
@Override
- public void setCurrentStackFrame(@NotNull XExecutionStack executionStack, @NotNull XStackFrame frame) {
+ public void setCurrentStackFrame(@NotNull XExecutionStack executionStack, @NotNull XStackFrame frame, boolean isTopFrame) {
if (mySuspendContext == null) return;
boolean frameChanged = myCurrentStackFrame != frame;
myCurrentExecutionStack = executionStack;
myCurrentStackFrame = frame;
+ myIsTopFrame = isTopFrame;
activateSession();
if (frameChanged) {
@@ -708,7 +717,9 @@ public class XDebugSessionImpl implements XDebugSession {
@Override
public void run() {
if (mySessionTab != null) {
- mySessionTab.toFront(true);
+ if (XDebuggerSettingsManager.getInstanceImpl().getGeneralSettings().isShowDebuggerOnBreakpoint()) {
+ mySessionTab.toFront(true);
+ }
mySessionTab.getUi().attractBy(XDebuggerUIConstants.LAYOUT_VIEW_BREAKPOINT_CONDITION);
}
}
@@ -781,14 +792,14 @@ public class XDebugSessionImpl implements XDebugSession {
mySuspendContext = suspendContext;
myCurrentExecutionStack = suspendContext.getActiveExecutionStack();
myCurrentStackFrame = myCurrentExecutionStack != null ? myCurrentExecutionStack.getTopFrame() : null;
- myCurrentPosition = myCurrentStackFrame != null ? myCurrentStackFrame.getSourcePosition() : null;
+ myTopFramePosition = myCurrentStackFrame != null ? myCurrentStackFrame.getSourcePosition() : null;
myPaused.set(true);
- if (myCurrentPosition != null) {
- myDebuggerManager.setActiveSession(this, myCurrentPosition, false, getPositionIconRenderer(true));
+ if (myTopFramePosition != null) {
+ myDebuggerManager.setActiveSession(this, myTopFramePosition, false, getPositionIconRenderer(true));
}
- adjustMouseTrackingCounter(myCurrentPosition, 1);
+ adjustMouseTrackingCounter(myTopFramePosition, 1);
if (myShowTabOnSuspend.compareAndSet(true, false)) {
UIUtil.invokeLaterIfNeeded(new Runnable() {
@@ -810,6 +821,7 @@ public class XDebugSessionImpl implements XDebugSession {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
+ if (myProject.isDisposed()) return;
Editor editor = XDebuggerUtilImpl.createEditor(new OpenFileDescriptor(myProject, position.getFile()));
if (editor != null) {
JComponent component = editor.getComponent();
@@ -855,8 +867,8 @@ public class XDebugSessionImpl implements XDebugSession {
mySessionTab.detachFromSession();
}
- adjustMouseTrackingCounter(myCurrentPosition, -1);
- myCurrentPosition = null;
+ adjustMouseTrackingCounter(myTopFramePosition, -1);
+ myTopFramePosition = null;
myCurrentExecutionStack = null;
myCurrentStackFrame = null;
mySuspendContext = null;
@@ -970,6 +982,9 @@ public class XDebugSessionImpl implements XDebugSession {
public void setWatchExpressions(@NotNull XExpression[] watchExpressions) {
mySessionData.setWatchExpressions(watchExpressions);
myDebuggerManager.getWatchesManager().setWatches(getWatchesKey(), watchExpressions);
+ if (Registry.is("debugger.watches.in.variables")) {
+ rebuildViews();
+ }
}
XExpression[] getWatchExpressions() {
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerSmartStepIntoHandler.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerSmartStepIntoHandler.java
index 6d09b8fd3128..2b84d05011c2 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerSmartStepIntoHandler.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerSmartStepIntoHandler.java
@@ -47,7 +47,7 @@ public class XDebuggerSmartStepIntoHandler extends XDebuggerSuspendedActionHandl
@Override
protected void perform(@NotNull XDebugSession session, DataContext dataContext) {
final XSmartStepIntoHandler<?> handler = session.getDebugProcess().getSmartStepIntoHandler();
- final XSourcePosition position = session.getCurrentPosition();
+ final XSourcePosition position = session.getTopFramePosition();
if (position == null || handler == null) return;
final FileEditor editor = FileEditorManager.getInstance(session.getProject()).getSelectedEditor(position.getFile());
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java
index e2ce9ca7c63d..855abaaad74e 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java
@@ -36,6 +36,7 @@ import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
+import com.intellij.util.DocumentUtil;
import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XDebuggerUtil;
import com.intellij.xdebugger.XSourcePosition;
@@ -91,7 +92,7 @@ public class XLineBreakpointImpl<P extends XBreakpointProperties> extends XBreak
RangeHighlighterEx highlighter = myHighlighter;
if (highlighter != null &&
(!highlighter.isValid()
- || highlighter.getStartOffset() >= document.getTextLength()
+ || !DocumentUtil.isValidOffset(highlighter.getStartOffset(), document)
|| !Comparing.equal(highlighter.getTextAttributes(), attributes)
// it seems that this check is not needed - we always update line number from the highlighter
// and highlighter is removed on line and file change anyway
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointManager.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointManager.java
index 098b64052284..e88f54f24799 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointManager.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointManager.java
@@ -261,7 +261,7 @@ public class XLineBreakpointManager {
|| mouseEvent.isMetaDown() || mouseEvent.isControlDown()
|| mouseEvent.getButton() != MouseEvent.BUTTON1
|| MarkupEditorFilterFactory.createIsDiffFilter().avaliableIn(editor)
- || e.getArea() != EditorMouseEventArea.LINE_MARKERS_AREA
+ || (e.getArea() != EditorMouseEventArea.LINE_MARKERS_AREA && e.getArea() != EditorMouseEventArea.FOLDING_OUTLINE_AREA)
|| ConsoleViewUtil.isConsoleViewEditor(editor)
||!isFromMyProject(editor)) {
return;
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointActionsPanel.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointActionsPanel.java
index 36584d1105d4..de4d45f483bf 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointActionsPanel.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointActionsPanel.java
@@ -122,6 +122,13 @@ public class XBreakpointActionsPanel<B extends XBreakpointBase<?,?,?>> extends X
}
}
+ JComponent getDefaultFocusComponent() {
+ if (myLogExpressionComboBox != null && myLogExpressionComboBox.getComboBox().isEnabled()) {
+ return myLogExpressionComboBox.getEditorComponent();
+ }
+ return null;
+ }
+
public void dispose() {
}
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java
index 75cbb569ddfd..4e91c27f011d 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java
@@ -180,8 +180,15 @@ public class XLightBreakpointPropertiesPanel<B extends XBreakpointBase<?,?,?>> i
myMainPanel.addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent event) {
- if (myConditionComboBox != null) {
- IdeFocusManager.findInstance().requestFocus(myConditionComboBox.getEditorComponent(), false);
+ JComponent compToFocus;
+ if (myConditionComboBox != null && myConditionComboBox.getComboBox().isEnabled()) {
+ compToFocus = myConditionComboBox.getEditorComponent();
+ }
+ else {
+ compToFocus = myActionsPanel.getDefaultFocusComponent();
+ }
+ if (compToFocus != null) {
+ IdeFocusManager.findInstance().requestFocus(compToFocus, false);
}
}
});
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/CodeFragmentInputComponent.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/CodeFragmentInputComponent.java
index 141a56c9b721..be44e2c01d2b 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/CodeFragmentInputComponent.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/CodeFragmentInputComponent.java
@@ -54,6 +54,7 @@ public class CodeFragmentInputComponent extends EvaluationInputComponent {
myMainPanel.add(editorPanel, BorderLayout.CENTER);
}
+ @NotNull
protected XDebuggerEditorBase getInputEditor() {
return myMultilineEditor;
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/EvaluationInputComponent.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/EvaluationInputComponent.java
index c702cae00c6e..3803945f9598 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/EvaluationInputComponent.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/EvaluationInputComponent.java
@@ -16,6 +16,7 @@
package com.intellij.xdebugger.impl.evaluate;
import com.intellij.xdebugger.impl.ui.XDebuggerEditorBase;
+import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -33,6 +34,7 @@ public abstract class EvaluationInputComponent {
return myTitle;
}
+ @NotNull
protected abstract XDebuggerEditorBase getInputEditor();
public abstract void addComponent(JPanel contentPanel, JPanel resultPanel);
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/ExpressionInputComponent.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/ExpressionInputComponent.java
index 15a8bf6aed84..45b140ddf8e8 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/ExpressionInputComponent.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/ExpressionInputComponent.java
@@ -63,6 +63,7 @@ public class ExpressionInputComponent extends EvaluationInputComponent {
contentPanel.add(hint, BorderLayout.SOUTH);
}
+ @NotNull
protected XDebuggerEditorBase getInputEditor() {
return myExpressionComboBox;
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java
index a3aa8ec43fc5..e73564095b21 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java
@@ -15,61 +15,214 @@
*/
package com.intellij.xdebugger.impl.evaluate;
+import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.EditorLinePainter;
import com.intellij.openapi.editor.LineExtensionInfo;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.registry.Registry;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.ui.Gray;
import com.intellij.ui.JBColor;
import com.intellij.ui.SimpleColoredText;
+import com.intellij.ui.SimpleTextAttributes;
+import com.intellij.xdebugger.XDebugSession;
+import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.frame.presentation.XValuePresentation;
+import com.intellij.xdebugger.impl.frame.XDebugView;
import com.intellij.xdebugger.impl.frame.XVariablesView;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueTextRendererImpl;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
+import java.util.List;
/**
* @author Konstantin Bulenkov
*/
public class XDebuggerEditorLinePainter extends EditorLinePainter {
+ public static final Key<Map<Variable, VariableValue>> CACHE = Key.create("debug.inline.variables.cache");
@Override
public Collection<LineExtensionInfo> getLineExtensions(@NotNull Project project, @NotNull VirtualFile file, int lineNumber) {
if (!Registry.is("ide.debugger.inline")) {
return null;
}
- Map<Pair<VirtualFile, Integer>, Set<XValueNodeImpl>> map = project.getUserData(XVariablesView.DEBUG_VARIABLES);
- if (map != null) {
- Set<XValueNodeImpl> values = map.get(Pair.create(file, lineNumber));
- if (values != null && !values.isEmpty()) {
- ArrayList<LineExtensionInfo> result = new ArrayList<LineExtensionInfo>();
- for (XValueNodeImpl value : values) {
- SimpleColoredText text = new SimpleColoredText();
- XValueTextRendererImpl renderer = new XValueTextRendererImpl(text);
- final XValuePresentation presentation = value.getValuePresentation();
- if (presentation == null) continue;
+ final Map<Pair<VirtualFile, Integer>, Set<XValueNodeImpl>> map = project.getUserData(XVariablesView.DEBUG_VARIABLES);
+ final Map<VirtualFile, Long> timestamps = project.getUserData(XVariablesView.DEBUG_VARIABLES_TIMESTAMPS);
+ final Document doc = FileDocumentManager.getInstance().getDocument(file);
+
+ if (map == null || timestamps == null || doc == null) {
+ return null;
+ }
+
+ Map<Variable, VariableValue> oldValues = project.getUserData(CACHE);
+ if (oldValues == null) {
+ oldValues = new HashMap<Variable, VariableValue>();
+ project.putUserData(CACHE, oldValues);
+ }
+ final Long timestamp = timestamps.get(file);
+ if (timestamp == null || timestamp < doc.getModificationStamp()) {
+ return null;
+ }
+ Set<XValueNodeImpl> values = map.get(Pair.create(file, lineNumber));
+ if (values != null && !values.isEmpty()) {
+ final int bpLine = getCurrentBreakPointLine(values);
+ ArrayList<LineExtensionInfo> result = new ArrayList<LineExtensionInfo>();
+ for (XValueNodeImpl value : values) {
+ SimpleColoredText text = new SimpleColoredText();
+ XValueTextRendererImpl renderer = new XValueTextRendererImpl(text);
+ final XValuePresentation presentation = value.getValuePresentation();
+ if (presentation == null) continue;
+ try {
if (presentation instanceof XValueCompactPresentation) {
((XValueCompactPresentation)presentation).renderValue(renderer, value);
} else {
presentation.renderValue(renderer);
}
- final Color color = new JBColor(new Color(61, 128, 101), new Color(61, 128, 101));
- result.add(new LineExtensionInfo(" " + value.getName() + ": ", color, null, null, Font.PLAIN));
+ if (StringUtil.isEmpty(text.toString())) {
+ final String type = value.getValuePresentation().getType();
+ if (!StringUtil.isEmpty(type)) {
+ text.append(type, SimpleTextAttributes.REGULAR_ATTRIBUTES);
+ }
+ }
+ } catch (Exception e) {
+ continue;
+ }
+ final Color color = bpLine == lineNumber ? new JBColor(Gray._180, new Color(147, 217, 186)) : getForeground();
+
+ final String name = value.getName();
+ if (StringUtil.isEmpty(text.toString())) {
+ continue;
+ }
+ result.add(new LineExtensionInfo(" " + name + ": ", color, null, null, Font.PLAIN));
+
+ Variable var = new Variable(name, lineNumber);
+ VariableValue variableValue = oldValues.get(var);
+ if (variableValue == null) {
+ variableValue = new VariableValue(text.toString(), null, value.hashCode());
+ oldValues.put(var, variableValue);
+ }
+ if (variableValue.valueNodeHashCode != value.hashCode()) {
+ variableValue.old = variableValue.actual;
+ variableValue.actual = text.toString();
+ variableValue.valueNodeHashCode = value.hashCode();
+ }
+
+ if (!variableValue.isChanged()) {
for (String s : text.getTexts()) {
result.add(new LineExtensionInfo(s, color, null, null, Font.PLAIN));
}
+ } else {
+ variableValue.produceChangedParts(result);
}
- return result;
}
+ return result;
}
return null;
}
+
+ private static int getCurrentBreakPointLine(Set<XValueNodeImpl> values) {
+ try {
+ final XValueNodeImpl node = values.iterator().next();
+ final XDebugSession session = XDebugView.getSession(node.getTree());
+ if (session != null) {
+ final XSourcePosition position = session.getCurrentPosition();
+ if (position != null) {
+ return position.getLine();
+ }
+ }
+ } catch (Exception ignore){}
+ return -1;
+ }
+
+ public static JBColor getForeground() {
+ return new JBColor(new Color(61, 128, 101), new Color(61, 128, 101));
+ }
+
+ public static JBColor getChangedForeground() {
+ return new JBColor(new Color(202, 128, 33), new Color(161, 131, 10));
+ }
+
+ static class Variable {
+ private int lineNumber;
+ private String name;
+
+ public Variable(String name, int lineNumber) {
+ this.lineNumber = lineNumber;
+ this.name = name;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Variable variable = (Variable)o;
+
+ if (lineNumber != variable.lineNumber) return false;
+ if (!name.equals(variable.name)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = lineNumber;
+ result = 31 * result + name.hashCode();
+ return result;
+ }
+ }
+
+ static class VariableValue {
+ private String actual;
+ private String old;
+ private int valueNodeHashCode;
+
+ public VariableValue(String actual, String old, int valueNodeHashCode) {
+ this.actual = actual;
+ this.old = old;
+ this.valueNodeHashCode = valueNodeHashCode;
+ }
+
+ public boolean isChanged() {
+ return old != null && !StringUtil.equals(actual, old);
+ }
+
+ public void produceChangedParts(List<LineExtensionInfo> result) {
+ if (isArray(actual) && isArray(old)) {
+ List<String> actualParts = getArrayParts(actual);
+ List<String> oldParts = getArrayParts(old);
+ result.add(new LineExtensionInfo("{", getForeground(), null, null, Font.PLAIN));
+ for (int i = 0; i < actualParts.size(); i++) {
+ if (i < oldParts.size() && StringUtil.equals(actualParts.get(i), oldParts.get(i))) {
+ result.add(new LineExtensionInfo(actualParts.get(i), getForeground(), null, null, Font.PLAIN));
+ } else {
+ result.add(new LineExtensionInfo(actualParts.get(i), getChangedForeground(), null, null, Font.BOLD));
+ }
+ if (i != actualParts.size() - 1) {
+ result.add(new LineExtensionInfo(", ", getForeground(), null, null, Font.PLAIN));
+ }
+ }
+ result.add(new LineExtensionInfo("}", getForeground(), null, null, Font.PLAIN));
+ return;
+ }
+
+ result.add(new LineExtensionInfo(actual, getChangedForeground(), null, null, Font.BOLD));
+ }
+
+ private static boolean isArray(String s) {
+ return s != null && s.startsWith("{") && s.endsWith("}");
+ }
+
+ private static List<String> getArrayParts(String array) {
+ return StringUtil.split(array.substring(1, array.length() - 1), ", ");
+ }
+ }
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java
index 37da856156ea..74b3b5202dbd 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java
@@ -18,6 +18,7 @@ package com.intellij.xdebugger.impl.evaluate;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CustomShortcutSet;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
@@ -79,13 +80,23 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
mySession.addSessionListener(new XDebugSessionAdapter() {
@Override
public void sessionStopped() {
- SwingUtilities.invokeLater(new Runnable() {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
close(CANCEL_EXIT_CODE);
}
});
}
+
+ @Override
+ public void stackFrameChanged() {
+ updateSourcePosition();
+ }
+
+ @Override
+ public void sessionPaused() {
+ updateSourcePosition();
+ }
}, myDisposable);
myTreePanel = new XDebuggerTreePanel(session.getProject(), editorsProvider, myDisposable, sourcePosition, XDebuggerActions.EVALUATE_DIALOG_TREE_POPUP_GROUP,
@@ -124,6 +135,15 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
init();
}
+ private void updateSourcePosition() {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ getInputEditor().setSourcePosition(mySession.getCurrentPosition());
+ }
+ });
+ }
+
@Override
protected void doOKAction() {
evaluate();
@@ -138,7 +158,7 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
super.actionPerformed(e);
if (myMode == EvaluationMode.EXPRESSION && ((e.getModifiers() & InputEvent.CTRL_MASK) != 0)) {
// add to watches
- XExpression expression = myInputComponent.getInputEditor().getExpression();
+ XExpression expression = getInputEditor().getExpression();
if (!XDebuggerUtilImpl.isEmptyExpression(expression)) {
XDebugSessionTab tab = ((XDebugSessionImpl)mySession).getSessionTab();
if (tab != null) {
@@ -179,7 +199,7 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
}
public XExpression getExpression() {
- return myInputComponent.getInputEditor().getExpression();
+ return getInputEditor().getExpression();
}
private static String getSwitchButtonText(EvaluationMode mode) {
@@ -205,12 +225,16 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
}
private void requestFocusInEditor() {
- JComponent preferredFocusedComponent = myInputComponent.getInputEditor().getPreferredFocusedComponent();
+ JComponent preferredFocusedComponent = getInputEditor().getPreferredFocusedComponent();
if (preferredFocusedComponent != null) {
IdeFocusManager.getInstance(mySession.getProject()).requestFocus(preferredFocusedComponent, true);
}
}
+ private XDebuggerEditorBase getInputEditor() {
+ return myInputComponent.getInputEditor();
+ }
+
private EvaluationInputComponent createInputComponent(EvaluationMode mode, XExpression text) {
final Project project = mySession.getProject();
text = XExpressionImpl.changeMode(text, mode);
@@ -223,7 +247,7 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
}
private void evaluate() {
- final XDebuggerEditorBase inputEditor = myInputComponent.getInputEditor();
+ final XDebuggerEditorBase inputEditor = getInputEditor();
int offset = -1;
//try to save caret position
@@ -262,7 +286,7 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
}
public void startEvaluation(@NotNull XDebuggerEvaluator.XEvaluationCallback evaluationCallback) {
- final XDebuggerEditorBase inputEditor = myInputComponent.getInputEditor();
+ final XDebuggerEditorBase inputEditor = getInputEditor();
inputEditor.saveTextInHistory();
XExpression expression = inputEditor.getExpression();
@@ -277,13 +301,13 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
@Override
public JComponent getPreferredFocusedComponent() {
- return myInputComponent.getInputEditor().getPreferredFocusedComponent();
+ return getInputEditor().getPreferredFocusedComponent();
}
private class SwitchModeAction extends AbstractAction {
@Override
public void actionPerformed(ActionEvent e) {
- XExpression text = myInputComponent.getInputEditor().getExpression();
+ XExpression text = getInputEditor().getExpression();
if (myMode == EvaluationMode.EXPRESSION) {
switchToMode(EvaluationMode.CODE_FRAGMENT, text);
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java
index b98440b5d69f..9999ac015b77 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java
@@ -188,10 +188,10 @@ public class XFramesView extends XDebugView {
return toolbar;
}
- private StackFramesListBuilder getOrCreateBuilder(XExecutionStack executionStack) {
+ private StackFramesListBuilder getOrCreateBuilder(XExecutionStack executionStack, XDebugSession session) {
StackFramesListBuilder builder = myBuilders.get(executionStack);
if (builder == null) {
- builder = new StackFramesListBuilder(executionStack);
+ builder = new StackFramesListBuilder(executionStack, session);
myBuilders.put(executionStack, builder);
}
return builder;
@@ -244,7 +244,6 @@ public class XFramesView extends XDebugView {
}
myToolbar.setAddSeparatorFirst(!invisible);
updateFrames(activeExecutionStack, session);
- myListenersEnabled = true;
}
@Override
@@ -270,19 +269,14 @@ public class XFramesView extends XDebugView {
return;
}
if (mySelectedStack != null) {
- getOrCreateBuilder(mySelectedStack).stop();
+ getOrCreateBuilder(mySelectedStack, session).stop();
}
mySelectedStack = executionStack;
if (executionStack != null) {
- StackFramesListBuilder builder = getOrCreateBuilder(executionStack);
+ StackFramesListBuilder builder = getOrCreateBuilder(executionStack, session);
builder.initModel(myFramesList.getModel());
builder.start();
- XStackFrame topFrame = executionStack.getTopFrame();
- if (topFrame != null) {
- myFramesList.setSelectedValue(topFrame, true);
- session.setCurrentStackFrame(executionStack, topFrame);
- }
}
}
@@ -303,7 +297,7 @@ public class XFramesView extends XDebugView {
if (selected instanceof XStackFrame) {
XDebugSession session = getSession(e);
if (session != null) {
- session.setCurrentStackFrame(mySelectedStack, (XStackFrame)selected);
+ session.setCurrentStackFrame(mySelectedStack, (XStackFrame)selected, myFramesList.getSelectedIndex() == 0);
}
}
}
@@ -312,21 +306,15 @@ public class XFramesView extends XDebugView {
private XExecutionStack myExecutionStack;
private final List<XStackFrame> myStackFrames;
private String myErrorMessage;
- private int myNextFrameIndex;
+ private int myNextFrameIndex = 0;
private boolean myRunning;
private boolean myAllFramesLoaded;
+ private final XDebugSession mySession;
- private StackFramesListBuilder(final XExecutionStack executionStack) {
+ private StackFramesListBuilder(final XExecutionStack executionStack, XDebugSession session) {
myExecutionStack = executionStack;
+ mySession = session;
myStackFrames = new ArrayList<XStackFrame>();
- XStackFrame topFrame = executionStack.getTopFrame();
- if (topFrame != null) {
- myStackFrames.add(topFrame);
- myNextFrameIndex = 1;
- }
- else {
- myNextFrameIndex = 0;
- }
}
@Override
@@ -336,6 +324,9 @@ public class XFramesView extends XDebugView {
public void run() {
myStackFrames.addAll(stackFrames);
addFrameListElements(stackFrames, last);
+ if (myNextFrameIndex == 0) {
+ selectTopFrame();
+ }
myNextFrameIndex += stackFrames.size();
myAllFramesLoaded = last;
if (last) {
@@ -399,6 +390,15 @@ public class XFramesView extends XDebugView {
myRunning = false;
}
+ private void selectTopFrame() {
+ if (!myStackFrames.isEmpty() && mySelectedStack != null) {
+ XStackFrame topFrame = myStackFrames.get(0);
+ myFramesList.setSelectedValue(topFrame, true);
+ mySession.setCurrentStackFrame(mySelectedStack, topFrame, true);
+ myListenersEnabled = true;
+ }
+ }
+
@SuppressWarnings("unchecked")
public void initModel(final DefaultListModel model) {
model.removeAllElements();
@@ -411,6 +411,7 @@ public class XFramesView extends XDebugView {
else if (!myAllFramesLoaded) {
model.addElement(null);
}
+ selectTopFrame();
}
}
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java
index df43b1147419..ea53645b57e5 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java
@@ -36,7 +36,8 @@ import static com.intellij.xdebugger.impl.ui.tree.nodes.MessageTreeNode.createIn
* @author nik
*/
public class XVariablesView extends XVariablesViewBase {
- public static final Key<Map<Pair<VirtualFile, Integer>, Set<XValueNodeImpl>>> DEBUG_VARIABLES = Key.create("debug.frame");
+ public static final Key<Map<Pair<VirtualFile, Integer>, Set<XValueNodeImpl>>> DEBUG_VARIABLES = Key.create("debug.variables");
+ public static final Key<Map<VirtualFile, Long>> DEBUG_VARIABLES_TIMESTAMPS = Key.create("debug.variables.timestamps");
public XVariablesView(@NotNull XDebugSessionImpl session) {
super(session.getProject(), session.getDebugProcess().getEditorsProvider(), session.getValueMarkers());
@@ -69,6 +70,7 @@ public class XVariablesView extends XVariablesViewBase {
protected void clear() {
XDebuggerTree tree = getTree();
tree.getProject().putUserData(DEBUG_VARIABLES, null);
+ tree.getProject().putUserData(DEBUG_VARIABLES_TIMESTAMPS, null);
tree.setSourcePosition(null);
XDebuggerTreeNode node;
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesViewBase.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesViewBase.java
index ace9938318df..d4bd27c30d9b 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesViewBase.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesViewBase.java
@@ -15,20 +15,42 @@
*/
package com.intellij.xdebugger.impl.frame;
+import com.intellij.codeInsight.hint.HintManager;
+import com.intellij.codeInsight.hint.HintUtil;
import com.intellij.ide.dnd.DnDManager;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.event.SelectionEvent;
+import com.intellij.openapi.editor.event.SelectionListener;
+import com.intellij.openapi.fileEditor.FileEditor;
+import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx;
+import com.intellij.openapi.fileEditor.impl.text.PsiAwareTextEditorImpl;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.registry.Registry;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.ui.SimpleColoredComponent;
+import com.intellij.ui.SimpleColoredText;
import com.intellij.xdebugger.XDebuggerBundle;
+import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
+import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
+import com.intellij.xdebugger.frame.XFullValueEvaluator;
import com.intellij.xdebugger.frame.XStackFrame;
+import com.intellij.xdebugger.frame.XValue;
+import com.intellij.xdebugger.frame.XValuePlace;
+import com.intellij.xdebugger.frame.presentation.XValuePresentation;
import com.intellij.xdebugger.impl.actions.XDebuggerActions;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreePanel;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreeRestorer;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreeState;
+import com.intellij.xdebugger.impl.ui.tree.nodes.XEvaluationCallbackBase;
import com.intellij.xdebugger.impl.ui.tree.nodes.XStackFrameNode;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
+import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodePresentationConfigurator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -51,17 +73,84 @@ public abstract class XVariablesViewBase extends XDebugView {
DnDManager.getInstance().registerSource(myDebuggerTreePanel, myDebuggerTreePanel.getTree());
}
- protected void buildTreeAndRestoreState(@NotNull XStackFrame stackFrame) {
+ protected void buildTreeAndRestoreState(@NotNull final XStackFrame stackFrame) {
XDebuggerTree tree = myDebuggerTreePanel.getTree();
- tree.setSourcePosition(stackFrame.getSourcePosition());
+ final XSourcePosition position = stackFrame.getSourcePosition();
+ tree.setSourcePosition(position);
tree.setRoot(new XStackFrameNode(tree, stackFrame), false);
- tree.getProject().putUserData(XVariablesView.DEBUG_VARIABLES, new HashMap<Pair<VirtualFile, Integer>, Set<XValueNodeImpl>>());
+ final Project project = tree.getProject();
+ project.putUserData(XVariablesView.DEBUG_VARIABLES, new HashMap<Pair<VirtualFile, Integer>, Set<XValueNodeImpl>>());
+ project.putUserData(XVariablesView.DEBUG_VARIABLES_TIMESTAMPS, new HashMap<VirtualFile, Long>());
Object newEqualityObject = stackFrame.getEqualityObject();
if (myFrameEqualityObject != null && newEqualityObject != null && myFrameEqualityObject.equals(newEqualityObject)
&& myTreeState != null) {
disposeTreeRestorer();
myTreeRestorer = myTreeState.restoreState(tree);
}
+ if (position != null && Registry.is("ide.debugger.inline")) {
+ final VirtualFile file = position.getFile();
+ final FileEditor fileEditor = FileEditorManagerEx.getInstanceEx(project).getSelectedEditor(file);
+ if (fileEditor instanceof PsiAwareTextEditorImpl) {
+ final Editor editor = ((PsiAwareTextEditorImpl)fileEditor).getEditor();
+ final SelectionListener listener = new SelectionListener() {
+ @Override
+ public void selectionChanged(SelectionEvent e) {
+ final String text = editor.getDocument().getText(e.getNewRange());
+ final XDebuggerEvaluator evaluator = stackFrame.getEvaluator();
+ if (evaluator != null && !StringUtil.isEmpty(text)
+ && !(text.contains("exec(") || text.contains("++") || text.contains("--") || text.contains("="))) {
+ evaluator.evaluate(text, new XEvaluationCallbackBase() {
+ @Override
+ public void evaluated(@NotNull XValue result) {
+ result.computePresentation(new XValueNodePresentationConfigurator.ConfigurableXValueNodeImpl() {
+ @Override
+ public void applyPresentation(@Nullable Icon icon,
+ @NotNull XValuePresentation valuePresenter,
+ boolean hasChildren) {
+ SimpleColoredText text = new SimpleColoredText();
+ XValueNodeImpl.buildText(valuePresenter, text, false);
+ SimpleColoredComponent component = HintUtil.createInformationComponent();
+ text.appendToComponent(component);
+ String str = text.toString();
+ if ("undefined".equals(str) || str.startsWith("Cannot find local variable")
+ || str.startsWith("Invalid expression")) {
+ return; //todo[kb] this is temporary solution
+ }
+ HintManager.getInstance().hideAllHints();
+ HintManager.getInstance().showInformationHint(editor, component);
+ }
+
+ @Override
+ public void setFullValueEvaluator(@NotNull XFullValueEvaluator fullValueEvaluator) {
+ }
+
+ @Override
+ public boolean isObsolete() {
+ return true;
+ }
+ }, XValuePlace.TOOLTIP);
+ }
+
+ @Override
+ public void errorOccurred(@NotNull String errorMessage) {
+ System.out.println(errorMessage);
+ }
+ }, position);
+ }
+ }
+ };
+ editor.getSelectionModel().addSelectionListener(listener);
+ Disposer.register(tree, new Disposable() {
+ @Override
+ public void dispose() {
+ final FileEditor fileEditor = FileEditorManagerEx.getInstanceEx(project).getSelectedEditor(file);
+ if (fileEditor instanceof PsiAwareTextEditorImpl) {
+ ((PsiAwareTextEditorImpl)fileEditor).getEditor().getSelectionModel().removeSelectionListener(listener);
+ }
+ }
+ });
+ }
+ }
}
protected void saveCurrentTreeState(@Nullable XStackFrame stackFrame) {
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/GeneralConfigurableUi.form b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/GeneralConfigurableUi.form
index 4d1f8e52d24f..1260cb3ff44a 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/GeneralConfigurableUi.form
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/GeneralConfigurableUi.form
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.xdebugger.impl.settings.GeneralConfigurableUi">
- <grid id="27dc6" binding="rootPanel" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="27dc6" binding="rootPanel" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="500" height="400"/>
@@ -10,7 +10,7 @@
<children>
<component id="4b50" class="javax.swing.JCheckBox" binding="hideDebugWindowCheckBox">
<constraints>
- <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/XDebuggerBundle" key="setting.hide.window.label"/>
@@ -18,7 +18,7 @@
</component>
<vspacer id="8e2ed">
<constraints>
- <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+ <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<component id="fc652" class="javax.swing.JCheckBox" binding="focusApplicationOnBreakpointCheckBox" default-binding="true">
@@ -29,6 +29,14 @@
<text resource-bundle="messages/XDebuggerBundle" key="setting.focus.app.on.breakpoint.label"/>
</properties>
</component>
+ <component id="4c3e" class="javax.swing.JCheckBox" binding="myShowDebugWindowOnCheckBox" default-binding="true">
+ <constraints>
+ <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text resource-bundle="messages/XDebuggerBundle" key="settings.show.window.label"/>
+ </properties>
+ </component>
</children>
</grid>
</form>
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/GeneralConfigurableUi.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/GeneralConfigurableUi.java
index 273c5490e35d..bab2c88465ad 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/GeneralConfigurableUi.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/GeneralConfigurableUi.java
@@ -25,23 +25,27 @@ class GeneralConfigurableUi implements ConfigurableUi<XDebuggerGeneralSettings>
private JPanel rootPanel;
private JCheckBox hideDebugWindowCheckBox;
private JCheckBox focusApplicationOnBreakpointCheckBox;
+ private JCheckBox myShowDebugWindowOnCheckBox;
@Override
public void reset(@NotNull XDebuggerGeneralSettings settings) {
focusApplicationOnBreakpointCheckBox.setSelected(Registry.is("debugger.mayBringFrameToFrontOnBreakpoint"));
hideDebugWindowCheckBox.setSelected(settings.isHideDebuggerOnProcessTermination());
+ myShowDebugWindowOnCheckBox.setSelected(settings.isShowDebuggerOnBreakpoint());
}
@Override
public boolean isModified(@NotNull XDebuggerGeneralSettings settings) {
return focusApplicationOnBreakpointCheckBox.isSelected() != Registry.is("debugger.mayBringFrameToFrontOnBreakpoint") ||
- hideDebugWindowCheckBox.isSelected() != settings.isHideDebuggerOnProcessTermination();
+ hideDebugWindowCheckBox.isSelected() != settings.isHideDebuggerOnProcessTermination() ||
+ myShowDebugWindowOnCheckBox.isSelected() != settings.isShowDebuggerOnBreakpoint();
}
@Override
public void apply(@NotNull XDebuggerGeneralSettings settings) {
Registry.get("debugger.mayBringFrameToFrontOnBreakpoint").setValue(focusApplicationOnBreakpointCheckBox.isSelected());
settings.setHideDebuggerOnProcessTermination(hideDebugWindowCheckBox.isSelected());
+ settings.setShowDebuggerOnBreakpoint(myShowDebugWindowOnCheckBox.isSelected());
}
@NotNull
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerGeneralSettings.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerGeneralSettings.java
index 9720d9517c51..205c1c3948ed 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerGeneralSettings.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerGeneralSettings.java
@@ -27,6 +27,7 @@ public class XDebuggerGeneralSettings {
private boolean myUnmuteOnStop = false;
private boolean hideDebuggerOnProcessTermination;
+ private boolean myShowDebuggerOnBreakpoint = true;
@Tag("evaluation-dialog-mode")
public EvaluationMode getEvaluationDialogMode() {
@@ -53,4 +54,12 @@ public class XDebuggerGeneralSettings {
public void setHideDebuggerOnProcessTermination(boolean hideDebuggerOnProcessTermination) {
this.hideDebuggerOnProcessTermination = hideDebuggerOnProcessTermination;
}
+
+ public boolean isShowDebuggerOnBreakpoint() {
+ return myShowDebuggerOnBreakpoint;
+ }
+
+ public void setShowDebuggerOnBreakpoint(boolean showDebuggerOnBreakpoint) {
+ this.myShowDebuggerOnBreakpoint = showDebuggerOnBreakpoint;
+ }
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerCopyPastePreprocessor.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerCopyPastePreprocessor.java
new file mode 100644
index 000000000000..7041b24f07fc
--- /dev/null
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerCopyPastePreprocessor.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.xdebugger.impl.ui;
+
+import com.intellij.codeInsight.editorActions.CopyPastePreProcessor;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.RawText;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Key;
+import com.intellij.psi.PsiFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author egor
+ */
+public class DebuggerCopyPastePreprocessor implements CopyPastePreProcessor {
+ public static final Key<Boolean> REMOVE_NEWLINES_ON_PASTE = new Key<Boolean>("REMOVE_NEWLINES_ON_PASTE");
+
+ @Nullable
+ @Override
+ public String preprocessOnCopy(PsiFile file, int[] startOffsets, int[] endOffsets, String text) {
+ return null;
+ }
+
+ @NotNull
+ @Override
+ public String preprocessOnPaste(Project project, PsiFile file, Editor editor, String text, RawText rawText) {
+ if (editor.getUserData(REMOVE_NEWLINES_ON_PASTE) != null) {
+ return text.replace("\n", " ");
+ }
+ return text;
+ }
+}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java
index 4c3766f23f5d..1a4505f6d85b 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java
@@ -227,6 +227,7 @@ public class XDebugSessionTab extends DebuggerSessionTabBase {
final Executor debugExecutor = DefaultDebugExecutor.getDebugExecutorInstance();
ExecutionEnvironment environment = getEnvironment();
if (environment != null) {
+ leftToolbar.add(ActionManager.getInstance().getAction(IdeActions.ACTION_RERUN));
List<AnAction> additionalRestartActions = session.getRestartActions();
if (!additionalRestartActions.isEmpty()) {
leftToolbar.addAll(additionalRestartActions);
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerEditorBase.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerEditorBase.java
index 991036b7f438..61a499ccf4dd 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerEditorBase.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerEditorBase.java
@@ -59,7 +59,7 @@ public abstract class XDebuggerEditorBase {
private final XDebuggerEditorsProvider myDebuggerEditorsProvider;
@NotNull private final EvaluationMode myMode;
@Nullable private final String myHistoryId;
- private final XSourcePosition mySourcePosition;
+ @Nullable private XSourcePosition mySourcePosition;
private int myHistoryIndex;
private final JLabel myChooseFactory = new JLabel();
@@ -124,6 +124,13 @@ public abstract class XDebuggerEditorBase {
return panel;
}
+ public void setSourcePosition(@Nullable XSourcePosition sourcePosition) {
+ if (mySourcePosition != sourcePosition) {
+ mySourcePosition = sourcePosition;
+ setExpression(getExpression(), false);
+ }
+ }
+
@NotNull
public EvaluationMode getMode() {
return myMode;
@@ -137,10 +144,16 @@ public abstract class XDebuggerEditorBase {
protected abstract void doSetText(XExpression text);
public void setExpression(@Nullable XExpression text) {
+ setExpression(text, true);
+ }
+
+ private void setExpression(@Nullable XExpression text, boolean saveInHistory) {
if (text == null) {
text = getMode() == EvaluationMode.EXPRESSION ? XExpressionImpl.EMPTY_EXPRESSION : XExpressionImpl.EMPTY_CODE_FRAGMENT;
}
- saveTextInHistory(text);
+ if (saveInHistory) {
+ saveTextInHistory(text);
+ }
Language language = text.getLanguage();
if (language == null) {
if (mySourcePosition != null) {
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerExpressionComboBox.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerExpressionComboBox.java
index 051683b875c1..3039d2acda7f 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerExpressionComboBox.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerExpressionComboBox.java
@@ -17,9 +17,7 @@ package com.intellij.xdebugger.impl.ui;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.editor.event.DocumentAdapter;
-import com.intellij.openapi.editor.event.DocumentEvent;
-import com.intellij.openapi.editor.event.DocumentListener;
+import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.ui.EditorComboBoxEditor;
@@ -101,6 +99,11 @@ public class XDebuggerExpressionComboBox extends XDebuggerEditorBase {
}
super.setItem(createDocument(((XExpression)anObject)));
}
+
+ @Override
+ protected void onEditorCreate(EditorEx editor) {
+ editor.putUserData(DebuggerCopyPastePreprocessor.REMOVE_NEWLINES_ON_PASTE, true);
+ }
};
myEditor.getEditorComponent().setFontInheritedFromLAF(false);
myComboBox.setEditor(myEditor);
@@ -110,23 +113,6 @@ public class XDebuggerExpressionComboBox extends XDebuggerEditorBase {
}
@Override
- protected Document createDocument(XExpression text) {
- Document document = super.createDocument(text);
- document.addDocumentListener(REPLACE_NEWLINES_LISTENER);
- return document;
- }
-
- private static DocumentListener REPLACE_NEWLINES_LISTENER = new DocumentAdapter() {
- @Override
- public void documentChanged(DocumentEvent e) {
- String text = e.getNewFragment().toString();
- if (text.contains("\n")) {
- e.getDocument().replaceString(e.getOffset(), e.getOffset() + e.getNewLength(), text.replace('\n', ' '));
- }
- }
- };
-
- @Override
protected void onHistoryChanged() {
fillComboBox();
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerMultilineEditor.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerMultilineEditor.java
index aa3445b4b421..3f06418ac8ac 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerMultilineEditor.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerMultilineEditor.java
@@ -71,7 +71,7 @@ public class XDebuggerMultilineEditor extends XDebuggerEditorBase {
@Override
public XExpression getExpression() {
- return XExpressionImpl.fromText(myEditorTextField.getText(), EvaluationMode.CODE_FRAGMENT);
+ return getEditorsProvider().createExpression(getProject(), myEditorTextField.getDocument(), myExpression.getLanguage(), EvaluationMode.CODE_FRAGMENT);
}
@Override
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/ShowReferringObjectsAction.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/ShowReferringObjectsAction.java
new file mode 100644
index 000000000000..4c2962f7f576
--- /dev/null
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/ShowReferringObjectsAction.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.xdebugger.impl.ui.tree.actions;
+
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.xdebugger.XDebuggerBundle;
+import com.intellij.xdebugger.frame.XReferrersProvider;
+import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
+import com.intellij.xdebugger.impl.ui.tree.XInspectDialog;
+import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author egor
+ */
+public class ShowReferringObjectsAction extends XDebuggerTreeActionBase {
+
+ @Override
+ protected boolean isEnabled(@NotNull XValueNodeImpl node, @NotNull AnActionEvent e) {
+ return node.getValueContainer().getReferrersProvider() != null;
+ }
+
+ @Override
+ protected void perform(XValueNodeImpl node, @NotNull String nodeName, AnActionEvent e) {
+ XReferrersProvider referrersProvider = node.getValueContainer().getReferrersProvider();
+ if (referrersProvider != null) {
+ XDebuggerTree tree = XDebuggerTree.getTree(e.getDataContext());
+ XInspectDialog dialog = new XInspectDialog(tree.getProject(),
+ tree.getEditorsProvider(),
+ tree.getSourcePosition(),
+ nodeName,
+ referrersProvider.getReferringObjectsValue(),
+ tree.getValueMarkers());
+ dialog.setTitle(XDebuggerBundle.message("showReferring.dialog.title", nodeName));
+ dialog.show();
+ }
+ }
+}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XAddToWatchesAction.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XAddToWatchesAction.java
index 7c77bafc6553..211fddae40ea 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XAddToWatchesAction.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XAddToWatchesAction.java
@@ -23,6 +23,7 @@ import com.intellij.xdebugger.XDebuggerManager;
import com.intellij.xdebugger.impl.XDebugSessionImpl;
import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl;
import com.intellij.xdebugger.impl.frame.XWatchesView;
+import com.intellij.xdebugger.impl.ui.XDebugSessionTab;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
import org.jetbrains.annotations.NotNull;
@@ -41,10 +42,7 @@ class XAddToWatchesAction extends XDebuggerTreeActionBase {
if (watchesView != null) {
String expression = node.getValueContainer().getEvaluationExpression();
if (!StringUtil.isEmpty(expression)) {
- XExpressionImpl watchExpression = XExpressionImpl.fromText(expression);
- if (watchExpression != null) {
- watchesView.addWatchExpression(watchExpression, -1, true);
- }
+ watchesView.addWatchExpression(XExpressionImpl.fromText(expression), -1, true);
}
}
}
@@ -55,7 +53,10 @@ class XAddToWatchesAction extends XDebuggerTreeActionBase {
if (view == null && project != null) {
XDebugSession session = XDebuggerManager.getInstance(project).getCurrentSession();
if (session != null) {
- return ((XDebugSessionImpl)session).getSessionTab().getWatchesView();
+ XDebugSessionTab tab = ((XDebugSessionImpl)session).getSessionTab();
+ if (tab != null) {
+ return tab.getWatchesView();
+ }
}
}
return view;
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XStackFrameNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XStackFrameNode.java
index fa32ebcc4d75..b7b21560f438 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XStackFrameNode.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XStackFrameNode.java
@@ -15,7 +15,16 @@
*/
package com.intellij.xdebugger.impl.ui.tree.nodes;
+import com.intellij.openapi.util.registry.Registry;
+import com.intellij.xdebugger.XDebugSession;
+import com.intellij.xdebugger.XExpression;
+import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
import com.intellij.xdebugger.frame.XStackFrame;
+import com.intellij.xdebugger.frame.XValue;
+import com.intellij.xdebugger.frame.XValueChildrenList;
+import com.intellij.xdebugger.impl.XDebugSessionImpl;
+import com.intellij.xdebugger.impl.frame.XDebugView;
+import com.intellij.xdebugger.impl.ui.XDebugSessionData;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import org.jetbrains.annotations.NotNull;
@@ -27,4 +36,32 @@ public class XStackFrameNode extends XValueContainerNode<XStackFrame> {
super(tree, null, xStackFrame);
setLeaf(false);
}
+
+ @Override
+ public void startComputingChildren() {
+ if (Registry.is("debugger.watches.in.variables")) {
+ XDebugSession session = XDebugView.getSession(getTree());
+ XDebuggerEvaluator evaluator = getValueContainer().getEvaluator();
+ if (session != null && evaluator != null) {
+ XDebugSessionData data = ((XDebugSessionImpl)session).getSessionData();
+ XExpression[] expressions = data.getWatchExpressions();
+ for (final XExpression expression : expressions) {
+ evaluator.evaluate(expression, new XDebuggerEvaluator.XEvaluationCallback() {
+ @Override
+ public void evaluated(@NotNull XValue result) {
+ XValueChildrenList watches = new XValueChildrenList();
+ watches.add(expression.getExpression(), result);
+ addChildren(watches, false);
+ }
+
+ @Override
+ public void errorOccurred(@NotNull String errorMessage) {
+ // do not add anything
+ }
+ }, getValueContainer().getSourcePosition());
+ }
+ }
+ }
+ super.startComputingChildren();
+ }
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java
index b9f90fe86b2b..a2fb3d51d253 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
*/
package com.intellij.xdebugger.impl.ui.tree.nodes;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.ObjectUtils;
import com.intellij.util.SmartList;
@@ -90,6 +91,11 @@ public abstract class XValueContainerNode<ValueContainer extends XValueContainer
XValueNodeImpl node = new XValueNodeImpl(myTree, XValueContainerNode.this, children.getName(i), children.getValue(i));
myValueChildren.add(node);
newChildren.add(node);
+
+ if (Registry.is("ide.debugger.inline") && "this".equals(node.getName())) { //todo[kb]: try to generify this dirty hack
+ //initialize "this" fields to display in inline view
+ node.getChildren();
+ }
}
myTopGroups = createGroupNodes(children.getTopGroups(), myTopGroups, newChildren);
myBottomGroups = createGroupNodes(children.getBottomGroups(), myBottomGroups, newChildren);
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java
index 1f3d4c77e84f..292cca541699 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java
@@ -16,6 +16,8 @@
package com.intellij.xdebugger.impl.ui.tree.nodes;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
@@ -24,9 +26,11 @@ import com.intellij.ui.AppUIUtil;
import com.intellij.ui.ColoredTextContainer;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.NotNullFunction;
+import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.frame.*;
import com.intellij.xdebugger.frame.presentation.XValuePresentation;
+import com.intellij.xdebugger.impl.frame.XDebugView;
import com.intellij.xdebugger.impl.frame.XValueMarkers;
import com.intellij.xdebugger.impl.frame.XVariablesView;
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
@@ -120,26 +124,7 @@ public class XValueNodeImpl extends XValueContainerNode<XValue> implements XValu
myValuePresentation = valuePresentation;
myRawValue = XValuePresentationUtil.computeValueText(valuePresentation);
if (Registry.is("ide.debugger.inline")) {
- try {
- getValueContainer().computeSourcePosition(new XNavigatable() {
- @Override
- public void setSourcePosition(@Nullable XSourcePosition sourcePosition) {
- Map<Pair<VirtualFile, Integer>, Set<XValueNodeImpl>> map = myTree.getProject().getUserData(XVariablesView.DEBUG_VARIABLES);
- if (map == null || sourcePosition == null) return;
- VirtualFile file = sourcePosition.getFile();
- int line = sourcePosition.getLine();
- Pair<VirtualFile, Integer> key = Pair.create(file, line);
- Set<XValueNodeImpl> presentations = map.get(key);
- if (presentations == null) {
- presentations = new LinkedHashSet<XValueNodeImpl>();
- map.put(key, presentations);
- }
- presentations.add(XValueNodeImpl.this);
- }
- });
- }
- catch (Exception ignore) {
- }
+ updateInlineDebuggerData();
}
updateText();
setLeaf(!hasChildren);
@@ -147,6 +132,39 @@ public class XValueNodeImpl extends XValueContainerNode<XValue> implements XValu
myTree.nodeLoaded(this, myName);
}
+ public void updateInlineDebuggerData() {
+ try {
+ final XDebugSession session = XDebugView.getSession(getTree());
+ if (session != null) {
+ final XSourcePosition position = session.getCurrentPosition();
+ if (position != null) {
+ getValueContainer().computeSourcePosition(new XNearestSourcePosition() {
+ @Override
+ public void setSourcePosition(@Nullable XSourcePosition sourcePosition) {
+ final Map<Pair<VirtualFile, Integer>, Set<XValueNodeImpl>> map = myTree.getProject().getUserData(XVariablesView.DEBUG_VARIABLES);
+ final Map<VirtualFile, Long> timestamps = myTree.getProject().getUserData(XVariablesView.DEBUG_VARIABLES_TIMESTAMPS);
+ if (map == null || timestamps == null || sourcePosition == null) return;
+ VirtualFile file = sourcePosition.getFile();
+ final Document doc = FileDocumentManager.getInstance().getDocument(file);
+ if (doc == null) return;
+ int line = sourcePosition.getLine();
+ Pair<VirtualFile, Integer> key = Pair.create(file, line);
+ Set<XValueNodeImpl> presentations = map.get(key);
+ if (presentations == null) {
+ presentations = new LinkedHashSet<XValueNodeImpl>();
+ map.put(key, presentations);
+ timestamps.put(file, doc.getModificationStamp());
+ }
+ presentations.add(XValueNodeImpl.this);
+ }
+ });
+ }
+ }
+ }
+ catch (Exception ignore) {
+ }
+ }
+
@Override
public void setFullValueEvaluator(@NotNull final XFullValueEvaluator fullValueEvaluator) {
AppUIUtil.invokeOnEdt(new Runnable() {
@@ -179,7 +197,13 @@ public class XValueNodeImpl extends XValueContainerNode<XValue> implements XValu
}
public static void buildText(@NotNull XValuePresentation valuePresenter, @NotNull ColoredTextContainer text) {
- XValuePresentationUtil.appendSeparator(text, valuePresenter.getSeparator());
+ buildText(valuePresenter, text, true);
+ }
+
+ public static void buildText(@NotNull XValuePresentation valuePresenter, @NotNull ColoredTextContainer text, boolean appendSeparator) {
+ if (appendSeparator) {
+ XValuePresentationUtil.appendSeparator(text, valuePresenter.getSeparator());
+ }
String type = valuePresenter.getType();
if (type != null) {
text.append("{" + type + "} ", XDebuggerUIConstants.TYPE_ATTRIBUTES);
diff --git a/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ShowByteCodeAction.java b/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ShowByteCodeAction.java
index 39d01579b342..1a8bfb7a3558 100644
--- a/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ShowByteCodeAction.java
+++ b/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ShowByteCodeAction.java
@@ -41,7 +41,6 @@ import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.ui.awt.RelativePoint;
-import com.intellij.ui.popup.NotLookupOrSearchCondition;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -138,7 +137,6 @@ public class ShowByteCodeAction extends AnAction {
};
final JBPopup popup = JBPopupFactory.getInstance().createComponentPopupBuilder(component, null)
- .setRequestFocusCondition(project, NotLookupOrSearchCondition.INSTANCE)
.setProject(project)
.setDimensionServiceKey(project, DocumentationManager.JAVADOC_LOCATION_AND_SIZE, false)
.setResizable(true)
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml
index c8854d4dbb26..81cc13aea292 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml
@@ -202,6 +202,10 @@
key="equals.between.inconvertible.types.display.name" groupBundle="messages.InspectionsBundle"
groupKey="group.names.probable.bugs" enabledByDefault="true" level="WARNING"
implementationClass="com.siyeh.ig.bugs.EqualsBetweenInconvertibleTypesInspection"/>
+ <localInspection language="JAVA" shortName="EqualsWithItself" bundle="com.siyeh.InspectionGadgetsBundle"
+ key="equals.with.itself.display.name" groupBundle="messages.InspectionsBundle"
+ groupKey="group.names.probable.bugs" enabledByDefault="true" level="WARNING"
+ implementationClass="com.siyeh.ig.bugs.EqualsWithItselfInspection"/>
<localInspection language="JAVA" suppressId="NonFinalFieldReferenceInEquals" shortName="EqualsUsesNonFinalVariable"
bundle="com.siyeh.InspectionGadgetsBundle" key="non.final.field.in.equals.display.name"
groupBundle="messages.InspectionsBundle" groupKey="group.names.probable.bugs" enabledByDefault="false" level="WARNING"
@@ -1379,6 +1383,14 @@
key="junit3.style.test.method.in.junit4.class.display.name" groupBundle="messages.InspectionsBundle"
groupKey="group.names.junit.issues" enabledByDefault="false" level="WARNING"
implementationClass="com.siyeh.ig.junit.JUnit3StyleTestMethodInJUnit4ClassInspection"/>
+ <localInspection language="JAVA" shortName="JUnit3MethodNamingConvention"
+ bundle="com.siyeh.InspectionGadgetsBundle" key="junit3.method.naming.convention.display.name"
+ groupBundle="messages.InspectionsBundle" groupKey="group.names.junit.issues" enabledByDefault="false"
+ level="WARNING" implementationClass="com.siyeh.ig.junit.JUnit3MethodNamingConventionInspection"/>
+ <localInspection language="JAVA" shortName="JUnit4MethodNamingConvention"
+ bundle="com.siyeh.InspectionGadgetsBundle" key="junit4.method.naming.convention.display.name"
+ groupBundle="messages.InspectionsBundle" groupKey="group.names.junit.issues" enabledByDefault="false"
+ level="WARNING" implementationClass="com.siyeh.ig.junit.JUnit4MethodNamingConventionInspection"/>
<localInspection language="JAVA" shortName="JUnit4AnnotatedMethodInJUnit3TestCase" bundle="com.siyeh.InspectionGadgetsBundle"
key="junit4.test.method.in.class.extending.junit3.testcase.display.name" groupBundle="messages.InspectionsBundle"
groupKey="group.names.junit.issues" enabledByDefault="true" level="WARNING"
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
index 1dfdfb9eb50a..1df72421fd4d 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
@@ -1741,6 +1741,7 @@ ignore.test.method.in.class.extending.junit3.testcase.problem.descriptor=JUnit 3
ignore.test.method.in.class.extending.junit3.testcase.quickfix=Remove ''@Ignore'' and rename method to ''{0}''
convert.junit3.test.class.quickfix=Convert JUnit 3 class ''{0}'' to JUnit 4
remove.junit4.test.annotation.quickfix=Remove '@Test' annotation
+remove.junit4.test.annotation.and.rename.quickfix=Remove '@Test' annotation and rename to ''{0}''
equals.called.on.enum.constant.display.name='equals()' called on Enum value
equals.called.on.enum.constant.problem.descriptor=<code>#ref()</code> called on Enum value #loc
equals.called.on.enum.constant.quickfix=Replace 'equals()' with '=='
@@ -2100,3 +2101,13 @@ assignment.to.lambda.parameter.problem.descriptor=Assignment to lambda parameter
class.with.only.private.constructors.display.name=Class with only 'private' constructors should be declared 'final'
class.with.only.private.constructors.problem.descriptor=Class <code>#ref</code> with only 'private' constructors should be declared 'final'
property.value.set.to.itself.display.name=Property value set to itself
+equals.with.itself.display.name='equals()' called on itself
+equals.with.itself.problem.descriptor=Identical qualifier and argument to <code>#ref()</code> call
+junit4.method.naming.convention.display.name=JUnit 4 test method naming convention
+junit4.method.naming.convention.problem.descriptor.short=JUnit 4 test method name <code>#ref</code> is too short ({0} < {1}) #loc
+junit4.method.naming.convention.problem.descriptor.long=JUnit 4 test method name <code>#ref</code> is too long ({0} > {1}) #loc
+junit4.method.naming.convention.problem.descriptor.regex.mismatch=JUnit 4 test method name <code>#ref</code> doesn''t match regex ''{0}'' #loc
+junit3.method.naming.convention.display.name=JUnit 3 test method naming convention
+junit3.method.naming.convention.problem.descriptor.short=JUnit 3 test method name <code>#ref</code> is too short ({0} < {1}) #loc
+junit3.method.naming.convention.problem.descriptor.long=JUnit 3 test method name <code>#ref</code> is too long ({0} > {1}) #loc
+junit3.method.naming.convention.problem.descriptor.regex.mismatch=JUnit 3 test method name <code>#ref</code> doesn''t match regex ''{0}'' #loc
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/TypeMayBeWeakenedInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/TypeMayBeWeakenedInspection.java
index bf23939f2c86..2787f34e4dcf 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/TypeMayBeWeakenedInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/TypeMayBeWeakenedInspection.java
@@ -21,7 +21,6 @@ import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
-import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.OverridingMethodsSearch;
import com.intellij.util.Query;
import com.siyeh.InspectionGadgetsBundle;
@@ -64,9 +63,9 @@ public class TypeMayBeWeakenedInspection extends BaseInspection {
@NonNls final StringBuilder builder = new StringBuilder();
final Iterator<PsiClass> iterator = weakerClasses.iterator();
if (iterator.hasNext()) {
- builder.append('\'').append(iterator.next().getQualifiedName()).append('\'');
+ builder.append('\'').append(getClassName(iterator.next())).append('\'');
while (iterator.hasNext()) {
- builder.append(", '").append(iterator.next().getQualifiedName()).append('\'');
+ builder.append(", '").append(getClassName(iterator.next())).append('\'');
}
}
final Object info = infos[0];
@@ -85,6 +84,14 @@ public class TypeMayBeWeakenedInspection extends BaseInspection {
return InspectionGadgetsBundle.message("type.may.be.weakened.problem.descriptor", builder.toString());
}
+ private static String getClassName(PsiClass aClass) {
+ final String qualifiedName = aClass.getQualifiedName();
+ if (qualifiedName == null) {
+ return aClass.getName();
+ }
+ return qualifiedName;
+ }
+
@Override
@Nullable
public JComponent createOptionsPanel() {
@@ -106,11 +113,11 @@ public class TypeMayBeWeakenedInspection extends BaseInspection {
final Iterable<PsiClass> weakerClasses = (Iterable<PsiClass>)infos[1];
final Collection<InspectionGadgetsFix> fixes = new ArrayList();
for (PsiClass weakestClass : weakerClasses) {
- final String qualifiedName = weakestClass.getQualifiedName();
- if (qualifiedName == null) {
+ final String className = getClassName(weakestClass);
+ if (className == null) {
continue;
}
- fixes.add(new TypeMayBeWeakenedFix(qualifiedName));
+ fixes.add(new TypeMayBeWeakenedFix(className));
}
return fixes.toArray(new InspectionGadgetsFix[fixes.size()]);
}
@@ -162,31 +169,30 @@ public class TypeMayBeWeakenedInspection extends BaseInspection {
if (!(oldType instanceof PsiClassType)) {
return;
}
- final PsiClassType classType = (PsiClassType)oldType;
- final PsiType[] parameterTypes = classType.getParameters();
- final GlobalSearchScope scope = element.getResolveScope();
+ final PsiClassType oldClassType = (PsiClassType)oldType;
+ final PsiType[] parameterTypes = oldClassType.getParameters();
final JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
- final PsiClass aClass = facade.findClass(fqClassName, scope);
- if (aClass == null) {
+ final PsiElementFactory factory = facade.getElementFactory();
+ final PsiType type = factory.createTypeFromText(fqClassName, element);
+ if (!(type instanceof PsiClassType)) {
return;
}
- final PsiTypeParameter[] typeParameters = aClass.getTypeParameters();
- final PsiElementFactory factory = facade.getElementFactory();
- final PsiClassType type;
- if (typeParameters.length != 0 && typeParameters.length == parameterTypes.length) {
- final Map<PsiTypeParameter, PsiType> typeParameterMap = new HashMap();
- for (int i = 0; i < typeParameters.length; i++) {
- final PsiTypeParameter typeParameter = typeParameters[i];
- final PsiType parameterType = parameterTypes[i];
- typeParameterMap.put(typeParameter, parameterType);
+ PsiClassType classType = (PsiClassType)type;
+ final PsiClass aClass = classType.resolve();
+ if (aClass != null) {
+ final PsiTypeParameter[] typeParameters = aClass.getTypeParameters();
+ if (typeParameters.length != 0 && typeParameters.length == parameterTypes.length) {
+ final Map<PsiTypeParameter, PsiType> typeParameterMap = new HashMap();
+ for (int i = 0; i < typeParameters.length; i++) {
+ final PsiTypeParameter typeParameter = typeParameters[i];
+ final PsiType parameterType = parameterTypes[i];
+ typeParameterMap.put(typeParameter, parameterType);
+ }
+ final PsiSubstitutor substitutor = factory.createSubstitutor(typeParameterMap);
+ classType = factory.createType(aClass, substitutor);
}
- final PsiSubstitutor substitutor = factory.createSubstitutor(typeParameterMap);
- type = factory.createType(aClass, substitutor);
- }
- else {
- type = factory.createTypeByFQClassName(fqClassName, scope);
}
- final PsiJavaCodeReferenceElement referenceElement = factory.createReferenceElementByType(type);
+ final PsiJavaCodeReferenceElement referenceElement = factory.createReferenceElementByType(classType);
final PsiElement replacement = componentReferenceElement.replace(referenceElement);
final JavaCodeStyleManager javaCodeStyleManager = JavaCodeStyleManager.getInstance(project);
javaCodeStyleManager.shortenClassReferences(replacement);
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EqualsWithItselfInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EqualsWithItselfInspection.java
new file mode 100644
index 000000000000..698ace189a6b
--- /dev/null
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EqualsWithItselfInspection.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.siyeh.ig.bugs;
+
+import com.intellij.psi.PsiExpression;
+import com.intellij.psi.PsiExpressionList;
+import com.intellij.psi.PsiMethodCallExpression;
+import com.intellij.psi.PsiReferenceExpression;
+import com.siyeh.InspectionGadgetsBundle;import com.siyeh.ig.BaseInspection;
+import com.siyeh.ig.BaseInspectionVisitor;
+import com.siyeh.ig.psiutils.EquivalenceChecker;
+import com.siyeh.ig.psiutils.MethodCallUtils;
+import com.siyeh.ig.psiutils.SideEffectChecker;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class EqualsWithItselfInspection extends BaseInspection {
+ @Nls
+ @NotNull
+ @Override
+ public String getDisplayName() {
+ return InspectionGadgetsBundle.message("equals.with.itself.display.name");
+ }
+
+ @NotNull
+ @Override
+ protected String buildErrorString(Object... infos) {
+ return InspectionGadgetsBundle.message("equals.with.itself.problem.descriptor");
+ }
+
+ @Override
+ public BaseInspectionVisitor buildVisitor() {
+ return new EqualsWithIfSelfVisitor();
+ }
+
+ private static class EqualsWithIfSelfVisitor extends BaseInspectionVisitor {
+
+ @Override
+ public void visitMethodCallExpression(PsiMethodCallExpression expression) {
+ super.visitMethodCallExpression(expression);
+ if (!MethodCallUtils.isEqualsCall(expression)) {
+ return;
+ }
+ final PsiReferenceExpression methodExpression = expression.getMethodExpression();
+ final PsiExpression qualifier = methodExpression.getQualifierExpression();
+ if (qualifier == null) {
+ return;
+ }
+ final PsiExpressionList argumentList = expression.getArgumentList();
+ final PsiExpression[] arguments = argumentList.getExpressions();
+ if (arguments.length != 1) {
+ return;
+ }
+ final PsiExpression argument = arguments[0];
+ if (!EquivalenceChecker.expressionsAreEquivalent(qualifier, argument) ||
+ SideEffectChecker.mayHaveSideEffects(qualifier)) {
+ return;
+ }
+ registerMethodCallError(expression);
+ }
+ }
+}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/StaticInheritanceFix.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/StaticInheritanceFix.java
index 1289bbdbe694..c24de84ba1ea 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/StaticInheritanceFix.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/StaticInheritanceFix.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,6 +30,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.psi.*;
import com.intellij.psi.impl.DebugUtil;
+import com.intellij.psi.search.SearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
@@ -91,7 +92,13 @@ class StaticInheritanceFix extends InspectionGadgetsFix {
@Override
public void run(@NotNull ProgressIndicator indicator) {
for (final PsiField field : allFields) {
- final Query<PsiReference> search = ReferencesSearch.search(field, implementingClass.getUseScope(), false);
+ SearchScope scope = ApplicationManager.getApplication().runReadAction(new Computable<SearchScope>() {
+ @Override
+ public SearchScope compute() {
+ return implementingClass.getUseScope();
+ }
+ });
+ final Query<PsiReference> search = ReferencesSearch.search(field, scope, false);
for (PsiReference reference : search) {
if (!(reference instanceof PsiReferenceExpression)) {
continue;
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/JUnit3MethodNamingConventionInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/JUnit3MethodNamingConventionInspectionBase.java
new file mode 100644
index 000000000000..8f27342d8d2b
--- /dev/null
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/JUnit3MethodNamingConventionInspectionBase.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.siyeh.ig.junit;
+
+import com.intellij.psi.PsiIdentifier;
+import com.intellij.psi.PsiMethod;
+import com.siyeh.InspectionGadgetsBundle;
+import com.siyeh.ig.BaseInspectionVisitor;
+import com.siyeh.ig.naming.ConventionInspection;
+import com.siyeh.ig.psiutils.LibraryUtil;
+import com.siyeh.ig.psiutils.MethodUtils;
+import com.siyeh.ig.psiutils.TestUtils;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class JUnit3MethodNamingConventionInspectionBase extends ConventionInspection {
+
+ @Nls
+ @NotNull
+ @Override
+ public String getDisplayName() {
+ return InspectionGadgetsBundle.message("junit3.method.naming.convention.display.name");
+ }
+
+ @Override
+ @NotNull
+ public String buildErrorString(Object... infos) {
+ final String methodName = (String)infos[0];
+ final int length = methodName.length();
+ if (length < getMinLength()) {
+ return InspectionGadgetsBundle.message("junit3.method.naming.convention.problem.descriptor.short",
+ Integer.valueOf(length), Integer.valueOf(getMinLength()));
+ }
+ else if (length > getMaxLength()) {
+ return InspectionGadgetsBundle.message("junit3.method.naming.convention.problem.descriptor.long",
+ Integer.valueOf(length), Integer.valueOf(getMaxLength()));
+ }
+ return InspectionGadgetsBundle.message("junit3.method.naming.convention.problem.descriptor.regex.mismatch", getRegex());
+ }
+
+ @Override
+ protected String getDefaultRegex() {
+ return "test[A-Za-z_\\d]*";
+ }
+
+ @Override
+ protected int getDefaultMinLength() {
+ return 8;
+ }
+
+ @Override
+ protected int getDefaultMaxLength() {
+ return 64;
+ }
+
+ @Override
+ public BaseInspectionVisitor buildVisitor() {
+ return new JUnit3MethodNamingConventionVisitor();
+ }
+
+ private class JUnit3MethodNamingConventionVisitor extends BaseInspectionVisitor {
+
+ @Override
+ public void visitMethod(PsiMethod method) {
+ super.visitMethod(method);
+ if (!TestUtils.isJUnit3TestMethod(method) || !TestUtils.isRunnable(method)) {
+ return;
+ }
+ final PsiIdentifier nameIdentifier = method.getNameIdentifier();
+ if (nameIdentifier == null) {
+ return;
+ }
+ final String name = method.getName();
+ if (isValid(name)) {
+ return;
+ }
+ if (!isOnTheFly() && MethodUtils.hasSuper(method)) {
+ return;
+ }
+ if (LibraryUtil.isOverrideOfLibraryMethod(method)) {
+ return;
+ }
+ registerMethodError(method, name);
+ }
+ }
+}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/JUnit3StyleTestMethodInJUnit4ClassInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/JUnit3StyleTestMethodInJUnit4ClassInspection.java
index 8a6ebeff68ce..c39865049e95 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/JUnit3StyleTestMethodInJUnit4ClassInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/JUnit3StyleTestMethodInJUnit4ClassInspection.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@ import com.siyeh.ig.DelegatingFix;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.psiutils.TestUtils;
import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -71,70 +72,45 @@ public class JUnit3StyleTestMethodInJUnit4ClassInspection extends BaseInspection
if (!name.startsWith("test")) {
return;
}
- if (method.hasModifierProperty(PsiModifier.ABSTRACT) || !method.hasModifierProperty(PsiModifier.PUBLIC)) {
+ if (!TestUtils.isRunnable(method)) {
return;
}
if (TestUtils.isJUnit4TestMethod(method)) {
return;
}
- final PsiType returnType = method.getReturnType();
- if (returnType == null || !returnType.equals(PsiType.VOID)) {
- return;
- }
- final PsiParameterList parameterList = method.getParameterList();
- if (parameterList.getParametersCount() != 0) {
- return;
- }
final PsiClass containingClass = method.getContainingClass();
if (TestUtils.isJUnitTestClass(containingClass)) {
return;
}
- if (!containsReferenceToClass(containingClass, "org.junit.Test")) {
+ if (!containsJUnit4Annotation(containingClass)) {
return;
}
registerMethodError(method);
}
}
- public static boolean containsReferenceToClass(PsiElement element, String fullyQualifiedName) {
- final ClassReferenceVisitor visitor = new ClassReferenceVisitor(fullyQualifiedName);
+ public static boolean containsJUnit4Annotation(PsiElement element) {
+ final JUnit4AnnotationVisitor visitor = new JUnit4AnnotationVisitor();
element.accept(visitor);
- return visitor.isReferenceFound();
+ return visitor.isJUnit4AnnotationFound();
}
- private static class ClassReferenceVisitor extends JavaRecursiveElementVisitor {
-
- private final String fullyQualifiedName;
- private boolean referenceFound = false;
+ private static class JUnit4AnnotationVisitor extends JavaRecursiveElementWalkingVisitor {
- private ClassReferenceVisitor(String fullyQualifiedName) {
- this.fullyQualifiedName = fullyQualifiedName;
- }
+ private boolean myJUnit4AnnotationFound = false;
@Override
- public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
- super.visitReferenceElement(reference);
- if (referenceFound) {
- return;
- }
- if (!(reference.getParent() instanceof PsiAnnotation)) {
- // optimization
- return;
- }
- final PsiElement element = reference.resolve();
- if (!(element instanceof PsiClass) || element instanceof PsiTypeParameter) {
- return;
- }
- final PsiClass aClass = (PsiClass)element;
- final String classQualifiedName = aClass.getQualifiedName();
- if (classQualifiedName == null || !classQualifiedName.equals(fullyQualifiedName)) {
+ public void visitAnnotation(PsiAnnotation annotation) {
+ super.visitAnnotation(annotation);
+ @NonNls final String qualifiedName = annotation.getQualifiedName();
+ if (qualifiedName == null || !qualifiedName.startsWith("org.junit.")) {
return;
}
- referenceFound = true;
+ myJUnit4AnnotationFound = true;
}
- public boolean isReferenceFound() {
- return referenceFound;
+ public boolean isJUnit4AnnotationFound() {
+ return myJUnit4AnnotationFound;
}
}
}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/JUnit4MethodNamingConventionInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/JUnit4MethodNamingConventionInspectionBase.java
new file mode 100644
index 000000000000..eb0f3d7b91c7
--- /dev/null
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/JUnit4MethodNamingConventionInspectionBase.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.siyeh.ig.junit;
+
+import com.intellij.psi.PsiIdentifier;
+import com.intellij.psi.PsiMethod;
+import com.siyeh.InspectionGadgetsBundle;
+import com.siyeh.ig.BaseInspectionVisitor;
+import com.siyeh.ig.naming.ConventionInspection;
+import com.siyeh.ig.psiutils.LibraryUtil;
+import com.siyeh.ig.psiutils.MethodUtils;
+import com.siyeh.ig.psiutils.TestUtils;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class JUnit4MethodNamingConventionInspectionBase extends ConventionInspection {
+
+ @Nls
+ @NotNull
+ @Override
+ public String getDisplayName() {
+ return InspectionGadgetsBundle.message("junit4.method.naming.convention.display.name");
+ }
+
+ @Override
+ @NotNull
+ public String buildErrorString(Object... infos) {
+ final String methodName = (String)infos[0];
+ final int length = methodName.length();
+ if (length < getMinLength()) {
+ return InspectionGadgetsBundle.message("junit4.method.naming.convention.problem.descriptor.short",
+ Integer.valueOf(length), Integer.valueOf(getMinLength()));
+ }
+ else if (length > getMaxLength()) {
+ return InspectionGadgetsBundle.message("junit4.method.naming.convention.problem.descriptor.long",
+ Integer.valueOf(length), Integer.valueOf(getMaxLength()));
+ }
+ return InspectionGadgetsBundle.message("junit4.method.naming.convention.problem.descriptor.regex.mismatch", getRegex());
+ }
+
+ @Override
+ protected String getDefaultRegex() {
+ return "[a-z][A-Za-z_\\d]*";
+ }
+
+ @Override
+ protected int getDefaultMinLength() {
+ return 4;
+ }
+
+ @Override
+ protected int getDefaultMaxLength() {
+ return 64;
+ }
+
+ @Override
+ public BaseInspectionVisitor buildVisitor() {
+ return new JUnit4MethodNamingConventionVisitor();
+ }
+
+ private class JUnit4MethodNamingConventionVisitor extends BaseInspectionVisitor {
+
+ @Override
+ public void visitMethod(PsiMethod method) {
+ super.visitMethod(method);
+ if (!TestUtils.isJUnit4TestMethod(method) || !TestUtils.isRunnable(method)) {
+ return;
+ }
+ final PsiIdentifier nameIdentifier = method.getNameIdentifier();
+ if (nameIdentifier == null) {
+ return;
+ }
+ final String name = method.getName();
+ if (isValid(name)) {
+ return;
+ }
+ if (!isOnTheFly() && MethodUtils.hasSuper(method)) {
+ return;
+ }
+ if (LibraryUtil.isOverrideOfLibraryMethod(method)) {
+ return;
+ }
+ registerMethodError(method, name);
+ }
+ }
+}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/TestMethodIsPublicVoidNoArgInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/TestMethodIsPublicVoidNoArgInspection.java
index 02d8cd5b7c8e..4b9a794a143a 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/TestMethodIsPublicVoidNoArgInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/TestMethodIsPublicVoidNoArgInspection.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers
+ * Copyright 2003-2014 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,14 +15,14 @@
*/
package com.siyeh.ig.junit;
-import com.intellij.codeInsight.AnnotationUtil;
-import com.intellij.psi.*;
-import com.intellij.psi.util.InheritanceUtil;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiModifier;
+import com.intellij.psi.PsiParameterList;
+import com.intellij.psi.PsiType;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.psiutils.TestUtils;
-import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
public class TestMethodIsPublicVoidNoArgInspection extends BaseInspection {
@@ -70,23 +70,20 @@ public class TestMethodIsPublicVoidNoArgInspection extends BaseInspection {
@Override
public void visitMethod(@NotNull PsiMethod method) {
//note: no call to super;
- @NonNls final String methodName = method.getName();
- if (!methodName.startsWith("test") &&
- !TestUtils.isJUnit4TestMethod(method)) {
+ if (method.isConstructor()) {
return;
}
- final PsiType returnType = method.getReturnType();
- if (returnType == null) {
+ if (!TestUtils.isJUnit3TestMethod(method) && !TestUtils.isJUnit4TestMethod(method)) {
return;
}
+ final PsiType returnType = method.getReturnType();
final PsiParameterList parameterList = method.getParameterList();
final boolean takesArguments;
final boolean isStatic;
if (parameterList.getParametersCount() == 0) {
takesArguments = false;
isStatic = method.hasModifierProperty(PsiModifier.STATIC);
- if (!isStatic && returnType.equals(PsiType.VOID) &&
- method.hasModifierProperty(PsiModifier.PUBLIC)) {
+ if (!isStatic && PsiType.VOID.equals(returnType) && method.hasModifierProperty(PsiModifier.PUBLIC)) {
return;
}
}
@@ -94,14 +91,6 @@ public class TestMethodIsPublicVoidNoArgInspection extends BaseInspection {
isStatic = false;
takesArguments = true;
}
- final PsiClass targetClass = method.getContainingClass();
- if (!AnnotationUtil.isAnnotated(method, "org.junit.Test", true)) {
- if (targetClass == null ||
- !InheritanceUtil.isInheritor(targetClass,
- "junit.framework.TestCase")) {
- return;
- }
- }
registerMethodError(method, Boolean.valueOf(takesArguments),
Boolean.valueOf(isStatic));
}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/InstanceMethodNamingConventionInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/InstanceMethodNamingConventionInspectionBase.java
index 3ec38f55053c..964ce0b0aace 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/InstanceMethodNamingConventionInspectionBase.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/InstanceMethodNamingConventionInspectionBase.java
@@ -15,25 +15,22 @@
*/
package com.siyeh.ig.naming;
+import com.intellij.openapi.extensions.Extensions;
import com.intellij.psi.PsiIdentifier;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiModifier;
-import com.intellij.util.ui.CheckBox;
+import com.intellij.testIntegration.TestFramework;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.psiutils.LibraryUtil;
import com.siyeh.ig.psiutils.MethodUtils;
+import com.siyeh.ig.psiutils.TestUtils;
import org.jetbrains.annotations.NotNull;
-import javax.swing.*;
-
public class InstanceMethodNamingConventionInspectionBase extends ConventionInspection {
private static final int DEFAULT_MIN_LENGTH = 4;
private static final int DEFAULT_MAX_LENGTH = 32;
- @SuppressWarnings("PublicField")
- public boolean ignoreNativeMethods = true;
-
@Override
@NotNull
public String getDisplayName() {
@@ -59,13 +56,6 @@ public class InstanceMethodNamingConventionInspectionBase extends ConventionInsp
}
@Override
- public JComponent[] createExtraOptions() {
- return new JComponent[] {
- new CheckBox("ignore 'native' methods", this, "ignoreNativeMethods")
- };
- }
-
- @Override
protected String getDefaultRegex() {
return "[a-z][A-Za-z\\d]*";
}
@@ -80,6 +70,16 @@ public class InstanceMethodNamingConventionInspectionBase extends ConventionInsp
return DEFAULT_MAX_LENGTH;
}
+ private static boolean isTestNGTestMethod(PsiMethod method) {
+ final TestFramework[] testFrameworks = Extensions.getExtensions(TestFramework.EXTENSION_NAME);
+ for (TestFramework framework : testFrameworks) {
+ if ("TestNG".equals(framework.getName())) {
+ return framework.isTestMethod(method);
+ }
+ }
+ return false;
+ }
+
@Override
public BaseInspectionVisitor buildVisitor() {
return new NamingConventionsVisitor();
@@ -93,13 +93,24 @@ public class InstanceMethodNamingConventionInspectionBase extends ConventionInsp
if (method.isConstructor() || method.hasModifierProperty(PsiModifier.STATIC)) {
return;
}
- if (ignoreNativeMethods && method.hasModifierProperty(PsiModifier.NATIVE)) {
+ if (method.hasModifierProperty(PsiModifier.NATIVE) && isInspectionEnabled("NativeMethodNamingConvention", method)) {
return;
}
final PsiIdentifier nameIdentifier = method.getNameIdentifier();
if (nameIdentifier == null) {
return;
}
+ if (TestUtils.isRunnable(method)) {
+ if (TestUtils.isJUnit4TestMethod(method) && isInspectionEnabled("JUnit4MethodNamingConvention", method)) {
+ return;
+ }
+ if (TestUtils.isJUnit3TestMethod(method) && isInspectionEnabled("JUnit3MethodNamingConvention", method)) {
+ return;
+ }
+ }
+ if (isTestNGTestMethod(method) && isInspectionEnabled("TestNGMethodNamingConvention", method)) {
+ return;
+ }
final String name = method.getName();
if (isValid(name)) {
return;
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/NativeMethodNamingConventionInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/NativeMethodNamingConventionInspectionBase.java
index a8ceb11a11b1..2231fa152678 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/NativeMethodNamingConventionInspectionBase.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/NativeMethodNamingConventionInspectionBase.java
@@ -77,7 +77,7 @@ public class NativeMethodNamingConventionInspectionBase extends ConventionInspec
@Override
public void visitMethod(@NotNull PsiMethod method) {
super.visitMethod(method);
- if (method.isConstructor() || method.hasModifierProperty(PsiModifier.STATIC)) {
+ if (method.isConstructor()) {
return;
}
if (!method.hasModifierProperty(PsiModifier.NATIVE)) {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/StaticMethodNamingConventionInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/StaticMethodNamingConventionInspectionBase.java
index 116d2208e452..3e0d08998ec0 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/StaticMethodNamingConventionInspectionBase.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/StaticMethodNamingConventionInspectionBase.java
@@ -17,20 +17,14 @@ package com.siyeh.ig.naming;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiModifier;
-import com.intellij.util.ui.CheckBox;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspectionVisitor;
import org.jetbrains.annotations.NotNull;
-import javax.swing.*;
-
public class StaticMethodNamingConventionInspectionBase extends ConventionInspection {
private static final int DEFAULT_MIN_LENGTH = 4;
private static final int DEFAULT_MAX_LENGTH = 32;
- @SuppressWarnings("PublicField")
- public boolean ignoreNativeMethods = true;
-
@Override
@NotNull
public String getDisplayName() {
@@ -61,13 +55,6 @@ public class StaticMethodNamingConventionInspectionBase extends ConventionInspec
}
@Override
- public JComponent[] createExtraOptions() {
- return new JComponent[]{
- new CheckBox("ignore 'native' methods", this, "ignoreNativeMethods")
- };
- }
-
- @Override
protected String getDefaultRegex() {
return "[a-z][A-Za-z\\d]*";
}
@@ -95,7 +82,7 @@ public class StaticMethodNamingConventionInspectionBase extends ConventionInspec
if (!method.hasModifierProperty(PsiModifier.STATIC)) {
return;
}
- if (ignoreNativeMethods && method.hasModifierProperty(PsiModifier.NATIVE)) {
+ if (method.hasModifierProperty(PsiModifier.NATIVE) && isInspectionEnabled("NativeMethodNamingConvention", method)) {
return;
}
final String name = method.getName();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/PointlessArithmeticExpressionInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/PointlessArithmeticExpressionInspection.java
index 023b4bc9f949..2dde6969545d 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/PointlessArithmeticExpressionInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/PointlessArithmeticExpressionInspection.java
@@ -29,6 +29,7 @@ import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.PsiReplacementUtil;
import com.siyeh.ig.psiutils.EquivalenceChecker;
import com.siyeh.ig.psiutils.ExpressionUtils;
+import com.siyeh.ig.psiutils.SideEffectChecker;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -232,7 +233,7 @@ public class PointlessArithmeticExpressionInspection
for (int i = 0; i < expressions.length; i++) {
PsiExpression expression = expressions[i];
if (previousExpression != null &&
- (isZero(expression) || i == 1 && EquivalenceChecker.expressionsAreEquivalent(previousExpression, expression))) {
+ (isZero(expression) || areExpressionsIdenticalWithoutSideEffects(previousExpression, expression, i))) {
return true;
}
previousExpression = expression;
@@ -260,9 +261,10 @@ public class PointlessArithmeticExpressionInspection
private boolean divideExpressionIsPointless(PsiExpression[] expressions) {
PsiExpression previousExpression = null;
- for (PsiExpression expression : expressions) {
+ for (int i = 0; i < expressions.length; i++) {
+ final PsiExpression expression = expressions[i];
if (previousExpression != null &&
- (isOne(expression) || EquivalenceChecker.expressionsAreEquivalent(previousExpression, expression))) {
+ (isOne(expression) || areExpressionsIdenticalWithoutSideEffects(previousExpression, expression, i))) {
return true;
}
previousExpression = expression;
@@ -272,15 +274,21 @@ public class PointlessArithmeticExpressionInspection
private boolean modExpressionIsPointless(PsiExpression[] expressions) {
PsiExpression previousExpression = null;
- for (PsiExpression expression : expressions) {
+ for (int i = 0; i < expressions.length; i++) {
+ final PsiExpression expression = expressions[i];
if (previousExpression != null &&
- (isOne(expression) || EquivalenceChecker.expressionsAreEquivalent(previousExpression, expression))) {
+ (isOne(expression) || areExpressionsIdenticalWithoutSideEffects(previousExpression, expression, i))) {
return true;
}
previousExpression = expression;
}
return false;
}
+
+ private boolean areExpressionsIdenticalWithoutSideEffects(PsiExpression expression1, PsiExpression expression2, int index) {
+ return index == 1 && EquivalenceChecker.expressionsAreEquivalent(expression1, expression2) &&
+ !SideEffectChecker.mayHaveSideEffects(expression1);
+ }
}
boolean isZero(PsiExpression expression) {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ImportUtils.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ImportUtils.java
index 9b4a3a832913..7bfaae8cc722 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ImportUtils.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ImportUtils.java
@@ -67,6 +67,9 @@ public class ImportUtils {
!hasDefaultImportConflict(qualifiedName, javaFile) && !hasOnDemandImportConflict(qualifiedName, javaFile)) {
return;
}
+ if (hasExactImportConflict(qualifiedName, javaFile)) {
+ return;
+ }
final Project project = importList.getProject();
final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
final PsiElementFactory elementFactory = psiFacade.getElementFactory();
@@ -156,7 +159,7 @@ public class ImportUtils {
return false;
}
- private static boolean hasExactImportConflict(String fqName, PsiJavaFile file) {
+ public static boolean hasExactImportConflict(String fqName, PsiJavaFile file) {
final PsiImportList imports = file.getImportList();
if (imports == null) {
return false;
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/InheritanceUtil.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/InheritanceUtil.java
index 9661ba10e4c4..faea625f1db5 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/InheritanceUtil.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/InheritanceUtil.java
@@ -15,6 +15,7 @@
*/
package com.siyeh.ig.psiutils;
+import com.intellij.codeInspection.inheritance.ImplementedAtRuntimeCondition;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.psi.CommonClassNames;
import com.intellij.psi.PsiClass;
@@ -80,6 +81,11 @@ public class InheritanceUtil {
public static boolean hasImplementation(@NotNull PsiClass aClass) {
final SearchScope scope = GlobalSearchScope.projectScope(aClass.getProject());
if (aClass.isInterface() && FunctionalExpressionSearch.search(aClass, scope).findFirst() != null) return true;
+ for (ImplementedAtRuntimeCondition condition : ImplementedAtRuntimeCondition.EP_NAME.getExtensions()) {
+ if (condition.isImplementedAtRuntime(aClass)) {
+ return true;
+ }
+ }
final Query<PsiClass> search = ClassInheritorsSearch.search(aClass, scope, true, true);
return !search.forEach(new Processor<PsiClass>() {
@Override
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/SideEffectChecker.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/SideEffectChecker.java
index 5063ef7c2ea7..782b667469af 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/SideEffectChecker.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/SideEffectChecker.java
@@ -17,6 +17,7 @@ package com.siyeh.ig.psiutils;
import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.util.PropertyUtil;
import org.jetbrains.annotations.NotNull;
public class SideEffectChecker {
@@ -59,6 +60,14 @@ public class SideEffectChecker {
return;
}
super.visitMethodCallExpression(expression);
+ final PsiReferenceExpression methodExpression = expression.getMethodExpression();
+ final String methodName = methodExpression.getReferenceName();
+ if ((methodName.startsWith("is") || methodName.startsWith("get")) && expression.getArgumentList().getExpressions().length == 0) {
+ final PsiMethod method = expression.resolveMethod();
+ if (PropertyUtil.isSimpleGetter(method)) {
+ return;
+ }
+ }
mayHaveSideEffects = true;
}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/TestUtils.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/TestUtils.java
index cf2133299768..dcaf8390dc5d 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/TestUtils.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/TestUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers
+ * Copyright 2003-2014 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,8 +22,8 @@ import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
-import com.intellij.psi.util.*;
import com.intellij.psi.util.InheritanceUtil;
+import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -66,34 +66,37 @@ public class TestUtils {
}
public static boolean isJUnitTestMethod(@Nullable PsiMethod method) {
+ return isRunnable(method) && (isJUnit3TestMethod(method) || isJUnit4TestMethod(method));
+ }
+
+ public static boolean isRunnable(PsiMethod method) {
if (method == null) {
return false;
}
- if (isJUnit4TestMethod(method)) {
- return true;
- }
- final String methodName = method.getName();
- @NonNls final String test = "test";
- if (!methodName.startsWith(test)) {
- return false;
- }
if (method.hasModifierProperty(PsiModifier.ABSTRACT) ||
+ method.hasModifierProperty(PsiModifier.STATIC) ||
!method.hasModifierProperty(PsiModifier.PUBLIC)) {
return false;
}
final PsiType returnType = method.getReturnType();
- if (returnType == null) {
+ if (!PsiType.VOID.equals(returnType)) {
return false;
}
- if (!returnType.equals(PsiType.VOID)) {
+ final PsiParameterList parameterList = method.getParameterList();
+ return parameterList.getParametersCount() == 0;
+ }
+
+ public static boolean isJUnit3TestMethod(@Nullable PsiMethod method) {
+ if (method == null) {
return false;
}
- final PsiParameterList parameterList = method.getParameterList();
- if (parameterList.getParametersCount() != 0) {
+ final String methodName = method.getName();
+ @NonNls final String test = "test";
+ if (!methodName.startsWith(test)) {
return false;
}
- final PsiClass targetClass = method.getContainingClass();
- return isJUnitTestClass(targetClass);
+ final PsiClass containingClass = method.getContainingClass();
+ return isJUnitTestClass(containingClass);
}
public static boolean isJUnit4TestMethod(@Nullable PsiMethod method) {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessarilyQualifiedInnerClassAccessInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessarilyQualifiedInnerClassAccessInspection.java
index 78e32e5eee60..e449ad98fc8f 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessarilyQualifiedInnerClassAccessInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessarilyQualifiedInnerClassAccessInspection.java
@@ -99,7 +99,10 @@ public class UnnecessarilyQualifiedInnerClassAccessInspection extends BaseInspec
}
final PsiClass aClass = (PsiClass)target;
ImportUtils.addImportIfNeeded(aClass, element);
- element.delete();
+ final String shortName = aClass.getName();
+ if (isReferenceToTarget(shortName, aClass, parent)) {
+ element.delete();
+ }
}
}
@@ -108,6 +111,20 @@ public class UnnecessarilyQualifiedInnerClassAccessInspection extends BaseInspec
return new UnnecessarilyQualifiedInnerClassAccessVisitor();
}
+ private static boolean isReferenceToTarget(String referenceText, @NotNull PsiClass target, PsiElement context) {
+ final PsiJavaCodeReferenceElement reference =
+ JavaPsiFacade.getElementFactory(target.getProject()).createReferenceFromText(referenceText, context);
+ final JavaResolveResult[] results = reference.multiResolve(false);
+ if (results.length == 0) {
+ return true;
+ }
+ if (results.length > 1) {
+ return false;
+ }
+ final JavaResolveResult result = results[0];
+ return result.isAccessible() && target.equals(result.getElement());
+ }
+
private class UnnecessarilyQualifiedInnerClassAccessVisitor
extends BaseInspectionVisitor {
@@ -175,20 +192,6 @@ public class UnnecessarilyQualifiedInnerClassAccessInspection extends BaseInspec
visitReferenceElement(expression);
}
- private boolean isReferenceToTarget(String referenceText, @NotNull PsiClass target, PsiElement context) {
- final PsiJavaCodeReferenceElement reference =
- JavaPsiFacade.getElementFactory(target.getProject()).createReferenceFromText(referenceText, context);
- final JavaResolveResult[] results = reference.multiResolve(false);
- if (results.length == 0) {
- return true;
- }
- if (results.length > 1) {
- return false;
- }
- final JavaResolveResult result = results[0];
- return result.isAccessible() && target.equals(result.getElement());
- }
-
private boolean isInImportOrPackage(PsiElement element) {
while (element instanceof PsiJavaCodeReferenceElement) {
element = element.getParent();
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/JUnit3MethodNamingConventionInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/JUnit3MethodNamingConventionInspection.java
new file mode 100644
index 000000000000..29dcf0bf1a01
--- /dev/null
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/JUnit3MethodNamingConventionInspection.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.siyeh.ig.junit;
+
+import com.siyeh.ig.InspectionGadgetsFix;
+import com.siyeh.ig.fixes.RenameFix;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class JUnit3MethodNamingConventionInspection extends JUnit3MethodNamingConventionInspectionBase {
+
+ @Override
+ protected InspectionGadgetsFix buildFix(Object... infos) {
+ return new RenameFix();
+ }
+}
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/JUnit4AnnotatedMethodInJUnit3TestCaseInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/JUnit4AnnotatedMethodInJUnit3TestCaseInspection.java
index 252411527cc1..89ad944a0f78 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/JUnit4AnnotatedMethodInJUnit3TestCaseInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/JUnit4AnnotatedMethodInJUnit3TestCaseInspection.java
@@ -18,6 +18,7 @@ package com.siyeh.ig.junit;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.siyeh.InspectionGadgetsBundle;
@@ -41,7 +42,16 @@ public class JUnit4AnnotatedMethodInJUnit3TestCaseInspection extends JUnit4Annot
fixes.add(new RemoveIgnoreAndRename(method));
}
if (TestUtils.isJUnit4TestMethod(method)) {
- fixes.add(new RemoveTestAnnotationFix());
+ String methodName = method.getName();
+ String newMethodName;
+ if (methodName.startsWith("test")) {
+ newMethodName = null;
+ }
+ else {
+ boolean lowCaseStyle = methodName.contains("_");
+ newMethodName = "test" + (lowCaseStyle ? "_" + methodName : StringUtil.capitalize(methodName));
+ }
+ fixes.add(new RemoveTestAnnotationFix(newMethodName));
}
final PsiClass aClass = (PsiClass)infos[0];
final String className = aClass.getName();
@@ -233,22 +243,33 @@ public class JUnit4AnnotatedMethodInJUnit3TestCaseInspection extends JUnit4Annot
}
}
- private static class RemoveTestAnnotationFix extends InspectionGadgetsFix {
+ private static class RemoveTestAnnotationFix extends RenameFix {
+ private final String myNewName;
+
+ public RemoveTestAnnotationFix(String newName) {
+ super(newName);
+ myNewName = newName;
+ }
+
@Override
@NotNull
public String getFamilyName() {
- return getName();
+ return InspectionGadgetsBundle.message("remove.junit4.test.annotation.quickfix");
}
@Override
@NotNull
public String getName() {
- return InspectionGadgetsBundle.message("remove.junit4.test.annotation.quickfix");
+ return myNewName == null ? getFamilyName()
+ : InspectionGadgetsBundle.message("remove.junit4.test.annotation.and.rename.quickfix", myNewName);
}
@Override
- protected void doFix(Project project, ProblemDescriptor descriptor) {
+ public void doFix(Project project, ProblemDescriptor descriptor) {
deleteAnnotation(descriptor, "org.junit.Test");
+ if (myNewName != null) {
+ super.doFix(project, descriptor);
+ }
}
}
}
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/JUnit4MethodNamingConventionInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/JUnit4MethodNamingConventionInspection.java
new file mode 100644
index 000000000000..22c8937d48d9
--- /dev/null
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/JUnit4MethodNamingConventionInspection.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.siyeh.ig.junit;
+
+import com.siyeh.ig.InspectionGadgetsFix;
+import com.siyeh.ig.fixes.RenameFix;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class JUnit4MethodNamingConventionInspection extends JUnit4MethodNamingConventionInspectionBase {
+
+ @Override
+ protected InspectionGadgetsFix buildFix(Object... infos) {
+ return new RenameFix();
+ }
+}
diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/EqualsWithItself.html b/plugins/InspectionGadgets/src/inspectionDescriptions/EqualsWithItself.html
new file mode 100644
index 000000000000..3e1491edd22e
--- /dev/null
+++ b/plugins/InspectionGadgets/src/inspectionDescriptions/EqualsWithItself.html
@@ -0,0 +1,10 @@
+<html>
+<body>
+Reports call to <b>equals()</b> were an object is compared for equality with itself.
+This means that the argument and the qualifier to the call are identical.
+In this case <b>equals()</b> will always return <b>true</b>.
+<!-- tooltip end -->
+<p>
+<small>New in 14</small>
+</body>
+</html> \ No newline at end of file
diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceMethodNamingConvention.html b/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceMethodNamingConvention.html
index a6933cf0c7b8..4bf1c67710c5 100644
--- a/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceMethodNamingConvention.html
+++ b/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceMethodNamingConvention.html
@@ -8,8 +8,6 @@ methods are ignored by this inspection.
Use the fields below to specify minimum length, maximum length and regular expression expected for instance method names.
Specify <b>0</b> to not check the length of names. Regular expressions are in standard <b>java.util.regex</b> format.
<p>
-Use the checkbox below to ignore native methods.
-<p>
</body>
</html> \ No newline at end of file
diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/JUnit3MethodNamingConvention.html b/plugins/InspectionGadgets/src/inspectionDescriptions/JUnit3MethodNamingConvention.html
new file mode 100644
index 000000000000..253c7297cdcc
--- /dev/null
+++ b/plugins/InspectionGadgets/src/inspectionDescriptions/JUnit3MethodNamingConvention.html
@@ -0,0 +1,13 @@
+<html>
+<body>
+Reports JUnit 3 test methods whose names are either too short, too long, or do not follow the specified regular expression pattern.
+When this inspection is enabled, the <i>Instance method naming convention</i> inspection
+will ignore JUnit 3 test methods automatically.
+<!-- tooltip end -->
+<p>
+Use the fields below to specify minimum length, maximum length and regular expression expected for JUnit 3 test method names.
+Specify <b>0</b> to not check the length of names. Regular expressions are in standard <b>java.util.regex</b> format.
+<p>
+<small>New in 14</small>
+</body>
+</html> \ No newline at end of file
diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/JUnit4MethodNamingConvention.html b/plugins/InspectionGadgets/src/inspectionDescriptions/JUnit4MethodNamingConvention.html
new file mode 100644
index 000000000000..a53cc8817015
--- /dev/null
+++ b/plugins/InspectionGadgets/src/inspectionDescriptions/JUnit4MethodNamingConvention.html
@@ -0,0 +1,13 @@
+<html>
+<body>
+Reports JUnit 4 test methods whose names are either too short, too long, or do not follow the specified regular expression pattern.
+When this inspection is enabled, the <i>Instance method naming convention</i> inspection
+will ignore JUnit 4 test methods automatically.
+<!-- tooltip end -->
+<p>
+Use the fields below to specify minimum length, maximum length and regular expression expected for JUnit 4 test method names.
+Specify <b>0</b> to not check the length of names. Regular expressions are in standard <b>java.util.regex</b> format.
+<p>
+<small>New in 14</small>
+</body>
+</html> \ No newline at end of file
diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NativeMethodNamingConvention.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NativeMethodNamingConvention.html
index c2e866b3d223..2ffd3a2a27a3 100644
--- a/plugins/InspectionGadgets/src/inspectionDescriptions/NativeMethodNamingConvention.html
+++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NativeMethodNamingConvention.html
@@ -1,11 +1,13 @@
<html>
<body>
-Reports 'native' methods whose names are either too short, too long, or do not follow
+Reports <b>native</b> methods whose names are either too short, too long, or do not follow
the specified regular expression pattern. Methods that override library
methods are ignored by this inspection.
+When this inspection is enabled, the <i>Instance method naming convention</i> and
+<i>'static' method naming convention</i> inspections will ignore <b>native</b> methods automatically.
<!-- tooltip end -->
<p>
-Use the fields below to specify minimum length, maximum length and regular expression expected for 'native' method names.
+Use the fields below to specify minimum length, maximum length and regular expression expected for <b>native</b> method names.
Specify <b>0</b> to not check the length of names. Regular expressions are in standard <b>java.util.regex</b> format.
<p>
<small>New in 14</small>
diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StaticMethodNamingConvention.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StaticMethodNamingConvention.html
index 37d12a6af08d..c0ced0ba01bd 100644
--- a/plugins/InspectionGadgets/src/inspectionDescriptions/StaticMethodNamingConvention.html
+++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StaticMethodNamingConvention.html
@@ -7,8 +7,6 @@ the specified regular expression pattern.
Use the fields below to specify minimum length, maximum length and regular expression expected for static method names.
Specify <b>0</b> to not check the length of names. Regular expressions are in standard <b>java.util.regex</b> format.
<p>
-Use the checkbox below to ignore native methods.
-<p>
</body>
</html> \ No newline at end of file
diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/TestMethodIsPublicVoidNoArg.html b/plugins/InspectionGadgets/src/inspectionDescriptions/TestMethodIsPublicVoidNoArg.html
index a31b39a1a710..fe227cae1fbc 100644
--- a/plugins/InspectionGadgets/src/inspectionDescriptions/TestMethodIsPublicVoidNoArg.html
+++ b/plugins/InspectionGadgets/src/inspectionDescriptions/TestMethodIsPublicVoidNoArg.html
@@ -1,8 +1,8 @@
<html>
<body>
-Reports any JUnit test methods whose names which are not declared
+Reports any JUnit test methods which are declared <b>static</b>, not declared
<b>public</b>, do not return
-<b>void</b>, or take arguments.
+<b>void</b>, or have parameters.
Such test methods are easy to create inadvertently, but will not be executed by
JUnit test runners.
<!-- tooltip end -->
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/abstraction/type_may_be_weakened/LocalClass.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/abstraction/type_may_be_weakened/LocalClass.after.java
new file mode 100644
index 000000000000..42653ac7af63
--- /dev/null
+++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/abstraction/type_may_be_weakened/LocalClass.after.java
@@ -0,0 +1,11 @@
+class LocalClass {
+
+ void foo() {
+ class A<T> {
+ void foo() {}
+ }
+ class B<T> extends A<T> {}
+ A<String> bb = new B();
+ bb.foo();
+ }
+} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/abstraction/type_may_be_weakened/LocalClass.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/abstraction/type_may_be_weakened/LocalClass.java
new file mode 100644
index 000000000000..1c905035b914
--- /dev/null
+++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/abstraction/type_may_be_weakened/LocalClass.java
@@ -0,0 +1,11 @@
+class LocalClass {
+
+ void foo() {
+ class A<T> {
+ void foo() {}
+ }
+ class B<T> extends A<T> {}
+ B<String> b<caret>b = new B();
+ bb.foo();
+ }
+} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/weaken_type/TypeMayBeWeakened.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/weaken_type/TypeMayBeWeakened.java
index 370aba53a19c..a134fcd8d9fb 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/weaken_type/TypeMayBeWeakened.java
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/weaken_type/TypeMayBeWeakened.java
@@ -162,4 +162,15 @@ class Test implements Foo2 {
interface Foo {
void bar();
}
-interface Foo2 extends Foo {} \ No newline at end of file
+interface Foo2 extends Foo {}
+class Helper {
+
+ void foo() {
+ class A<T> {
+ void foo() {}
+ }
+ class B<T> extends A<T> {}
+ B<String> <warning descr="Type of variable 'b' may be weakened to 'A'">b</warning> = new B();
+ b.foo();
+ }
+} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/equals_with_itself/EqualsWithItself.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/equals_with_itself/EqualsWithItself.java
new file mode 100644
index 000000000000..03347da345a5
--- /dev/null
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/equals_with_itself/EqualsWithItself.java
@@ -0,0 +1,23 @@
+class EqualsWithItself {
+
+ boolean foo(Object o) {
+ return o.<warning descr="Identical qualifier and argument to 'equals()' call">equals</warning>(((o)));
+ }
+
+ boolean withGetter() {
+ return getValue().<warning descr="Identical qualifier and argument to 'equals()' call">equals</warning>(getValue());
+ }
+
+ boolean withMethodCall() {
+ return build().equals(build());
+ }
+
+ private Integer value = 1;
+ public Integer getValue() {
+ return value;
+ }
+
+ public Object build() {
+ return new Object();
+ }
+} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/junit/TestCaseWithNoTestMethodsInspection.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/junit/TestCaseWithNoTestMethodsInspection.java
deleted file mode 100644
index f2f0afea3a7c..000000000000
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/junit/TestCaseWithNoTestMethodsInspection.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.siyeh.igtest.junit;
-
-import junit.framework.TestCase;
-
-public class TestCaseWithNoTestMethodsInspection extends TestCase
-{
- public TestCaseWithNoTestMethodsInspection()
- {
- }
-
- public void teardown()
- {
-
- }
-}
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/junit/junit3_method_naming_convention/JUnit3MethodNamingConvention.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/junit/junit3_method_naming_convention/JUnit3MethodNamingConvention.java
new file mode 100644
index 000000000000..fbe2e70e0945
--- /dev/null
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/junit/junit3_method_naming_convention/JUnit3MethodNamingConvention.java
@@ -0,0 +1,10 @@
+public class JUnit3MethodNamingConvention extends junit.framework.TestCase {
+
+ public void <warning descr="JUnit 3 test method name 'testA' is too short (5 < 8)">testA</warning>() {}
+
+ public void <warning descr="JUnit 3 test method name 'testAbcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz' is too long (82 > 64)">testAbcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz</warning>() {}
+
+ public void <warning descr="JUnit 3 test method name 'testGiveMeMore$$$' doesn't match regex 'test[A-Za-z_\d]*'">testGiveMeMore$$$</warning>() {}
+
+ public void test_me_properly() {}
+} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/junit/junit3_style_test_method_in_junit4_class/BeforeAnnotationUsed.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/junit/junit3_style_test_method_in_junit4_class/BeforeAnnotationUsed.java
new file mode 100644
index 000000000000..6ef566f99035
--- /dev/null
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/junit/junit3_style_test_method_in_junit4_class/BeforeAnnotationUsed.java
@@ -0,0 +1,9 @@
+import org.junit.Before;
+
+public class BeforeAnnotationUsed {
+
+ @Before
+ public void before() {}
+
+ public void <warning descr="Old style JUnit test method 'testOldStyle()' in JUnit 4 class">testOldStyle</warning>() {}
+} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/junit/junit3_style_test_method_in_junit4_class/JUnit3StyleTestMethodInJUnit4Class.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/junit/junit3_style_test_method_in_junit4_class/JUnit3StyleTestMethodInJUnit4Class.java
new file mode 100644
index 000000000000..e5df9e6d40ba
--- /dev/null
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/junit/junit3_style_test_method_in_junit4_class/JUnit3StyleTestMethodInJUnit4Class.java
@@ -0,0 +1,10 @@
+import org.junit.Test;
+
+public class JUnit3StyleTestMethodInJUnit4Class {
+
+ @Test
+ public void junit4Test() {
+ }
+
+ public void <warning descr="Old style JUnit test method 'testJUnit3()' in JUnit 4 class">testJUnit3</warning>() {}
+} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/junit/junit4_method_naming_convention/JUnit4MethodNamingConvention.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/junit/junit4_method_naming_convention/JUnit4MethodNamingConvention.java
new file mode 100644
index 000000000000..69379a9abb87
--- /dev/null
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/junit/junit4_method_naming_convention/JUnit4MethodNamingConvention.java
@@ -0,0 +1,16 @@
+import org.junit.Test;
+
+public class JUnit4MethodNamingConvention {
+
+ @Test
+ public void <warning descr="JUnit 4 test method name 'a' is too short (1 < 4)">a</warning>() {}
+
+ @Test
+ public void <warning descr="JUnit 4 test method name 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz' is too long (78 > 64)">abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz</warning>() {}
+
+ @Test
+ public void <warning descr="JUnit 4 test method name 'more$$$' doesn't match regex '[a-z][A-Za-z_\d]*'">more$$$</warning>() {}
+
+ @Test
+ public void assure_foo_is_never_null() {}
+} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/junit/test_case_with_no_test_methods/TestCaseWithNoTestMethods.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/junit/test_case_with_no_test_methods/TestCaseWithNoTestMethods.java
new file mode 100644
index 000000000000..559dcce72720
--- /dev/null
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/junit/test_case_with_no_test_methods/TestCaseWithNoTestMethods.java
@@ -0,0 +1,19 @@
+public class <warning descr="JUnit test case 'TestCaseWithNoTestMethods' has no tests">TestCaseWithNoTestMethods</warning> extends junit.framework.TestCase {
+
+ TestCaseWithNoTestMethods() {}
+
+ public int testOne() {
+ return 1;
+ }
+
+ public static void testTwo() {}
+ void testThree() {}
+ public void testFour(int i) {}
+
+ public void setUp() throws Exception {
+ super.setUp();
+ }
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/junit/test_method_is_public_void_no_arg/JUnit3TestMethodIsPublicVoidNoArg.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/junit/test_method_is_public_void_no_arg/JUnit3TestMethodIsPublicVoidNoArg.java
new file mode 100644
index 000000000000..68a5df1305f6
--- /dev/null
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/junit/test_method_is_public_void_no_arg/JUnit3TestMethodIsPublicVoidNoArg.java
@@ -0,0 +1,16 @@
+public class JUnit3TestMethodIsPublicVoidNoArg extends junit.framework.TestCase {
+
+ public JUnit3TestMethodIsPublicVoidNoArg() {}
+
+ void <warning descr="Test method 'testOne()' is not declared 'public void'">testOne</warning>() {}
+
+ public int <warning descr="Test method 'testTwo()' is not declared 'public void'">testTwo</warning>() {
+ return 2;
+ }
+
+ public static void <warning descr="Test method 'testThree()' should not be 'static'">testThree</warning>() {}
+
+ public void <warning descr="Test method 'testFour()' should probably not have parameters">testFour</warning>(int i) {}
+
+ public void testFive() {}
+} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/junit/test_method_is_public_void_no_arg/JUnit4TestMethodIsPublicVoidNoArg.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/junit/test_method_is_public_void_no_arg/JUnit4TestMethodIsPublicVoidNoArg.java
new file mode 100644
index 000000000000..8641acb3b49e
--- /dev/null
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/junit/test_method_is_public_void_no_arg/JUnit4TestMethodIsPublicVoidNoArg.java
@@ -0,0 +1,24 @@
+import org.junit.Test;
+
+public class JUnit4TestMethodIsPublicVoidNoArg {
+
+ @Test
+ JUnit4TestMethodIsPublicVoidNoArg() {}
+
+ @Test
+ void <warning descr="Test method 'testOne()' is not declared 'public void'">testOne</warning>() {}
+
+ @Test
+ public int <warning descr="Test method 'testTwo()' is not declared 'public void'">testTwo</warning>() {
+ return 2;
+ }
+
+ @Test
+ public static void <warning descr="Test method 'testThree()' should not be 'static'">testThree</warning>() {}
+
+ @Test
+ public void <warning descr="Test method 'testFour()' should probably not have parameters">testFour</warning>(int i) {}
+
+ @Test
+ public void testFive() {}
+} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/if_switch/IfCanBeSwitch.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/if_switch/IfCanBeSwitch.java
index 7bfc8aa08ff0..a0456798059d 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/if_switch/IfCanBeSwitch.java
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/if_switch/IfCanBeSwitch.java
@@ -2,15 +2,15 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
class IfCanBeSwitch {
void m1(int i) { // ok
- if (i == 0) System.out.println("zero"); else if (i == 1) System.out.println("one"); else System.out.println("many");
+ <warning descr="'if' statement replaceable with 'switch' statement">if</warning> (i == 0) System.out.println("zero"); else if (i == 1) System.out.println("one"); else System.out.println("many");
}
void m1(char c) { // ok
- if (c == '0') System.out.println("zero"); else if (c == '1') System.out.println("one"); else System.out.println("many");
+ <warning descr="'if' statement replaceable with 'switch' statement">if</warning> (c == '0') System.out.println("zero"); else if (c == '1') System.out.println("one"); else System.out.println("many");
}
void m1(byte i) { // ok
- if (i == (byte)0) System.out.println("zero"); else if (i == (byte)1) System.out.println("one"); else System.out.println("many");
+ <warning descr="'if' statement replaceable with 'switch' statement">if</warning> (i == (byte)0) System.out.println("zero"); else if (i == (byte)1) System.out.println("one"); else System.out.println("many");
}
void m2(int i) { // bad, long literals
@@ -23,7 +23,7 @@ class IfCanBeSwitch {
void polyadic() {
String s = null;
- if (s.equals("asdf") || s.equals("addd") || s.equals("lkjh")) {
+ <warning descr="'if' statement replaceable with 'switch' statement">if</warning> (s.equals("asdf") || s.equals("addd") || s.equals("lkjh")) {
System.out.println("asdf");
} else if (s.equals("null")) {
@@ -59,14 +59,14 @@ class IfCanBeSwitch {
}
void nullSafe(String earth) {
- if (earth.equals("foo")) {
+ <warning descr="'if' statement replaceable with 'switch' statement">if</warning> (earth.equals("foo")) {
} else if ("bar".equals(earth)) {
} else {
}
}
void nullSafe2(@NotNull String narf) {
- if ("foo".equals((narf))) {
+ <warning descr="'if' statement replaceable with 'switch' statement">if</warning> ("foo".equals((narf))) {
// do this
} else if ("bar".equals(narf)){
// do that
@@ -75,4 +75,21 @@ class IfCanBeSwitch {
// do something else.
}
}
+
+ Num num;
+ enum Num {
+ ONE, TWO
+ }
+ Num getNum() {
+ return num;
+ }
+ void ifWithGetterToSwitch() {
+ <warning descr="'if' statement replaceable with 'switch' statement">if</warning> (getNum() == Num.ONE) {
+ System.out.println(1);
+ } else if (getNum() == Num.TWO) {
+ System.out.println(2);
+ } else {
+ System.out.println("-");
+ }
+ }
} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/if_switch/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/if_switch/expected.xml
deleted file mode 100644
index e56ebb574747..000000000000
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/if_switch/expected.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<problems>
- <problem>
- <file>IfCanBeSwitch.java</file>
- <line>5</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">'if' replaceable with 'switch'</problem_class>
- <description>&lt;code&gt;if&lt;/code&gt; statement replaceable with 'switch' statement #loc</description>
- </problem>
-
- <problem>
- <file>IfCanBeSwitch.java</file>
- <line>9</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">'if' replaceable with 'switch'</problem_class>
- <description>&lt;code&gt;if&lt;/code&gt; statement replaceable with 'switch' statement #loc</description>
- </problem>
-
- <problem>
- <file>IfCanBeSwitch.java</file>
- <line>13</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">'if' replaceable with 'switch'</problem_class>
- <description>&lt;code&gt;if&lt;/code&gt; statement replaceable with 'switch' statement #loc</description>
- </problem>
-
- <problem>
- <file>IfCanBeSwitch.java</file>
- <line>26</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">'if' replaceable with 'switch'</problem_class>
- <description>&lt;code&gt;if&lt;/code&gt; statement replaceable with 'switch' statement #loc</description>
- </problem>
-
- <problem>
- <file>IfCanBeSwitch.java</file>
- <line>62</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">'if' replaceable with 'switch'</problem_class>
- <description>&lt;code&gt;if&lt;/code&gt; statement replaceable with 'switch' statement #loc</description>
- </problem>
-
- <problem>
- <file>IfCanBeSwitch.java</file>
- <line>69</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">'if' replaceable with 'switch'</problem_class>
- <description>&lt;code&gt;if&lt;/code&gt; statement replaceable with 'switch' statement #loc</description>
- </problem>
-</problems> \ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/native_method_naming_convention/NativeMethodNamingConvention.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/native_method_naming_convention/NativeMethodNamingConvention.java
index 9f39c4ceb884..9b8a8e66d289 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/native_method_naming_convention/NativeMethodNamingConvention.java
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/native_method_naming_convention/NativeMethodNamingConvention.java
@@ -28,4 +28,6 @@ public class NativeMethodNamingConvention implements Runnable
public native void run();
private void a() {}
+
+ public static native void <warning descr="'native' method name 'b' is too short">b</warning>();
}
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/numeric/pointless_arithmetic_expression/PointlessArithmeticExpression.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/numeric/pointless_arithmetic_expression/PointlessArithmeticExpression.java
index 4ba7a97033ad..9a10262e3148 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/numeric/pointless_arithmetic_expression/PointlessArithmeticExpression.java
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/numeric/pointless_arithmetic_expression/PointlessArithmeticExpression.java
@@ -1,5 +1,7 @@
package com.siyeh.igtest.numeric.pointless_arithmetic_expression;
+import java.util.Random;
+
public class PointlessArithmeticExpression
{
private static final int ZERO_CONSTANT = 0;
@@ -8,11 +10,11 @@ public class PointlessArithmeticExpression
public static void main(String[] args)
{
final int i = 2;
- final int j = i + 0;
+ final int j = <warning descr="'i + 0' can be replaced with 'i'">i + 0</warning>;
System.out.println(j);
- int k = 0+j;
+ int k = <warning descr="'0+j' can be replaced with 'j'">0+j</warning>;
System.out.println(k);
- k = j - 0;
+ k = <warning descr="'j - 0' can be replaced with 'j'">j - 0</warning>;
System.out.println(k);
k = 0 - j;
System.out.println(k);
@@ -20,11 +22,11 @@ public class PointlessArithmeticExpression
System.out.println(k);
k = j * ONE_CONSTANT;
System.out.println(k);
- k = j / 1;
+ k = <warning descr="'j / 1' can be replaced with 'j'">j / 1</warning>;
System.out.println(k);
String string = "foo" + 0;
- k = j%1;
+ k = <warning descr="'j%1' can be replaced with '0'">j%1</warning>;
System.out.println(k);
if(k<=Integer.MAX_VALUE)
@@ -90,9 +92,9 @@ public class PointlessArithmeticExpression
}
void more(int i) {
- System.out.println(i / i);
- System.out.println(i - i);
- System.out.println(i % i);
+ System.out.println(<warning descr="'i / i' can be replaced with '1'">i / i</warning>);
+ System.out.println(<warning descr="'i - i' can be replaced with '0'">i - i</warning>);
+ System.out.println(<warning descr="'i % i' can be replaced with '0'">i % i</warning>);
}
}
class Main {
@@ -111,18 +113,29 @@ class Main {
return (CONST + (new Main(5).i) * 8) - (Main.CONST + new Main(5).i * (8));
}
- int one = 5/5;
+ int one = <warning descr="'5/5' can be replaced with '1'">5/5</warning>;
}
class Expanded {{
- int m = 1/**/ - (byte)0 - 9; // warn
- int j = 8 * 0 * 8;
- int k = 1 + /*a*/0 +/**/ 9;
- byte l = (byte) (1L - 1L);
+ int m = <warning descr="'1/**/ - (byte)0 - 9' can be replaced with '1/**/ - 9'">1/**/ - (byte)0 - 9</warning>; // warn
+ int j = <warning descr="'8 * 0 * 8' can be replaced with '0'">8 * 0 * 8</warning>;
+ int k = <warning descr="'1 + /*a*/0 +/**/ 9' can be replaced with '1 + /*a*//**/ 9'">1 + /*a*/0 +/**/ 9</warning>;
+ byte l = (byte) (<warning descr="'1L - 1L' can be replaced with '0L'">1L - 1L</warning>);
byte u = 1;
- int z = 2 / 1 / 1;
- System.out.println(u * 1);
- long g = 8L / 8L;
- long h = 9L * 0L;
- int a = 8 * 0 * 8 * ; // don't warn
+ int z = <warning descr="'2 / 1 / 1' can be replaced with '2 / 1'">2 / 1 / 1</warning>;
+ System.out.println(<warning descr="'u * 1' can be replaced with 'u'">u * 1</warning>);
+ long g = <warning descr="'8L / 8L' can be replaced with '1L'">8L / 8L</warning>;
+ long h = <warning descr="'9L * 0L' can be replaced with '0L'">9L * 0L</warning>;
+ int a = 8 * 0 * 8 *<error descr="Expression expected"> </error>; // don't warn
int minus = 2 - 1 - 1;
-}} \ No newline at end of file
+ int div = 3 / 2 / 2;
+ int mod = 3 % 2 % 2;
+}}
+class SideEffects {
+ public static void main( String args[] ){
+ Random rand = new Random();
+ int array[] = {1, 2, 4};
+ int i = 1;
+ int b = array[i++] - array[i++];
+ System.out.println(rand.nextInt(1000) - rand.nextInt(1000));
+ }
+} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/numeric/pointless_arithmetic_expression/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/numeric/pointless_arithmetic_expression/expected.xml
deleted file mode 100644
index f6af12237ea0..000000000000
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/numeric/pointless_arithmetic_expression/expected.xml
+++ /dev/null
@@ -1,129 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<problems>
-
- <problem>
- <file>PointlessArithmeticExpression.java</file>
- <line>11</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Pointless arithmetic expression</problem_class>
- <description>&lt;code&gt;i + 0&lt;/code&gt; can be replaced with 'i' #loc</description>
- </problem>
-
- <problem>
- <file>PointlessArithmeticExpression.java</file>
- <line>13</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Pointless arithmetic expression</problem_class>
- <description>&lt;code&gt;0+j&lt;/code&gt; can be replaced with 'j' #loc</description>
- </problem>
-
- <problem>
- <file>PointlessArithmeticExpression.java</file>
- <line>15</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Pointless arithmetic expression</problem_class>
- <description>&lt;code&gt;j - 0&lt;/code&gt; can be replaced with 'j' #loc</description>
- </problem>
-
- <problem>
- <file>PointlessArithmeticExpression.java</file>
- <line>23</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Pointless arithmetic expression</problem_class>
- <description>&lt;code&gt;j / 1&lt;/code&gt; can be replaced with 'j' #loc</description>
- </problem>
-
- <problem>
- <file>PointlessArithmeticExpression.java</file>
- <line>27</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Pointless arithmetic expression</problem_class>
- <description>&lt;code&gt;j%1&lt;/code&gt; can be replaced with '0' #loc</description>
- </problem>
-
- <problem>
- <file>PointlessArithmeticExpression.java</file>
- <line>93</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Pointless arithmetic expression</problem_class>
- <description>&lt;code&gt;i / i&lt;/code&gt; can be replaced with '1' #loc</description>
- </problem>
-
- <problem>
- <file>PointlessArithmeticExpression.java</file>
- <line>94</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Pointless arithmetic expression</problem_class>
- <description>&lt;code&gt;i - i&lt;/code&gt; can be replaced with '0' #loc</description>
- </problem>
-
- <problem>
- <file>PointlessArithmeticExpression.java</file>
- <line>95</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Pointless arithmetic expression</problem_class>
- <description>&lt;code&gt;i % i&lt;/code&gt; can be replaced with '0' #loc</description>
- </problem>
-
- <problem>
- <file>PointlessArithmeticExpression.java</file>
- <line>111</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Pointless arithmetic expression</problem_class>
- <description>&lt;code&gt;(CONST + (new Main(5).i) * 8) - (Main.CONST + new Main(5).i * (8))&lt;/code&gt; can be replaced with '0' #loc</description>
- </problem>
-
- <problem>
- <file>PointlessArithmeticExpression.java</file>
- <line>114</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Pointless arithmetic expression</problem_class>
- <description>&lt;code&gt;5/5&lt;/code&gt; can be replaced with '1' #loc</description>
- </problem>
-
- <problem>
- <file>PointlessArithmeticExpression.java</file>
- <line>117</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Pointless arithmetic expression</problem_class>
- <description>&lt;code&gt;1/**/ - (byte)0 - 9&lt;/code&gt; can be replaced with '1/**/ - 9' #loc</description>
- </problem>
-
- <problem>
- <file>PointlessArithmeticExpression.java</file>
- <line>118</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Pointless arithmetic expression</problem_class>
- <description>&lt;code&gt;8 * 0 * 8&lt;/code&gt; can be replaced with '0' #loc</description>
- </problem>
-
- <problem>
- <file>PointlessArithmeticExpression.java</file>
- <line>119</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Pointless arithmetic expression</problem_class>
- <description>&lt;code&gt;1 + /*a*/0 +/**/ 9&lt;/code&gt; can be replaced with '1 + /*a*//**/ 9' #loc</description>
- </problem>
-
- <problem>
- <file>PointlessArithmeticExpression.java</file>
- <line>120</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Pointless arithmetic expression</problem_class>
- <description>&lt;code&gt;1L - 1L&lt;/code&gt; can be replaced with '0L' #loc</description>
- </problem>
-
- <problem>
- <file>PointlessArithmeticExpression.java</file>
- <line>122</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Pointless arithmetic expression</problem_class>
- <description>&lt;code&gt;2 / 1 / 1&lt;/code&gt; can be replaced with '2 / 1' #loc</description>
- </problem>
-
- <problem>
- <file>PointlessArithmeticExpression.java</file>
- <line>123</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Pointless arithmetic expression</problem_class>
- <description>&lt;code&gt;u * 1&lt;/code&gt; can be replaced with 'u' #loc</description>
- </problem>
-
- <problem>
- <file>PointlessArithmeticExpression.java</file>
- <line>124</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Pointless arithmetic expression</problem_class>
- <description>&lt;code&gt;8L / 8L&lt;/code&gt; can be replaced with '1L' #loc</description>
- </problem>
-
- <problem>
- <file>PointlessArithmeticExpression.java</file>
- <line>125</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Pointless arithmetic expression</problem_class>
- <description>&lt;code&gt;9L * 0L&lt;/code&gt; can be replaced with '0L' #loc</description>
- </problem>
-</problems> \ No newline at end of file
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/LightInspectionTestCase.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/LightInspectionTestCase.java
index d262e31333ba..951d14ad9f8b 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/LightInspectionTestCase.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/LightInspectionTestCase.java
@@ -109,15 +109,20 @@ public abstract class LightInspectionTestCase extends LightCodeInsightFixtureTes
lastWord = lastWord.substring(0, lastWord.length() - 10);
}
final int length = lastWord.length();
+ boolean upperCase = false;
for (int i = 0; i < length; i++) {
final char ch = lastWord.charAt(i);
if (Character.isUpperCase(ch)) {
- if (i != 0) {
- basePath.append('_');
+ if (!upperCase) {
+ upperCase = true;
+ if (i != 0) {
+ basePath.append('_');
+ }
}
basePath.append(Character.toLowerCase(ch));
}
else {
+ upperCase = false;
basePath.append(ch);
}
}
diff --git a/platform/platform-impl/src/com/intellij/ide/actionMacro/EditMacrosDialog.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/EqualsWithItselfInspectionTest.java
index 8b2c9acfaef5..868884ffa6db 100644
--- a/platform/platform-impl/src/com/intellij/ide/actionMacro/EditMacrosDialog.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/EqualsWithItselfInspectionTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,25 +13,22 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.intellij.ide.actionMacro;
+package com.siyeh.ig.bugs;
-import com.intellij.openapi.options.ex.SingleConfigurableEditor;
-import com.intellij.openapi.project.Project;
+import com.intellij.codeInspection.InspectionProfileEntry;
+import com.siyeh.ig.LightInspectionTestCase;
import org.jetbrains.annotations.Nullable;
/**
- * Created by IntelliJ IDEA.
- * User: max
- * Date: Jul 22, 2003
- * Time: 3:30:56 PM
- * To change this template use Options | File Templates.
+ * @author Bas Leijdekkers
*/
-public class EditMacrosDialog extends SingleConfigurableEditor {
- public EditMacrosDialog(@Nullable Project project) {
- super(project, new ActionMacroConfigurable());
- }
+public class EqualsWithItselfInspectionTest extends LightInspectionTestCase {
+
+ public void testEqualsWithItself() { doTest(); }
- protected String getDimensionServiceKey(){
- return "#com.intellij.ide.actionMacro.EditMacrosDialog";
+ @Nullable
+ @Override
+ protected InspectionProfileEntry getInspection() {
+ return new EqualsWithItselfInspection();
}
-}
+} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/abstraction/TypeMayBeWeakenedFixTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/abstraction/TypeMayBeWeakenedFixTest.java
index 58373f3a3955..d4b9ec3039bb 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/abstraction/TypeMayBeWeakenedFixTest.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/abstraction/TypeMayBeWeakenedFixTest.java
@@ -12,10 +12,13 @@ public class TypeMayBeWeakenedFixTest extends IGQuickFixesTestCase {
@Override
public void setUp() throws Exception {
super.setUp();
- myFixture.enableInspections(new TypeMayBeWeakenedInspection());
+ final TypeMayBeWeakenedInspection inspection = new TypeMayBeWeakenedInspection();
+ inspection.onlyWeakentoInterface = false;
+ myFixture.enableInspections(inspection);
myRelativePath = "abstraction/type_may_be_weakened";
}
public void testShorten() { doTest(InspectionGadgetsBundle.message("type.may.be.weakened.quickfix", "java.util.Collection")); }
+ public void testLocalClass() { doTest(InspectionGadgetsBundle.message("type.may.be.weakened.quickfix", "A")); }
}
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/junit/JUnit3MethodNamingConventionInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/junit/JUnit3MethodNamingConventionInspectionTest.java
new file mode 100644
index 000000000000..d71792bcbbc9
--- /dev/null
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/junit/JUnit3MethodNamingConventionInspectionTest.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.siyeh.ig.junit;
+
+import com.intellij.codeInspection.InspectionProfileEntry;
+import com.siyeh.ig.LightInspectionTestCase;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class JUnit3MethodNamingConventionInspectionTest extends LightInspectionTestCase {
+
+ public void testJUnit3MethodNamingConvention() { doTest(); }
+
+ @Nullable
+ @Override
+ protected InspectionProfileEntry getInspection() {
+ return new JUnit3MethodNamingConventionInspection();
+ }
+
+ @Override
+ protected String[] getEnvironmentClasses() {
+ return new String[] {
+ "package junit.framework;" +
+ "public abstract class TestCase {" +
+ " protected void setUp() throws Exception {}" +
+ " protected void tearDown() throws Exception {}" +
+ "}"
+ };
+ }
+}
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/junit/JUnit3StyleTestMethodInJUnit4ClassInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/junit/JUnit3StyleTestMethodInJUnit4ClassInspectionTest.java
new file mode 100644
index 000000000000..eb7e979f81e1
--- /dev/null
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/junit/JUnit3StyleTestMethodInJUnit4ClassInspectionTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.siyeh.ig.junit;
+
+import com.intellij.codeInspection.InspectionProfileEntry;
+import com.siyeh.ig.LightInspectionTestCase;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class JUnit3StyleTestMethodInJUnit4ClassInspectionTest extends LightInspectionTestCase {
+
+ public void testJUnit3StyleTestMethodInJUnit4Class() { doTest(); }
+ public void testBeforeAnnotationUsed() { doTest(); }
+
+ @Nullable
+ @Override
+ protected InspectionProfileEntry getInspection() {
+ return new JUnit3StyleTestMethodInJUnit4ClassInspection();
+ }
+
+ @Override
+ protected String[] getEnvironmentClasses() {
+ return new String[] {
+ "package org.junit;" +
+ "import java.lang.annotation.ElementType;" +
+ "import java.lang.annotation.Retention;" +
+ "import java.lang.annotation.RetentionPolicy;" +
+ "import java.lang.annotation.Target;" +
+ "@Retention(RetentionPolicy.RUNTIME)" +
+ "@Target({ElementType.METHOD})" +
+ "public @interface Before {}",
+ "package org.junit;" +
+ "import java.lang.annotation.ElementType;" +
+ "import java.lang.annotation.Retention;" +
+ "import java.lang.annotation.RetentionPolicy;" +
+ "import java.lang.annotation.Target;" +
+ "@Retention(RetentionPolicy.RUNTIME)" +
+ "@Target({ElementType.METHOD})" +
+ "public @interface Test {}"
+ };
+ }
+}
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/junit/JUnit4MethodNamingConventionInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/junit/JUnit4MethodNamingConventionInspectionTest.java
new file mode 100644
index 000000000000..bff20e9bd24a
--- /dev/null
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/junit/JUnit4MethodNamingConventionInspectionTest.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.siyeh.ig.junit;
+
+import com.intellij.codeInspection.InspectionProfileEntry;
+import com.siyeh.ig.LightInspectionTestCase;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class JUnit4MethodNamingConventionInspectionTest extends LightInspectionTestCase {
+
+ public void testJUnit4MethodNamingConvention() { doTest(); }
+
+ @Nullable
+ @Override
+ protected InspectionProfileEntry getInspection() {
+ return new JUnit4MethodNamingConventionInspection();
+ }
+
+ @Override
+ protected String[] getEnvironmentClasses() {
+ return new String[] {
+ "package org.junit;" +
+ "import java.lang.annotation.ElementType;" +
+ "import java.lang.annotation.Retention;" +
+ "import java.lang.annotation.RetentionPolicy;" +
+ "import java.lang.annotation.Target;" +
+ "@Retention(RetentionPolicy.RUNTIME)" +
+ "@Target({ElementType.METHOD})" +
+ "public @interface Test {}"
+ };
+ }
+} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/junit/TestCaseWithNoTestMethodsInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/junit/TestCaseWithNoTestMethodsInspectionTest.java
new file mode 100644
index 000000000000..e8566eacdcd0
--- /dev/null
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/junit/TestCaseWithNoTestMethodsInspectionTest.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.siyeh.ig.junit;
+
+import com.intellij.codeInspection.InspectionProfileEntry;
+import com.siyeh.ig.LightInspectionTestCase;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class TestCaseWithNoTestMethodsInspectionTest extends LightInspectionTestCase {
+
+ public void testTestCaseWithNoTestMethods() { doTest(); }
+
+ @Nullable
+ @Override
+ protected InspectionProfileEntry getInspection() {
+ return new TestCaseWithNoTestMethodsInspection();
+ }
+
+ @Override
+ protected String[] getEnvironmentClasses() {
+ return new String[] {
+ "package junit.framework;" +
+ "public abstract class TestCase {" +
+ " protected void setUp() throws Exception {}" +
+ " protected void tearDown() throws Exception {}" +
+ "}"
+ };
+ }
+}
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/junit/TestMethodIsPublicVoidNoArgInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/junit/TestMethodIsPublicVoidNoArgInspectionTest.java
new file mode 100644
index 000000000000..72406191f2b1
--- /dev/null
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/junit/TestMethodIsPublicVoidNoArgInspectionTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.siyeh.ig.junit;
+
+import com.intellij.codeInspection.InspectionProfileEntry;
+import com.siyeh.ig.LightInspectionTestCase;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class TestMethodIsPublicVoidNoArgInspectionTest extends LightInspectionTestCase {
+
+ public void testJUnit3TestMethodIsPublicVoidNoArg() { doTest(); }
+ public void testJUnit4TestMethodIsPublicVoidNoArg() { doTest(); }
+
+ @Nullable
+ @Override
+ protected InspectionProfileEntry getInspection() {
+ return new TestMethodIsPublicVoidNoArgInspection();
+ }
+
+ @Override
+ protected String[] getEnvironmentClasses() {
+ return new String[] {
+ "package org.junit; " +
+ "public @interface Test {\n" +
+ " java.lang.Class<? extends java.lang.Throwable> expected() default org.junit.Test.None.class;" +
+ "}",
+ "package junit.framework;" +
+ "public abstract class TestCase {}"};
+ }
+}
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/migration/IfCanBeSwitchInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/migration/IfCanBeSwitchInspectionTest.java
index 9b1f2574dd77..a13e61bfd234 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/migration/IfCanBeSwitchInspectionTest.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/migration/IfCanBeSwitchInspectionTest.java
@@ -15,25 +15,36 @@
*/
package com.siyeh.ig.migration;
+import com.intellij.codeInspection.InspectionProfileEntry;
import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.testFramework.IdeaTestUtil;
+import com.intellij.testFramework.LightProjectDescriptor;
import com.siyeh.ig.IGInspectionTestCase;
+import com.siyeh.ig.LightInspectionTestCase;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
-public class IfCanBeSwitchInspectionTest extends IGInspectionTestCase {
+public class IfCanBeSwitchInspectionTest extends LightInspectionTestCase {
- @Override
- protected Sdk getTestProjectSdk() {
- LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.JDK_1_7);
- return IdeaTestUtil.getMockJdk17();
+ public void testIfCanBeSwitch() throws Exception {
+ doTest();
}
- public void test() throws Exception {
+ @Nullable
+ @Override
+ protected InspectionProfileEntry getInspection() {
final IfCanBeSwitchInspection inspection = new IfCanBeSwitchInspection();
inspection.suggestIntSwitches = true;
+ inspection.suggestEnumSwitches = true;
inspection.setOnlySuggestNullSafe(true);
- doTest("com/siyeh/igtest/migration/if_switch", new LocalInspectionToolWrapper(inspection));
+ return inspection;
+ }
+
+ @Override
+ protected String getBasePath() {
+ return "/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/if_switch";
}
}
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/naming/InstanceMethodNamingConventionInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/naming/InstanceMethodNamingConventionInspectionTest.java
index e408509b51d5..6479236acbb3 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/naming/InstanceMethodNamingConventionInspectionTest.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/naming/InstanceMethodNamingConventionInspectionTest.java
@@ -24,6 +24,14 @@ import com.siyeh.ig.LightInspectionTestCase;
public class InstanceMethodNamingConventionInspectionTest extends LightInspectionTestCase {
@Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ final NativeMethodNamingConventionInspection inspection = new NativeMethodNamingConventionInspection();
+ inspection.m_minLength = 0;
+ myFixture.enableInspections(inspection);
+ }
+
+ @Override
protected InspectionProfileEntry getInspection() {
return new InstanceMethodNamingConventionInspection();
}
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/naming/com/siyeh/ig/naming/OverloadedVarargsMethodInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/naming/OverloadedVarargsMethodInspectionTest.java
index 2ca586feef18..cc20bb3cc8fb 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/naming/com/siyeh/ig/naming/OverloadedVarargsMethodInspectionTest.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/naming/OverloadedVarargsMethodInspectionTest.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.siyeh.ig.naming.com.siyeh.ig.naming;
+package com.siyeh.ig.naming;
import com.intellij.codeInspection.InspectionProfileEntry;
import com.siyeh.ig.LightInspectionTestCase;
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/naming/StaticMethodNamingConventionInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/naming/StaticMethodNamingConventionInspectionTest.java
index 53e2b6a37f87..5c1eb29822c9 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/naming/StaticMethodNamingConventionInspectionTest.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/naming/StaticMethodNamingConventionInspectionTest.java
@@ -24,6 +24,14 @@ import com.siyeh.ig.LightInspectionTestCase;
public class StaticMethodNamingConventionInspectionTest extends LightInspectionTestCase {
@Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ final NativeMethodNamingConventionInspection inspection = new NativeMethodNamingConventionInspection();
+ inspection.m_minLength = 0;
+ myFixture.enableInspections(inspection);
+ }
+
+ @Override
protected InspectionProfileEntry getInspection() {
return new StaticMethodNamingConventionInspection();
}
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/numeric/PointlessArithmeticExpressionInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/numeric/PointlessArithmeticExpressionInspectionTest.java
index 48914c37605f..58bbf452bd9c 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/numeric/PointlessArithmeticExpressionInspectionTest.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/numeric/PointlessArithmeticExpressionInspectionTest.java
@@ -1,11 +1,18 @@
package com.siyeh.ig.numeric;
-import com.siyeh.ig.IGInspectionTestCase;
+import com.intellij.codeInspection.InspectionProfileEntry;
+import com.siyeh.ig.LightInspectionTestCase;
+import org.jetbrains.annotations.Nullable;
-public class PointlessArithmeticExpressionInspectionTest extends IGInspectionTestCase {
+public class PointlessArithmeticExpressionInspectionTest extends LightInspectionTestCase {
- public void test() throws Exception {
- doTest("com/siyeh/igtest/numeric/pointless_arithmetic_expression",
- new PointlessArithmeticExpressionInspection());
+ public void testPointlessArithmeticExpression() {
+ doTest();
+ }
+
+ @Nullable
+ @Override
+ protected InspectionProfileEntry getInspection() {
+ return new PointlessArithmeticExpressionInspection();
}
} \ No newline at end of file
diff --git a/plugins/ShortcutPromoter/src/com/intellij/promoter/ShortcutPromoterManager.java b/plugins/ShortcutPromoter/src/com/intellij/promoter/ShortcutPromoterManager.java
index 02356825404b..227d96245080 100644
--- a/plugins/ShortcutPromoter/src/com/intellij/promoter/ShortcutPromoterManager.java
+++ b/plugins/ShortcutPromoter/src/com/intellij/promoter/ShortcutPromoterManager.java
@@ -15,6 +15,7 @@ import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.io.File;
import java.util.HashMap;
+import java.util.LinkedHashMap;
/**
* @author Konstantin Bulenkov
@@ -29,7 +30,7 @@ import java.util.HashMap;
)
public class ShortcutPromoterManager implements ApplicationComponent, AnActionListener, ExportableApplicationComponent,
PersistentStateComponent<Element> {
- private final HashMap<String, PromoterState> myState = new HashMap<String, PromoterState>();
+ private final HashMap<String, PromoterState> myState = new LinkedHashMap<String, PromoterState>();
private final HashMap<String, ShortcutPromoterEP> myExtensions = new HashMap<String, ShortcutPromoterEP>();
@Override
@@ -96,6 +97,10 @@ public class ShortcutPromoterManager implements ApplicationComponent, AnActionLi
@Nullable
@Override
public Element getState() {
+ if (myState.isEmpty()) {
+ return null;
+ }
+
final Element actions = new Element("actions");
for (String id : myState.keySet()) {
final Element action = new Element("action");
diff --git a/plugins/ant/src/com/intellij/lang/ant/config/execution/AntRunner.java b/plugins/ant/src/com/intellij/lang/ant/config/execution/AntRunner.java
index 1398718e293a..d66e041f1f16 100644
--- a/plugins/ant/src/com/intellij/lang/ant/config/execution/AntRunner.java
+++ b/plugins/ant/src/com/intellij/lang/ant/config/execution/AntRunner.java
@@ -23,7 +23,6 @@ import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.runners.GenericProgramRunner;
import com.intellij.execution.ui.RunContentDescriptor;
import com.intellij.openapi.fileEditor.FileDocumentManager;
-import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -32,10 +31,7 @@ public class AntRunner extends GenericProgramRunner {
@Nullable
@Override
- protected RunContentDescriptor doExecute(@NotNull Project project,
- @NotNull RunProfileState state,
- @Nullable RunContentDescriptor contentToReuse,
- @NotNull ExecutionEnvironment environment) throws ExecutionException {
+ protected RunContentDescriptor doExecute(@NotNull RunProfileState state, @NotNull ExecutionEnvironment environment) throws ExecutionException {
FileDocumentManager.getInstance().saveAllDocuments();
state.execute(environment.getExecutor(), this);
return null;
diff --git a/plugins/ant/src/com/intellij/lang/ant/config/impl/AntToolWindowFactory.java b/plugins/ant/src/com/intellij/lang/ant/config/impl/AntToolWindowFactory.java
index 02d8f0696e7f..1a75326f2959 100644
--- a/plugins/ant/src/com/intellij/lang/ant/config/impl/AntToolWindowFactory.java
+++ b/plugins/ant/src/com/intellij/lang/ant/config/impl/AntToolWindowFactory.java
@@ -16,6 +16,7 @@
package com.intellij.lang.ant.config.impl;
import com.intellij.lang.ant.config.explorer.AntExplorer;
+import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.wm.ToolWindow;
@@ -27,7 +28,7 @@ import org.jetbrains.annotations.NotNull;
/**
* @author yole
*/
-public class AntToolWindowFactory implements ToolWindowFactory {
+public class AntToolWindowFactory implements ToolWindowFactory, DumbAware{
@Override
public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) {
AntExplorer explorer = new AntExplorer(project);
diff --git a/plugins/copyright/src/META-INF/plugin.xml b/plugins/copyright/src/META-INF/plugin.xml
index 8d0c4b038d85..594c28e20966 100644
--- a/plugins/copyright/src/META-INF/plugin.xml
+++ b/plugins/copyright/src/META-INF/plugin.xml
@@ -11,7 +11,7 @@
<depends optional="true" config-file="java.xml">com.intellij.modules.java</depends>
<extensions defaultExtensionNs="com.intellij">
- <projectConfigurable groupId="editor" dynamic="true" displayName="Copyright" instance="com.maddyhome.idea.copyright.ui.CopyrightProjectConfigurable"/>
+ <projectConfigurable groupId="editor" groupWeight="110" dynamic="true" displayName="Copyright" instance="com.maddyhome.idea.copyright.ui.CopyrightProjectConfigurable"/>
<errorHandler implementation="com.intellij.diagnostic.ITNReporter"/>
<checkinHandlerFactory implementation="com.maddyhome.idea.copyright.actions.UpdateCopyrightCheckinHandlerFactory"/>
<applicationService serviceInterface="com.maddyhome.idea.copyright.util.FileTypeUtil"
diff --git a/plugins/copyright/src/com/maddyhome/idea/copyright/ui/CopyrightProfilesPanel.java b/plugins/copyright/src/com/maddyhome/idea/copyright/ui/CopyrightProfilesPanel.java
index 20ef5847f156..bdbe32db040b 100644
--- a/plugins/copyright/src/com/maddyhome/idea/copyright/ui/CopyrightProfilesPanel.java
+++ b/plugins/copyright/src/com/maddyhome/idea/copyright/ui/CopyrightProfilesPanel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,12 +16,13 @@
package com.maddyhome.idea.copyright.ui;
-import com.intellij.ide.actions.OpenProjectFileChooserDescriptor;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonShortcuts;
import com.intellij.openapi.actionSystem.CustomShortcutSet;
import com.intellij.openapi.fileChooser.FileChooser;
+import com.intellij.openapi.fileChooser.FileChooserDescriptor;
+import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SearchableConfigurable;
@@ -33,6 +34,7 @@ import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.PopupStep;
import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
+import com.intellij.openapi.util.Condition;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Consumer;
@@ -200,34 +202,26 @@ public class CopyrightProfilesPanel extends MasterDetailsComponent implements Se
result.add(new AnAction("Import", "Import", PlatformIcons.IMPORT_ICON) {
@Override
public void actionPerformed(AnActionEvent event) {
- final OpenProjectFileChooserDescriptor descriptor = new OpenProjectFileChooserDescriptor(true) {
- @Override
- public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) {
- return super.isFileVisible(file, showHiddenFiles) || canContainCopyright(file);
- }
-
- @Override
- public boolean isFileSelectable(VirtualFile file) {
- return super.isFileSelectable(file) || canContainCopyright(file);
- }
-
- private boolean canContainCopyright(VirtualFile file) {
- return !file.isDirectory() && (file.getFileType() == StdFileTypes.IDEA_MODULE || file.getFileType() == StdFileTypes.XML);
- }
- };
- descriptor.setTitle("Choose file containing copyright notice");
+ FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor()
+ .withFileFilter(new Condition<VirtualFile>() {
+ @Override
+ public boolean value(VirtualFile file) {
+ return file.getFileType() == StdFileTypes.IDEA_MODULE || file.getFileType() == StdFileTypes.XML;
+ }
+ })
+ .withTitle("Choose file containing copyright notice");
FileChooser.chooseFile(descriptor, myProject, null, new Consumer<VirtualFile>() {
@Override
public void consume(VirtualFile file) {
- final List<CopyrightProfile> copyrightProfiles = ExternalOptionHelper.loadOptions(VfsUtilCore.virtualToIoFile(file));
- if (copyrightProfiles == null) return;
- if (!copyrightProfiles.isEmpty()) {
- if (copyrightProfiles.size() == 1) {
- importProfile(copyrightProfiles.get(0));
+ final List<CopyrightProfile> profiles = ExternalOptionHelper.loadOptions(VfsUtilCore.virtualToIoFile(file));
+ if (profiles == null) return;
+ if (!profiles.isEmpty()) {
+ if (profiles.size() == 1) {
+ importProfile(profiles.get(0));
}
else {
JBPopupFactory.getInstance()
- .createListPopup(new BaseListPopupStep<CopyrightProfile>("Choose profile to import", copyrightProfiles) {
+ .createListPopup(new BaseListPopupStep<CopyrightProfile>("Choose profile to import", profiles) {
@Override
public PopupStep onChosen(final CopyrightProfile selectedValue, boolean finalChoice) {
return doFinalStep(new Runnable() {
@@ -243,7 +237,8 @@ public class CopyrightProfilesPanel extends MasterDetailsComponent implements Se
public String getTextFor(CopyrightProfile value) {
return value.getName();
}
- }).showUnderneathOf(myNorthPanel);
+ })
+ .showUnderneathOf(myNorthPanel);
}
}
else {
diff --git a/plugins/cvs/javacvs-src/org/netbeans/lib/cvsclient/ConnectionStreams.java b/plugins/cvs/javacvs-src/org/netbeans/lib/cvsclient/ConnectionStreams.java
index d5e89f20dbb3..5484909b35f0 100644
--- a/plugins/cvs/javacvs-src/org/netbeans/lib/cvsclient/ConnectionStreams.java
+++ b/plugins/cvs/javacvs-src/org/netbeans/lib/cvsclient/ConnectionStreams.java
@@ -17,7 +17,6 @@ import org.netbeans.lib.cvsclient.file.IReaderFactory;
import org.netbeans.lib.cvsclient.file.IWriterFactory;
import org.netbeans.lib.cvsclient.io.IStreamLogger;
import org.netbeans.lib.cvsclient.util.BugLog;
-import org.jetbrains.annotations.NonNls;
import java.io.*;
import java.util.zip.Deflater;
@@ -43,8 +42,6 @@ public final class ConnectionStreams
private OutputStream outputStream;
private DeflaterOutputStream deflaterOutputStream;
private final String myCharset;
- @NonNls private static final String UNTIL_HERE_THE_CONTENT_IS_GZIPPED_MESSAGE = "@until here the content is gzipped@";
- @NonNls private static final String FROM_NOW_ON_THE_CONTENT_IS_GZIPPED_MESSAGE = "@from now on the content is gzipped@";
// Setup ==================================================================
@@ -111,8 +108,6 @@ public final class ConnectionStreams
loggedWriter.flush();
if (deflaterOutputStream != null) {
deflaterOutputStream.finish();
-
- println(UNTIL_HERE_THE_CONTENT_IS_GZIPPED_MESSAGE, streamLogger.getOutputLogStream());
}
loggedOutputStream.flush();
}
@@ -155,9 +150,6 @@ public final class ConnectionStreams
loggedWriter.flush();
loggedOutputStream.flush();
- println(FROM_NOW_ON_THE_CONTENT_IS_GZIPPED_MESSAGE, streamLogger.getInputLogStream());
- println(FROM_NOW_ON_THE_CONTENT_IS_GZIPPED_MESSAGE, streamLogger.getOutputLogStream());
-
deflaterOutputStream = new DeflaterOutputStream(connection.getOutputStream(), new Deflater(6));
setOutputStream(deflaterOutputStream);
@@ -179,15 +171,4 @@ public final class ConnectionStreams
this.loggedOutputStream = streamLogger.createLoggingOutputStream(outputStream);
this.loggedWriter = createWriter(this.loggedOutputStream);
}
-
- private void println(String text, OutputStream outputStream) throws IOException {
- final OutputStreamWriter writerNoSpecialEncoding = new OutputStreamWriter(outputStream);
- println(text, writerNoSpecialEncoding);
- writerNoSpecialEncoding.flush();
- }
-
- private void println(String text, Writer writer) throws IOException {
- writer.write(text);
- writer.write('\n');
- }
}
diff --git a/plugins/devkit/resources/META-INF/plugin.xml b/plugins/devkit/resources/META-INF/plugin.xml
index 0a9501ebef94..ef3688448fda 100644
--- a/plugins/devkit/resources/META-INF/plugin.xml
+++ b/plugins/devkit/resources/META-INF/plugin.xml
@@ -152,6 +152,7 @@
implementationClass="org.jetbrains.idea.devkit.navigation.DescriptionTypeRelatedItemLineMarkerProvider"/>
<codeInsight.lineMarkerProvider language="JAVA"
implementationClass="org.jetbrains.idea.devkit.navigation.ExtensionPointDeclarationRelatedItemLineMarkerProvider"/>
+ <codeInsight.implementedAtRuntime implementation="org.jetbrains.idea.devkit.inspections.DevKitImplementedAtRuntimeCondition"/>
</extensions>
<project-components>
diff --git a/plugins/devkit/src/actions/NewActionDialog.java b/plugins/devkit/src/actions/NewActionDialog.java
index faa1db563ec2..779929ceb818 100644
--- a/plugins/devkit/src/actions/NewActionDialog.java
+++ b/plugins/devkit/src/actions/NewActionDialog.java
@@ -26,6 +26,7 @@ import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiNameHelper;
import com.intellij.ui.ColoredListCellRenderer;
import com.intellij.ui.ListSpeedSearch;
import com.intellij.ui.SimpleTextAttributes;
@@ -247,7 +248,7 @@ public class NewActionDialog extends DialogWrapper implements ActionData {
setOKActionEnabled(myActionIdEdit.getText().length() > 0 &&
myActionNameEdit.getText().length() > 0 &&
myActionTextEdit.getText().length() > 0 &&
- (!myActionNameEdit.isEditable() || JavaPsiFacade.getInstance(myProject).getNameHelper().isIdentifier(myActionNameEdit.getText())));
+ (!myActionNameEdit.isEditable() || PsiNameHelper.getInstance(myProject).isIdentifier(myActionNameEdit.getText())));
myAnchorBeforeRadio.setEnabled(myActionList.getSelectedValue() != null);
myAnchorAfterRadio.setEnabled(myActionList.getSelectedValue() != null);
diff --git a/plugins/devkit/src/dom/generator/DomGenPanel.java b/plugins/devkit/src/dom/generator/DomGenPanel.java
index e0c21611554b..eaa90acf9e39 100644
--- a/plugins/devkit/src/dom/generator/DomGenPanel.java
+++ b/plugins/devkit/src/dom/generator/DomGenPanel.java
@@ -16,6 +16,7 @@
package org.jetbrains.idea.devkit.dom.generator;
import com.intellij.ide.util.PropertiesComponent;
+import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.fileChooser.FileTypeDescriptor;
import com.intellij.openapi.project.Project;
@@ -101,7 +102,8 @@ public class DomGenPanel {
}
});
myOutputDir = new TextFieldWithBrowseButton();
- myOutputDir.addBrowseFolderListener("Select Output For Generated Files", "", myProject, FileChooserDescriptorFactory.getDirectoryChooserDescriptor("Output For Generated Files"));
+ FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor();
+ myOutputDir.addBrowseFolderListener("Select Output Directory For Generated Files", "", myProject, descriptor);
}
public JComponent getComponent() {
diff --git a/plugins/devkit/src/inspections/DevKitImplementedAtRuntimeCondition.java b/plugins/devkit/src/inspections/DevKitImplementedAtRuntimeCondition.java
new file mode 100644
index 000000000000..3c5aff386203
--- /dev/null
+++ b/plugins/devkit/src/inspections/DevKitImplementedAtRuntimeCondition.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.idea.devkit.inspections;
+
+import com.intellij.codeInspection.inheritance.ImplementedAtRuntimeCondition;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.util.InheritanceUtil;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public class DevKitImplementedAtRuntimeCondition extends ImplementedAtRuntimeCondition {
+ @Override
+ public boolean isImplementedAtRuntime(@NotNull PsiClass psiClass) {
+ return DevKitImplicitUsageProvider.isDomElementClass(psiClass) ||
+ InheritanceUtil.isInheritor(psiClass, "com.intellij.jam.JamElement");
+ }
+}
diff --git a/plugins/devkit/src/inspections/DevKitImplicitUsageProvider.java b/plugins/devkit/src/inspections/DevKitImplicitUsageProvider.java
index fa87c70ad337..7aeb7a047046 100644
--- a/plugins/devkit/src/inspections/DevKitImplicitUsageProvider.java
+++ b/plugins/devkit/src/inspections/DevKitImplicitUsageProvider.java
@@ -50,7 +50,7 @@ public class DevKitImplicitUsageProvider implements ImplicitUsageProvider {
return false;
}
- private static boolean isDomElementClass(PsiClass psiClass) {
+ static boolean isDomElementClass(PsiClass psiClass) {
if (psiClass.isEnum() ||
psiClass.isAnnotationType() ||
psiClass.hasModifierProperty(PsiModifier.PRIVATE)) {
diff --git a/plugins/devkit/src/run/PluginRunConfiguration.java b/plugins/devkit/src/run/PluginRunConfiguration.java
index ed0764c5581c..2c7361f8f571 100644
--- a/plugins/devkit/src/run/PluginRunConfiguration.java
+++ b/plugins/devkit/src/run/PluginRunConfiguration.java
@@ -163,10 +163,10 @@ public class PluginRunConfiguration extends RunConfigurationBase implements Modu
prefix = PlatformUtils.WEB_PREFIX;
}
else if (buildNumber.startsWith("OC")) {
- prefix = buildNumber.contains("121") ? "CIDR" : PlatformUtils.APPCODE_PREFIX;
+ prefix = PlatformUtils.APPCODE_PREFIX;
}
- else if (buildNumber.startsWith("CP")) {
- prefix = PlatformUtils.CPP_PREFIX;
+ else if (buildNumber.startsWith("CL")) {
+ prefix = PlatformUtils.CLION_PREFIX;
}
else if (buildNumber.startsWith("DB")) {
prefix = PlatformUtils.DBE_PREFIX;
diff --git a/plugins/devkit/testData/inspections/implicitUsage/ImplementedAtRuntimeDomElementImpl.java b/plugins/devkit/testData/inspections/implicitUsage/ImplementedAtRuntimeDomElementImpl.java
new file mode 100644
index 000000000000..eb0409eb7f93
--- /dev/null
+++ b/plugins/devkit/testData/inspections/implicitUsage/ImplementedAtRuntimeDomElementImpl.java
@@ -0,0 +1 @@
+public abstract class ImplementedAtRuntimeDomElementImpl implements com.intellij.util.xml.DomElement {} \ No newline at end of file
diff --git a/plugins/devkit/testData/inspections/implicitUsage/ImplementedAtRuntimeJamElementImpl.java b/plugins/devkit/testData/inspections/implicitUsage/ImplementedAtRuntimeJamElementImpl.java
new file mode 100644
index 000000000000..27dfb2d006fa
--- /dev/null
+++ b/plugins/devkit/testData/inspections/implicitUsage/ImplementedAtRuntimeJamElementImpl.java
@@ -0,0 +1 @@
+public abstract class ImplementedAtRuntimeJamElementImpl implements com.intellij.jam.JamElement {} \ No newline at end of file
diff --git a/plugins/devkit/testSources/inspections/DevKitImplicitUsageProviderTest.java b/plugins/devkit/testSources/inspections/DevKitImplicitUsageProviderTest.java
index bf33c2174159..a7fedaeaa74d 100644
--- a/plugins/devkit/testSources/inspections/DevKitImplicitUsageProviderTest.java
+++ b/plugins/devkit/testSources/inspections/DevKitImplicitUsageProviderTest.java
@@ -20,6 +20,7 @@ import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection;
import com.intellij.openapi.application.PluginPathManager;
import com.intellij.testFramework.TestDataPath;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
+import com.siyeh.ig.inheritance.AbstractClassNeverImplementedInspection;
@TestDataPath("$CONTENT_ROOT/testData/inspections/implicitUsage")
public class DevKitImplicitUsageProviderTest extends LightCodeInsightFixtureTestCase {
@@ -37,14 +38,35 @@ public class DevKitImplicitUsageProviderTest extends LightCodeInsightFixtureTest
myFixture.addClass("package com.intellij.util.xml; public interface DomElementVisitor {}");
myFixture.addClass("package com.intellij.util.xml; public interface GenericAttributeValue<T> extends DomElement {}");
- myFixture.enableInspections(new UnusedSymbolLocalInspection(), new UnusedDeclarationInspection());
+ myFixture.addClass("package com.intellij.jam; public interface JamElement {}");
}
public void testImplicitUsagesDomElement() {
+ enableImplicitUsageInspections();
myFixture.testHighlighting("ImplicitUsagesDomElement.java");
}
public void testImplicitUsagesDomElementVisitor() {
+ enableImplicitUsageInspections();
myFixture.testHighlighting("ImplicitUsagesDomElementVisitor.java");
}
+
+ private void enableImplicitUsageInspections() {
+ myFixture.enableInspections(new UnusedSymbolLocalInspection(), new UnusedDeclarationInspection());
+ }
+
+
+ public void testImplementedAtRuntimeDomElementImpl() {
+ enableImplementedAtRuntimeInspections();
+ myFixture.testHighlighting("ImplementedAtRuntimeDomElementImpl.java");
+ }
+
+ public void testImplementedAtRuntimeJamElementImpl() {
+ enableImplementedAtRuntimeInspections();
+ myFixture.testHighlighting("ImplementedAtRuntimeJamElementImpl.java");
+ }
+
+ private void enableImplementedAtRuntimeInspections() {
+ myFixture.enableInspections(new AbstractClassNeverImplementedInspection());
+ }
}
diff --git a/plugins/eclipse/testData/iml/allProps/expected/expected.iml b/plugins/eclipse/testData/iml/allProps/expected/expected.iml
index 142bc1072c84..d47060bab059 100644
--- a/plugins/eclipse/testData/iml/allProps/expected/expected.iml
+++ b/plugins/eclipse/testData/iml/allProps/expected/expected.iml
@@ -92,7 +92,7 @@
<orderEntry type="module-library">
<library name="junit3">
<CLASSES>
- <root url="jar://$JUNIT$/lib/junit.jar!/" />
+ <root url="jar://$JUNIT$/junit.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
@@ -101,7 +101,7 @@
<orderEntry type="module-library">
<library name="junit4">
<CLASSES>
- <root url="jar://$JUNIT$/lib/junit-4.11.jar!/" />
+ <root url="jar://$JUNIT$/junit-4.11.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
diff --git a/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseImlTest.java b/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseImlTest.java
index 5e1cc3f87921..4b64e08f04d6 100644
--- a/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseImlTest.java
+++ b/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseImlTest.java
@@ -22,8 +22,8 @@ package org.jetbrains.idea.eclipse;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.PathMacros;
-import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.application.PluginPathManager;
+import com.intellij.openapi.application.ex.PathManagerEx;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.components.PathMacroManager;
import com.intellij.openapi.module.Module;
@@ -38,8 +38,7 @@ import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.testFramework.IdeaTestCase;
-import junit.framework.Assert;
-import org.jdom.Document;
+import com.intellij.testFramework.PlatformTestUtil;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.idea.eclipse.conversion.EclipseClasspathReader;
@@ -49,7 +48,7 @@ import java.util.ArrayList;
import java.util.HashSet;
public class EclipseImlTest extends IdeaTestCase {
- @NonNls public static final String JUNIT = "JUNIT";
+ @NonNls private static final String JUNIT = "JUNIT";
@Override
protected void setUp() throws Exception {
@@ -75,11 +74,8 @@ public class EclipseImlTest extends IdeaTestCase {
if (!SystemInfo.isWindows) {
fileText = fileText.replaceAll(EclipseXml.FILE_PROTOCOL + "/", EclipseXml.FILE_PROTOCOL);
}
- String communityAppDir = PathManager.getHomePath();
- if (new File(PathManager.getHomePath(), "community").exists()) {
- communityAppDir += "/community";
- }
- fileText = fileText.replaceAll("\\$" + JUNIT + "\\$", communityAppDir);
+ String communityLib = FileUtil.toSystemIndependentName(PathManagerEx.findFileUnderCommunityHome("lib").getAbsolutePath());
+ fileText = fileText.replaceAll("\\$" + JUNIT + "\\$", communityLib);
final Element classpathElement = JDOMUtil.loadDocument(fileText).getRootElement();
final Module module = WriteCommandAction.runWriteCommandAction(null, new Computable<Module>() {
@Override
@@ -104,15 +100,14 @@ public class EclipseImlTest extends IdeaTestCase {
final Element actualImlElement = new Element("root");
((ModuleRootManagerImpl)ModuleRootManager.getInstance(module)).getState().writeExternal(actualImlElement);
- PathMacros.getInstance().setMacro(JUNIT, communityAppDir);
+ PathMacros.getInstance().setMacro(JUNIT, communityLib);
PathMacroManager.getInstance(module).collapsePaths(actualImlElement);
PathMacroManager.getInstance(project).collapsePaths(actualImlElement);
PathMacros.getInstance().removeMacro(JUNIT);
final Element expectedIml =
JDOMUtil.loadDocument(new File(project.getBaseDir().getPath() + "/expected", "expected.iml")).getRootElement();
- Assert.assertTrue(new String(JDOMUtil.printDocument(new Document(actualImlElement), "\n")),
- JDOMUtil.areElementsEqual(expectedIml, actualImlElement));
+ PlatformTestUtil.assertElementsEqual(expectedIml, actualImlElement);
}
diff --git a/plugins/git4idea/src/git4idea/GitTaskHandler.java b/plugins/git4idea/src/git4idea/GitTaskHandler.java
index 7dac4654d860..5d88d526e038 100644
--- a/plugins/git4idea/src/git4idea/GitTaskHandler.java
+++ b/plugins/git4idea/src/git4idea/GitTaskHandler.java
@@ -54,6 +54,11 @@ public class GitTaskHandler extends VcsTaskHandler {
}
@Override
+ public boolean isEnabled(Project project) {
+ return !myRepositoryManager.getRepositories().isEmpty();
+ }
+
+ @Override
public TaskInfo startNewTask(final String taskName) {
List<GitRepository> repositories = myRepositoryManager.getRepositories();
List<GitRepository> problems = ContainerUtil.filter(repositories, new Condition<GitRepository>() {
diff --git a/plugins/git4idea/src/git4idea/commands/GitSSHGUIHandler.java b/plugins/git4idea/src/git4idea/commands/GitSSHGUIHandler.java
index 4d1c13415ec2..9d337971c1e7 100644
--- a/plugins/git4idea/src/git4idea/commands/GitSSHGUIHandler.java
+++ b/plugins/git4idea/src/git4idea/commands/GitSSHGUIHandler.java
@@ -16,6 +16,8 @@
package git4idea.commands;
import com.intellij.ide.passwordSafe.ui.PasswordSafePromptDialog;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
@@ -28,7 +30,6 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.text.JTextComponent;
import java.awt.*;
-import java.lang.reflect.InvocationTargetException;
import java.util.Vector;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
@@ -56,11 +57,11 @@ public class GitSSHGUIHandler {
message = GitBundle.message("ssh.changed.host.key", hostname, port, fingerprint, serverHostKeyAlgorithm);
}
final AtomicBoolean rc = new AtomicBoolean();
- UIUtil.invokeAndWaitIfNeeded(new Runnable() {
+ ApplicationManager.getApplication().invokeAndWait(new Runnable() {
public void run() {
rc.set(Messages.YES == Messages.showYesNoDialog(myProject, message, GitBundle.getString("ssh.confirm.key.titile"), null));
}
- });
+ }, ModalityState.any());
return rc.get();
}
@@ -84,11 +85,11 @@ public class GitSSHGUIHandler {
private String processLastError(boolean resetPassword, final String lastError) {
String error;
if (lastError != null && lastError.length() != 0 && !resetPassword) {
- UIUtil.invokeAndWaitIfNeeded(new Runnable() {
+ ApplicationManager.getApplication().invokeAndWait(new Runnable() {
public void run() {
showError(lastError);
}
- });
+ }, ModalityState.any());
error = null;
}
else {
@@ -124,25 +125,17 @@ public class GitSSHGUIHandler {
final Vector<Boolean> echo,
final String lastError) {
final AtomicReference<Vector<String>> rc = new AtomicReference<Vector<String>>();
- try {
- EventQueue.invokeAndWait(new Runnable() {
- public void run() {
- showError(lastError);
- GitSSHKeyboardInteractiveDialog dialog =
- new GitSSHKeyboardInteractiveDialog(name, numPrompts, instruction, prompt, echo, username);
- dialog.show();
- if (dialog.isOK()) {
- rc.set(dialog.getResults());
- }
+ ApplicationManager.getApplication().invokeAndWait(new Runnable() {
+ public void run() {
+ showError(lastError);
+ GitSSHKeyboardInteractiveDialog dialog =
+ new GitSSHKeyboardInteractiveDialog(name, numPrompts, instruction, prompt, echo, username);
+ dialog.show();
+ if (dialog.isOK()) {
+ rc.set(dialog.getResults());
}
- });
- }
- catch (InterruptedException e) {
- throw new RuntimeException("dialog failed", e);
- }
- catch (InvocationTargetException e) {
- throw new RuntimeException("dialog failed", e);
- }
+ }
+ }, ModalityState.any());
return rc.get();
}
diff --git a/plugins/git4idea/src/git4idea/log/GitBekParentFixer.java b/plugins/git4idea/src/git4idea/log/GitBekParentFixer.java
index 054ed9f90b48..4bcfade3cfa8 100644
--- a/plugins/git4idea/src/git4idea/log/GitBekParentFixer.java
+++ b/plugins/git4idea/src/git4idea/log/GitBekParentFixer.java
@@ -126,6 +126,12 @@ class GitBekParentFixer {
@Nullable
@Override
+ public VcsLogHashFilter getHashFilter() {
+ return null;
+ }
+
+ @Nullable
+ @Override
public VcsLogStructureFilter getStructureFilter() {
return null;
}
diff --git a/plugins/git4idea/src/git4idea/log/GitLogProvider.java b/plugins/git4idea/src/git4idea/log/GitLogProvider.java
index 435313fa5c7d..b5096a94f03b 100644
--- a/plugins/git4idea/src/git4idea/log/GitLogProvider.java
+++ b/plugins/git4idea/src/git4idea/log/GitLogProvider.java
@@ -308,7 +308,7 @@ public class GitLogProvider implements VcsLogProvider {
}
if (filterCollection.getTextFilter() != null) {
- String textFilter = StringUtil.escapeBackSlashes(filterCollection.getTextFilter().getText());
+ String textFilter = filterCollection.getTextFilter().getText();
filterParameters.add(prepareParameter("grep", textFilter));
}
diff --git a/plugins/git4idea/src/git4idea/push/GitPusher.java b/plugins/git4idea/src/git4idea/push/GitPusher.java
index 778d2dcd0033..1dfcdfaf327d 100644
--- a/plugins/git4idea/src/git4idea/push/GitPusher.java
+++ b/plugins/git4idea/src/git4idea/push/GitPusher.java
@@ -256,7 +256,7 @@ public final class GitPusher {
@NotNull GitCommitsByRepoAndBranch commits,
@NotNull GitRepository repository) {
GitPushSpec pushSpec = pushInfo.getPushSpecs().get(repository);
- GitSimplePushResult simplePushResult = pushAndGetSimpleResult(repository, pushSpec, commits.get(repository));
+ GitSimplePushResult simplePushResult = pushAndGetSimpleResult(repository, pushSpec);
String output = simplePushResult.getOutput();
switch (simplePushResult.getType()) {
case SUCCESS:
@@ -306,8 +306,7 @@ public final class GitPusher {
}
@NotNull
- private GitSimplePushResult pushAndGetSimpleResult(@NotNull GitRepository repository,
- @NotNull GitPushSpec pushSpec, @NotNull GitCommitsByBranch commitsByBranch) {
+ private GitSimplePushResult pushAndGetSimpleResult(@NotNull GitRepository repository, @NotNull GitPushSpec pushSpec) {
if (pushSpec.getDest() == NO_TARGET_BRANCH) {
return GitSimplePushResult.notPushed();
}
@@ -367,21 +366,6 @@ public final class GitPusher {
}
@NotNull
- private static String formPushSpec(@NotNull GitPushSpec spec, @NotNull GitRemote remote) {
- String destWithRemote = spec.getDest().getName();
- String prefix = remote.getName() + "/";
- String destName;
- if (destWithRemote.startsWith(prefix)) {
- destName = destWithRemote.substring(prefix.length());
- }
- else {
- LOG.error("Destination remote branch has invalid name. Remote branch name: " + destWithRemote + "\nRemote: " + remote);
- destName = destWithRemote;
- }
- return spec.getSource().getName() + ":" + destName;
- }
-
- @NotNull
private GitSimplePushResult pushNatively(GitRepository repository, GitPushSpec pushSpec, @NotNull String url) {
GitPushRejectedDetector rejectedDetector = new GitPushRejectedDetector();
GitLineHandlerListener progressListener = GitStandardProgressAnalyzer.createListener(myProgressIndicator);
diff --git a/plugins/git4idea/test-stepdefs/git4idea/GitCherryPickStepdefs.java b/plugins/git4idea/test-stepdefs/git4idea/GitCherryPickStepdefs.java
index 2fe42a0d76a1..553cf260e268 100644
--- a/plugins/git4idea/test-stepdefs/git4idea/GitCherryPickStepdefs.java
+++ b/plugins/git4idea/test-stepdefs/git4idea/GitCherryPickStepdefs.java
@@ -17,8 +17,7 @@ package git4idea;
import com.google.common.base.Function;
import com.google.common.collect.Collections2;
-import com.intellij.dvcs.test.MockVcsHelper;
-import com.intellij.dvcs.test.MockVirtualFile;
+import com.intellij.mock.MockVirtualFile;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.util.ThrowableComputable;
import com.intellij.openapi.util.text.StringUtil;
@@ -40,6 +39,7 @@ import cucumber.annotation.en.Then;
import cucumber.annotation.en.When;
import git4idea.cherrypick.GitCherryPicker;
import git4idea.config.GitVersionSpecialty;
+import git4idea.test.MockVcsHelper;
import java.util.*;
diff --git a/plugins/git4idea/test-stepdefs/git4idea/GitCucumberWorld.java b/plugins/git4idea/test-stepdefs/git4idea/GitCucumberWorld.java
index 2db213ca1a30..2a521f28db6f 100644
--- a/plugins/git4idea/test-stepdefs/git4idea/GitCucumberWorld.java
+++ b/plugins/git4idea/test-stepdefs/git4idea/GitCucumberWorld.java
@@ -15,7 +15,6 @@
*/
package git4idea;
-import com.intellij.dvcs.test.MockVcsHelper;
import com.intellij.idea.IdeaTestApplication;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ProjectComponent;
@@ -46,6 +45,7 @@ import git4idea.repo.GitRepository;
import git4idea.test.GitExecutor;
import git4idea.test.GitHttpAuthTestService;
import git4idea.test.GitTestUtil;
+import git4idea.test.MockVcsHelper;
import org.jetbrains.annotations.NotNull;
import org.junit.Assert;
import org.picocontainer.MutablePicoContainer;
diff --git a/plugins/git4idea/tests/git4idea/repo/GitRepositoryReaderTest.java b/plugins/git4idea/tests/git4idea/repo/GitRepositoryReaderTest.java
index b8bce9b7ee82..7c233195a7f2 100644
--- a/plugins/git4idea/tests/git4idea/repo/GitRepositoryReaderTest.java
+++ b/plugins/git4idea/tests/git4idea/repo/GitRepositoryReaderTest.java
@@ -54,7 +54,7 @@ public class GitRepositoryReaderTest extends GitPlatformTest {
});
}
- @SuppressWarnings({"JUnitTestCaseWithNonTrivialConstructors", "UnusedParameters"})
+ @SuppressWarnings({"UnusedParameters"})
public GitRepositoryReaderTest(@NotNull String name, @NotNull File testDir) {
myTestCaseDir = testDir;
}
diff --git a/plugins/git4idea/tests/git4idea/test/GitPlatformTest.java b/plugins/git4idea/tests/git4idea/test/GitPlatformTest.java
index c02ec553dd8f..b433a5b8a0bf 100644
--- a/plugins/git4idea/tests/git4idea/test/GitPlatformTest.java
+++ b/plugins/git4idea/tests/git4idea/test/GitPlatformTest.java
@@ -30,6 +30,7 @@ import com.intellij.testFramework.UsefulTestCase;
import com.intellij.testFramework.fixtures.IdeaProjectTestFixture;
import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory;
import com.intellij.testFramework.vcs.AbstractVcsTestCase;
+import com.intellij.util.ArrayUtil;
import com.intellij.util.ObjectUtils;
import git4idea.DialogManager;
import git4idea.GitPlatformFacade;
@@ -43,6 +44,7 @@ import git4idea.repo.GitRepositoryManager;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
+import java.util.*;
public abstract class GitPlatformTest extends UsefulTestCase {
@@ -157,13 +159,20 @@ public abstract class GitPlatformTest extends UsefulTestCase {
}
private void enableDebugLogging() {
- TestLoggerFactory.enableDebugLogging(myTestRootDisposable, "#" + Executor.class.getName(),
- "#" + GitHandler.class.getName(),
- GitHandler.class.getName());
+ List<String> commonCategories = new ArrayList<String>(Arrays.asList("#" + Executor.class.getName(),
+ "#" + GitHandler.class.getName(),
+ GitHandler.class.getName()));
+ commonCategories.addAll(getDebugLogCategories());
+ TestLoggerFactory.enableDebugLogging(myTestRootDisposable, ArrayUtil.toStringArray(commonCategories));
myTestStartedIndicator = createTestStartedIndicator();
LOG.info(myTestStartedIndicator);
}
+ @NotNull
+ protected Collection<String> getDebugLogCategories() {
+ return Collections.emptyList();
+ }
+
@Override
protected void defaultRunBare() throws Throwable {
try {
diff --git a/platform/dvcs-impl/testFramework/com/intellij/dvcs/test/MockVcsHelper.java b/plugins/git4idea/tests/git4idea/test/MockVcsHelper.java
index 55e0a0e68b17..45f1e3965bea 100644
--- a/platform/dvcs-impl/testFramework/com/intellij/dvcs/test/MockVcsHelper.java
+++ b/plugins/git4idea/tests/git4idea/test/MockVcsHelper.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.intellij.dvcs.test;
+package git4idea.test;
import com.intellij.ide.errorTreeView.HotfixData;
import com.intellij.openapi.project.Project;
@@ -41,9 +41,6 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
-/**
- * @author Kirill Likhodedov
- */
public class MockVcsHelper extends AbstractVcsHelper {
private volatile boolean myCommitDialogShown;
private volatile boolean myMergeDialogShown;
diff --git a/platform/dvcs-impl/testFramework/com/intellij/dvcs/test/MockVirtualFile.java b/plugins/git4idea/tests/git4idea/test/MockVirtualFile.java
index 3b36381dcf85..e3f0a3afe071 100644
--- a/platform/dvcs-impl/testFramework/com/intellij/dvcs/test/MockVirtualFile.java
+++ b/plugins/git4idea/tests/git4idea/test/MockVirtualFile.java
@@ -13,12 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.intellij.dvcs.test;
+package git4idea.test;
import com.intellij.mock.MockVirtualFileSystem;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypes;
-import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileSystem;
@@ -26,7 +25,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
-import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -34,8 +32,6 @@ import java.io.OutputStream;
* VirtualFile implementation for tests based on {@link java.io.File}.
* Not reusing {@link com.intellij.mock.MockVirtualFile}, because the latter holds everything in memory, which is fast, but requires
* synchronization with the real file system.
- *
- * @author Kirill Likhodedov
*/
public class MockVirtualFile extends VirtualFile {
@@ -43,31 +39,6 @@ public class MockVirtualFile extends VirtualFile {
private final String myPath;
- @NotNull
- static VirtualFile fromPath(@NotNull String absolutePath) {
- return new MockVirtualFile(FileUtil.toSystemIndependentName(absolutePath));
- }
-
- @NotNull
- static VirtualFile fromPath(@NotNull String relativePath, @NotNull Project project) {
- try {
- return fromPath(new File(project.getBaseDir().getPath() + "/" + relativePath).getCanonicalPath());
- }
- catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- @NotNull
- static VirtualFile fromPath(@NotNull String relativePath, @NotNull String basePath) {
- try {
- return fromPath(new File(basePath + "/" + relativePath).getCanonicalPath());
- }
- catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
public MockVirtualFile(@NotNull String path) {
myPath = FileUtil.toSystemIndependentName(path);
}
diff --git a/plugins/git4idea/tests/git4idea/validators/GitRefNameValidatorTest.java b/plugins/git4idea/tests/git4idea/validators/GitRefNameValidatorTest.java
index 1b4908f3a41e..c7da36abec88 100644
--- a/plugins/git4idea/tests/git4idea/validators/GitRefNameValidatorTest.java
+++ b/plugins/git4idea/tests/git4idea/validators/GitRefNameValidatorTest.java
@@ -16,8 +16,12 @@
package git4idea.validators;
import com.intellij.util.Function;
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Test;
+import com.intellij.util.containers.ContainerUtil;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Collection;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
@@ -26,52 +30,16 @@ import static org.testng.Assert.assertTrue;
* The test for {@link GitRefNameValidator}.
* Tests are based on the <a href="http://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html">
* specification of valid Git references</a>
- *
- * @author Kirill Likhodedov
*/
+@RunWith(Parameterized.class)
public class GitRefNameValidatorTest {
-
- @DataProvider(name = "valid")
- public Object[][] createValidData() {
- return new Object[][] {
- { "WORD", "branch" },
- { "UNDERSCORED_WORD", "new_branch" },
- { "HIERARCHY", "user/branch" },
- { "HIERARCHY_2", "user/branch/sub_branch" },
- { "BEGINS_WITH_SLASH", "/branch" }, // actual branch name will be with trimmed slash
- { "NON_CONS_DOTS", "complex.branch.name" }
- };
- }
-
- @DataProvider(name = "simple_invalid")
- public Object[][] createInvalidData() {
- return new Object[][] {
- { "BEGIN_WITH_DOT", ".branch" },
- { "ONLY_DOT", "." },
- { "ENDS_WITH_SLASH", "branch/" },
- { "ENDS_WITH_DOT", "branch." },
- { "ENDS_WITH_LOCK", "branch.lock" },
- { "TWO_DOTS_1", "branch..name" },
- { "TWO_DOTS_2", "..name" },
- { "TWO_DOTS_3", "..branch" }
- };
- }
private static final String[] ILLEGAL_CHARS = { " ", "~", "^", ":", "?", "*", "[", "@{", "\\" };
-
- @DataProvider(name = "invalid_chars")
- public Object[][] createInvalidCharsData() {
- return populateWithIllegalChars(ILLEGAL_CHARS, new Function<String, String>() {
- @Override public String fun(String s) {
- return s;
- }
- });
- }
-
- private static final int CONTROL_CHARS_START = 5; // we can't test from 0 to 4 via @DataProvider due to TestNG limitations
+ private static final int CONTROL_CHARS_START = 0;
private static final int CONTROL_CHARS_END = 31;
private static final int CONTROL_CHARS_SIZE = CONTROL_CHARS_END - CONTROL_CHARS_START + 1;
private static final String[] CONTROL_CHARS = new String[CONTROL_CHARS_SIZE + 1]; // + DEL
+
static {
for (int i = CONTROL_CHARS_START; i <= CONTROL_CHARS_END; i++) {
CONTROL_CHARS[i-CONTROL_CHARS_START] = String.valueOf((char)i);
@@ -79,8 +47,42 @@ public class GitRefNameValidatorTest {
CONTROL_CHARS[CONTROL_CHARS_SIZE] = "\u007F"; // DEL
}
- @DataProvider(name = "invalid_control_chars")
- public Object[][] createInvalidControlCharsData() {
+ private final String myRefNameToTest;
+ private final boolean myIsExpectedValid;
+
+ private static Object[][] createValidData() {
+ return new Object[][] {
+ { "WORD", "branch" },
+ { "UNDERSCORED_WORD", "new_branch" },
+ { "HIERARCHY", "user/branch" },
+ { "HIERARCHY_2", "user/branch/sub_branch" },
+ { "BEGINS_WITH_SLASH", "/branch" }, // actual branch name will be with trimmed slash
+ { "NON_CONS_DOTS", "complex.branch.name" }
+ };
+ }
+
+ private static Object[][] createInvalidData() {
+ return new Object[][] {
+ { "BEGIN_WITH_DOT", ".branch" },
+ { "ONLY_DOT", "." },
+ { "ENDS_WITH_SLASH", "branch/" },
+ { "ENDS_WITH_DOT", "branch." },
+ { "ENDS_WITH_LOCK", "branch.lock" },
+ { "TWO_DOTS_1", "branch..name" },
+ { "TWO_DOTS_2", "..name" },
+ { "TWO_DOTS_3", "..branch" }
+ };
+ }
+
+ public static Object[][] createInvalidCharsData() {
+ return populateWithIllegalChars(ILLEGAL_CHARS, new Function<String, String>() {
+ @Override public String fun(String s) {
+ return s;
+ }
+ });
+ }
+
+ public static Object[][] createInvalidControlCharsData() {
return populateWithIllegalChars(CONTROL_CHARS, new Function<String, String>() {
@Override public String fun(String s) {
Character c = s.charAt(0);
@@ -99,34 +101,38 @@ public class GitRefNameValidatorTest {
return data;
}
- @Test(dataProvider = "valid")
- public void testValid(String testName, String branchName) {
- assertValid(branchName);
+ @Parameterized.Parameters(name = "{0}")
+ public static Collection<Object[]> data() {
+ Collection<Object[]> data = ContainerUtil.newArrayList();
+ populateData(data, createValidData(), true);
+ populateData(data, createInvalidData(), false);
+ populateData(data, createInvalidCharsData(), false);
+ populateData(data, createInvalidControlCharsData(), false);
+ return data;
}
- @Test(dataProvider = "simple_invalid")
- public void testSimpleInvalid(String testName, String branchName) {
- assertInvalid(branchName);
+ private static void populateData(Collection<Object[]> data, Object[][] source, boolean valid) {
+ for (Object[] testCase : source) {
+ data.add(new Object[] {testCase[0], testCase[1], valid});
+ }
}
- @Test(dataProvider = "invalid_chars")
- public void testInvalidChars(String testName, String branchName) {
- assertInvalid(branchName);
+ @SuppressWarnings("UnusedParameters")
+ public GitRefNameValidatorTest(String name, String refNameToTest, boolean valid) {
+ myRefNameToTest = refNameToTest;
+ myIsExpectedValid = valid;
}
- @Test(dataProvider = "invalid_control_chars")
- public void control_chars_are_invalid(String testName, String branchName) {
- assertInvalid(branchName);
- }
-
- // \u0000 to \u0004 can't be passed to the TestNG DataProvider - see org.testng.remote.strprotocol.MessageHelper
@Test
- public void control_chars_from_0_to_4_are_invalid() {
- for (int i = 0; i < 5; i++) {
- assertInvalid("bra" + (char)i + "nch");
+ public void testAll() {
+ if (myIsExpectedValid) {
+ assertValid(myRefNameToTest);
+ }
+ else {
+ assertInvalid(myRefNameToTest);
}
}
-
+
private static void assertValid(String branchName) {
assertTrue(GitRefNameValidator.getInstance().checkInput(branchName), "Should be valid");
assertTrue(GitRefNameValidator.getInstance().canClose(branchName), "Should be valid");
diff --git a/plugins/github/test/org/jetbrains/plugins/github/test/GithubTest.java b/plugins/github/test/org/jetbrains/plugins/github/test/GithubTest.java
index 3d3d8201e03a..da64988f5b16 100644
--- a/plugins/github/test/org/jetbrains/plugins/github/test/GithubTest.java
+++ b/plugins/github/test/org/jetbrains/plugins/github/test/GithubTest.java
@@ -176,7 +176,6 @@ public abstract class GithubTest extends GitPlatformTest {
myHttpAuthService = (GitHttpAuthTestService)ServiceManager.getService(GitHttpAuthService.class);
-
try {
beforeTest();
}
@@ -197,7 +196,7 @@ public abstract class GithubTest extends GitPlatformTest {
afterTest();
}
finally {
- myHttpAuthService.cleanup();
+ if (myHttpAuthService != null) myHttpAuthService.cleanup();
super.tearDown();
}
}
diff --git a/plugins/gradle/jps-plugin/gradle-jps-plugin.iml b/plugins/gradle/jps-plugin/gradle-jps-plugin.iml
index 0d1d5300e84b..03feae393c00 100644
--- a/plugins/gradle/jps-plugin/gradle-jps-plugin.iml
+++ b/plugins/gradle/jps-plugin/gradle-jps-plugin.iml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
- <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_5" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java
index 7e182a6eda66..4ec3f9dd7e06 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java
@@ -1,26 +1,35 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package org.jetbrains.plugins.gradle.util;
-import com.intellij.ide.actions.OpenProjectFileChooserDescriptor;
-import com.intellij.ide.plugins.IdeaPluginDescriptor;
-import com.intellij.ide.plugins.PluginManager;
-import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.ide.util.PropertiesComponent;
-import com.intellij.openapi.extensions.PluginId;
import com.intellij.openapi.externalSystem.model.ExternalSystemException;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
+import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.fileChooser.FileTypeDescriptor;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.ContainerUtilRt;
import com.intellij.util.containers.Stack;
import org.gradle.tooling.model.GradleProject;
import org.gradle.tooling.model.gradle.GradleScript;
import org.gradle.wrapper.WrapperConfiguration;
import org.gradle.wrapper.WrapperExecutor;
-import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -36,12 +45,9 @@ import java.util.Properties;
* @since 8/25/11 1:19 PM
*/
public class GradleUtil {
+ private static final String LAST_USED_GRADLE_HOME_KEY = "last.used.gradle.home";
- private static final String LAST_USED_GRADLE_HOME_KEY = "last.used.gradle.home";
- @NonNls private static final String JVM_ARG_FORMAT = "-D%1$s=%2$s";
-
- private GradleUtil() {
- }
+ private GradleUtil() { }
/**
* Allows to retrieve file chooser descriptor that filters gradle scripts.
@@ -53,12 +59,12 @@ public class GradleUtil {
*/
@NotNull
public static FileChooserDescriptor getGradleProjectFileChooserDescriptor() {
- return DescriptorHolder.GRADLE_BUILD_FILE_CHOOSER_DESCRIPTOR;
+ return FileChooserDescriptorFactory.createSingleFileDescriptor(GradleConstants.EXTENSION);
}
@NotNull
public static FileChooserDescriptor getGradleHomeFileChooserDescriptor() {
- return DescriptorHolder.GRADLE_HOME_FILE_CHOOSER_DESCRIPTOR;
+ return FileChooserDescriptorFactory.createSingleFolderDescriptor();
}
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
@@ -69,7 +75,7 @@ public class GradleUtil {
/**
* Tries to retrieve what settings should be used with gradle wrapper for the gradle project located at the given path.
*
- * @param gradleProjectPath target gradle project config's (*.gradle) path or config file's directory path.
+ * @param gradleProjectPath target gradle project config (*.gradle) path or config file's directory path.
* @return gradle wrapper settings should be used with gradle wrapper for the gradle project located at the given path
* if any; <code>null</code> otherwise
*/
@@ -118,30 +124,6 @@ public class GradleUtil {
}
/**
- * We use this class in order to avoid static initialisation of the wrapped object - it loads number of pico container-based
- * dependencies that are unavailable to the slave gradle project, so, we don't want to get unexpected NPE there.
- */
- private static class DescriptorHolder {
- public static final FileChooserDescriptor GRADLE_BUILD_FILE_CHOOSER_DESCRIPTOR = new OpenProjectFileChooserDescriptor(true) {
- @Override
- public boolean isFileSelectable(VirtualFile file) {
- return file.getName().endsWith(GradleConstants.EXTENSION);
- }
-
- @Override
- public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) {
- if (!super.isFileVisible(file, showHiddenFiles)) {
- return false;
- }
- return file.isDirectory() || file.getName().endsWith(GradleConstants.EXTENSION);
- }
- };
-
- public static final FileChooserDescriptor GRADLE_HOME_FILE_CHOOSER_DESCRIPTOR
- = new FileChooserDescriptor(false, true, false, false, false, false);
- }
-
- /**
* Allows to build file system path to the target gradle sub-project given the root project path.
*
* @param subProject target sub-project which config path we're interested in
@@ -242,9 +224,4 @@ public class GradleUtil {
return candidates[0];
}
-
- @NotNull
- public static String createJvmArg(@NotNull String name, @NotNull String value) {
- return String.format(JVM_ARG_FORMAT, name, value);
- }
}
diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/findUsages/AnnotatedMembersSearcher.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/findUsages/AnnotatedMembersSearcher.java
index cf1fe7234f77..eb702e373b59 100644
--- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/findUsages/AnnotatedMembersSearcher.java
+++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/findUsages/AnnotatedMembersSearcher.java
@@ -15,9 +15,7 @@
*/
package org.jetbrains.plugins.groovy.findUsages;
-import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.util.Computable;
import com.intellij.psi.*;
import com.intellij.psi.impl.search.AnnotatedElementsSearcher;
@@ -48,7 +46,12 @@ public class AnnotatedMembersSearcher implements QueryExecutor<PsiModifierListOw
@NotNull
private static List<PsiModifierListOwner> getAnnotatedMemberCandidates(final PsiClass clazz, final GlobalSearchScope scope) {
- final String name = clazz.getName();
+ final String name = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
+ @Override
+ public String compute() {
+ return clazz.getName();
+ }
+ });
if (name == null) return Collections.emptyList();
final Collection<PsiElement> members = ApplicationManager.getApplication().runReadAction(new Computable<Collection<PsiElement>>() {
@Override
@@ -60,14 +63,20 @@ public class AnnotatedMembersSearcher implements QueryExecutor<PsiModifierListOw
return Collections.emptyList();
}
- final ArrayList<PsiModifierListOwner> result = new ArrayList<PsiModifierListOwner>();
- for (PsiElement element : members) {
- if (element instanceof GroovyFile) {
- element = ((GroovyFile)element).getPackageDefinition();
- }
- if (element instanceof PsiModifierListOwner) {
- result.add((PsiModifierListOwner)element);
- }
+ final List<PsiModifierListOwner> result = new ArrayList<PsiModifierListOwner>();
+ for (final PsiElement element : members) {
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ @Override
+ public void run() {
+ PsiElement e =
+ element instanceof GroovyFile ?
+ ((GroovyFile)element).getPackageDefinition() : element;
+
+ if (e instanceof PsiModifierListOwner) {
+ result.add((PsiModifierListOwner)e);
+ }
+ }
+ });
}
return result;
}
@@ -77,14 +86,12 @@ public class AnnotatedMembersSearcher implements QueryExecutor<PsiModifierListOw
final PsiClass annClass = p.getAnnotationClass();
assert annClass.isAnnotationType() : "Annotation type should be passed to annotated members search";
- AccessToken token = ReadAction.start();
- final String annotationFQN;
- try {
- annotationFQN = annClass.getQualifiedName();
- }
- finally {
- token.finish();
- }
+ final String annotationFQN = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
+ @Override
+ public String compute() {
+ return annClass.getQualifiedName();
+ }
+ });
assert annotationFQN != null;
final SearchScope scope = p.getScope();
@@ -92,44 +99,49 @@ public class AnnotatedMembersSearcher implements QueryExecutor<PsiModifierListOw
final List<PsiModifierListOwner> candidates;
if (scope instanceof GlobalSearchScope) {
candidates = getAnnotatedMemberCandidates(annClass, ((GlobalSearchScope)scope));
- } else {
+ }
+ else {
candidates = new ArrayList<PsiModifierListOwner>();
- for (PsiElement element : ((LocalSearchScope)scope).getScope()) {
- if (element instanceof GroovyPsiElement) {
- ((GroovyPsiElement)element).accept(new GroovyRecursiveElementVisitor() {
- @Override
- public void visitMethod(GrMethod method) {
- candidates.add(method);
- }
+ for (final PsiElement element : ((LocalSearchScope)scope).getScope()) {
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ @Override
+ public void run() {
+ if (element instanceof GroovyPsiElement) {
+ ((GroovyPsiElement)element).accept(new GroovyRecursiveElementVisitor() {
+ @Override
+ public void visitMethod(GrMethod method) {
+ candidates.add(method);
+ }
- @Override
- public void visitField(GrField field) {
- candidates.add(field);
+ @Override
+ public void visitField(GrField field) {
+ candidates.add(field);
+ }
+ });
}
- });
- }
+ }
+ });
}
}
- for (PsiModifierListOwner candidate : candidates) {
- token = ReadAction.start();
- try {
- if (!AnnotatedElementsSearcher.isInstanceof(candidate, p.getTypes())) {
- continue;
- }
-
- PsiModifierList list = candidate.getModifierList();
- if (list != null) {
- for (PsiAnnotation annotation : list.getAnnotations()) {
- if (annotationFQN.equals(annotation.getQualifiedName()) && !consumer.process(candidate)) {
- return false;
+ for (final PsiModifierListOwner candidate : candidates) {
+ boolean accepted = ApplicationManager.getApplication().runReadAction(new Computable<Boolean>(){
+ @Override
+ public Boolean compute() {
+ if (AnnotatedElementsSearcher.isInstanceof(candidate, p.getTypes())) {
+ PsiModifierList list = candidate.getModifierList();
+ if (list != null) {
+ for (PsiAnnotation annotation : list.getAnnotations()) {
+ if (annotationFQN.equals(annotation.getQualifiedName()) && !consumer.process(candidate)) {
+ return false;
+ }
+ }
}
}
+ return true;
}
- }
- finally {
- token.finish();
- }
+ });
+ if (!accepted) return false;
}
return true;
diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/members/GrMethodBaseImpl.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/members/GrMethodBaseImpl.java
index 0b82ae756d03..bcba56016d87 100644
--- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/members/GrMethodBaseImpl.java
+++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/members/GrMethodBaseImpl.java
@@ -447,7 +447,7 @@ public abstract class GrMethodBaseImpl extends GrStubElementBase<GrMethodStub> i
GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(nameElement.getProject());
PsiElement newNameElement;
- if (JavaPsiFacade.getInstance(getProject()).getNameHelper().isIdentifier(name)) {
+ if (PsiNameHelper.getInstance(getProject()).isIdentifier(name)) {
try {
GrMethod method = factory.createMethod(name, null);
newNameElement = method.getNameIdentifierGroovy();
diff --git a/plugins/groovy/rt/src/org/jetbrains/groovy/compiler/rt/GroovycRunner.java b/plugins/groovy/rt/src/org/jetbrains/groovy/compiler/rt/GroovycRunner.java
index aaa42bca43c3..6e464d6c2642 100644
--- a/plugins/groovy/rt/src/org/jetbrains/groovy/compiler/rt/GroovycRunner.java
+++ b/plugins/groovy/rt/src/org/jetbrains/groovy/compiler/rt/GroovycRunner.java
@@ -100,6 +100,9 @@ public class GroovycRunner {
method.invoke(null, forStubs, argPath);
}
catch (Throwable e) {
+ while (e.getCause() != null) {
+ e = e.getCause();
+ }
e.printStackTrace();
System.exit(1);
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/GroovyCreateClassDialog.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/GroovyCreateClassDialog.java
index c7a2c3ae4625..5ed50b62efef 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/GroovyCreateClassDialog.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/GroovyCreateClassDialog.java
@@ -99,7 +99,7 @@ public class GroovyCreateClassDialog extends DialogWrapper {
myPackageTextField.getDocument().addDocumentListener(new DocumentAdapter() {
@Override
public void documentChanged(DocumentEvent e) {
- PsiNameHelper nameHelper = JavaPsiFacade.getInstance(myProject).getNameHelper();
+ PsiNameHelper nameHelper = PsiNameHelper.getInstance(myProject);
String packageName = getPackageName();
getOKAction().setEnabled(nameHelper.isQualifiedName(packageName) || packageName != null && packageName.isEmpty());
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GrHighlightHandlerFactory.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GrHighlightHandlerFactory.java
index 811f8caec379..a25abdf311ef 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GrHighlightHandlerFactory.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GrHighlightHandlerFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,14 +15,14 @@
*/
package org.jetbrains.plugins.groovy.findUsages;
-import com.intellij.codeInsight.TargetElementUtilBase;
import com.intellij.codeInsight.highlighting.HighlightUsagesHandlerBase;
-import com.intellij.codeInsight.highlighting.HighlightUsagesHandlerFactory;
+import com.intellij.codeInsight.highlighting.HighlightUsagesHandlerFactoryBase;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrReferenceList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
@@ -30,13 +30,9 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefini
/**
* @author Max Medvedev
*/
-public class GrHighlightHandlerFactory implements HighlightUsagesHandlerFactory {
+public class GrHighlightHandlerFactory extends HighlightUsagesHandlerFactoryBase {
@Override
- public HighlightUsagesHandlerBase createHighlightUsagesHandler(Editor editor, PsiFile file) {
- int offset = TargetElementUtilBase.adjustOffset(file, editor.getDocument(), editor.getCaretModel().getOffset());
- final PsiElement target = file.findElementAt(offset);
- if (target == null) return null;
-
+ public HighlightUsagesHandlerBase createHighlightUsagesHandler(@NotNull Editor editor, @NotNull PsiFile file, @NotNull PsiElement target) {
ASTNode node = target.getNode();
if (node == null) return null;
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/parameterToEntry/ConvertParameterToMapEntryIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/parameterToEntry/ConvertParameterToMapEntryIntention.java
index 318db55df11b..befb360e5885 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/parameterToEntry/ConvertParameterToMapEntryIntention.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/parameterToEntry/ConvertParameterToMapEntryIntention.java
@@ -23,6 +23,7 @@ import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
@@ -459,17 +460,33 @@ public class ConvertParameterToMapEntryIntention extends Intention {
}
};
ReferencesSearch.search(namedElem).forEach(consumer);
- if (namedElem instanceof GrField && ((GrField)namedElem).isProperty()) {
- final GrAccessorMethod[] getters = ((GrField)namedElem).getGetters();
+ boolean isProperty = ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
+ @Override
+ public Boolean compute() {
+ return namedElem instanceof GrField && ((GrField)namedElem).isProperty();
+ }
+ });
+ if (isProperty) {
+ final GrAccessorMethod[] getters = ApplicationManager.getApplication().runReadAction(new Computable<GrAccessorMethod[]>() {
+ @Override
+ public GrAccessorMethod[] compute() {
+ return ((GrField)namedElem).getGetters();
+ }
+ });
for (GrAccessorMethod getter : getters) {
MethodReferencesSearch.search(getter).forEach(consumer);
}
}
- for (PsiReference reference : references) {
- final PsiElement element = reference.getElement();
- if (element != null) {
- occurrences.add(element);
- }
+ for (final PsiReference reference : references) {
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ @Override
+ public void run() {
+ final PsiElement element = reference.getElement();
+ if (element != null) {
+ occurrences.add(element);
+ }
+ }
+ });
}
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyNameSuggestionUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyNameSuggestionUtil.java
index 6ba946c6798b..b1856c124e0e 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyNameSuggestionUtil.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyNameSuggestionUtil.java
@@ -128,7 +128,7 @@ public class GroovyNameSuggestionUtil {
NameValidator validator,
boolean forStaticVariable,
Project project) {
- if (!JavaPsiFacade.getInstance(project).getNameHelper().isIdentifier(value)) return;
+ if (!PsiNameHelper.getInstance(project).isIdentifier(value)) return;
if (forStaticVariable) {
StringBuilder buffer = new StringBuilder(value.length() + 10);
char[] chars = new char[value.length()];
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureUtil.java
index 8c8b156eace4..097d90024daf 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureUtil.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureUtil.java
@@ -17,13 +17,14 @@ package org.jetbrains.plugins.groovy.refactoring.changeSignature;
import com.intellij.openapi.project.Project;
import com.intellij.psi.JavaPsiFacade;
+import com.intellij.psi.PsiNameHelper;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.lang.psi.util.GrStringUtil;
public class GrChangeSignatureUtil {
@NotNull
public static String getNameWithQuotesIfNeeded(@NotNull final String originalName, @NotNull final Project project) {
- return JavaPsiFacade.getInstance(project).getNameHelper().isIdentifier(originalName)
+ return PsiNameHelper.getInstance(project).isIdentifier(originalName)
? originalName
: GrStringUtil.getLiteralTextByValue(originalName).toString();
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrIntroduceConstantDialog.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrIntroduceConstantDialog.java
index 7658a3e2f211..a6f9673fbe62 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrIntroduceConstantDialog.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrIntroduceConstantDialog.java
@@ -354,7 +354,7 @@ public class GrIntroduceConstantDialog extends DialogWrapper
return;
}
final String trimmed = targetClassName.trim();
- if (!JavaPsiFacade.getInstance(myContext.getProject()).getNameHelper().isQualifiedName(trimmed)) {
+ if (!PsiNameHelper.getInstance(myContext.getProject()).isQualifiedName(trimmed)) {
setOKActionEnabled(false);
return;
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrIntroduceConstantProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrIntroduceConstantProcessor.java
index d3531eac1720..297f3fa7770a 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrIntroduceConstantProcessor.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrIntroduceConstantProcessor.java
@@ -155,13 +155,11 @@ public class GrIntroduceConstantProcessor {
return GroovyRefactoringBundle.message("class.language.is.not.groovy");
}
- final JavaPsiFacade facade = JavaPsiFacade.getInstance(context.getProject());
-
if (fieldName == null || fieldName.isEmpty()) {
return RefactoringBundle.message("no.field.name.specified");
}
- else if (!facade.getNameHelper().isIdentifier(fieldName)) {
+ else if (!PsiNameHelper.getInstance(context.getProject()).isIdentifier(fieldName)) {
return RefactoringMessageUtil.getIncorrectIdentifierMessage(fieldName);
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/DefaultGroovyScriptRunner.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/DefaultGroovyScriptRunner.java
index 90e4131f1ef9..7673ff1c334b 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/DefaultGroovyScriptRunner.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/DefaultGroovyScriptRunner.java
@@ -60,8 +60,6 @@ public class DefaultGroovyScriptRunner extends GroovyScriptRunner {
ModulesConfigurator.showDialog(module.getProject(), module.getName(), ClasspathEditor.NAME);
return false;
}
-
-
return true;
}
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTestCase.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTestCase.java
index e227a1b34663..790bd2dd5879 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTestCase.java
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTestCase.java
@@ -42,6 +42,7 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.PsiFile;
import com.intellij.testFramework.CompilerTester;
import com.intellij.testFramework.IdeaTestUtil;
@@ -77,7 +78,7 @@ public abstract class GroovyCompilerTestCase extends JavaCodeInsightFixtureTestC
@Override
protected void tuneFixture(JavaModuleFixtureBuilder moduleBuilder) throws Exception {
- moduleBuilder.setMockJdkLevel(JavaModuleFixtureBuilder.MockJdkLevel.jdk15);
+ moduleBuilder.setLanguageLevel(LanguageLevel.JDK_1_6);
moduleBuilder.addJdk(IdeaTestUtil.getMockJdk17Path().getPath());
super.tuneFixture(moduleBuilder);
}
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/actions/generate/GroovyGenerateMembersTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/actions/generate/GroovyGenerateMembersTest.groovy
index 9cc93a625c7c..53965939d7e1 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/actions/generate/GroovyGenerateMembersTest.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/actions/generate/GroovyGenerateMembersTest.groovy
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@ import com.intellij.psi.PsiClass
import com.intellij.psi.PsiFile
import com.intellij.psi.impl.source.PostprocessReformattingAspect
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
+import com.intellij.util.ui.UIUtil
import org.jetbrains.annotations.Nullable
import org.jetbrains.plugins.groovy.actions.generate.accessors.GroovyGenerateGetterSetterAction
import org.jetbrains.plugins.groovy.actions.generate.constructors.GroovyGenerateConstructorHandler
@@ -382,6 +383,7 @@ class GrImportStatementStub {
return members
}
}.invoke(project, myFixture.editor, myFixture.file);
+ UIUtil.dispatchAllInvocationEvents()
PostprocessReformattingAspect.getInstance(project).doPostponedFormatting()
}
}.execute()
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgChangeProvider.java b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgChangeProvider.java
index daaf6ec33fc5..02e49354f3ab 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgChangeProvider.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgChangeProvider.java
@@ -68,6 +68,7 @@ public class HgChangeProvider implements ChangeProvider {
public void getChanges(VcsDirtyScope dirtyScope, ChangelistBuilder builder,
ProgressIndicator progress, ChangeListManagerGate addGate) throws VcsException {
+ if (myProject.isDisposed()) return;
final Collection<HgChange> changes = new HashSet<HgChange>();
changes.addAll(process(builder, dirtyScope.getRecursivelyDirtyDirectories()));
changes.addAll(process(builder, dirtyScope.getDirtyFiles()));
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgOutgoingCommitsProvider.java b/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgOutgoingCommitsProvider.java
index 70055cafe1a1..a3ea93d7f0b9 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgOutgoingCommitsProvider.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgOutgoingCommitsProvider.java
@@ -16,7 +16,6 @@
package org.zmlx.hg4idea.push;
import com.intellij.dvcs.push.*;
-import com.intellij.dvcs.repo.Repository;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
@@ -27,6 +26,7 @@ import org.zmlx.hg4idea.command.HgOutgoingCommand;
import org.zmlx.hg4idea.execution.HgCommandResult;
import org.zmlx.hg4idea.log.HgBaseLogParser;
import org.zmlx.hg4idea.log.HgHistoryUtil;
+import org.zmlx.hg4idea.repo.HgRepository;
import org.zmlx.hg4idea.util.HgChangesetUtil;
import org.zmlx.hg4idea.util.HgErrorUtil;
import org.zmlx.hg4idea.util.HgVersion;
@@ -35,7 +35,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-public class HgOutgoingCommitsProvider extends OutgoingCommitsProvider {
+public class HgOutgoingCommitsProvider extends OutgoingCommitsProvider<HgRepository, HgPushSource, HgTarget> {
private static final Logger LOG = Logger.getInstance(HgOutgoingCommitsProvider.class);
@@ -43,8 +43,8 @@ public class HgOutgoingCommitsProvider extends OutgoingCommitsProvider {
@NotNull
@Override
- public OutgoingResult getOutgoingCommits(@NotNull final Repository repository,
- @NotNull final PushSpec pushSpec,
+ public OutgoingResult getOutgoingCommits(@NotNull final HgRepository repository,
+ @NotNull final PushSpec<HgPushSource, HgTarget> pushSpec,
boolean initial) {
final Project project = repository.getProject();
HgVcs hgvcs = HgVcs.getInstance(project);
@@ -52,9 +52,9 @@ public class HgOutgoingCommitsProvider extends OutgoingCommitsProvider {
final HgVersion version = hgvcs.getVersion();
String[] templates = HgBaseLogParser.constructFullTemplateArgument(true, version);
HgOutgoingCommand hgOutgoingCommand = new HgOutgoingCommand(project);
- HgTarget hgTarget = (HgTarget)pushSpec.getTarget();
+ HgTarget hgTarget = pushSpec.getTarget();
List<VcsError> errors = new ArrayList<VcsError>();
- if (hgTarget == null || StringUtil.isEmptyOrSpaces(hgTarget.myTarget)) {
+ if (StringUtil.isEmptyOrSpaces(hgTarget.myTarget)) {
errors.add(new VcsError("Hg push path could not be empty."));
return new OutgoingResult(Collections.<VcsFullCommitDetails>emptyList(), errors);
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushSupport.java b/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushSupport.java
index 4bfa134a5e26..13f4aaa08f6a 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushSupport.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushSupport.java
@@ -15,12 +15,14 @@
*/
package org.zmlx.hg4idea.push;
+import com.intellij.dvcs.DvcsUtil;
import com.intellij.dvcs.push.*;
-import com.intellij.dvcs.repo.Repository;
import com.intellij.dvcs.repo.RepositoryManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.AbstractVcs;
+import com.intellij.ui.SimpleColoredText;
+import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.Function;
import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.ContainerUtil;
@@ -30,10 +32,11 @@ import org.zmlx.hg4idea.HgVcs;
import org.zmlx.hg4idea.repo.HgRepository;
import org.zmlx.hg4idea.util.HgUtil;
-import java.util.Collection;
+import java.util.List;
-public class HgPushSupport extends PushSupport<HgRepository> {
+public class HgPushSupport extends PushSupport<HgRepository, HgPushSource, HgTarget> {
+ private final static String ENTER_REMOTE = "Enter Remote";
@NotNull private final Project myProject;
@NotNull private final HgVcs myVcs;
@@ -50,13 +53,13 @@ public class HgPushSupport extends PushSupport<HgRepository> {
@NotNull
@Override
- public Pusher getPusher() {
+ public Pusher<HgRepository, HgPushSource, HgTarget> getPusher() {
return new HgPusher();
}
@NotNull
@Override
- public OutgoingCommitsProvider getOutgoingCommitsProvider() {
+ public OutgoingCommitsProvider<HgRepository, HgPushSource, HgTarget> getOutgoingCommitsProvider() {
return new HgOutgoingCommitsProvider();
}
@@ -69,13 +72,13 @@ public class HgPushSupport extends PushSupport<HgRepository> {
@NotNull
@Override
- public Collection<String> getTargetNames(@NotNull HgRepository repository) {
- return ContainerUtil.map(repository.getRepositoryConfig().getPaths(), new Function<String, String>() {
+ public List<String> getTargetNames(@NotNull HgRepository repository) {
+ return ContainerUtil.sorted(ContainerUtil.map(repository.getRepositoryConfig().getPaths(), new Function<String, String>() {
@Override
public String fun(String s) {
return HgUtil.removePasswordIfNeeded(s);
}
- });
+ }));
}
@NotNull
@@ -86,6 +89,7 @@ public class HgPushSupport extends PushSupport<HgRepository> {
}
@Override
+ @NotNull
public HgTarget createTarget(@NotNull HgRepository repository, @NotNull String targetName) {
return new HgTarget(targetName);
}
@@ -103,7 +107,17 @@ public class HgPushSupport extends PushSupport<HgRepository> {
@Override
@Nullable
- public VcsError validate(@NotNull Repository repository, @Nullable String targetToValidate) {
- return StringUtil.isEmptyOrSpaces(targetToValidate) ? new VcsError("Please, specify remote push path for repository!") : null;
+ public VcsError validate(@NotNull HgRepository repository, @Nullable String targetToValidate) {
+ return StringUtil.isEmptyOrSpaces(targetToValidate)
+ ? VcsError.createEmptyTargetError(DvcsUtil.getShortRepositoryName(repository))
+ : null;
+ }
+
+ @Override
+ public SimpleColoredText renderTarget(@Nullable HgTarget target) {
+ if (target == null || StringUtil.isEmptyOrSpaces(target.getPresentation())) {
+ return new SimpleColoredText(ENTER_REMOTE, SimpleTextAttributes.GRAY_ITALIC_ATTRIBUTES);
+ }
+ return new SimpleColoredText(target.getPresentation(), SimpleTextAttributes.SYNTHETIC_ATTRIBUTES);
}
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPusher.java b/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPusher.java
index f019035a373f..e3c91e0103d9 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPusher.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPusher.java
@@ -18,7 +18,6 @@ package org.zmlx.hg4idea.push;
import com.intellij.dvcs.push.PushSpec;
import com.intellij.dvcs.push.Pusher;
import com.intellij.dvcs.push.VcsPushOptionValue;
-import com.intellij.dvcs.repo.Repository;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
@@ -37,33 +36,30 @@ import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-public class HgPusher extends Pusher {
+public class HgPusher extends Pusher<HgRepository, HgPushSource, HgTarget> {
private static final Logger LOG = Logger.getInstance(HgPusher.class);
private static final String ONE = "one";
private static Pattern PUSH_COMMITS_PATTERN = Pattern.compile(".*(?:added|pushed) (\\d+|" + ONE + ") changeset.*");
// hg push command has definite exit values for some cases:
// mercurial returns 0 if push was successful, 1 if nothing to push. see hg push --help
- private static int PUSH_SUCCEEDED_EXIT_VALUE = 0;
- private static int NOTHING_TO_PUSH_EXIT_VALUE = 1;
+ static int PUSH_SUCCEEDED_EXIT_VALUE = 0;
+ static int NOTHING_TO_PUSH_EXIT_VALUE = 1;
@Override
- public void push(@NotNull Map<Repository, PushSpec> pushSpecs, @Nullable VcsPushOptionValue vcsPushOptionValue, boolean force) {
- for (Map.Entry<Repository, PushSpec> entry : pushSpecs.entrySet()) {
- Repository repository = entry.getKey();
- HgRepository hgRepository = (HgRepository)repository;
- PushSpec hgSpec = entry.getValue();
- HgTarget destination = (HgTarget)hgSpec.getTarget();
- if (destination == null) {
- continue;
- }
- HgPushSource source = (HgPushSource)hgSpec.getSource();
+ public void push(@NotNull Map<HgRepository, PushSpec<HgPushSource, HgTarget>> pushSpecs,
+ @Nullable VcsPushOptionValue vcsPushOptionValue, boolean force) {
+ for (Map.Entry<HgRepository, PushSpec<HgPushSource, HgTarget>> entry : pushSpecs.entrySet()) {
+ HgRepository repository = entry.getKey();
+ PushSpec<HgPushSource, HgTarget> hgSpec = entry.getValue();
+ HgTarget destination = hgSpec.getTarget();
+ HgPushSource source = hgSpec.getSource();
Project project = repository.getProject();
final HgPushCommand pushCommand = new HgPushCommand(project, repository.getRoot(), destination.myTarget);
pushCommand.setIsNewBranch(true); // set always true, because it just allow mercurial to create a new one if needed
pushCommand.setForce(force);
String branchName = source.getBranch();
- if (branchName.equals(hgRepository.getCurrentBookmark())) {
+ if (branchName.equals(repository.getCurrentBookmark())) {
if (vcsPushOptionValue == HgVcsPushOptionValue.Current) {
pushCommand.setBookmarkName(branchName);
}
@@ -105,7 +101,7 @@ public class HgPusher extends Pusher {
});
}
- private static int getNumberOfPushedCommits(@NotNull HgCommandResult result) {
+ static int getNumberOfPushedCommits(@NotNull HgCommandResult result) {
int numberOfCommitsInAllSubrepos = 0;
final List<String> outputLines = result.getOutputLines();
for (String outputLine : outputLines) {
diff --git a/plugins/hg4idea/testSrc/org/zmlx/hg4idea/push/HgPushParseTest.java b/plugins/hg4idea/testSrc/org/zmlx/hg4idea/push/HgPushParseTest.java
new file mode 100644
index 000000000000..5b1774caa2fd
--- /dev/null
+++ b/plugins/hg4idea/testSrc/org/zmlx/hg4idea/push/HgPushParseTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.zmlx.hg4idea.push;
+
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.zmlx.hg4idea.execution.HgCommandResult;
+
+import java.io.StringWriter;
+import java.util.Collection;
+
+import static org.junit.Assert.assertEquals;
+
+@RunWith(Parameterized.class)
+public class HgPushParseTest {
+
+ @NotNull private final String myOutput;
+ private final int myExpected;
+
+ @SuppressWarnings({"JUnitTestCaseWithNonTrivialConstructors", "UnusedParameters"})
+ public HgPushParseTest(@NotNull String name, @NotNull String output, int expected) {
+ myOutput = output;
+ myExpected = expected;
+ }
+
+ @Parameterized.Parameters(name = "{0}")
+ public static Collection<Object[]> createData() {
+ return ContainerUtil.newArrayList(new Object[][]{
+ {"DEFAULT_1", "pushing to /Users/user/TTT/AHG\n" +
+ "searching for changes\n" +
+ "adding changesets\n" +
+ "adding manifests\n" +
+ "adding file changes\n" +
+ "added 1 changesets with 1 changes to 1 files", 1},
+ {"DEFAULT_2", "pushing to /Users/user/TTT/AHG\n" +
+ "searching for changes\n" +
+ "adding changesets\n" +
+ "adding manifests\n" +
+ "adding file changes\n" +
+ "added 2 changesets with 3 changes to 1 files", 2},
+ {"EXTENSION_KILN_ONE", "hg push http://<my repo>\n" +
+ "pushing to http://<my repo>\n" +
+ "searching for changes\n" +
+ " \"remote: kiln: successfully pushed one changeset", 1},
+ {"EXTENSION_KILN_4", "hg push http://<my repo>\n" +
+ "pushing to http://<my repo>\n" +
+ "searching for changes\n" +
+ "remote: kiln: successfully pushed 4 changesets", 4}
+ });
+ }
+
+ @Test
+ public void testValid() {
+ StringWriter outWriter = new StringWriter();
+ outWriter.write(myOutput);
+ assertEquals(" Wrong commits number for " + myOutput, myExpected,
+ HgPusher.getNumberOfPushedCommits(new HgCommandResult(outWriter, new StringWriter(), 0)));
+ }
+}
diff --git a/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/GenerateGetterSetterTest.java b/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/GenerateGetterSetterTest.java
index 8be55aba835a..3c41bf68379a 100644
--- a/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/GenerateGetterSetterTest.java
+++ b/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/GenerateGetterSetterTest.java
@@ -23,6 +23,7 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.testFramework.PlatformTestCase;
import com.intellij.testFramework.PsiTestUtil;
+import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -55,6 +56,7 @@ public class GenerateGetterSetterTest extends DaemonAnalyzerTestCase {
return members;
}
}.invoke(getProject(), getEditor(), getFile());
+ UIUtil.dispatchAllInvocationEvents();
checkResultByFile("/generateGetterSetter/after" + getTestName(false) + ".java");
}
diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/codeInsight/JavaFxGetterSetterPrototypeProvider.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/codeInsight/JavaFxGetterSetterPrototypeProvider.java
index 8ed3fd8f0e87..8c0ce5742b35 100644
--- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/codeInsight/JavaFxGetterSetterPrototypeProvider.java
+++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/codeInsight/JavaFxGetterSetterPrototypeProvider.java
@@ -15,6 +15,7 @@
*/
package org.jetbrains.plugins.javaFX.codeInsight;
+import com.intellij.codeInsight.generation.GenerateMembersUtil;
import com.intellij.codeInsight.generation.GetterSetterPrototypeProvider;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
@@ -42,7 +43,7 @@ public class JavaFxGetterSetterPrototypeProvider extends GetterSetterPrototypePr
public PsiMethod[] generateGetters(PsiField field) {
final Project project = field.getProject();
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
- final PsiMethod getter = PropertyUtil.generateGetterPrototype(field);
+ final PsiMethod getter = GenerateMembersUtil.generateGetterPrototype(field);
final PsiType wrappedType = JavaFxPsiUtil.getWrappedPropertyType(field, project, JavaFxCommonClassNames.ourReadOnlyMap);
@@ -56,12 +57,12 @@ public class JavaFxGetterSetterPrototypeProvider extends GetterSetterPrototypePr
final PsiMethod propertyGetter = PropertyUtil.generateGetterPrototype(field);
propertyGetter.setName(JavaCodeStyleManager.getInstance(project).variableNameToPropertyName(field.getName(), VariableKind.FIELD) + "Property");
- return new PsiMethod[] {getter, propertyGetter};
+ return new PsiMethod[] {getter, GenerateMembersUtil.annotateOnOverrideImplement(field.getContainingClass(), propertyGetter)};
}
@Override
public PsiMethod[] generateSetters(PsiField field) {
- final PsiMethod setter = PropertyUtil.generateSetterPrototype(field);
+ final PsiMethod setter = GenerateMembersUtil.generateSetterPrototype(field);
final Project project = field.getProject();
final PsiType wrappedType = JavaFxPsiUtil.getWrappedPropertyType(field, project, JavaFxCommonClassNames.ourWritableMap);
diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxControllerFieldSearcher.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxControllerFieldSearcher.java
index 0f3a1846b4e2..742f84fd3efc 100644
--- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxControllerFieldSearcher.java
+++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxControllerFieldSearcher.java
@@ -16,6 +16,7 @@
package org.jetbrains.plugins.javaFX.fxml.refs;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
@@ -23,6 +24,7 @@ import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
+import com.intellij.psi.util.PsiUtilCore;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.util.Processor;
@@ -43,7 +45,12 @@ public class JavaFxControllerFieldSearcher implements QueryExecutor<PsiReference
final PsiElement elementToSearch = queryParameters.getElementToSearch();
if (elementToSearch instanceof PsiField) {
final PsiField field = (PsiField)elementToSearch;
- final PsiClass containingClass = field.getContainingClass();
+ final PsiClass containingClass = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass>() {
+ @Override
+ public PsiClass compute() {
+ return field.getContainingClass();
+ }
+ });
if (containingClass != null) {
final String qualifiedName = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
@Override
@@ -52,45 +59,40 @@ public class JavaFxControllerFieldSearcher implements QueryExecutor<PsiReference
}
});
if (qualifiedName != null) {
- final List<PsiFile> fxmlWithController =
- JavaFxControllerClassIndex.findFxmlWithController(containingClass.getProject(), qualifiedName);
- final String fieldName = field.getName();
+ Project project = PsiUtilCore.getProjectInReadAction(containingClass);
+ final List<PsiFile> fxmlWithController =
+ JavaFxControllerClassIndex.findFxmlWithController(project, qualifiedName);
for (final PsiFile file : fxmlWithController) {
- final VirtualFile virtualFile = file.getViewProvider().getVirtualFile();
- final SearchScope searchScope = ApplicationManager.getApplication().runReadAction(new Computable<SearchScope>() {
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
- public SearchScope compute() {
- return queryParameters.getEffectiveSearchScope();
- }
- });
- if (searchScope instanceof LocalSearchScope) {
- if (!((LocalSearchScope)searchScope).isInScope(virtualFile)) continue;
- } else if (searchScope instanceof GlobalSearchScope) {
- if (!((GlobalSearchScope)searchScope).contains(virtualFile)) continue;
- }
- final Runnable runnable = new Runnable() {
public void run() {
- file.accept(new XmlRecursiveElementVisitor() {
- @Override
- public void visitXmlAttributeValue(final XmlAttributeValue value) {
- final PsiReference reference = value.getReference();
- if (reference != null) {
- final PsiElement resolve = reference.resolve();
- if (resolve instanceof XmlAttributeValue) {
- final PsiElement parent = resolve.getParent();
- if (parent instanceof XmlAttribute) {
- final XmlAttribute attribute = (XmlAttribute)parent;
- if (FxmlConstants.FX_ID.equals(attribute.getName()) && fieldName.equals(attribute.getValue())) {
- consumer.process(reference);
+ final String fieldName = field.getName();
+ final VirtualFile virtualFile = file.getViewProvider().getVirtualFile();
+ final SearchScope searchScope = queryParameters.getEffectiveSearchScope();
+ boolean contains = searchScope instanceof LocalSearchScope ? ((LocalSearchScope)searchScope).isInScope(virtualFile) :
+ ((GlobalSearchScope)searchScope).contains(virtualFile);
+ if (contains) {
+ file.accept(new XmlRecursiveElementVisitor() {
+ @Override
+ public void visitXmlAttributeValue(final XmlAttributeValue value) {
+ final PsiReference reference = value.getReference();
+ if (reference != null) {
+ final PsiElement resolve = reference.resolve();
+ if (resolve instanceof XmlAttributeValue) {
+ final PsiElement parent = resolve.getParent();
+ if (parent instanceof XmlAttribute) {
+ final XmlAttribute attribute = (XmlAttribute)parent;
+ if (FxmlConstants.FX_ID.equals(attribute.getName()) && fieldName.equals(attribute.getValue())) {
+ consumer.process(reference);
+ }
}
}
}
}
- }
- });
+ });
+ }
}
- };
- ApplicationManager.getApplication().runReadAction(runnable);
+ });
}
}
}
diff --git a/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/model/MavenConstants.java b/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/model/MavenConstants.java
index 6ba71e747aa1..eb1ba34a325c 100644
--- a/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/model/MavenConstants.java
+++ b/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/model/MavenConstants.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,8 +36,6 @@ public class MavenConstants {
public static final String SCOPE_COMPILE = "compile";
public static final String SCOPE_PROVIDED = "provided";
- /* @deprecated to remove in IDEA 14 */
- @SuppressWarnings({"UnusedDeclaration", "SpellCheckingInspection"}) public static final String SCOPE_PROVIDEED = SCOPE_PROVIDED;
public static final String SCOPE_RUNTIME = "runtime";
public static final String SCOPE_TEST = "test";
public static final String SCOPE_SYSTEM = "system";
diff --git a/plugins/properties/properties-psi-api/resources/messages/PropertiesBundle.properties b/plugins/properties/properties-psi-api/resources/messages/PropertiesBundle.properties
index 61b69161c5e3..f8439f059b7e 100644
--- a/plugins/properties/properties-psi-api/resources/messages/PropertiesBundle.properties
+++ b/plugins/properties/properties-psi-api/resources/messages/PropertiesBundle.properties
@@ -52,5 +52,8 @@ resource.bundle.renamer.dialog.description=Rename resource bundle properties fil
resource.bundle.renamer.entity.name=Resource bundle
resource.bundle.renamer.option=Rename bound &resource bundle
+combine.properties.files.prompt.text=Combine properties files to resource bundle with bundle base name
+combine.properties.files.title=Combine to Resource Bundle
+
inline.property.refactoring=Inline Property
inline.property.confirmation=Inline property ''{0}'' with value ''{1}''?
diff --git a/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/PropertiesUtil.java b/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/PropertiesUtil.java
index bb9b9449166f..0867b6b5faa1 100644
--- a/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/PropertiesUtil.java
+++ b/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/PropertiesUtil.java
@@ -16,16 +16,14 @@
package com.intellij.lang.properties;
import com.intellij.lang.properties.psi.PropertiesFile;
-import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectRootManager;
-import com.intellij.openapi.util.NullableComputable;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
-import com.intellij.psi.PsiFile;
import com.intellij.util.SmartList;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -38,8 +36,8 @@ import java.util.regex.Pattern;
* @author cdr
*/
public class PropertiesUtil {
- private final static Pattern LOCALE_PATTERN = Pattern.compile("(_[a-zA-Z]{2,8}(_[a-zA-Z]{2}|[0-9]{3})?(_[\\w\\-]+)?)\\.[^_]+$");
- private final static Locale DEFAULT_LOCALE = new Locale("", "", "");
+ public final static Pattern LOCALE_PATTERN = Pattern.compile("(_[a-zA-Z]{2,8}(_[a-zA-Z]{2}|[0-9]{3})?(_[\\w\\-]+)?)\\.[^_]+$");
+ public static final Set<Character> BASE_NAME_BORDER_CHAR = ContainerUtil.newHashSet('-', '_', '.');
/**
@@ -59,12 +57,28 @@ public class PropertiesUtil {
}
@NotNull
- public static String getBaseName(@NotNull PsiFile file) {
- return getBaseName(file.getContainingFile().getVirtualFile());
+ public static String getDefaultBaseName(final Collection<PropertiesFile> files) {
+ String commonPrefix = null;
+ for (PropertiesFile file : files) {
+ final String baseName = file.getVirtualFile().getNameWithoutExtension();
+ if (commonPrefix == null) {
+ commonPrefix = baseName;
+ } else {
+ commonPrefix = StringUtil.commonPrefix(commonPrefix, baseName);
+ if (commonPrefix.isEmpty()) {
+ break;
+ }
+ }
+ }
+ assert commonPrefix != null;
+ if (!commonPrefix.isEmpty() && BASE_NAME_BORDER_CHAR.contains(commonPrefix.charAt(commonPrefix.length() - 1))) {
+ commonPrefix = commonPrefix.substring(0, commonPrefix.length() - 1);
+ }
+ return commonPrefix;
}
@NotNull
- public static String getBaseName(@NotNull VirtualFile file) {
+ public static String getDefaultBaseName(@NotNull final VirtualFile file) {
final String name = file.getName();
final Matcher matcher = LOCALE_PATTERN.matcher(name);
final String baseNameWithExtension;
@@ -105,44 +119,21 @@ public class PropertiesUtil {
return null;
}
- @Nullable
- public static String getFullName(final PropertiesFile propertiesFile) {
- return ApplicationManager.getApplication().runReadAction(new NullableComputable<String>() {
- public String compute() {
- PsiDirectory directory = propertiesFile.getParent();
- String packageQualifiedName = getPackageQualifiedName(directory);
- if (packageQualifiedName == null) {
- return null;
- }
- StringBuilder qName = new StringBuilder(packageQualifiedName);
- if (qName.length() > 0) {
- qName.append(".");
- }
- qName.append(getBaseName(propertiesFile.getContainingFile()));
- return qName.toString();
- }
- });
- }
-
+ /**
+ * @deprecated use PropertiesUtil.findAllProperties(ResourceBundle resourceBundle, String key)
+ */
@NotNull
- public static Locale getLocale(final VirtualFile propertiesFile) {
- String name = propertiesFile.getName();
- final Matcher matcher = LOCALE_PATTERN.matcher(name);
- if (matcher.find()) {
- String rawLocale = matcher.group(1);
- String[] splittedRawLocale = rawLocale.split("_");
- if (splittedRawLocale.length > 1 && splittedRawLocale[1].length() == 2) {
- final String language = splittedRawLocale[1];
- final String country = splittedRawLocale.length > 2 ? splittedRawLocale[2] : "";
- final String variant = splittedRawLocale.length > 3 ? splittedRawLocale[3] : "";
- return new Locale(language, country, variant);
- }
+ @Deprecated
+ public static List<IProperty> findAllProperties(Project project, @NotNull ResourceBundle resourceBundle, String key) {
+ List<IProperty> result = new SmartList<IProperty>();
+ List<PropertiesFile> propertiesFiles = resourceBundle.getPropertiesFiles();
+ for (PropertiesFile propertiesFile : propertiesFiles) {
+ result.addAll(propertiesFile.findPropertiesByKey(key));
}
- return DEFAULT_LOCALE;
+ return result;
}
- @NotNull
- public static List<IProperty> findAllProperties(Project project, @NotNull ResourceBundle resourceBundle, String key) {
+ public static List<IProperty> findAllProperties(@NotNull ResourceBundle resourceBundle, String key) {
List<IProperty> result = new SmartList<IProperty>();
List<PropertiesFile> propertiesFiles = resourceBundle.getPropertiesFiles();
for (PropertiesFile propertiesFile : propertiesFiles) {
diff --git a/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/ResourceBundle.java b/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/ResourceBundle.java
index 7ea56269949d..b53cdae358f0 100644
--- a/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/ResourceBundle.java
+++ b/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/ResourceBundle.java
@@ -26,8 +26,8 @@ import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.openapi.actionSystem.DataKey;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.PsiDirectory;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.util.List;
@@ -38,26 +38,34 @@ public abstract class ResourceBundle {
public abstract List<PropertiesFile> getPropertiesFiles();
/**
- * @deprecated, use getPropertiesFiles() instead this method
+ * @deprecated use getPropertiesFiles() instead this method
*/
@Deprecated
@NotNull
- public abstract List<PropertiesFile> getPropertiesFiles(final Project project);
+ public List<PropertiesFile> getPropertiesFiles(final Project project) {
+ return getPropertiesFiles();
+ }
@NotNull
public abstract PropertiesFile getDefaultPropertiesFile();
/**
- * @deprecated, use getDefaultPropertiesFile() instead this method
+ * @deprecated use getDefaultPropertiesFile() instead this method
*/
@Deprecated
@NotNull
- public abstract PropertiesFile getDefaultPropertiesFile(final Project project);
+ public PropertiesFile getDefaultPropertiesFile(final Project project) {
+ return getDefaultPropertiesFile();
+ }
@NotNull
public abstract String getBaseName();
- @NotNull
+ /**
+ * @return null if resource bundle is not default ( == instance of ResourceBundleImpl)
+ */
+ @Deprecated
+ @Nullable
public abstract VirtualFile getBaseDirectory();
@NotNull
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/BundleNameEvaluator.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/BundleNameEvaluator.java
index ebe28b38b37e..52b57238d138 100644
--- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/BundleNameEvaluator.java
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/BundleNameEvaluator.java
@@ -37,7 +37,7 @@ public interface BundleNameEvaluator {
if (qName.length() > 0) {
qName.append(".");
}
- qName.append(PropertiesUtil.getBaseName(psiFile));
+ qName.append(ResourceBundleManager.getInstance(psiFile.getProject()).getBaseName(psiFile));
return qName.toString();
}
return null;
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/CustomResourceBundle.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/CustomResourceBundle.java
new file mode 100644
index 000000000000..d712dc3d8655
--- /dev/null
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/CustomResourceBundle.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.lang.properties;
+
+import com.intellij.lang.properties.psi.PropertiesFile;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileManager;
+import com.intellij.psi.PsiManager;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * @author Dmitry Batkovich
+ */
+public class CustomResourceBundle extends ResourceBundle {
+ private final static Logger LOG = Logger.getInstance(CustomResourceBundle.class);
+
+ private final List<PropertiesFile> myFiles;
+ private final String myBaseName;
+
+ private CustomResourceBundle(final List<PropertiesFile> files, final @NotNull String baseName) {
+ LOG.assertTrue(!files.isEmpty());
+ myFiles = new ArrayList<PropertiesFile>(files);
+ Collections.sort(myFiles, new Comparator<PropertiesFile>() {
+ @Override
+ public int compare(PropertiesFile f1, PropertiesFile f2) {
+ return f1.getName().compareTo(f2.getName());
+ }
+ });
+ myBaseName = baseName;
+ }
+
+ public static CustomResourceBundle fromState(final CustomResourceBundleState state, final Project project) {
+ final PsiManager psiManager = PsiManager.getInstance(project);
+ final List<PropertiesFile> files =
+ ContainerUtil.map(state.getFiles(VirtualFileManager.getInstance()), new Function<VirtualFile, PropertiesFile>() {
+ @Override
+ public PropertiesFile fun(VirtualFile virtualFile) {
+ return PropertiesImplUtil.getPropertiesFile(psiManager.findFile(virtualFile));
+ }
+ });
+ return files.size() < 2 ? null : new CustomResourceBundle(files, state.getBaseName());
+ }
+
+ @NotNull
+ @Override
+ public List<PropertiesFile> getPropertiesFiles() {
+ return myFiles;
+ }
+
+ @NotNull
+ @Override
+ public PropertiesFile getDefaultPropertiesFile() {
+ return ContainerUtil.getFirstItem(myFiles);
+ }
+
+ @NotNull
+ @Override
+ public String getBaseName() {
+ return myBaseName;
+ }
+
+ @Nullable
+ @Override
+ public VirtualFile getBaseDirectory() {
+ return null;
+ }
+
+ @NotNull
+ @Override
+ public Project getProject() {
+ return getDefaultPropertiesFile().getProject();
+ }
+
+ public boolean equals(final Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ final CustomResourceBundle resourceBundle = (CustomResourceBundle)o;
+ return resourceBundle.getPropertiesFiles().equals(resourceBundle.getPropertiesFiles()) &&
+ resourceBundle.getBaseName().equals(getBaseName());
+ }
+
+ public int hashCode() {
+ return myFiles.hashCode() * 31 + myBaseName.hashCode();
+ }
+}
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/CustomResourceBundleState.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/CustomResourceBundleState.java
new file mode 100644
index 000000000000..9be149d6a4db
--- /dev/null
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/CustomResourceBundleState.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.lang.properties;
+
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileManager;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.HashSet;
+import com.intellij.util.xmlb.annotations.AbstractCollection;
+import com.intellij.util.xmlb.annotations.Property;
+import com.intellij.util.xmlb.annotations.Tag;
+import com.intellij.util.xmlb.annotations.Transient;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author Dmitry Batkovich
+ */
+@Tag("custom-resource-bundle")
+public class CustomResourceBundleState {
+
+ @Property(surroundWithTag = false)
+ @AbstractCollection(surroundWithTag = false, elementTag = "file", elementValueAttribute = "value")
+ public Set<String> myFileUrls = new HashSet<String>();
+
+ @Tag("base-name")
+ public String myBaseName;
+
+ @Transient
+ @NotNull
+ public String getBaseName() {
+ return myBaseName;
+ }
+
+ public Set<String> getFileUrls() {
+ return myFileUrls;
+ }
+
+ public List<VirtualFile> getFiles(@NotNull final VirtualFileManager manager) {
+ return ContainerUtil.mapNotNull(getFileUrls(), new Function<String, VirtualFile>() {
+ @Override
+ public VirtualFile fun(String url) {
+ return manager.findFileByUrl(url);
+ }
+ });
+ }
+
+ @Nullable
+ public CustomResourceBundleState removeNonExistentFiles(final VirtualFileManager virtualFileManager) {
+ final List<String> existentFiles = ContainerUtil.filter(myFileUrls, new Condition<String>() {
+ @Override
+ public boolean value(String url) {
+ return virtualFileManager.findFileByUrl(url) != null;
+ }
+ });
+ if (existentFiles.isEmpty()) {
+ return null;
+ }
+ final CustomResourceBundleState customResourceBundleState = new CustomResourceBundleState();
+ customResourceBundleState.myFileUrls.addAll(existentFiles);
+ customResourceBundleState.myBaseName = myBaseName;
+ return customResourceBundleState;
+ }
+
+ public CustomResourceBundleState addAll(final Collection<String> urls) {
+ myFileUrls.addAll(urls);
+ return this;
+ }
+
+ public CustomResourceBundleState setBaseName(String baseName) {
+ myBaseName = baseName;
+ return this;
+ }
+}
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/PropertiesImplUtil.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/PropertiesImplUtil.java
index f667b1a93da0..15e73791f8ea 100644
--- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/PropertiesImplUtil.java
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/PropertiesImplUtil.java
@@ -15,6 +15,7 @@
*/
package com.intellij.lang.properties;
+import com.intellij.lang.HtmlScriptContentProvider;
import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.lang.properties.psi.PropertyKeyIndex;
import com.intellij.lang.properties.xml.XmlPropertiesFileImpl;
@@ -48,7 +49,23 @@ public class PropertiesImplUtil extends PropertiesUtil {
if (!containingFile.isValid()) {
return EmptyResourceBundle.getInstance();
}
- final String baseName = getBaseName(containingFile);
+ final ResourceBundleManager manager = ResourceBundleManager.getInstance(representative.getProject());
+ final CustomResourceBundle customResourceBundle =
+ manager.getCustomResourceBundle(representative);
+ if (customResourceBundle != null) {
+ return customResourceBundle;
+ }
+
+ final VirtualFile virtualFile = representative.getVirtualFile();
+ if (virtualFile == null) {
+ return EmptyResourceBundle.getInstance();
+ }
+ if (manager.isDefaultDissociated(virtualFile)) {
+ return new ResourceBundleImpl(representative);
+ }
+
+
+ final String baseName = manager.getBaseName(containingFile);
final PsiDirectory directory = ApplicationManager.getApplication().runReadAction(new Computable<PsiDirectory>() {
@Nullable
public PsiDirectory compute() {
@@ -61,14 +78,9 @@ public class PropertiesImplUtil extends PropertiesUtil {
@Nullable
private static ResourceBundle getResourceBundle(@NotNull final String baseName, @NotNull final PsiDirectory baseDirectory) {
PropertiesFile defaultPropertiesFile = null;
- final PsiFile[] files = ApplicationManager.getApplication().runReadAction(new Computable<PsiFile[]>() {
- @Override
- public PsiFile[] compute() {
- return baseDirectory.getFiles();
- }
- });
- for (final PsiFile psiFile : files) {
- if (baseName.equals(getBaseName(psiFile))) {
+ final ResourceBundleManager bundleBaseNameManager = ResourceBundleManager.getInstance(baseDirectory.getProject());
+ for (final PsiFile psiFile : baseDirectory.getFiles()) {
+ if (baseName.equals(bundleBaseNameManager.getBaseName(psiFile))) {
final PropertiesFile propertiesFile = getPropertiesFile(psiFile);
if (propertiesFile != null) {
if (defaultPropertiesFile == null || defaultPropertiesFile.getName().compareTo(propertiesFile.getName()) > 0) {
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/ResourceBundleImpl.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/ResourceBundleImpl.java
index ca5c8aa39a36..bad9957f7523 100644
--- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/ResourceBundleImpl.java
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/ResourceBundleImpl.java
@@ -27,6 +27,7 @@ import com.intellij.psi.PsiFile;
import com.intellij.util.SmartList;
import org.jetbrains.annotations.NotNull;
+import java.util.Collections;
import java.util.List;
public class ResourceBundleImpl extends ResourceBundle {
@@ -39,12 +40,15 @@ public class ResourceBundleImpl extends ResourceBundle {
@NotNull
@Override
public List<PropertiesFile> getPropertiesFiles() {
+ if (ResourceBundleManager.getInstance(getProject()).isDefaultDissociated(myDefaultPropertiesFile.getVirtualFile())) {
+ return Collections.singletonList(myDefaultPropertiesFile);
+ }
PsiFile[] children = myDefaultPropertiesFile.getParent().getFiles();
final String baseName = getBaseName();
List<PropertiesFile> result = new SmartList<PropertiesFile>();
for (PsiFile file : children) {
if (!file.isValid() || file.getVirtualFile().getExtension() == null) continue;
- if (Comparing.strEqual(PropertiesUtil.getBaseName(file), baseName)) {
+ if (Comparing.strEqual(PropertiesUtil.getDefaultBaseName(file.getVirtualFile()), baseName)) {
PropertiesFile propertiesFile = PropertiesImplUtil.getPropertiesFile(file);
if (propertiesFile != null) {
result.add(propertiesFile);
@@ -56,26 +60,14 @@ public class ResourceBundleImpl extends ResourceBundle {
@NotNull
@Override
- public List<PropertiesFile> getPropertiesFiles(final Project project) {
- return getPropertiesFiles();
- }
-
- @NotNull
- @Override
public PropertiesFile getDefaultPropertiesFile() {
return myDefaultPropertiesFile;
}
@NotNull
@Override
- public PropertiesFile getDefaultPropertiesFile(final Project project) {
- return getDefaultPropertiesFile();
- }
-
- @NotNull
- @Override
public String getBaseName() {
- return PropertiesUtil.getBaseName(myDefaultPropertiesFile.getContainingFile());
+ return ResourceBundleManager.getInstance(getProject()).getBaseName(myDefaultPropertiesFile.getContainingFile());
}
@NotNull
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/ResourceBundleManager.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/ResourceBundleManager.java
new file mode 100644
index 000000000000..a01c123f8763
--- /dev/null
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/ResourceBundleManager.java
@@ -0,0 +1,256 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.lang.properties;
+
+import com.intellij.lang.properties.psi.PropertiesFile;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.components.*;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.NullableComputable;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.*;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+import java.util.Locale;
+import java.util.regex.Matcher;
+
+/**
+ * @author Dmitry Batkovich
+ */
+@State(
+ name = "ResourceBundleManager",
+ storages = {
+ @Storage(file = StoragePathMacros.PROJECT_FILE),
+ @Storage(file = StoragePathMacros.PROJECT_CONFIG_DIR + "/resourceBundles.xml", scheme = StorageScheme.DIRECTORY_BASED)
+ })
+public class ResourceBundleManager implements PersistentStateComponent<ResourceBundleManagerState> {
+ private final static Logger LOG = Logger.getInstance(ResourceBundleManager.class);
+ private final static Locale DEFAULT_LOCALE = new Locale("", "", "");
+
+ private ResourceBundleManagerState myState = new ResourceBundleManagerState();
+
+ public ResourceBundleManager(final PsiManager manager) {
+ manager.addPsiTreeChangeListener(new PsiTreeChangeAdapter() {
+ @Override
+ public void childMoved(@NotNull PsiTreeChangeEvent event) {
+ final PsiElement child = event.getChild();
+ if (!(child instanceof PsiFile)) {
+ return;
+ }
+ final PropertiesFile propertiesFile = PropertiesImplUtil.getPropertiesFile((PsiFile)child);
+ if (propertiesFile == null) {
+ return;
+ }
+ final String oldParentUrl = getUrl(event.getOldParent());
+ final String newParentUrl = getUrl(event.getNewParent());
+ if (oldParentUrl == null || newParentUrl == null) {
+ return;
+ }
+ final String newUrl = propertiesFile.getVirtualFile().getUrl();
+ final String oldUrl = oldParentUrl + newUrl.substring(newParentUrl.length());
+ if (myState.getDissociatedFiles().remove(oldUrl)) {
+ myState.getDissociatedFiles().add(newUrl);
+ }
+
+ for (CustomResourceBundleState customResourceBundleState : myState.getCustomResourceBundles()) {
+ if (customResourceBundleState.getFileUrls().remove(oldUrl)) {
+ customResourceBundleState.getFileUrls().add(newUrl);
+ break;
+ }
+ }
+ }
+
+ @Nullable
+ private String getUrl(PsiElement element) {
+ return !(element instanceof PsiDirectory) ? null : ((PsiDirectory)element).getVirtualFile().getUrl();
+ }
+
+ @Override
+ public void childReplaced(@NotNull PsiTreeChangeEvent event) {
+ super.childReplaced(event);
+ }
+
+ @Override
+ public void beforeChildMovement(@NotNull PsiTreeChangeEvent event) {
+ super.beforeChildMovement(event);
+ }
+
+ @Override
+ public void propertyChanged(@NotNull PsiTreeChangeEvent event) {
+ super.propertyChanged(event);
+ }
+
+ @Override
+ public void childRemoved(@NotNull PsiTreeChangeEvent event) {
+ final PsiElement child = event.getChild();
+ if (!(child instanceof PsiFile)) {
+ return;
+ }
+ PropertiesFile file = PropertiesImplUtil.getPropertiesFile((PsiFile)child);
+ if (file == null) {
+ return;
+ }
+ final VirtualFile virtualFile = file.getVirtualFile();
+ final String url = virtualFile.getUrl();
+ myState.getDissociatedFiles().remove(url);
+ for (CustomResourceBundleState customResourceBundleState : myState.getCustomResourceBundles()) {
+ if (customResourceBundleState.getFileUrls().remove(url)) {
+ if (customResourceBundleState.getFileUrls().size() < 2) {
+ myState.getCustomResourceBundles().remove(customResourceBundleState);
+ }
+ break;
+ }
+ }
+ }
+ });
+ }
+
+ public static ResourceBundleManager getInstance(final Project project) {
+ return ServiceManager.getService(project, ResourceBundleManager.class);
+ }
+
+ @Nullable
+ public String getFullName(final @NotNull PropertiesFile propertiesFile) {
+ return ApplicationManager.getApplication().runReadAction(new NullableComputable<String>() {
+ public String compute() {
+ final PsiDirectory directory = propertiesFile.getParent();
+ final String packageQualifiedName = PropertiesUtil.getPackageQualifiedName(directory);
+ if (packageQualifiedName == null) {
+ return null;
+ }
+ final StringBuilder qName = new StringBuilder(packageQualifiedName);
+ if (qName.length() > 0) {
+ qName.append(".");
+ }
+ qName.append(getBaseName(propertiesFile.getContainingFile()));
+ return qName.toString();
+ }
+ });
+ }
+
+ @NotNull
+ public Locale getLocale(final @NotNull VirtualFile propertiesFile) {
+ final String customResourceBundleName = getCustomResourceBundleName(propertiesFile);
+
+ String name = propertiesFile.getName();
+ if (customResourceBundleName != null) {
+ name = name.substring(customResourceBundleName.length());
+ }
+
+ final Matcher matcher = PropertiesUtil.LOCALE_PATTERN.matcher(name);
+ if (matcher.find()) {
+ final String rawLocale = matcher.group(1);
+ final String[] splittedRawLocale = rawLocale.split("_");
+ if (splittedRawLocale.length > 1 && splittedRawLocale[1].length() >= 2) {
+ final String language = splittedRawLocale[1];
+ final String country = splittedRawLocale.length > 2 ? splittedRawLocale[2] : "";
+ final String variant = splittedRawLocale.length > 3 ? splittedRawLocale[3] : "";
+ return new Locale(language, country, variant);
+ }
+ }
+ return DEFAULT_LOCALE;
+ }
+
+ @NotNull
+ public String getBaseName(@NotNull final PsiFile file) {
+ return getBaseName(file.getVirtualFile());
+ }
+
+ @NotNull
+ private String getBaseName(@NotNull final VirtualFile file) {
+ final CustomResourceBundleState customResourceBundle = getCustomResourceBundleState(file);
+ if (customResourceBundle != null) {
+ return customResourceBundle.getBaseName();
+ }
+ if (isDefaultDissociated(file)) {
+ return file.getNameWithoutExtension();
+ }
+ return PropertiesUtil.getDefaultBaseName(file);
+ }
+
+
+ public void dissociateResourceBundle(final @NotNull ResourceBundle resourceBundle) {
+ if (resourceBundle instanceof CustomResourceBundle) {
+ final CustomResourceBundleState state =
+ getCustomResourceBundleState(resourceBundle.getDefaultPropertiesFile().getVirtualFile());
+ LOG.assertTrue(state != null);
+ myState.getCustomResourceBundles().remove(state);
+ } else {
+ for (final PropertiesFile propertiesFile : resourceBundle.getPropertiesFiles()) {
+ final VirtualFile file = propertiesFile.getContainingFile().getVirtualFile();
+ myState.getDissociatedFiles().add(file.getUrl());
+ }
+ }
+ }
+
+ public void combineToResourceBundle(final @NotNull List<PropertiesFile> propertiesFiles, final String baseName) {
+ myState.getCustomResourceBundles()
+ .add(new CustomResourceBundleState().addAll(ContainerUtil.map(propertiesFiles, new Function<PropertiesFile, String>() {
+ @Override
+ public String fun(PropertiesFile file) {
+ return file.getVirtualFile().getUrl();
+ }
+ })).setBaseName(baseName));
+ }
+
+ @Nullable
+ public CustomResourceBundle getCustomResourceBundle(final @NotNull PropertiesFile file) {
+ final VirtualFile virtualFile = file.getVirtualFile();
+ if (virtualFile == null) {
+ return null;
+ }
+ final CustomResourceBundleState state = getCustomResourceBundleState(virtualFile);
+ return state == null ? null : CustomResourceBundle.fromState(state, file.getProject());
+ }
+
+ public boolean isDefaultDissociated(final @NotNull VirtualFile virtualFile) {
+ final String url = virtualFile.getUrl();
+ return myState.getDissociatedFiles().contains(url) || getCustomResourceBundleState(virtualFile) != null;
+ }
+
+ @Nullable
+ private String getCustomResourceBundleName(final @NotNull VirtualFile virtualFile) {
+ final CustomResourceBundleState customResourceBundle = getCustomResourceBundleState(virtualFile);
+ return customResourceBundle == null ? null : customResourceBundle.getBaseName();
+ }
+
+ @Nullable
+ private CustomResourceBundleState getCustomResourceBundleState(final @NotNull VirtualFile virtualFile) {
+ final String url = virtualFile.getUrl();
+ for (CustomResourceBundleState customResourceBundleState : myState.getCustomResourceBundles()) {
+ if (customResourceBundleState.getFileUrls().contains(url)) {
+ return customResourceBundleState;
+ }
+ }
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public ResourceBundleManagerState getState() {
+ return myState.isEmpty() ? null : myState;
+ }
+
+ @Override
+ public void loadState(ResourceBundleManagerState state) {
+ myState = state.removeNonExistentFiles();
+ }
+}
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/ResourceBundleManagerState.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/ResourceBundleManagerState.java
new file mode 100644
index 000000000000..c4d1e5c5cb2d
--- /dev/null
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/ResourceBundleManagerState.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.lang.properties;
+
+import com.intellij.openapi.vfs.VirtualFileManager;
+import com.intellij.util.containers.HashSet;
+import com.intellij.util.xmlb.annotations.AbstractCollection;
+import com.intellij.util.xmlb.annotations.Property;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author Dmitry Batkovich
+ */
+public class ResourceBundleManagerState {
+
+ @Property(surroundWithTag = false)
+ @AbstractCollection(elementValueAttribute = "url", elementTag = "file", surroundWithTag = false)
+ public Set<String> myDissociatedFiles = new HashSet<String>();
+
+ @Property(surroundWithTag = false)
+ @AbstractCollection(elementTag = "custom-rb", surroundWithTag = false)
+ public List<CustomResourceBundleState> myCustomResourceBundles = new ArrayList<CustomResourceBundleState>();
+
+ public Set<String> getDissociatedFiles() {
+ return myDissociatedFiles;
+ }
+
+ public List<CustomResourceBundleState> getCustomResourceBundles() {
+ return myCustomResourceBundles;
+ }
+
+ public boolean isEmpty() {
+ return myCustomResourceBundles.isEmpty() && myDissociatedFiles.isEmpty();
+ }
+
+ public ResourceBundleManagerState removeNonExistentFiles() {
+ final ResourceBundleManagerState newState = new ResourceBundleManagerState();
+
+ final VirtualFileManager virtualFileManager = VirtualFileManager.getInstance();
+
+ for (final String dissociatedFileUrl : myDissociatedFiles) {
+ if (virtualFileManager.findFileByUrl(dissociatedFileUrl) != null) {
+ newState.myDissociatedFiles.add(dissociatedFileUrl);
+ }
+ }
+
+ for (CustomResourceBundleState customResourceBundle : myCustomResourceBundles) {
+ final CustomResourceBundleState updatedCustomResourceBundle = customResourceBundle.removeNonExistentFiles(virtualFileManager);
+ if (updatedCustomResourceBundle != null) {
+ newState.myCustomResourceBundles.add(updatedCustomResourceBundle);
+ }
+ }
+
+ return newState;
+ }
+}
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundlePropertyStructureViewElement.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundlePropertyStructureViewElement.java
index 724a794ca3bb..14cb1cb940c4 100644
--- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundlePropertyStructureViewElement.java
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundlePropertyStructureViewElement.java
@@ -20,11 +20,8 @@
package com.intellij.lang.properties.editor;
import com.intellij.ide.structureView.StructureViewTreeElement;
-import com.intellij.lang.properties.IProperty;
-import com.intellij.lang.properties.PropertiesHighlighter;
-import com.intellij.lang.properties.PropertiesUtil;
+import com.intellij.lang.properties.*;
import com.intellij.lang.properties.ResourceBundle;
-import com.intellij.lang.properties.psi.Property;
import com.intellij.navigation.ColoredItemPresentation;
import com.intellij.navigation.ItemPresentation;
import com.intellij.openapi.editor.colors.EditorColorsManager;
@@ -62,7 +59,7 @@ public class ResourceBundlePropertyStructureViewElement implements StructureView
@Override
public PsiElement[] getPsiElements() {
- return new PsiElement[] {getProperty().getPsiElement()};
+ return new PsiElement[] {getValue()};
}
public void setPresentableName(final String presentableName) {
@@ -70,8 +67,8 @@ public class ResourceBundlePropertyStructureViewElement implements StructureView
}
@Override
- public Property getValue() {
- return (Property)myProperty.getPsiElement();
+ public PsiElement getValue() {
+ return myProperty.getPsiElement();
}
@Override
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertiesFileImpl.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertiesFileImpl.java
index 759ce6cb46fb..99d06e8da06b 100644
--- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertiesFileImpl.java
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertiesFileImpl.java
@@ -20,6 +20,7 @@ import com.intellij.lang.ASTFactory;
import com.intellij.lang.ASTNode;
import com.intellij.lang.properties.*;
import com.intellij.lang.properties.ResourceBundle;
+import com.intellij.lang.properties.ResourceBundleManager;
import com.intellij.lang.properties.parsing.PropertiesElementTypes;
import com.intellij.lang.properties.psi.PropertiesElementFactory;
import com.intellij.lang.properties.psi.PropertiesFile;
@@ -120,7 +121,7 @@ public class PropertiesFileImpl extends PsiFileBase implements PropertiesFile {
@Override
@NotNull
public Locale getLocale() {
- return PropertiesUtil.getLocale(getVirtualFile());
+ return ResourceBundleManager.getInstance(getProject()).getLocale(getVirtualFile());
}
@Override
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/xml/XmlPropertiesFileImpl.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/xml/XmlPropertiesFileImpl.java
index 4b8953f47e9c..6c2453b94144 100644
--- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/xml/XmlPropertiesFileImpl.java
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/xml/XmlPropertiesFileImpl.java
@@ -17,8 +17,8 @@ package com.intellij.lang.properties.xml;
import com.intellij.lang.properties.IProperty;
import com.intellij.lang.properties.PropertiesImplUtil;
-import com.intellij.lang.properties.PropertiesUtil;
import com.intellij.lang.properties.ResourceBundle;
+import com.intellij.lang.properties.ResourceBundleManager;
import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.lang.properties.psi.Property;
import com.intellij.openapi.project.Project;
@@ -107,7 +107,7 @@ public class XmlPropertiesFileImpl extends XmlPropertiesFile {
@NotNull
@Override
public Locale getLocale() {
- return PropertiesUtil.getLocale(getVirtualFile());
+ return ResourceBundleManager.getInstance(getProject()).getLocale(getVirtualFile());
}
@NotNull
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/properties/PropertiesCoreEnvironment.java b/plugins/properties/properties-psi-impl/src/com/intellij/properties/PropertiesCoreEnvironment.java
index f946e41c26ae..52d4d5934b40 100644
--- a/plugins/properties/properties-psi-impl/src/com/intellij/properties/PropertiesCoreEnvironment.java
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/properties/PropertiesCoreEnvironment.java
@@ -25,6 +25,7 @@ import com.intellij.lang.LanguageParserDefinitions;
import com.intellij.lang.findUsages.LanguageFindUsages;
import com.intellij.lang.folding.LanguageFolding;
import com.intellij.lang.properties.*;
+import com.intellij.lang.properties.ResourceBundleManager;
import com.intellij.lang.properties.editor.PropertiesFoldingBuilder;
import com.intellij.lang.properties.findUsages.PropertiesFindUsagesProvider;
import com.intellij.lang.properties.parsing.PropertiesElementTypes;
@@ -87,6 +88,7 @@ public class PropertiesCoreEnvironment {
public ProjectEnvironment(CoreProjectEnvironment projectEnvironment) {
projectEnvironment.getProject().registerService(PropertiesReferenceManager.class);
projectEnvironment.getProject().registerService(PropertiesSeparatorManager.class);
+ projectEnvironment.getProject().registerService(ResourceBundleManager.class);
}
}
}
diff --git a/plugins/properties/src/META-INF/plugin.xml b/plugins/properties/src/META-INF/plugin.xml
index 513678dcbf72..672add1a002d 100644
--- a/plugins/properties/src/META-INF/plugin.xml
+++ b/plugins/properties/src/META-INF/plugin.xml
@@ -34,6 +34,7 @@
implementationClass="com.intellij.lang.properties.PropertyManipulator"/>
<projectService serviceInterface="com.intellij.lang.properties.structureView.PropertiesSeparatorManager"
serviceImplementation="com.intellij.lang.properties.structureView.PropertiesSeparatorManager"/>
+ <projectService serviceImplementation="com.intellij.lang.properties.ResourceBundleManager"/>
<codeInsight.wordCompletionFilter language="Properties"
implementationClass="com.intellij.lang.properties.PropertiesWordCompletionFilter"/>
<lang.psiStructureViewFactory language="Properties"
@@ -98,6 +99,12 @@
</project-components>
<actions>
+ <action id="DissociateResourceBundleAction" class="com.intellij.lang.properties.customizeActions.DissociateResourceBundleAction">
+ <add-to-group group-id="ProjectViewPopupMenu"/>
+ </action>
+ <action id="CombinePropertiesFilesAction" class="com.intellij.lang.properties.customizeActions.CombinePropertiesFilesAction">
+ <add-to-group group-id="ProjectViewPopupMenu"/>
+ </action>
<action id="ChooseNextSubsequentPropertyValueEditorAction"
class="com.intellij.lang.properties.editor.ChooseSubsequentPropertyValueEditorAction$Next"
text="Choose Next Property Value Editor"
diff --git a/plugins/properties/src/com/intellij/lang/properties/PropertiesFilesManager.java b/plugins/properties/src/com/intellij/lang/properties/PropertiesFilesManager.java
index 60d337681a31..5477c137021e 100644
--- a/plugins/properties/src/com/intellij/lang/properties/PropertiesFilesManager.java
+++ b/plugins/properties/src/com/intellij/lang/properties/PropertiesFilesManager.java
@@ -20,7 +20,7 @@ import com.intellij.openapi.components.AbstractProjectComponent;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.encoding.EncodingManager;
import com.intellij.psi.search.FileTypeIndex;
@@ -44,20 +44,24 @@ public class PropertiesFilesManager extends AbstractProjectComponent {
super(project);
}
+ @Override
public void projectOpened() {
final PropertyChangeListener myListener = new PropertyChangeListener() {
+ @Override
public void propertyChange(final PropertyChangeEvent evt) {
String propertyName = evt.getPropertyName();
if (EncodingManager.PROP_NATIVE2ASCII_SWITCH.equals(propertyName) ||
EncodingManager.PROP_PROPERTIES_FILES_ENCODING.equals(propertyName)
) {
DumbService.getInstance(myProject).smartInvokeLater(new Runnable(){
+ @Override
public void run() {
ApplicationManager.getApplication().runWriteAction(new Runnable(){
+ @Override
public void run() {
Collection<VirtualFile> filesToRefresh = FileBasedIndex.getInstance()
.getContainingFiles(FileTypeIndex.NAME, PropertiesFileType.INSTANCE, GlobalSearchScope.allScope(myProject));
- VirtualFile[] virtualFiles = VfsUtil.toVirtualFileArray(filesToRefresh);
+ VirtualFile[] virtualFiles = VfsUtilCore.toVirtualFileArray(filesToRefresh);
FileDocumentManager.getInstance().saveAllDocuments();
//force to re-detect encoding
@@ -75,6 +79,7 @@ public class PropertiesFilesManager extends AbstractProjectComponent {
EncodingManager.getInstance().addPropertyChangeListener(myListener,myProject);
}
+ @Override
@NotNull
public String getComponentName() {
return "PropertiesFileManager";
diff --git a/plugins/properties/src/com/intellij/lang/properties/ResourceBundleReference.java b/plugins/properties/src/com/intellij/lang/properties/ResourceBundleReference.java
index 5f708c3eda61..14ac858d9917 100644
--- a/plugins/properties/src/com/intellij/lang/properties/ResourceBundleReference.java
+++ b/plugins/properties/src/com/intellij/lang/properties/ResourceBundleReference.java
@@ -97,14 +97,14 @@ public class ResourceBundleReference extends PsiReferenceBase<PsiElement> implem
if (!(element instanceof PropertiesFile)) {
throw new IncorrectOperationException();
}
- final String name = PropertiesUtil.getFullName((PropertiesFile)element);
+ final String name = ResourceBundleManager.getInstance(element.getProject()).getFullName((PropertiesFile)element);
return super.handleElementRename(name);
}
public boolean isReferenceTo(PsiElement element) {
if (element instanceof PropertiesFile) {
- final String name = PropertiesUtil.getFullName((PropertiesFile)element);
+ final String name = ResourceBundleManager.getInstance(element.getProject()).getFullName((PropertiesFile)element);
if (name != null && name.equals(myBundleName)) {
return true;
}
diff --git a/plugins/properties/src/com/intellij/lang/properties/customizeActions/CombinePropertiesFilesAction.java b/plugins/properties/src/com/intellij/lang/properties/customizeActions/CombinePropertiesFilesAction.java
new file mode 100644
index 000000000000..b90e74a2c767
--- /dev/null
+++ b/plugins/properties/src/com/intellij/lang/properties/customizeActions/CombinePropertiesFilesAction.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.lang.properties.customizeActions;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.projectView.ProjectView;
+import com.intellij.lang.properties.PropertiesBundle;
+import com.intellij.lang.properties.PropertiesImplUtil;
+import com.intellij.lang.properties.PropertiesUtil;
+import com.intellij.lang.properties.ResourceBundle;
+import com.intellij.lang.properties.ResourceBundleManager;
+import com.intellij.lang.properties.editor.ResourceBundleAsVirtualFile;
+import com.intellij.lang.properties.psi.PropertiesFile;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.LangDataKeys;
+import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.InputValidatorEx;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Dmitry Batkovich
+ */
+public class CombinePropertiesFilesAction extends AnAction {
+
+ public CombinePropertiesFilesAction() {
+ super(PropertiesBundle.message("combine.properties.files.title"), null, AllIcons.FileTypes.Properties);
+ }
+
+ @Override
+ public void actionPerformed(final AnActionEvent e) {
+ final List<PropertiesFile> propertiesFiles = getPropertiesFiles(e);
+ final String newBaseName = Messages.showInputDialog(propertiesFiles.get(0).getProject(),
+ PropertiesBundle.message("combine.properties.files.prompt.text"),
+ PropertiesBundle.message("combine.properties.files.title"),
+ Messages.getQuestionIcon(),
+ PropertiesUtil.getDefaultBaseName(propertiesFiles),
+ new MyInputValidator(propertiesFiles));
+ if (newBaseName != null) {
+ final Project project = propertiesFiles.get(0).getProject();
+ ResourceBundleManager.getInstance(project).combineToResourceBundle(propertiesFiles, newBaseName);
+ final ResourceBundle resourceBundle = propertiesFiles.get(0).getResourceBundle();
+ FileEditorManager.getInstance(project).openFile(new ResourceBundleAsVirtualFile(resourceBundle), true);
+ ProjectView.getInstance(project).refresh();
+ }
+ }
+
+ @Override
+ public void update(final AnActionEvent e) {
+ final List<PropertiesFile> propertiesFiles = getPropertiesFiles(e);
+ boolean isAvailable = propertiesFiles != null && propertiesFiles.size() > 1;
+ if (isAvailable) {
+ for (PropertiesFile propertiesFile : propertiesFiles) {
+ if (propertiesFile.getResourceBundle().getPropertiesFiles().size() != 1) {
+ isAvailable = false;
+ break;
+ }
+ }
+ }
+ e.getPresentation().setVisible(isAvailable);
+ }
+
+ @Nullable
+ private static List<PropertiesFile> getPropertiesFiles(AnActionEvent e) {
+ final PsiElement[] psiElements = e.getData(LangDataKeys.PSI_ELEMENT_ARRAY);
+ if (psiElements == null || psiElements.length == 0) {
+ return null;
+ }
+ final List<PropertiesFile> files = new ArrayList<PropertiesFile>(psiElements.length);
+ for (PsiElement psiElement : psiElements) {
+ if (!(psiElement instanceof PsiFile)) {
+ return null;
+ }
+ final PropertiesFile propertiesFile = PropertiesImplUtil.getPropertiesFile((PsiFile)psiElement);
+ if (propertiesFile == null) {
+ return null;
+ }
+ files.add(propertiesFile);
+ }
+ return files;
+ }
+
+ @Override
+ public boolean isDumbAware() {
+ return true;
+ }
+
+ private static class MyInputValidator implements InputValidatorEx {
+ private final List<PropertiesFile> myPropertiesFiles;
+
+ private MyInputValidator(final List<PropertiesFile> propertiesFiles) {
+ myPropertiesFiles = propertiesFiles;
+ }
+
+ @Override
+ public boolean checkInput(final String newBaseName) {
+ return !newBaseName.isEmpty() && checkBaseName(newBaseName) == null;
+ }
+
+ @Override
+ public boolean canClose(final String newBaseName) {
+ return true;
+ }
+
+ @Nullable
+ @Override
+ public String getErrorText(String inputString) {
+ return checkInput(inputString) ? null : String.format("Base name must be valid for file \'%s\'", checkBaseName(inputString).getFailedFile());
+ }
+
+ @Nullable
+ private BaseNameError checkBaseName(final String baseNameCandidate) {
+ for (PropertiesFile propertiesFile : myPropertiesFiles) {
+ final String name = propertiesFile.getVirtualFile().getName();
+ if (!name.startsWith(baseNameCandidate) || !PropertiesUtil.BASE_NAME_BORDER_CHAR.contains(name.charAt(baseNameCandidate.length()))) {
+ return new BaseNameError(name);
+ }
+ }
+ return null;
+ }
+
+ private static class BaseNameError {
+
+ private final String myFailedFile;
+
+ private BaseNameError(String failedFile) {
+ myFailedFile = failedFile;
+ }
+
+ public String getFailedFile() {
+ return myFailedFile;
+ }
+ }
+ }
+}
diff --git a/plugins/properties/src/com/intellij/lang/properties/customizeActions/DissociateResourceBundleAction.java b/plugins/properties/src/com/intellij/lang/properties/customizeActions/DissociateResourceBundleAction.java
new file mode 100644
index 000000000000..10041448d97c
--- /dev/null
+++ b/plugins/properties/src/com/intellij/lang/properties/customizeActions/DissociateResourceBundleAction.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.lang.properties.customizeActions;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.projectView.ProjectView;
+import com.intellij.lang.properties.PropertiesImplUtil;
+import com.intellij.lang.properties.ResourceBundle;
+import com.intellij.lang.properties.ResourceBundleManager;
+import com.intellij.lang.properties.editor.ResourceBundleAsVirtualFile;
+import com.intellij.lang.properties.psi.PropertiesFile;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.PlatformDataKeys;
+import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.project.Project;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Dmitry Batkovich
+ */
+public class DissociateResourceBundleAction extends AnAction {
+ private static final String PRESENTATION_TEXT_TEMPLATE = "Dissociate Resource Bundle '%s'";
+
+ public DissociateResourceBundleAction() {
+ super(null, null, AllIcons.FileTypes.Properties);
+ }
+
+ @Override
+ public void actionPerformed(final AnActionEvent e) {
+ final ResourceBundle resourceBundle = extractResourceBundle(e);
+ assert resourceBundle != null;
+ final Project project = resourceBundle.getProject();
+ final FileEditorManager fileEditorManager = FileEditorManager.getInstance(project);
+ fileEditorManager.closeFile(new ResourceBundleAsVirtualFile(resourceBundle));
+ for (final PropertiesFile propertiesFile : resourceBundle.getPropertiesFiles()) {
+ fileEditorManager.closeFile(propertiesFile.getVirtualFile());
+ }
+ ResourceBundleManager.getInstance(e.getProject()).dissociateResourceBundle(resourceBundle);
+ ProjectView.getInstance(project).refresh();
+ }
+
+ @Override
+ public void update(final AnActionEvent e) {
+ final ResourceBundle resourceBundle = extractResourceBundle(e);
+ if (resourceBundle != null) {
+ e.getPresentation().setText(String.format(PRESENTATION_TEXT_TEMPLATE, resourceBundle.getBaseName()), false);
+ e.getPresentation().setVisible(true);
+ } else {
+ e.getPresentation().setVisible(false);
+ }
+ }
+
+ @Nullable
+ private static ResourceBundle extractResourceBundle(final AnActionEvent event) {
+ final ResourceBundle[] data = event.getData(ResourceBundle.ARRAY_DATA_KEY);
+ if (data != null && data.length == 1 && data[0].getPropertiesFiles().size() > 1) {
+ return data[0];
+ }
+ final PropertiesFile propertiesFile = PropertiesImplUtil.getPropertiesFile(event.getData(PlatformDataKeys.PSI_FILE));
+ if (propertiesFile == null) {
+ return null;
+ }
+ final ResourceBundle resourceBundle = propertiesFile.getResourceBundle();
+ return resourceBundle.getPropertiesFiles().size() > 1 ? resourceBundle : null;
+ }
+}
diff --git a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleAsVirtualFile.java b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleAsVirtualFile.java
index 36915e7e6962..bae39bd9f2d0 100644
--- a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleAsVirtualFile.java
+++ b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleAsVirtualFile.java
@@ -23,14 +23,10 @@ import com.intellij.ide.presentation.Presentation;
import com.intellij.lang.properties.PropertiesImplUtil;
import com.intellij.lang.properties.PropertiesUtil;
import com.intellij.lang.properties.ResourceBundle;
-import com.intellij.lang.properties.psi.PropertiesFile;
-import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileSystem;
-import com.intellij.psi.PsiManager;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.io.InputStream;
@@ -38,25 +34,15 @@ import java.io.OutputStream;
@Presentation(icon = "AllIcons.Nodes.ResourceBundle")
public class ResourceBundleAsVirtualFile extends VirtualFile {
- private final VirtualFile myBasePropertiesFile;
+ private final ResourceBundle myResourceBundle;
- private ResourceBundleAsVirtualFile(@NotNull final VirtualFile basePropertiesFile) {
- myBasePropertiesFile = basePropertiesFile;
+ public ResourceBundleAsVirtualFile(@NotNull final ResourceBundle resourceBundle) {
+ myResourceBundle = resourceBundle;
}
@NotNull
- public static ResourceBundleAsVirtualFile fromResourceBundle(final @NotNull ResourceBundle resourceBundle) {
- return new ResourceBundleAsVirtualFile(resourceBundle.getDefaultPropertiesFile().getVirtualFile());
- }
-
- @Nullable
- public ResourceBundle getResourceBundle(final Project project) {
- final PsiManager psiManager = PsiManager.getInstance(project);
- final PropertiesFile file = PropertiesImplUtil.getPropertiesFile(psiManager.findFile(myBasePropertiesFile));
- if (file == null) {
- return null;
- }
- return PropertiesImplUtil.getResourceBundle(file);
+ public ResourceBundle getResourceBundle() {
+ return myResourceBundle;
}
@Override
@@ -74,7 +60,7 @@ public class ResourceBundleAsVirtualFile extends VirtualFile {
@Override
@NotNull
public String getName() {
- return PropertiesUtil.getBaseName(myBasePropertiesFile);
+ return myResourceBundle.getBaseName();
}
public boolean equals(final Object o) {
@@ -83,13 +69,13 @@ public class ResourceBundleAsVirtualFile extends VirtualFile {
final ResourceBundleAsVirtualFile resourceBundleAsVirtualFile = (ResourceBundleAsVirtualFile)o;
- if (!myBasePropertiesFile.equals(resourceBundleAsVirtualFile.myBasePropertiesFile)) return false;
+ if (!myResourceBundle.equals(resourceBundleAsVirtualFile.myResourceBundle)) return false;
return true;
}
public int hashCode() {
- return myBasePropertiesFile.hashCode();
+ return myResourceBundle.hashCode();
}
@Override
@@ -114,7 +100,7 @@ public class ResourceBundleAsVirtualFile extends VirtualFile {
@Override
public VirtualFile getParent() {
- return myBasePropertiesFile.getParent();
+ return myResourceBundle.getBaseDirectory();
}
@Override
diff --git a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditor.java b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditor.java
index 39e9ed67e7b2..27deebbff2af 100644
--- a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditor.java
+++ b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditor.java
@@ -170,7 +170,7 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit
TreeElement[] children = myStructureViewComponent.getTreeModel().getRoot().getChildren();
if (children.length != 0) {
TreeElement child = children[0];
- String propName = ((ResourceBundlePropertyStructureViewElement)child).getValue().getUnescapedKey();
+ String propName = ((ResourceBundlePropertyStructureViewElement)child).getProperty().getUnescapedKey();
setState(new ResourceBundleEditorState(propName));
}
myDataProviderPanel = new DataProviderPanel(splitPanel);
@@ -248,7 +248,7 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit
DefaultMutableTreeNode node = toCheck.pop();
final ResourceBundleEditorViewElement element = getSelectedElement(node);
String value = element instanceof ResourceBundlePropertyStructureViewElement
- ? ((ResourceBundlePropertyStructureViewElement)element).getValue().getUnescapedKey()
+ ? ((ResourceBundlePropertyStructureViewElement)element).getProperty().getUnescapedKey()
: null;
if (propertyName.equals(value)) {
nodeToSelect = node;
diff --git a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditorProvider.java b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditorProvider.java
index fdbc2c0c5e59..d70dd358a9a9 100644
--- a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditorProvider.java
+++ b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditorProvider.java
@@ -50,7 +50,7 @@ public class ResourceBundleEditorProvider extends FileTypeFactory implements Fil
public FileEditor createEditor(@NotNull Project project, @NotNull final VirtualFile file){
ResourceBundle resourceBundle;
if (file instanceof ResourceBundleAsVirtualFile) {
- resourceBundle = ((ResourceBundleAsVirtualFile)file).getResourceBundle(project);
+ resourceBundle = ((ResourceBundleAsVirtualFile)file).getResourceBundle();
}
else {
PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
diff --git a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleStructureViewComponent.java b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleStructureViewComponent.java
index da376abe05b2..f950f613ecb9 100644
--- a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleStructureViewComponent.java
+++ b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleStructureViewComponent.java
@@ -72,7 +72,7 @@ class ResourceBundleStructureViewComponent extends PropertiesGroupingStructureVi
public Object getData(final String dataId) {
if (CommonDataKeys.VIRTUAL_FILE.is(dataId)) {
- return ResourceBundleAsVirtualFile.fromResourceBundle(myResourceBundle);
+ return new ResourceBundleAsVirtualFile(myResourceBundle);
} else if (PlatformDataKeys.FILE_EDITOR.is(dataId)) {
return getFileEditor();
} else if (LangDataKeys.PSI_ELEMENT_ARRAY.is(dataId)) {
diff --git a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleUtil.java b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleUtil.java
index e4a35e7e677c..51c3764b7f2e 100644
--- a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleUtil.java
+++ b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleUtil.java
@@ -56,7 +56,7 @@ public class ResourceBundleUtil {
}
final Project project = CommonDataKeys.PROJECT.getData(dataContext);
if (virtualFile instanceof ResourceBundleAsVirtualFile && project != null) {
- return ((ResourceBundleAsVirtualFile)virtualFile).getResourceBundle(project);
+ return ((ResourceBundleAsVirtualFile)virtualFile).getResourceBundle();
}
if (project != null) {
final PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile);
diff --git a/plugins/properties/src/com/intellij/lang/properties/projectView/CustomResourceBundlePropertiesFileNode.java b/plugins/properties/src/com/intellij/lang/properties/projectView/CustomResourceBundlePropertiesFileNode.java
new file mode 100644
index 000000000000..605b8c843a47
--- /dev/null
+++ b/plugins/properties/src/com/intellij/lang/properties/projectView/CustomResourceBundlePropertiesFileNode.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.lang.properties.projectView;
+
+import com.intellij.ide.projectView.PresentationData;
+import com.intellij.ide.projectView.ViewSettings;
+import com.intellij.ide.projectView.impl.nodes.PsiFileNode;
+import com.intellij.lang.properties.PropertiesBundle;
+import com.intellij.lang.properties.PropertiesImplUtil;
+import com.intellij.lang.properties.ResourceBundle;
+import com.intellij.lang.properties.psi.PropertiesFile;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiManager;
+import com.intellij.ui.SimpleTextAttributes;
+
+/**
+ * @author Dmitry Batkovich
+ */
+public class CustomResourceBundlePropertiesFileNode extends PsiFileNode {
+ public CustomResourceBundlePropertiesFileNode(Project project, PsiFile value, ViewSettings viewSettings) {
+ super(project, value, viewSettings);
+ setUpdateCount(-1);
+ }
+
+ @Override
+ public void update(PresentationData data) {
+ super.update(data);
+ final PropertiesFile propertiesFile = PropertiesImplUtil.getPropertiesFile(getValue());
+ assert propertiesFile != null;
+ final ResourceBundle resourceBundle = propertiesFile.getResourceBundle();
+ data.setLocationString(PropertiesBundle.message("project.view.resource.bundle.tree.node.text", resourceBundle.getBaseName()));
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (!(object instanceof CustomResourceBundlePropertiesFileNode)) {
+ return false;
+ }
+ return Comparing.equal(getValue(), ((CustomResourceBundlePropertiesFileNode)object).getValue());
+ }
+}
diff --git a/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleGrouper.java b/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleGrouper.java
index 0ac072c062c2..f6f268df3597 100644
--- a/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleGrouper.java
+++ b/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleGrouper.java
@@ -18,6 +18,7 @@ package com.intellij.lang.properties.projectView;
import com.intellij.ide.projectView.TreeStructureProvider;
import com.intellij.ide.projectView.ViewSettings;
import com.intellij.ide.util.treeView.AbstractTreeNode;
+import com.intellij.lang.properties.CustomResourceBundle;
import com.intellij.lang.properties.PropertiesImplUtil;
import com.intellij.lang.properties.ResourceBundle;
import com.intellij.lang.properties.psi.PropertiesFile;
@@ -83,6 +84,10 @@ public class ResourceBundleGrouper implements TreeStructureProvider, DumbAware {
ResourceBundle bundle = propertiesFile.getResourceBundle();
if (childBundles.get(bundle).size() != 1) {
continue;
+ } else if (bundle instanceof CustomResourceBundle) {
+ final CustomResourceBundlePropertiesFileNode node =
+ new CustomResourceBundlePropertiesFileNode(myProject, (PsiFile)f, settings);
+ result.add(node);
}
}
}
diff --git a/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleNode.java b/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleNode.java
index a415e4544aa0..b9f61643095d 100644
--- a/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleNode.java
+++ b/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleNode.java
@@ -86,7 +86,7 @@ public class ResourceBundleNode extends ProjectViewNode<ResourceBundle>{
}
public void navigate(final boolean requestFocus) {
- OpenFileDescriptor descriptor = new OpenFileDescriptor(getProject(), ResourceBundleAsVirtualFile.fromResourceBundle(getValue()));
+ OpenFileDescriptor descriptor = new OpenFileDescriptor(getProject(), new ResourceBundleAsVirtualFile(getValue()));
FileEditorManager.getInstance(getProject()).openTextEditor(descriptor, requestFocus);
}
diff --git a/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/RenamePropertyProcessor.java b/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/RenamePropertyProcessor.java
index f3c81736673f..6f0d52f1c294 100644
--- a/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/RenamePropertyProcessor.java
+++ b/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/RenamePropertyProcessor.java
@@ -46,7 +46,7 @@ public class RenamePropertyProcessor extends RenamePsiElementProcessor {
allRenames.clear();
for (final Map.Entry<PsiElement, String> e : allRenamesCopy.entrySet()) {
final IProperty property = (IProperty) e.getKey();
- final List<IProperty> properties = PropertiesUtil.findAllProperties(project, resourceBundle, property.getUnescapedKey());
+ final List<IProperty> properties = PropertiesUtil.findAllProperties(resourceBundle, property.getUnescapedKey());
for (final IProperty toRename : properties) {
allRenames.put(toRename.getPsiElement(), e.getValue());
}
diff --git a/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleRenamer.java b/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleRenamer.java
index ab1b4391b0f6..000f72ef5ae3 100644
--- a/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleRenamer.java
+++ b/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleRenamer.java
@@ -16,7 +16,7 @@
package com.intellij.lang.properties.refactoring.rename;
import com.intellij.lang.properties.PropertiesBundle;
-import com.intellij.lang.properties.PropertiesUtil;
+import com.intellij.lang.properties.ResourceBundleManager;
import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiNamedElement;
@@ -28,7 +28,10 @@ import org.jetbrains.annotations.NonNls;
*/
public class ResourceBundleRenamer extends AutomaticRenamer {
+ private final ResourceBundleManager myResourceBundleManager;
+
public ResourceBundleRenamer(final PropertiesFile propertiesFile, final String newName) {
+ myResourceBundleManager = ResourceBundleManager.getInstance(propertiesFile.getProject());
for (final PropertiesFile file : propertiesFile.getResourceBundle().getPropertiesFiles()) {
if (file.equals(propertiesFile)) {
continue;
@@ -41,12 +44,12 @@ public class ResourceBundleRenamer extends AutomaticRenamer {
@Override
protected String nameToCanonicalName(@NonNls final String name, final PsiNamedElement element) {
- return PropertiesUtil.getBaseName((PsiFile)element);
+ return myResourceBundleManager.getBaseName((PsiFile)element);
}
@Override
protected String canonicalNameToName(@NonNls final String canonicalName, final PsiNamedElement element) {
- final String oldCanonicalName = PropertiesUtil.getBaseName((PsiFile)element);
+ final String oldCanonicalName = myResourceBundleManager.getBaseName((PsiFile)element);
final String oldName = element.getName();
assert oldName != null;
return canonicalName + oldName.substring(oldCanonicalName.length());
diff --git a/plugins/properties/testSrc/com/intellij/lang/properties/CustomResourceBundleTest.java b/plugins/properties/testSrc/com/intellij/lang/properties/CustomResourceBundleTest.java
new file mode 100644
index 000000000000..69e8621ac8db
--- /dev/null
+++ b/plugins/properties/testSrc/com/intellij/lang/properties/CustomResourceBundleTest.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.lang.properties;
+
+import com.intellij.lang.properties.psi.PropertiesFile;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiManager;
+import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesProcessor;
+import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import static com.intellij.util.containers.ContainerUtil.list;
+import static com.intellij.util.containers.ContainerUtil.map;
+
+/**
+ * @author Dmitry Batkovich
+ */
+public class CustomResourceBundleTest extends LightPlatformCodeInsightFixtureTestCase {
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ ResourceBundleManager.getInstance(getProject()).loadState(new ResourceBundleManagerState());
+ }
+
+ public void testDissociateDefaultBaseName() {
+ final PsiFile file = myFixture.addFileToProject("some_property_file.properties", "");
+ final PsiFile file2 = myFixture.addFileToProject("some_property_filee.properties", "");
+ final PropertiesFile propertiesFile = PropertiesImplUtil.getPropertiesFile(file);
+ assertNotNull(propertiesFile);
+ final ResourceBundle resourceBundle = propertiesFile.getResourceBundle();
+ final ResourceBundleManager resourceBundleBaseNameManager = ResourceBundleManager.getInstance(getProject());
+ resourceBundleBaseNameManager.dissociateResourceBundle(resourceBundle);
+ for (final PsiFile psiFile : list(file, file2)) {
+ assertEquals(psiFile.getVirtualFile().getNameWithoutExtension(), resourceBundleBaseNameManager.getBaseName(psiFile));
+ final PropertiesFile somePropertyFile = PropertiesImplUtil.getPropertiesFile(file);
+ assertNotNull(somePropertyFile);
+ assertOneElement(somePropertyFile.getResourceBundle().getPropertiesFiles());
+ }
+ }
+
+ public void testCombineToCustomResourceBundleAndDissociateAfter() {
+ final PropertiesFile file = PropertiesImplUtil.getPropertiesFile(myFixture.addFileToProject("resources-dev/my-app-dev.properties", ""));
+ final PropertiesFile file2 = PropertiesImplUtil.getPropertiesFile(myFixture.addFileToProject("resources-prod/my-app-prod.properties", ""));
+ assertNotNull(file);
+ assertNotNull(file2);
+ assertOneElement(file.getResourceBundle().getPropertiesFiles());
+ assertOneElement(file2.getResourceBundle().getPropertiesFiles());
+
+ final ResourceBundleManager resourceBundleBaseNameManager = ResourceBundleManager.getInstance(getProject());
+ final String newBaseName = "my-app";
+ resourceBundleBaseNameManager.combineToResourceBundle(list(file, file2), newBaseName);
+ final ResourceBundle resourceBundle = file.getResourceBundle();
+ assertEquals(2, resourceBundle.getPropertiesFiles().size());
+ assertEquals(newBaseName, resourceBundle.getBaseName());
+
+ resourceBundleBaseNameManager.dissociateResourceBundle(resourceBundle);
+ assertOneElement(file.getResourceBundle().getPropertiesFiles());
+ assertOneElement(file2.getResourceBundle().getPropertiesFiles());
+ }
+
+ public void testCustomResourceBundleFilesMovedOrDeleted() throws IOException {
+ final PropertiesFile file = PropertiesImplUtil.getPropertiesFile(myFixture.addFileToProject("resources-dev/my-app-dev.properties", ""));
+ final PropertiesFile file2 = PropertiesImplUtil.getPropertiesFile(myFixture.addFileToProject("resources-dev/my-app-test.properties", ""));
+ final PropertiesFile file3 = PropertiesImplUtil.getPropertiesFile(myFixture.addFileToProject("resources-prod/my-app-prod.properties", ""));
+ assertNotNull(file);
+ assertNotNull(file2);
+ assertNotNull(file3);
+ assertOneElement(file.getResourceBundle().getPropertiesFiles());
+ assertOneElement(file2.getResourceBundle().getPropertiesFiles());
+ assertOneElement(file3.getResourceBundle().getPropertiesFiles());
+ final ResourceBundleManager resourceBundleBaseNameManager = ResourceBundleManager.getInstance(getProject());
+ resourceBundleBaseNameManager.combineToResourceBundle(list(file, file2, file3), "my-app");
+
+ assertSize(3, file.getResourceBundle().getPropertiesFiles());
+
+ final PsiDirectory newDir = PsiManager.getInstance(getProject()).findDirectory(myFixture.getTempDirFixture().findOrCreateDir("new-resources-dir"));
+ new MoveFilesOrDirectoriesProcessor(getProject(), new PsiElement[] {file2.getContainingFile()}, newDir, false, false, null, null).run();
+ file3.getContainingFile().delete();
+
+ assertSize(2, file.getResourceBundle().getPropertiesFiles());
+
+ final ResourceBundleManagerState state = ResourceBundleManager.getInstance(getProject()).getState();
+ assertNotNull(state);
+ assertSize(1, state.getCustomResourceBundles());
+ assertSize(2, state.getCustomResourceBundles().get(0).getFileUrls());
+ }
+
+ public void testLocaleIfCanExtractFromCustomResourceBundle() {
+ final PsiFile file = myFixture.addFileToProject("Base_Page.properties", "");
+ final PsiFile file2 = myFixture.addFileToProject("Base_Page_en.properties", "");
+ final ResourceBundleManager resourceBundleBaseNameManager = ResourceBundleManager.getInstance(getProject());
+ final PropertiesFile propertiesFile = PropertiesImplUtil.getPropertiesFile(file);
+ assertNotNull(propertiesFile);
+ resourceBundleBaseNameManager.dissociateResourceBundle(propertiesFile.getResourceBundle());
+ resourceBundleBaseNameManager.combineToResourceBundle(map(list(file, file2), new Function<PsiFile, PropertiesFile>() {
+ @Override
+ public PropertiesFile fun(final PsiFile psiFile) {
+ return PropertiesImplUtil.getPropertiesFile(psiFile);
+ }
+ }), "Base_Page");
+ final PropertiesFile propertiesFile2 = PropertiesImplUtil.getPropertiesFile(file2);
+ assertNotNull(propertiesFile2);
+ final Locale locale = propertiesFile2.getLocale();
+ assertEquals("en", locale.getLanguage());
+ }
+
+ public void testSuggestedCustomResourceBundleName() {
+ final PsiFile file = myFixture.addFileToProject("Base_Page.properties", "");
+ final PsiFile file2 = myFixture.addFileToProject("Base_Page_en.properties", "");
+ final String baseName =
+ PropertiesUtil.getDefaultBaseName(ContainerUtil.map(list(file, file2), new Function<PsiFile, PropertiesFile>() {
+ @Override
+ public PropertiesFile fun(PsiFile psiFile) {
+ return PropertiesImplUtil.getPropertiesFile(file);
+ }
+ }));
+ assertEquals("Base_Page", baseName);
+ }
+}
diff --git a/plugins/properties/testSrc/com/intellij/lang/properties/PropertiesUtilTest.java b/plugins/properties/testSrc/com/intellij/lang/properties/PropertiesUtilTest.java
index 20c44e9f47e0..44765f96fc69 100644
--- a/plugins/properties/testSrc/com/intellij/lang/properties/PropertiesUtilTest.java
+++ b/plugins/properties/testSrc/com/intellij/lang/properties/PropertiesUtilTest.java
@@ -15,12 +15,7 @@
*/
package com.intellij.lang.properties;
-import com.intellij.openapi.vfs.newvfs.impl.StubVirtualFile;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.impl.FakePsiElement;
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
-import junit.framework.TestCase;
-import org.jetbrains.annotations.NotNull;
/**
* @author Dmitry Batkovich
@@ -59,18 +54,8 @@ public class PropertiesUtilTest extends LightPlatformCodeInsightFixtureTestCase
assertBaseNameEquals("Base_Properties.utf8.properties", "Base_Properties.utf8");
}
- public void _test1() {
- assertBaseNameEquals("Base_Page_fr.utf8.properties", "Base_Page.utf8");
- }
- public void _test2() {
- assertBaseNameEquals("Base_Page_en.utf8.properties", "Base_Page.utf8");
- }
- public void _test3() {
- assertBaseNameEquals("Base_Page.utf8.properties", "Base_Page.utf8");
- }
-
private void assertBaseNameEquals(final String propertyFileName, final String expectedBaseName) {
- final String actualBaseName = PropertiesUtil.getBaseName(myFixture.configureByText(propertyFileName, ""));
+ final String actualBaseName = ResourceBundleManager.getInstance(getProject()).getBaseName(myFixture.configureByText(propertyFileName, ""));
assertEquals(expectedBaseName, actualBaseName);
}
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java
index aaf46003c1dd..cd0a321d5a58 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java
@@ -790,7 +790,9 @@ public class SvnUtil {
e.contains(SVNErrorCode.UNVERSIONED_RESOURCE) ||
e.contains(SVNErrorCode.WC_NOT_WORKING_COPY) ||
// thrown when getting info from repository for non-existent item - like HEAD revision for deleted file
- e.contains(SVNErrorCode.ILLEGAL_TARGET);
+ e.contains(SVNErrorCode.ILLEGAL_TARGET) ||
+ // for svn 1.6
+ StringUtil.containsIgnoreCase(e.getMessage(), "(not a versioned resource)");
}
// TODO: Create custom Target class and implement append there
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java
index e5018f3319d5..f4f3ee98f549 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java
@@ -32,6 +32,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Trinity;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vcs.*;
import com.intellij.openapi.vcs.annotate.AnnotationProvider;
import com.intellij.openapi.vcs.changes.*;
@@ -63,10 +64,7 @@ import org.jetbrains.idea.svn.actions.CleanupWorker;
import org.jetbrains.idea.svn.actions.ShowPropertiesDiffWithLocalAction;
import org.jetbrains.idea.svn.actions.SvnMergeProvider;
import org.jetbrains.idea.svn.annotate.SvnAnnotationProvider;
-import org.jetbrains.idea.svn.api.ClientFactory;
-import org.jetbrains.idea.svn.api.CmdClientFactory;
-import org.jetbrains.idea.svn.api.Depth;
-import org.jetbrains.idea.svn.api.SvnKitClientFactory;
+import org.jetbrains.idea.svn.api.*;
import org.jetbrains.idea.svn.auth.SvnAuthenticationNotifier;
import org.jetbrains.idea.svn.branchConfig.SvnLoadedBranchesStorage;
import org.jetbrains.idea.svn.checkin.SvnCheckinEnvironment;
@@ -264,13 +262,7 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
}
public boolean checkCommandLineVersion() {
- boolean isValid = true;
-
- if (!isProject16() && (myConfiguration.isCommandLine() || isProject18OrGreater())) {
- isValid = myChecker.checkExecutableAndNotifyIfNeeded();
- }
-
- return isValid;
+ return getFactory() != cmdClientFactory || myChecker.checkExecutableAndNotifyIfNeeded();
}
public void invokeRefreshSvnRoots() {
@@ -922,13 +914,9 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
@Override
public boolean isVcsBackgroundOperationsAllowed(@NotNull VirtualFile root) {
- // TODO: Currently myAuthNotifier.isAuthenticatedFor directly uses SVNKit to check credentials - so assume for now that background
- // TODO: operations are always allowed for command line. As sometimes this leads to errors - for instance, incoming changes are not
- // TODO: displayed in "Incoming" tab - incoming changes are collected using command line but not displayed because
- // TODO: SvnVcs.isVcsBackgroundOperationsAllowed is false.
ClientFactory factory = getFactory(VfsUtilCore.virtualToIoFile(root));
- return factory == cmdClientFactory || ThreeState.YES.equals(myAuthNotifier.isAuthenticatedFor(root));
+ return ThreeState.YES.equals(myAuthNotifier.isAuthenticatedFor(root, factory == cmdClientFactory ? factory : null));
}
public SvnBranchPointsCalculator getSvnBranchPointsCalculator() {
@@ -953,14 +941,6 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
return svnKitManager;
}
- public boolean isProject18OrGreater() {
- return getProjectRootFormat().isOrGreater(WorkingCopyFormat.ONE_DOT_EIGHT);
- }
-
- public boolean isProject16() {
- return WorkingCopyFormat.ONE_DOT_SIX.equals(getProjectRootFormat());
- }
-
@NotNull
private WorkingCopyFormat getProjectRootFormat() {
return !getProject().isDefault() ? getWorkingCopyFormat(new File(getProject().getBaseDir().getPath())) : WorkingCopyFormat.UNKNOWN;
@@ -1000,12 +980,13 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
@NotNull
private ClientFactory getFactory(@NotNull WorkingCopyFormat format, boolean useProjectRootForUnknown) {
boolean is18OrGreater = format.isOrGreater(WorkingCopyFormat.ONE_DOT_EIGHT);
- boolean is16 = WorkingCopyFormat.ONE_DOT_SIX.equals(format);
boolean isUnknown = WorkingCopyFormat.UNKNOWN.equals(format);
return is18OrGreater
? cmdClientFactory
- : (is16 ? svnKitClientFactory : (useProjectRootForUnknown && isUnknown ? getFactory() : getFactoryFromSettings()));
+ : (!isUnknown && !isSupportedByCommandLine(format)
+ ? svnKitClientFactory
+ : (useProjectRootForUnknown && isUnknown ? getFactory() : getFactoryFromSettings()));
}
@NotNull
@@ -1037,4 +1018,26 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
public ClientFactory getSvnKitFactory() {
return svnKitClientFactory;
}
+
+ @NotNull
+ public WorkingCopyFormat getLowestSupportedFormatForCommandLine() {
+ WorkingCopyFormat result;
+
+ try {
+ result = WorkingCopyFormat.from(CmdVersionClient.parseVersion(Registry.stringValue("svn.lowest.supported.format.for.command.line")));
+ }
+ catch (SvnBindException ignore) {
+ result = WorkingCopyFormat.ONE_DOT_SEVEN;
+ }
+
+ return result;
+ }
+
+ public boolean isSupportedByCommandLine(@NotNull WorkingCopyFormat format) {
+ return format.isOrGreater(getLowestSupportedFormatForCommandLine());
+ }
+
+ public boolean is16SupportedByCommandLine() {
+ return isSupportedByCommandLine(WorkingCopyFormat.ONE_DOT_SIX);
+ }
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/WorkingCopy.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/WorkingCopy.java
index 9b6530e3a914..0a23df56daad 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/WorkingCopy.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/WorkingCopy.java
@@ -15,25 +15,29 @@
*/
package org.jetbrains.idea.svn;
+import org.jetbrains.annotations.NotNull;
import org.tmatesoft.svn.core.SVNURL;
import java.io.File;
public class WorkingCopy {
private final boolean myIs17Copy;
- private final File myFile;
- private final SVNURL myUrl;
+ @NotNull private final File myFile;
+ @NotNull private final SVNURL myUrl;
- public WorkingCopy(File file, SVNURL url, boolean is17Copy) {
+ // TODO: is17Copy is currently true in all constructor usages - remove this field and revise is17Copy() usages
+ public WorkingCopy(@NotNull File file, @NotNull SVNURL url, boolean is17Copy) {
myFile = file;
myUrl = url;
myIs17Copy = is17Copy;
}
+ @NotNull
public File getFile() {
return myFile;
}
+ @NotNull
public SVNURL getUrl() {
return myUrl;
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/BaseSvnClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/BaseSvnClient.java
index 0d58355543ba..01689e586f81 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/BaseSvnClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/BaseSvnClient.java
@@ -6,13 +6,16 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.WorkingCopyFormat;
-import org.jetbrains.idea.svn.auth.IdeaSvnkitBasedAuthenticationCallback;
+import org.jetbrains.idea.svn.auth.AuthenticationService;
import org.jetbrains.idea.svn.commandLine.*;
import org.jetbrains.idea.svn.diff.DiffOptions;
import org.tmatesoft.svn.core.SVNCancelException;
import org.tmatesoft.svn.core.SVNDepth;
import org.tmatesoft.svn.core.SVNException;
-import org.tmatesoft.svn.core.wc.*;
+import org.tmatesoft.svn.core.wc.ISVNEventHandler;
+import org.tmatesoft.svn.core.wc.SVNDiffOptions;
+import org.tmatesoft.svn.core.wc.SVNEvent;
+import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc2.SvnTarget;
import java.io.File;
@@ -25,6 +28,7 @@ import java.util.List;
public abstract class BaseSvnClient implements SvnClient {
protected SvnVcs myVcs;
protected ClientFactory myFactory;
+ protected boolean myIsActive;
@NotNull
@Override
@@ -48,6 +52,11 @@ public abstract class BaseSvnClient implements SvnClient {
myFactory = factory;
}
+ @Override
+ public void setIsActive(boolean isActive) {
+ myIsActive = isActive;
+ }
+
protected void assertUrl(@NotNull SvnTarget target) {
if (!target.isURL()) {
throw new IllegalArgumentException("Target should be url " + target);
@@ -74,31 +83,22 @@ public abstract class BaseSvnClient implements SvnClient {
}
}
- /**
- * Utility method for running commands.
- * // TODO: Should be replaced with non-static analogue.
- *
- * @param vcs
- * @param target
- * @param name
- * @param parameters
- * @param listener
- * @throws com.intellij.openapi.vcs.VcsException
- */
- public static CommandExecutor execute(@NotNull SvnVcs vcs,
- @NotNull SvnTarget target,
- @NotNull SvnCommandName name,
- @NotNull List<String> parameters,
- @Nullable LineCommandListener listener) throws SvnBindException {
+ @NotNull
+ public CommandExecutor execute(@NotNull SvnVcs vcs,
+ @NotNull SvnTarget target,
+ @NotNull SvnCommandName name,
+ @NotNull List<String> parameters,
+ @Nullable LineCommandListener listener) throws SvnBindException {
return execute(vcs, target, null, name, parameters, listener);
}
- public static CommandExecutor execute(@NotNull SvnVcs vcs,
- @NotNull SvnTarget target,
- @Nullable File workingDirectory,
- @NotNull SvnCommandName name,
- @NotNull List<String> parameters,
- @Nullable LineCommandListener listener) throws SvnBindException {
+ @NotNull
+ public CommandExecutor execute(@NotNull SvnVcs vcs,
+ @NotNull SvnTarget target,
+ @Nullable File workingDirectory,
+ @NotNull SvnCommandName name,
+ @NotNull List<String> parameters,
+ @Nullable LineCommandListener listener) throws SvnBindException {
Command command = new Command(name);
command.setTarget(target);
@@ -106,7 +106,7 @@ public abstract class BaseSvnClient implements SvnClient {
command.setResultBuilder(listener);
command.put(parameters);
- CommandRuntime runtime = new CommandRuntime(vcs, new IdeaSvnkitBasedAuthenticationCallback(vcs));
+ CommandRuntime runtime = new CommandRuntime(vcs, new AuthenticationService(vcs, myIsActive));
return runtime.runWithAuthenticationAttempt(command);
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/ClientFactory.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/ClientFactory.java
index ba3e56de8e63..4eb5f8b0c7b7 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/ClientFactory.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/ClientFactory.java
@@ -1,5 +1,7 @@
package org.jetbrains.idea.svn.api;
+import com.intellij.util.ReflectionUtil;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnVcs;
@@ -18,17 +20,19 @@ import org.jetbrains.idea.svn.copy.CopyMoveClient;
import org.jetbrains.idea.svn.delete.DeleteClient;
import org.jetbrains.idea.svn.diff.DiffClient;
import org.jetbrains.idea.svn.history.HistoryClient;
+import org.jetbrains.idea.svn.info.InfoClient;
import org.jetbrains.idea.svn.integrate.MergeClient;
import org.jetbrains.idea.svn.lock.LockClient;
-import org.jetbrains.idea.svn.info.InfoClient;
-import org.jetbrains.idea.svn.status.StatusClient;
import org.jetbrains.idea.svn.properties.PropertyClient;
import org.jetbrains.idea.svn.revert.RevertClient;
+import org.jetbrains.idea.svn.status.StatusClient;
import org.jetbrains.idea.svn.update.RelocateClient;
import org.jetbrains.idea.svn.update.UpdateClient;
import org.jetbrains.idea.svn.upgrade.UpgradeClient;
import org.tmatesoft.svn.core.wc.ISVNStatusFileProvider;
+import java.util.Map;
+
/**
* @author Konstantin Kolosovsky.
*/
@@ -63,6 +67,8 @@ public abstract class ClientFactory {
protected CheckinClient myCheckinClient;
protected RepositoryFeaturesClient myRepositoryFeaturesClient;
+ @NotNull private final Map<Class, Class> myClientImplementations = ContainerUtil.newHashMap();
+
protected ClientFactory(@NotNull SvnVcs vcs) {
myVcs = vcs;
setup();
@@ -70,6 +76,33 @@ public abstract class ClientFactory {
protected abstract void setup();
+ protected <T extends SvnClient> void put(@NotNull Class<T> type, @NotNull Class<? extends T> implementation) {
+ myClientImplementations.put(type, implementation);
+ }
+
+ @SuppressWarnings("unchecked")
+ @NotNull
+ protected <T extends SvnClient> Class<? extends T> get(@NotNull Class<T> type) {
+ Class<? extends T> implementation = myClientImplementations.get(type);
+
+ if (implementation == null) {
+ throw new IllegalArgumentException("No implementation registered for " + type);
+ }
+
+ return implementation;
+ }
+
+ /**
+ * TODO: Provide more robust way for the default settings here - probably some default Command instance could be used.
+ */
+ @NotNull
+ public <T extends SvnClient> T create(@NotNull Class<T> type, boolean isActive) {
+ T client = prepare(ReflectionUtil.newInstance(get(type)));
+ client.setIsActive(isActive);
+
+ return client;
+ }
+
@NotNull
public AddClient createAddClient() {
return prepare(addClient);
@@ -209,6 +242,7 @@ public abstract class ClientFactory {
protected <T extends SvnClient> T prepare(@NotNull T client) {
client.setVcs(myVcs);
client.setFactory(this);
+ client.setIsActive(true);
return client;
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdClientFactory.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdClientFactory.java
index 54639b9e120b..6a5b9e8076f2 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdClientFactory.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdClientFactory.java
@@ -4,6 +4,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.add.CmdAddClient;
import org.jetbrains.idea.svn.annotate.CmdAnnotateClient;
+import org.jetbrains.idea.svn.browse.BrowseClient;
import org.jetbrains.idea.svn.browse.CmdBrowseClient;
import org.jetbrains.idea.svn.change.CmdChangeListClient;
import org.jetbrains.idea.svn.checkin.CmdCheckinClient;
@@ -11,18 +12,19 @@ import org.jetbrains.idea.svn.checkin.CmdImportClient;
import org.jetbrains.idea.svn.checkout.CmdCheckoutClient;
import org.jetbrains.idea.svn.checkout.CmdExportClient;
import org.jetbrains.idea.svn.cleanup.CmdCleanupClient;
-import org.jetbrains.idea.svn.status.CmdStatusClient;
-import org.jetbrains.idea.svn.info.CmdInfoClient;
import org.jetbrains.idea.svn.conflict.CmdConflictClient;
import org.jetbrains.idea.svn.content.CmdContentClient;
import org.jetbrains.idea.svn.copy.CmdCopyMoveClient;
import org.jetbrains.idea.svn.delete.CmdDeleteClient;
import org.jetbrains.idea.svn.diff.CmdDiffClient;
import org.jetbrains.idea.svn.history.CmdHistoryClient;
+import org.jetbrains.idea.svn.info.CmdInfoClient;
+import org.jetbrains.idea.svn.info.InfoClient;
import org.jetbrains.idea.svn.integrate.CmdMergeClient;
import org.jetbrains.idea.svn.lock.CmdLockClient;
import org.jetbrains.idea.svn.properties.CmdPropertyClient;
import org.jetbrains.idea.svn.revert.CmdRevertClient;
+import org.jetbrains.idea.svn.status.CmdStatusClient;
import org.jetbrains.idea.svn.update.CmdRelocateClient;
import org.jetbrains.idea.svn.update.CmdUpdateClient;
import org.jetbrains.idea.svn.update.UpdateClient;
@@ -64,6 +66,9 @@ public class CmdClientFactory extends ClientFactory {
statusClient = new CmdStatusClient();
infoClient = new CmdInfoClient();
myRepositoryFeaturesClient = new CmdRepositoryFeaturesClient();
+
+ put(BrowseClient.class, CmdBrowseClient.class);
+ put(InfoClient.class, CmdInfoClient.class);
}
@NotNull
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdVersionClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdVersionClient.java
index c3acfdc7c561..5b1484944285 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdVersionClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdVersionClient.java
@@ -2,7 +2,6 @@ package org.jetbrains.idea.svn.api;
import com.intellij.execution.process.ProcessOutput;
import com.intellij.openapi.util.Version;
-import com.intellij.openapi.vcs.VcsException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.svn.SvnApplicationSettings;
import org.jetbrains.idea.svn.commandLine.Command;
@@ -22,7 +21,7 @@ public class CmdVersionClient extends BaseSvnClient implements VersionClient {
@NotNull
@Override
- public Version getVersion() throws VcsException {
+ public Version getVersion() throws SvnBindException {
return parseVersion(runCommand());
}
@@ -38,9 +37,9 @@ public class CmdVersionClient extends BaseSvnClient implements VersionClient {
}
@NotNull
- private static Version parseVersion(@NotNull ProcessOutput output) throws VcsException {
+ private static Version parseVersion(@NotNull ProcessOutput output) throws SvnBindException {
if (output.isTimeout() || (output.getExitCode() != 0) || !output.getStderr().isEmpty()) {
- throw new VcsException(
+ throw new SvnBindException(
String.format("Exit code: %d, Error: %s, Timeout: %b", output.getExitCode(), output.getStderr(), output.isTimeout()));
}
@@ -48,7 +47,7 @@ public class CmdVersionClient extends BaseSvnClient implements VersionClient {
}
@NotNull
- public static Version parseVersion(@NotNull String versionText) throws VcsException {
+ public static Version parseVersion(@NotNull String versionText) throws SvnBindException {
Version result = null;
Exception cause = null;
@@ -65,7 +64,7 @@ public class CmdVersionClient extends BaseSvnClient implements VersionClient {
}
if (!found || cause != null) {
- throw new VcsException(String.format("Could not parse svn version: %s", versionText), cause);
+ throw new SvnBindException(String.format("Could not parse svn version: %s", versionText), cause);
}
return result;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnClient.java
index fcf100f62513..14bc054a4127 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnClient.java
@@ -17,4 +17,6 @@ public interface SvnClient {
void setVcs(@NotNull SvnVcs vcs);
void setFactory(@NotNull ClientFactory factory);
+
+ void setIsActive(boolean isActive);
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitClientFactory.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitClientFactory.java
index f46f5f06ebdb..95b17d95add8 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitClientFactory.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitClientFactory.java
@@ -5,6 +5,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.add.SvnKitAddClient;
import org.jetbrains.idea.svn.annotate.SvnKitAnnotateClient;
+import org.jetbrains.idea.svn.browse.BrowseClient;
import org.jetbrains.idea.svn.browse.SvnKitBrowseClient;
import org.jetbrains.idea.svn.change.SvnKitChangeListClient;
import org.jetbrains.idea.svn.checkin.SvnKitCheckinClient;
@@ -67,6 +68,8 @@ public class SvnKitClientFactory extends ClientFactory {
statusClient = new SvnKitStatusClient();
infoClient = new SvnKitInfoClient();
myRepositoryFeaturesClient = new SvnKitRepositoryFeaturesClient();
+
+ put(BrowseClient.class, SvnKitBrowseClient.class);
}
@NotNull
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitVersionClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitVersionClient.java
index 084f7f79d946..d0f5da5ad491 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitVersionClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitVersionClient.java
@@ -1,7 +1,6 @@
package org.jetbrains.idea.svn.api;
import com.intellij.openapi.util.Version;
-import com.intellij.openapi.vcs.VcsException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.svn.WorkingCopyFormat;
@@ -12,7 +11,7 @@ public class SvnKitVersionClient extends BaseSvnClient implements VersionClient
@NotNull
@Override
- public Version getVersion() throws VcsException {
+ public Version getVersion() {
return WorkingCopyFormat.ONE_DOT_SEVEN.getVersion();
}
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/VersionClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/VersionClient.java
index bbd70921d7a0..a37cbc17b13a 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/VersionClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/VersionClient.java
@@ -1,8 +1,8 @@
package org.jetbrains.idea.svn.api;
import com.intellij.openapi.util.Version;
-import com.intellij.openapi.vcs.VcsException;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.commandLine.SvnBindException;
/**
* @author Konstantin Kolosovsky.
@@ -10,5 +10,5 @@ import org.jetbrains.annotations.NotNull;
public interface VersionClient extends SvnClient {
@NotNull
- Version getVersion() throws VcsException;
+ Version getVersion() throws SvnBindException;
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/auth/AbstractAuthenticator.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/auth/AbstractAuthenticator.java
index 203265dea263..0c11d5a488e6 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/auth/AbstractAuthenticator.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/auth/AbstractAuthenticator.java
@@ -39,16 +39,16 @@ abstract class AbstractAuthenticator {
private static final Logger LOG = Logger.getInstance(AbstractAuthenticator.class);
- @NotNull protected final IdeaSvnkitBasedAuthenticationCallback myAuthService;
+ @NotNull protected final AuthenticationService myAuthenticationService;
@NotNull protected final SvnVcs myVcs;
@NotNull protected final SVNURL myUrl;
protected final String myRealm;
protected boolean myStoreInUsual;
protected SvnAuthenticationManager myTmpDirManager;
- AbstractAuthenticator(@NotNull IdeaSvnkitBasedAuthenticationCallback authService, @NotNull SVNURL url, String realm) {
- myAuthService = authService;
- myVcs = myAuthService.getVcs();
+ AbstractAuthenticator(@NotNull AuthenticationService authenticationService, @NotNull SVNURL url, String realm) {
+ myAuthenticationService = authenticationService;
+ myVcs = myAuthenticationService.getVcs();
myUrl = url;
myRealm = realm;
}
@@ -58,7 +58,7 @@ abstract class AbstractAuthenticator {
final SvnAuthenticationManager active = myVcs.getSvnConfiguration().getAuthenticationManager(myVcs);
try {
- boolean authenticated = getWithPassive(passive) || getWithActive(active);
+ boolean authenticated = getWithPassive(passive) || (myAuthenticationService.isActive() && getWithActive(active));
if (!authenticated) return false;
SvnAuthenticationManager manager = myStoreInUsual ? active : createTmpManager();
@@ -80,8 +80,8 @@ abstract class AbstractAuthenticator {
@NotNull
protected SvnAuthenticationManager createTmpManager() throws IOException {
if (myTmpDirManager == null) {
- myAuthService.initTmpDir(myVcs.getSvnConfiguration());
- myTmpDirManager = new SvnAuthenticationManager(myVcs.getProject(), myAuthService.getTempDirectory());
+ myAuthenticationService.initTmpDir(myVcs.getSvnConfiguration());
+ myTmpDirManager = new SvnAuthenticationManager(myVcs.getProject(), myAuthenticationService.getTempDirectory());
myTmpDirManager.setRuntimeStorage(SvnConfiguration.RUNTIME_AUTH_CACHE);
myTmpDirManager.setAuthenticationProvider(new SvnInteractiveAuthenticationProvider(myVcs, myTmpDirManager));
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/auth/IdeaSvnkitBasedAuthenticationCallback.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/auth/AuthenticationService.java
index 5b77f78aa7e1..9fb377e1dafe 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/auth/IdeaSvnkitBasedAuthenticationCallback.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/auth/AuthenticationService.java
@@ -20,7 +20,6 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.popup.util.PopupUtil;
import com.intellij.openapi.util.Getter;
-import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.WaitForProgressToShow;
@@ -32,7 +31,6 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnBundle;
import org.jetbrains.idea.svn.SvnConfiguration;
import org.jetbrains.idea.svn.SvnVcs;
-import org.jetbrains.idea.svn.commandLine.AuthenticationCallback;
import org.jetbrains.idea.svn.dialogs.SimpleCredentialsDialog;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
@@ -52,16 +50,19 @@ import java.util.Set;
* Date: 2/26/13
* Time: 1:27 PM
*/
-public class IdeaSvnkitBasedAuthenticationCallback implements AuthenticationCallback {
+public class AuthenticationService {
+
@NotNull private final SvnVcs myVcs;
- private static final Logger LOG = Logger.getInstance(IdeaSvnkitBasedAuthenticationCallback.class);
+ private final boolean myIsActive;
+ private static final Logger LOG = Logger.getInstance(AuthenticationService.class);
private File myTempDirectory;
private boolean myProxyCredentialsWereReturned;
private SvnConfiguration myConfiguration;
private final Set<String> myRequestedCredentials;
- public IdeaSvnkitBasedAuthenticationCallback(@NotNull SvnVcs vcs) {
+ public AuthenticationService(@NotNull SvnVcs vcs, boolean isActive) {
myVcs = vcs;
+ myIsActive = isActive;
myConfiguration = SvnConfiguration.getInstance(myVcs.getProject());
myRequestedCredentials = ContainerUtil.newHashSet();
}
@@ -76,8 +77,11 @@ public class IdeaSvnkitBasedAuthenticationCallback implements AuthenticationCall
return myTempDirectory;
}
- @Override
- public boolean authenticateFor(String realm, SVNURL repositoryUrl, boolean previousFailed, boolean passwordRequest) {
+ public boolean isActive() {
+ return myIsActive;
+ }
+
+ public boolean authenticateFor(@Nullable String realm, SVNURL repositoryUrl, boolean passwordRequest) {
if (repositoryUrl == null) {
return false;
}
@@ -85,20 +89,17 @@ public class IdeaSvnkitBasedAuthenticationCallback implements AuthenticationCall
}
@Nullable
- @Override
public SVNAuthentication requestCredentials(final SVNURL repositoryUrl, final String type) {
SVNAuthentication authentication = null;
if (repositoryUrl != null) {
final String realm = repositoryUrl.toDecodedString();
- authentication = requestCredentials(realm, type, new Getter<Pair<SVNAuthentication, Boolean>>() {
+ authentication = requestCredentials(realm, type, new Getter<SVNAuthentication>() {
@Override
- public Pair<SVNAuthentication, Boolean> get() {
- SVNAuthentication result = myVcs.getSvnConfiguration().getInteractiveManager(myVcs).getInnerProvider()
+ public SVNAuthentication get() {
+ return myVcs.getSvnConfiguration().getInteractiveManager(myVcs).getInnerProvider()
.requestClientAuthentication(type, repositoryUrl, realm, null, null, true);
-
- return new Pair<SVNAuthentication, Boolean>(result, true);
}
});
}
@@ -111,8 +112,8 @@ public class IdeaSvnkitBasedAuthenticationCallback implements AuthenticationCall
}
@Nullable
- private <T> T requestCredentials(@NotNull String realm, @NotNull String type, @NotNull Getter<Pair<T, Boolean>> fromUserProvider) {
- T result;
+ private <T> T requestCredentials(@NotNull String realm, @NotNull String type, @NotNull Getter<T> fromUserProvider) {
+ T result = null;
// Search for stored credentials not only by key but also by "parent" keys. This is useful when we work just with URLs
// (not working copy) and can't detect repository url beforehand because authentication is required. If found credentials of "parent"
// are not correct then current key will already be stored in myRequestedCredentials - thus user will be asked for credentials and
@@ -126,12 +127,10 @@ public class IdeaSvnkitBasedAuthenticationCallback implements AuthenticationCall
result = (T)data;
myRequestedCredentials.add(key);
}
- else {
+ else if (myIsActive) {
// ask user for credentials
- Pair<T, Boolean> userData = fromUserProvider.get();
- result = userData.first;
-
- if (result != null && userData.second) {
+ result = fromUserProvider.get();
+ if (result != null) {
// save user credentials to memory cache
myVcs.getSvnConfiguration().acknowledge(type, realm, result);
myRequestedCredentials.add(key);
@@ -141,14 +140,13 @@ public class IdeaSvnkitBasedAuthenticationCallback implements AuthenticationCall
return result;
}
- @Override
@Nullable
public String requestSshCredentials(@NotNull final String realm,
@NotNull final SimpleCredentialsDialog.Mode mode,
@NotNull final String key) {
- return requestCredentials(realm, ISVNAuthenticationManager.SSH, new Getter<Pair<String, Boolean>>() {
+ return requestCredentials(realm, ISVNAuthenticationManager.SSH, new Getter<String>() {
@Override
- public Pair<String, Boolean> get() {
+ public String get() {
final Ref<String> answer = new Ref<String>();
Runnable command = new Runnable() {
@@ -169,12 +167,11 @@ public class IdeaSvnkitBasedAuthenticationCallback implements AuthenticationCall
// the thread that started progress
WaitForProgressToShow.runOrInvokeAndWaitAboveProgress(command, ModalityState.any());
- return new Pair<String, Boolean>(answer.get(), true);
+ return answer.get();
}
});
}
- @Override
public boolean acceptSSLServerCertificate(final SVNURL repositoryUrl, final String realm) {
if (repositoryUrl == null) {
return false;
@@ -183,7 +180,6 @@ public class IdeaSvnkitBasedAuthenticationCallback implements AuthenticationCall
return new SSLServerCertificateAuthenticator(this, repositoryUrl, realm).tryAuthenticate();
}
- @Override
public void clearPassiveCredentials(String realm, SVNURL repositoryUrl, boolean password) {
if (repositoryUrl == null) {
return;
@@ -197,7 +193,6 @@ public class IdeaSvnkitBasedAuthenticationCallback implements AuthenticationCall
}
}
- @Override
public boolean haveDataForTmpConfig() {
final HttpConfigurable instance = HttpConfigurable.getInstance();
return SvnConfiguration.getInstance(myVcs.getProject()).isIsUseDefaultProxy() &&
@@ -227,7 +222,6 @@ public class IdeaSvnkitBasedAuthenticationCallback implements AuthenticationCall
return null;
}
- @Override
@Nullable
public PasswordAuthentication getProxyAuthentication(@NotNull SVNURL repositoryUrl) {
Proxy proxy = getIdeaDefinedProxy(repositoryUrl);
@@ -296,7 +290,6 @@ public class IdeaSvnkitBasedAuthenticationCallback implements AuthenticationCall
}
@Nullable
- @Override
public File getSpecialConfigDir() {
return myTempDirectory != null ? myTempDirectory : new File(myConfiguration.getConfigurationDirectory());
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/auth/CredentialsAuthenticator.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/auth/CredentialsAuthenticator.java
index 410cb0997201..9658e2adbba7 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/auth/CredentialsAuthenticator.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/auth/CredentialsAuthenticator.java
@@ -37,14 +37,12 @@ class CredentialsAuthenticator extends AbstractAuthenticator {
private String myRealm2;
private SVNAuthentication myAuthentication;
- CredentialsAuthenticator(@NotNull IdeaSvnkitBasedAuthenticationCallback authService,
- @NotNull SVNURL url,
- @Nullable String realm) {
- super(authService, url, realm == null ? url.getHost() : realm);
+ CredentialsAuthenticator(@NotNull AuthenticationService authenticationService, @NotNull SVNURL url, @Nullable String realm) {
+ super(authenticationService, url, realm == null ? url.getHost() : realm);
}
public boolean tryAuthenticate(boolean passwordRequest) {
- final List<String> kinds = IdeaSvnkitBasedAuthenticationCallback.getKinds(myUrl, passwordRequest);
+ final List<String> kinds = AuthenticationService.getKinds(myUrl, passwordRequest);
for (String kind : kinds) {
myKind = kind;
if (!tryAuthenticate()) {
@@ -58,8 +56,8 @@ class CredentialsAuthenticator extends AbstractAuthenticator {
protected boolean getWithPassive(SvnAuthenticationManager passive) throws SVNException {
myAuthentication = getWithPassiveImpl(passive);
if (myAuthentication != null && !checkAuthOk(myAuthentication)) {
- myAuthService.clearPassiveCredentials(myRealm, myUrl,
- myAuthentication instanceof SVNPasswordAuthentication); //clear passive also take into acconut ssl filepath
+ //clear passive also take into account ssl file path
+ myAuthenticationService.clearPassiveCredentials(myRealm, myUrl, myAuthentication instanceof SVNPasswordAuthentication);
myAuthentication = null;
}
return myAuthentication != null;
@@ -88,7 +86,7 @@ class CredentialsAuthenticator extends AbstractAuthenticator {
if (super.getWithActive(active)) return true;
}
myAuthentication = active.getProvider().requestClientAuthentication(myKind, myUrl, myRealm, null, null, true);
- myStoreInUsual = myAuthService.getTempDirectory() == null && myAuthentication != null && myAuthentication.isStorageAllowed();
+ myStoreInUsual = myAuthenticationService.getTempDirectory() == null && myAuthentication != null && myAuthentication.isStorageAllowed();
return myAuthentication != null;
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/auth/SSLServerCertificateAuthenticator.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/auth/SSLServerCertificateAuthenticator.java
index 3b78aa55d867..7d76a1fa0536 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/auth/SSLServerCertificateAuthenticator.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/auth/SSLServerCertificateAuthenticator.java
@@ -41,10 +41,8 @@ class SSLServerCertificateAuthenticator extends AbstractAuthenticator {
private int myResult;
private SVNAuthentication myAuthentication;
- SSLServerCertificateAuthenticator(@NotNull IdeaSvnkitBasedAuthenticationCallback authService,
- @NotNull SVNURL url,
- String realm) {
- super(authService, url, realm);
+ SSLServerCertificateAuthenticator(@NotNull AuthenticationService authenticationService, @NotNull SVNURL url, String realm) {
+ super(authenticationService, url, realm);
}
@Override
@@ -102,7 +100,7 @@ class SSLServerCertificateAuthenticator extends AbstractAuthenticator {
myCertificate = createCertificate(stored);
myCertificateRealm = myRealm;
}
- if (myAuthService.getTempDirectory() != null && myCertificate != null) {
+ if (myAuthenticationService.getTempDirectory() != null && myCertificate != null) {
storeServerCertificate();
if (myAuthentication != null) {
@@ -142,7 +140,7 @@ class SSLServerCertificateAuthenticator extends AbstractAuthenticator {
}
int failures = SVNSSLUtil.getServerCertificateFailures(x509Certificate, myUrl.getHost());
- storeServerCertificate(myAuthService.getTempDirectory(), myCertificateRealm, stored, failures);
+ storeServerCertificate(myAuthenticationService.getTempDirectory(), myCertificateRealm, stored, failures);
}
private void storeServerCertificate(final File configDir, String realm, String data, int failures) throws SVNException {
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/auth/SvnAuthenticationNotifier.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/auth/SvnAuthenticationNotifier.java
index ffc21a011334..29f15423e581 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/auth/SvnAuthenticationNotifier.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/auth/SvnAuthenticationNotifier.java
@@ -44,6 +44,10 @@ import com.intellij.util.proxy.CommonProxy;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.*;
+import org.jetbrains.idea.svn.api.ClientFactory;
+import org.jetbrains.idea.svn.commandLine.SvnBindException;
+import org.jetbrains.idea.svn.info.Info;
+import org.jetbrains.idea.svn.info.InfoClient;
import org.tmatesoft.svn.core.SVNAuthenticationException;
import org.tmatesoft.svn.core.SVNCancelException;
import org.tmatesoft.svn.core.SVNException;
@@ -172,6 +176,7 @@ public class SvnAuthenticationNotifier extends GenericNotifierImpl<SvnAuthentica
}
log("on state changed ");
ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
public void run() {
for (SVNURL key : outdatedRequests) {
removeLazyNotificationByKey(key);
@@ -223,7 +228,7 @@ public class SvnAuthenticationNotifier extends GenericNotifierImpl<SvnAuthentica
/**
* Bases on presence of notifications!
*/
- public ThreeState isAuthenticatedFor(@NotNull VirtualFile vf) {
+ public ThreeState isAuthenticatedFor(@NotNull VirtualFile vf, @Nullable ClientFactory factory) {
final WorkingCopy wcCopy = myRootsToWorkingCopies.getWcRoot(vf);
if (wcCopy == null) return ThreeState.UNSURE;
@@ -236,11 +241,24 @@ public class SvnAuthenticationNotifier extends GenericNotifierImpl<SvnAuthentica
if (Boolean.FALSE.equals(keptResult)) return ThreeState.NO;
// check have credentials
- final boolean calculatedResult = passiveValidation(myVcs.getProject(), wcCopy.getUrl());
+ final boolean calculatedResult =
+ factory == null ? passiveValidation(myVcs.getProject(), wcCopy.getUrl()) : passiveValidation(factory, wcCopy.getUrl());
myCopiesPassiveResults.put(wcCopy.getUrl(), calculatedResult);
return calculatedResult ? ThreeState.YES : ThreeState.NO;
}
+ private static boolean passiveValidation(@NotNull ClientFactory factory, @NotNull SVNURL url) {
+ Info info = null;
+
+ try {
+ info = factory.create(InfoClient.class, false).doInfo(url, SVNRevision.UNDEFINED, SVNRevision.UNDEFINED);
+ }
+ catch (SvnBindException ignore) {
+ }
+
+ return info != null;
+ }
+
@NotNull
@Override
protected String getNotificationContent(AuthenticationRequest obj) {
@@ -470,6 +488,7 @@ public class SvnAuthenticationNotifier extends GenericNotifierImpl<SvnAuthentica
final File authDir = new File(configuration.getConfigurationDirectory(), "auth");
if (authDir.exists()) {
final Runnable process = new Runnable() {
+ @Override
public void run() {
final ProgressIndicator ind = ProgressManager.getInstance().getProgressIndicator();
if (ind != null) {
@@ -477,7 +496,8 @@ public class SvnAuthenticationNotifier extends GenericNotifierImpl<SvnAuthentica
ind.setText("Clearing stored credentials in " + authDir.getAbsolutePath());
}
final File[] files = authDir.listFiles(new FilenameFilter() {
- public boolean accept(File dir, String name) {
+ @Override
+ public boolean accept(@NotNull File dir, @NotNull String name) {
return ourAuthKinds.contains(name);
}
});
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/BranchesLoader.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/BranchesLoader.java
index ba0288da9699..a51ce8c13629 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/BranchesLoader.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/BranchesLoader.java
@@ -21,13 +21,13 @@ import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.idea.svn.SvnConfiguration;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.api.Depth;
+import org.jetbrains.idea.svn.browse.BrowseClient;
import org.jetbrains.idea.svn.browse.DirectoryEntry;
import org.jetbrains.idea.svn.browse.DirectoryEntryConsumer;
-import org.tmatesoft.svn.core.*;
-import org.tmatesoft.svn.core.wc.SVNLogClient;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc2.SvnTarget;
@@ -75,23 +75,13 @@ public class BranchesLoader implements Runnable {
@NotNull
public List<SvnBranchItem> loadBranches() throws SVNException, VcsException {
- final SvnConfiguration configuration = SvnConfiguration.getInstance(myProject);
- final SvnVcs vcs = SvnVcs.getInstance(myProject);
+ SvnVcs vcs = SvnVcs.getInstance(myProject);
SVNURL branchesUrl = SVNURL.parseURIEncoded(myUrl);
List<SvnBranchItem> result = new LinkedList<SvnBranchItem>();
SvnTarget target = SvnTarget.fromURL(branchesUrl);
+ DirectoryEntryConsumer handler = createConsumer(result);
- if (!myPassive) {
- // TODO: Implement ability to specify interactive/non-interactive auth mode for clients
- DirectoryEntryConsumer handler = createConsumer(branchesUrl, result);
- vcs.getFactory(target).createBrowseClient().list(target, SVNRevision.HEAD, Depth.IMMEDIATES, handler);
- }
- else {
- ISVNDirEntryHandler handler = createHandler(branchesUrl, result);
- SVNLogClient client = vcs.getSvnKitManager().createLogClient(configuration.getPassiveAuthenticationManager(myProject));
- client
- .doList(target.getURL(), target.getPegRevision(), SVNRevision.HEAD, false, SVNDepth.IMMEDIATES, SVNDirEntry.DIRENT_ALL, handler);
- }
+ vcs.getFactory(target).create(BrowseClient.class, !myPassive).list(target, SVNRevision.HEAD, Depth.IMMEDIATES, handler);
Collections.sort(result);
return result;
@@ -105,25 +95,12 @@ public class BranchesLoader implements Runnable {
}
@NotNull
- private static ISVNDirEntryHandler createHandler(@NotNull final SVNURL branchesUrl, @NotNull final List<SvnBranchItem> result) {
- return new ISVNDirEntryHandler() {
- public void handleDirEntry(final SVNDirEntry dirEntry) throws SVNException {
- // TODO: Remove equality check with branchesUrl when SVNLogClient will not be used directly, but rather through BrowseClient.
- if (!branchesUrl.equals(dirEntry.getURL()) && dirEntry.getDate() != null) {
- result.add(new SvnBranchItem(dirEntry.getURL().toDecodedString(), dirEntry.getDate(), dirEntry.getRevision()));
- }
- }
- };
- }
-
- @NotNull
- private static DirectoryEntryConsumer createConsumer(@NotNull final SVNURL branchesUrl, @NotNull final List<SvnBranchItem> result) {
+ private static DirectoryEntryConsumer createConsumer(@NotNull final List<SvnBranchItem> result) {
return new DirectoryEntryConsumer() {
@Override
public void consume(final DirectoryEntry entry) throws SVNException {
- // TODO: Remove equality check with branchesUrl when SVNLogClient will not be used directly, but rather through BrowseClient.
- if (!branchesUrl.equals(entry.getUrl()) && entry.getDate() != null) {
+ if (entry.getDate() != null) {
result.add(new SvnBranchItem(entry.getUrl().toDecodedString(), entry.getDate(), entry.getRevision()));
}
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/browse/SvnKitBrowseClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/browse/SvnKitBrowseClient.java
index cdbb1ff1e67b..ac1d4a0486df 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/browse/SvnKitBrowseClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/browse/SvnKitBrowseClient.java
@@ -23,6 +23,7 @@ import org.jetbrains.idea.svn.api.BaseSvnClient;
import org.jetbrains.idea.svn.api.Depth;
import org.jetbrains.idea.svn.commandLine.SvnBindException;
import org.tmatesoft.svn.core.*;
+import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.wc.SVNLogClient;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc2.SvnTarget;
@@ -38,7 +39,7 @@ public class SvnKitBrowseClient extends BaseSvnClient implements BrowseClient {
@Nullable DirectoryEntryConsumer handler) throws VcsException {
assertUrl(target);
- SVNLogClient client = myVcs.getSvnKitManager().createLogClient();
+ SVNLogClient client = getLogClient();
ISVNDirEntryHandler wrappedHandler = wrapHandler(handler);
try {
@@ -69,6 +70,15 @@ public class SvnKitBrowseClient extends BaseSvnClient implements BrowseClient {
}
}
+ @NotNull
+ private SVNLogClient getLogClient() {
+ ISVNAuthenticationManager authManager = myIsActive
+ ? myVcs.getSvnConfiguration().getInteractiveManager(myVcs)
+ : myVcs.getSvnConfiguration().getPassiveAuthenticationManager(myVcs.getProject());
+
+ return myVcs.getSvnKitManager().createLogClient(authManager);
+ }
+
@Nullable
private static ISVNDirEntryHandler wrapHandler(@Nullable DirectoryEntryConsumer handler) {
return handler == null ? null : new SkipEmptyNameDirectoriesHandler(handler);
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/AuthCallbackCase.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/AuthCallbackCase.java
index 8a55a6e89860..77cca02a04fb 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/AuthCallbackCase.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/AuthCallbackCase.java
@@ -16,6 +16,7 @@
package org.jetbrains.idea.svn.commandLine;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.auth.AuthenticationService;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNURL;
@@ -25,10 +26,10 @@ import org.tmatesoft.svn.core.SVNURL;
public abstract class AuthCallbackCase {
protected final SVNURL myUrl;
protected boolean myTried = false;
- @NotNull protected final AuthenticationCallback myAuthenticationCallback;
+ @NotNull protected final AuthenticationService myAuthenticationService;
- AuthCallbackCase(@NotNull AuthenticationCallback callback, SVNURL url) {
- myAuthenticationCallback = callback;
+ AuthCallbackCase(@NotNull AuthenticationService authenticationService, SVNURL url) {
+ myAuthenticationService = authenticationService;
myUrl = url;
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/AuthenticationCallback.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/AuthenticationCallback.java
deleted file mode 100644
index 11fb831803bb..000000000000
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/AuthenticationCallback.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright 2000-2013 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jetbrains.idea.svn.commandLine;
-
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.idea.svn.dialogs.SimpleCredentialsDialog;
-import org.tmatesoft.svn.core.SVNURL;
-import org.tmatesoft.svn.core.auth.SVNAuthentication;
-
-import java.io.File;
-import java.net.PasswordAuthentication;
-
-/**
- * Passed for authentication purpose to SvnLineCommand
- * Called when svn command indicates that it needs credentials. It also means that credential was not found in standard place
- * (Subversion config directory)
- *
- * Implementations should 1) ask credential from user or take it from any other storage (memory, for instance)
- * 2) write credential in Subversion standard form into
- * a) standard config directory if user allowed to save *all* credentials
- * b) TMP directory and return path to the directory from getSpecialConfigDir() - if user rejected at least one credential storing
- *
- * Please note that several credentials could be asked during the command and therefore implementation class is used as
- * keeping its state, and that TMP directory should be reused for all written credentials
- *
- * User: Irina.Chernushina
- * Date: 2/26/13
- * Time: 1:05 PM
- */
-public interface AuthenticationCallback {
- /**
- * Authenticate for realm and base file belonging to corresponding working copy
- *
- * @param realm - realm that should be used for credential retrieval/storage.
- * @param repositoryUrl
- * @param previousFailed - whether previous credentials were correct
- * @param passwordRequest - if true, password should be asked. Otherwise that may be a certificate (determined by the protocol)
- * @return false if authentication canceled or was unsuccessful
- */
- boolean authenticateFor(@Nullable String realm, SVNURL repositoryUrl, boolean previousFailed, boolean passwordRequest);
-
- /**
- * Provides authentication information to access given url by authentication protocol identified by type.
- * For instance, username/password for http/svn protocols. SSL client certificate for two way SSL protocol.
- *
- * @param repositoryUrl
- * @param type authentication protocol type with svn specific values, like "svn.simple" for http.
- * @return
- */
- @Nullable
- SVNAuthentication requestCredentials(SVNURL repositoryUrl, String type);
-
- /**
- * @return config directory if TMP was created
- */
- @Nullable
- File getSpecialConfigDir();
-
- @Nullable
- String requestSshCredentials(@NotNull String realm,
- @NotNull SimpleCredentialsDialog.Mode mode,
- @NotNull String key);
-
- /**
- * Ask user or read from memory storage whether server certificate should be accepted
- *
- * @param repositoryUrl
- * @param realm - realm that should be used for credential retrieval/storage.
- * @return true is certificate was accepted
- */
- boolean acceptSSLServerCertificate(SVNURL repositoryUrl, final String realm);
-
- /**
- * Clear credentials stored anywhere - in case they were not full, wrong or anything else
- *
- * @param realm - required that credential
- * @param repositoryUrl
- * @param password - whether password credential should be deleted or certificate, if protocol might demand certificate
- */
- void clearPassiveCredentials(String realm, SVNURL repositoryUrl, boolean password);
-
- /**
- * @return true if there's something from IDEA config that should be persisted into Subversion tmp config directory
- * for successful call
- * (now it's IDEA proxy settings)
- */
- boolean haveDataForTmpConfig();
-
- @Nullable
- PasswordAuthentication getProxyAuthentication(@NotNull SVNURL repositoryUrl);
-
- void reset();
-}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/BaseCommandRuntimeModule.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/BaseCommandRuntimeModule.java
index 1b4235d8ffcf..86a27fa393b7 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/BaseCommandRuntimeModule.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/BaseCommandRuntimeModule.java
@@ -17,6 +17,7 @@ package org.jetbrains.idea.svn.commandLine;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.svn.SvnVcs;
+import org.jetbrains.idea.svn.auth.AuthenticationService;
/**
* @author Konstantin Kolosovsky.
@@ -24,12 +25,12 @@ import org.jetbrains.idea.svn.SvnVcs;
public abstract class BaseCommandRuntimeModule implements CommandRuntimeModule {
@NotNull protected final CommandRuntime myRuntime;
- @NotNull protected final AuthenticationCallback myAuthCallback;
+ @NotNull protected final AuthenticationService myAuthenticationService;
@NotNull protected final SvnVcs myVcs;
public BaseCommandRuntimeModule(@NotNull CommandRuntime runtime) {
myRuntime = runtime;
- myAuthCallback = runtime.getAuthCallback();
+ myAuthenticationService = runtime.getAuthenticationService();
myVcs = runtime.getVcs();
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CertificateCallbackCase.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CertificateCallbackCase.java
index a63d4544a5f5..f58a775079ed 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CertificateCallbackCase.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CertificateCallbackCase.java
@@ -17,6 +17,7 @@ package org.jetbrains.idea.svn.commandLine;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.auth.AuthenticationService;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNURL;
@@ -31,8 +32,8 @@ public class CertificateCallbackCase extends AuthCallbackCase {
private boolean accepted;
- CertificateCallbackCase(@NotNull AuthenticationCallback callback, SVNURL url) {
- super(callback, url);
+ CertificateCallbackCase(@NotNull AuthenticationService authenticationService, SVNURL url) {
+ super(authenticationService, url);
}
@Override
@@ -55,7 +56,7 @@ public class CertificateCallbackCase extends AuthCallbackCase {
realm = serverUrl != null ? serverUrl.toString() : realm;
}
- if (!myTried && myAuthenticationCallback.acceptSSLServerCertificate(myUrl, realm)) {
+ if (!myTried && myAuthenticationService.acceptSSLServerCertificate(myUrl, realm)) {
accepted = true;
myTried = true;
return true;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandParametersResolutionModule.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandParametersResolutionModule.java
index e4883549b0aa..e86fdf388a7f 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandParametersResolutionModule.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandParametersResolutionModule.java
@@ -43,7 +43,7 @@ public class CommandParametersResolutionModule extends BaseCommandRuntimeModule
if (command.getWorkingDirectory() == null) {
command.setWorkingDirectory(resolveWorkingDirectory(command));
}
- command.setConfigDir(myAuthCallback.getSpecialConfigDir());
+ command.setConfigDir(myAuthenticationService.getSpecialConfigDir());
command.saveOriginalParameters();
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandRuntime.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandRuntime.java
index 5cc66e0a3983..4902891163d6 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandRuntime.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandRuntime.java
@@ -24,6 +24,7 @@ import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.*;
+import org.jetbrains.idea.svn.auth.AuthenticationService;
import org.jetbrains.idea.svn.auth.SvnAuthenticationManager;
import org.tmatesoft.svn.core.SVNURL;
@@ -37,14 +38,14 @@ public class CommandRuntime {
private static final Logger LOG = Logger.getInstance(CommandRuntime.class);
- @NotNull private final AuthenticationCallback myAuthCallback;
+ @NotNull private final AuthenticationService myAuthenticationService;
@NotNull private final SvnVcs myVcs;
@NotNull private final List<CommandRuntimeModule> myModules;
private final String exePath;
- public CommandRuntime(@NotNull SvnVcs vcs, @NotNull AuthenticationCallback authCallback) {
+ public CommandRuntime(@NotNull SvnVcs vcs, @NotNull AuthenticationService authenticationService) {
myVcs = vcs;
- myAuthCallback = authCallback;
+ myAuthenticationService = authenticationService;
exePath = SvnApplicationSettings.getInstance().getCommandLinePath();
myModules = ContainerUtil.newArrayList();
@@ -130,8 +131,8 @@ public class CommandRuntime {
// "infinite" times despite it was cancelled.
if (!executor.checkCancelled() && callback != null) {
if (callback.getCredentials(errText)) {
- if (myAuthCallback.getSpecialConfigDir() != null) {
- command.setConfigDir(myAuthCallback.getSpecialConfigDir());
+ if (myAuthenticationService.getSpecialConfigDir() != null) {
+ command.setConfigDir(myAuthenticationService.getSpecialConfigDir());
}
callback.updateParameters(command);
return true;
@@ -153,7 +154,7 @@ public class CommandRuntime {
}
private void onFinish() {
- myAuthCallback.reset();
+ myAuthenticationService.reset();
}
private static void logNullExitCode(@NotNull CommandExecutor executor, @Nullable Integer exitCode) {
@@ -166,12 +167,12 @@ public class CommandRuntime {
private AuthCallbackCase createCallback(@NotNull final String errText, @Nullable final SVNURL url) {
List<AuthCallbackCase> authCases = ContainerUtil.newArrayList();
- authCases.add(new CertificateCallbackCase(myAuthCallback, url));
- authCases.add(new CredentialsCallback(myAuthCallback, url));
- authCases.add(new PassphraseCallback(myAuthCallback, url));
- authCases.add(new ProxyCallback(myAuthCallback, url));
- authCases.add(new TwoWaySslCallback(myAuthCallback, url));
- authCases.add(new UsernamePasswordCallback(myAuthCallback, url));
+ authCases.add(new CertificateCallbackCase(myAuthenticationService, url));
+ authCases.add(new CredentialsCallback(myAuthenticationService, url));
+ authCases.add(new PassphraseCallback(myAuthenticationService, url));
+ authCases.add(new ProxyCallback(myAuthenticationService, url));
+ authCases.add(new TwoWaySslCallback(myAuthenticationService, url));
+ authCases.add(new UsernamePasswordCallback(myAuthenticationService, url));
return ContainerUtil.find(authCases, new Condition<AuthCallbackCase>() {
@Override
@@ -242,8 +243,8 @@ public class CommandRuntime {
}
@NotNull
- public AuthenticationCallback getAuthCallback() {
- return myAuthCallback;
+ public AuthenticationService getAuthenticationService() {
+ return myAuthenticationService;
}
@NotNull
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CredentialsCallback.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CredentialsCallback.java
index 15f3a78aff5d..5304dff13e01 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CredentialsCallback.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CredentialsCallback.java
@@ -17,6 +17,7 @@ package org.jetbrains.idea.svn.commandLine;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.auth.AuthenticationService;
import org.tmatesoft.svn.core.SVNURL;
/**
@@ -26,8 +27,8 @@ public class CredentialsCallback extends AuthCallbackCase {
private static final String AUTHENTICATION_REALM = "Authentication realm:";
- CredentialsCallback(@NotNull AuthenticationCallback callback, SVNURL url) {
- super(callback, url);
+ CredentialsCallback(@NotNull AuthenticationService authenticationService, SVNURL url) {
+ super(authenticationService, url);
}
@Override
@@ -43,10 +44,10 @@ public class CredentialsCallback extends AuthCallbackCase {
: null;
final boolean isPassword = StringUtil.containsIgnoreCase(errText, "password");
if (myTried) {
- myAuthenticationCallback.clearPassiveCredentials(realm, myUrl, isPassword);
+ myAuthenticationService.clearPassiveCredentials(realm, myUrl, isPassword);
}
myTried = true;
- if (myAuthenticationCallback.authenticateFor(realm, myUrl, myAuthenticationCallback.getSpecialConfigDir() != null, isPassword)) {
+ if (myAuthenticationService.authenticateFor(realm, myUrl, isPassword)) {
return true;
}
throw new SvnBindException("Authentication canceled for realm: " + realm);
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/PassphraseCallback.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/PassphraseCallback.java
index 70e3d245329b..fe793c05fb31 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/PassphraseCallback.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/PassphraseCallback.java
@@ -16,6 +16,7 @@
package org.jetbrains.idea.svn.commandLine;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.auth.AuthenticationService;
import org.tmatesoft.svn.core.SVNURL;
/**
@@ -25,8 +26,8 @@ public class PassphraseCallback extends AuthCallbackCase {
private static final String PASSPHRASE_FOR = "Passphrase for";
- PassphraseCallback(@NotNull AuthenticationCallback callback, SVNURL url) {
- super(callback, url);
+ PassphraseCallback(@NotNull AuthenticationService authenticationService, SVNURL url) {
+ super(authenticationService, url);
}
@Override
@@ -38,10 +39,10 @@ public class PassphraseCallback extends AuthCallbackCase {
boolean getCredentials(String errText) throws SvnBindException {
// try to get from file
/*if (myTried) {
- myAuthenticationCallback.clearPassiveCredentials(null, myBase);
+ myAuthenticationService.clearPassiveCredentials(null, myBase);
}*/
myTried = true;
- if (myAuthenticationCallback.authenticateFor(null, myUrl, myAuthenticationCallback.getSpecialConfigDir() != null, false)) {
+ if (myAuthenticationService.authenticateFor(null, myUrl, false)) {
return true;
}
throw new SvnBindException("Authentication canceled for : " + errText.substring(PASSPHRASE_FOR.length()));
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/ProxyCallback.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/ProxyCallback.java
index 340100dcb3a6..a3afaf9a5c0c 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/ProxyCallback.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/ProxyCallback.java
@@ -20,6 +20,7 @@ import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.auth.AuthenticationService;
import org.tmatesoft.svn.core.SVNURL;
import java.net.PasswordAuthentication;
@@ -36,8 +37,8 @@ public class ProxyCallback extends AuthCallbackCase {
private PasswordAuthentication myProxyAuthentication;
- ProxyCallback(@NotNull AuthenticationCallback callback, SVNURL url) {
- super(callback, url);
+ ProxyCallback(@NotNull AuthenticationService authenticationService, SVNURL url) {
+ super(authenticationService, url);
}
@Override
@@ -61,8 +62,8 @@ public class ProxyCallback extends AuthCallbackCase {
result = true;
// explicit check if proxies are configured in IDEA is used here not to perform "proxy authentication" for proxies manually
// specified by users in svn "servers" file
- } else if (myAuthenticationCallback.haveDataForTmpConfig()) {
- myProxyAuthentication = myAuthenticationCallback.getProxyAuthentication(myUrl);
+ } else if (myAuthenticationService.haveDataForTmpConfig()) {
+ myProxyAuthentication = myAuthenticationService.getProxyAuthentication(myUrl);
result = myProxyAuthentication != null;
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/ProxyModule.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/ProxyModule.java
index 11bb9b654523..bdfdd55ed6e1 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/ProxyModule.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/ProxyModule.java
@@ -19,8 +19,8 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.svn.IdeaSVNConfigFile;
+import org.jetbrains.idea.svn.auth.AuthenticationService;
import org.jetbrains.idea.svn.auth.SvnAuthenticationManager;
-import org.jetbrains.idea.svn.auth.IdeaSvnkitBasedAuthenticationCallback;
import org.tmatesoft.svn.core.SVNURL;
import java.net.InetSocketAddress;
@@ -39,7 +39,7 @@ public class ProxyModule extends BaseCommandRuntimeModule {
@Override
public void onStart(@NotNull Command command) throws SvnBindException {
- if (myAuthCallback.haveDataForTmpConfig()) {
+ if (myAuthenticationService.haveDataForTmpConfig()) {
setupProxy(command);
}
}
@@ -50,7 +50,7 @@ public class ProxyModule extends BaseCommandRuntimeModule {
SVNURL repositoryUrl = command.getRepositoryUrl();
if (repositoryUrl != null) {
- Proxy proxy = IdeaSvnkitBasedAuthenticationCallback.getIdeaDefinedProxy(repositoryUrl);
+ Proxy proxy = AuthenticationService.getIdeaDefinedProxy(repositoryUrl);
if (proxy != null) {
String hostGroup = ensureGroupForHost(command, repositoryUrl.getHost());
@@ -68,7 +68,7 @@ public class ProxyModule extends BaseCommandRuntimeModule {
@NotNull
private String ensureGroupForHost(@NotNull Command command, @NotNull String host) {
- IdeaSVNConfigFile configFile = new IdeaSVNConfigFile(myAuthCallback.getSpecialConfigDir());
+ IdeaSVNConfigFile configFile = new IdeaSVNConfigFile(myAuthenticationService.getSpecialConfigDir());
String groupName = SvnAuthenticationManager.getGroupForHost(host, configFile);
if (StringUtil.isEmptyOrSpaces(groupName)) {
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnBindException.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnBindException.java
index 6694083b4d81..f4b4f0d4b0fc 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnBindException.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnBindException.java
@@ -21,6 +21,7 @@ import com.intellij.openapi.vcs.VcsException;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnUtil;
import org.tmatesoft.svn.core.SVNErrorCode;
import org.tmatesoft.svn.core.SVNErrorMessage;
@@ -52,18 +53,22 @@ public class SvnBindException extends VcsException {
errors.putValue(code.getCode(), getMessage());
}
- public SvnBindException(String message) {
- super(message);
+ public SvnBindException(@Nullable String message) {
+ this(message, null);
+ }
- if (!StringUtil.isEmpty(message)) {
- parse(message, SvnUtil.ERROR_PATTERN, errors);
- parse(message, SvnUtil.WARNING_PATTERN, warnings);
- }
+ public SvnBindException(@Nullable Throwable cause) {
+ this(null, cause);
}
- public SvnBindException(Throwable throwable) {
- super(throwable);
+ public SvnBindException(@Nullable String message, @Nullable Throwable cause) {
+ super(message, cause);
+
+ init(message);
+ init(cause);
+ }
+ private void init(@Nullable Throwable throwable) {
if (throwable instanceof SVNException) {
SVNException e = (SVNException)throwable;
int code = e.getErrorMessage().getErrorCode().getCode();
@@ -73,6 +78,13 @@ public class SvnBindException extends VcsException {
}
}
+ private void init(@Nullable String message) {
+ if (!StringUtil.isEmpty(message)) {
+ parse(message, SvnUtil.ERROR_PATTERN, errors);
+ parse(message, SvnUtil.WARNING_PATTERN, warnings);
+ }
+ }
+
public boolean contains(int code) {
return errors.containsKey(code) || warnings.containsKey(code);
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnExecutableChecker.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnExecutableChecker.java
index 4a5183ac5e4c..1add2022074a 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnExecutableChecker.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnExecutableChecker.java
@@ -26,6 +26,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnApplicationSettings;
import org.jetbrains.idea.svn.SvnBundle;
import org.jetbrains.idea.svn.SvnVcs;
+import org.jetbrains.idea.svn.WorkingCopyFormat;
/**
* Created with IntelliJ IDEA.
@@ -82,7 +83,7 @@ public class SvnExecutableChecker extends ExecutableValidator {
}
private boolean validateVersion(@NotNull Version version) {
- if (version.lessThan(1, 7)) {
+ if (!getVcs().isSupportedByCommandLine(WorkingCopyFormat.from(version))) {
setNotificationErrorDescription(getOldExecutableMessage(version));
return false;
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/TerminalSshModule.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/TerminalSshModule.java
index 5a624e9d3414..ca4fce9d910b 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/TerminalSshModule.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/TerminalSshModule.java
@@ -130,7 +130,7 @@ public class TerminalSshModule extends LineCommandAdapter implements CommandRunt
// TODO: authentication (like "svn info <file> -r HEAD"), if it is invoked before all working copy roots are resolved.
// TODO: resolving repositoryUrl logic should be updated so that repositoryUrl is not null here.
String auth =
- myRuntime.getAuthCallback().requestSshCredentials(repositoryUrl != null ? repositoryUrl.toDecodedString() : "", mode, key);
+ myRuntime.getAuthenticationService().requestSshCredentials(repositoryUrl != null ? repositoryUrl.toDecodedString() : "", mode, key);
if (!StringUtil.isEmpty(auth)) {
sendAnswer(auth);
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/TwoWaySslCallback.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/TwoWaySslCallback.java
index e9df472b65c2..fe8ad9208e5f 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/TwoWaySslCallback.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/TwoWaySslCallback.java
@@ -16,6 +16,7 @@
package org.jetbrains.idea.svn.commandLine;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.auth.AuthenticationService;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.auth.SVNSSLAuthentication;
@@ -28,8 +29,8 @@ public class TwoWaySslCallback extends UsernamePasswordCallback {
private static final String ACCESS_TO_PREFIX = "Access to ";
private static final String FORBIDDEN_STATUS = "forbidden";
- TwoWaySslCallback(AuthenticationCallback callback, SVNURL url) {
- super(callback, url);
+ TwoWaySslCallback(@NotNull AuthenticationService authenticationService, SVNURL url) {
+ super(authenticationService, url);
}
@Override
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UsernamePasswordCallback.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UsernamePasswordCallback.java
index caeb92f1d734..ad908b213ab3 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UsernamePasswordCallback.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UsernamePasswordCallback.java
@@ -15,7 +15,9 @@
*/
package org.jetbrains.idea.svn.commandLine;
+import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.auth.AuthenticationService;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.auth.SVNAuthentication;
@@ -32,6 +34,7 @@ import java.util.regex.Pattern;
*/
public class UsernamePasswordCallback extends AuthCallbackCase {
+ private static final String COULD_NOT_AUTHENTICATE_TO_SERVER_MESSAGE = "could not authenticate to server";
private static final String UNABLE_TO_CONNECT_MESSAGE = "Unable to connect to a repository";
private static final String AUTHENTICATION_FAILED_MESSAGE = "Authentication failed";
private static final String INVALID_CREDENTIALS_FOR_SVN_PROTOCOL = "svn: E170001: Can't get";
@@ -40,8 +43,8 @@ public class UsernamePasswordCallback extends AuthCallbackCase {
protected SVNAuthentication myAuthentication;
- UsernamePasswordCallback(@NotNull AuthenticationCallback callback, SVNURL url) {
- super(callback, url);
+ UsernamePasswordCallback(@NotNull AuthenticationService authenticationService, SVNURL url) {
+ super(authenticationService, url);
}
@Override
@@ -52,13 +55,14 @@ public class UsernamePasswordCallback extends AuthCallbackCase {
// svn protocol invalid credentials - messages could be "Can't get password", "Can't get username or password"
error.contains(INVALID_CREDENTIALS_FOR_SVN_PROTOCOL) && error.contains(PASSWORD_STRING) ||
// http/https protocol, svn 1.7, non-interactive
- error.contains(UNABLE_TO_CONNECT_MESSAGE);
+ error.contains(UNABLE_TO_CONNECT_MESSAGE) ||
+ // http, svn 1.6, non-interactive
+ StringUtil.containsIgnoreCase(error, COULD_NOT_AUTHENTICATE_TO_SERVER_MESSAGE);
}
@Override
boolean getCredentials(String errText) throws SvnBindException {
- myAuthentication = myAuthenticationCallback.requestCredentials(myUrl != null ? myUrl : parseUrlFromError(errText),
- getType());
+ myAuthentication = myAuthenticationService.requestCredentials(myUrl != null ? myUrl : parseUrlFromError(errText), getType());
return myAuthentication != null;
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/CmdUpdateClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/CmdUpdateClient.java
index 61b0592af085..8406f1ecec5b 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/CmdUpdateClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/CmdUpdateClient.java
@@ -18,6 +18,7 @@ package org.jetbrains.idea.svn.update;
import com.intellij.openapi.util.io.FileUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.WorkingCopyFormat;
import org.jetbrains.idea.svn.api.Depth;
import org.jetbrains.idea.svn.api.EventAction;
import org.jetbrains.idea.svn.api.ProgressEvent;
@@ -26,7 +27,10 @@ import org.jetbrains.idea.svn.commandLine.CommandUtil;
import org.jetbrains.idea.svn.commandLine.SvnBindException;
import org.jetbrains.idea.svn.commandLine.SvnCommandName;
import org.jetbrains.idea.svn.info.Info;
-import org.tmatesoft.svn.core.*;
+import org.tmatesoft.svn.core.SVNErrorCode;
+import org.tmatesoft.svn.core.SVNErrorMessage;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc2.SvnTarget;
@@ -163,7 +167,10 @@ public class CmdUpdateClient extends SvnKitUpdateClient {
CommandUtil.put(parameters, SvnTarget.fromURL(url, pegRevision));
CommandUtil.put(parameters, path, false);
fillParameters(parameters, revision, depth, depthIsSticky, allowUnversionedObstructions);
- parameters.add("--ignore-ancestry");
+ if (!myVcs.is16SupportedByCommandLine() ||
+ WorkingCopyFormat.from(myFactory.createVersionClient().getVersion()).isOrGreater(WorkingCopyFormat.ONE_DOT_SEVEN)) {
+ parameters.add("--ignore-ancestry");
+ }
long[] revisions = run(path, parameters, SvnCommandName.switchCopy);
diff --git a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnCachingRepositoryPoolTest.java b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnCachingRepositoryPoolTest.java
index e2475e020950..ecad58e2b20d 100644
--- a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnCachingRepositoryPoolTest.java
+++ b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnCachingRepositoryPoolTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -107,13 +107,7 @@ public class SvnCachingRepositoryPoolTest extends FileBasedTest {
}
}
};
- final EmptyProgressIndicator indicator = new EmptyProgressIndicator() {
- @Override
- public void cancel() {
- super.cancel();
- ProgressManagerImpl.canceled();
- }
- };
+ final EmptyProgressIndicator indicator = new EmptyProgressIndicator();
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
diff --git a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnCommandLineStabilityTest.java b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnCommandLineStabilityTest.java
index 76cc3c8ce9af..4918ef06eb39 100644
--- a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnCommandLineStabilityTest.java
+++ b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnCommandLineStabilityTest.java
@@ -1,16 +1,15 @@
package org.jetbrains.idea.svn;
import com.intellij.openapi.vcs.VcsException;
+import com.intellij.openapi.vfs.VfsUtilCore;
import junit.framework.Assert;
-import org.jetbrains.idea.svn.api.BaseSvnClient;
-import org.jetbrains.idea.svn.commandLine.CommandExecutor;
-import org.jetbrains.idea.svn.commandLine.SvnCommandName;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.auth.AuthenticationService;
+import org.jetbrains.idea.svn.commandLine.*;
import org.junit.Test;
import org.tmatesoft.svn.core.wc2.SvnTarget;
import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
/**
* Created with IntelliJ IDEA.
@@ -30,15 +29,22 @@ public class SvnCommandLineStabilityTest extends Svn17TestCase {
}
private void call() throws VcsException {
- List<String> parameters = new ArrayList<String>();
- parameters.add("--xml");
-
- SvnVcs vcs = SvnVcs.getInstance(myProject);
- File workingDirectory = new File(myWorkingCopyDir.getPath());
- CommandExecutor command =
- BaseSvnClient.execute(vcs, SvnTarget.fromFile(workingDirectory), workingDirectory, SvnCommandName.info, parameters, null);
- final String result = command.getOutput();
+ String result = runInfo().getOutput();
System.out.println(result);
Assert.assertNotNull(result);
}
+
+ @NotNull
+ private CommandExecutor runInfo() throws SvnBindException {
+ SvnVcs vcs = SvnVcs.getInstance(myProject);
+ File workingDirectory = VfsUtilCore.virtualToIoFile(myWorkingCopyDir);
+ Command command = new Command(SvnCommandName.info);
+
+ command.setTarget(SvnTarget.fromFile(workingDirectory));
+ command.setWorkingDirectory(workingDirectory);
+ command.put("--xml");
+
+ CommandRuntime runtime = new CommandRuntime(vcs, new AuthenticationService(vcs, true));
+ return runtime.runWithAuthenticationAttempt(command);
+ }
}
diff --git a/plugins/tasks/tasks-api/src/com/intellij/tasks/impl/BaseRepositoryImpl.java b/plugins/tasks/tasks-api/src/com/intellij/tasks/impl/BaseRepositoryImpl.java
index 30ecaf19f2da..ef3d88158f4d 100644
--- a/plugins/tasks/tasks-api/src/com/intellij/tasks/impl/BaseRepositoryImpl.java
+++ b/plugins/tasks/tasks-api/src/com/intellij/tasks/impl/BaseRepositoryImpl.java
@@ -1,7 +1,6 @@
package com.intellij.tasks.impl;
import com.intellij.openapi.components.ServiceManager;
-import com.intellij.openapi.diagnostic.Logger;
import com.intellij.tasks.TaskRepositoryType;
import com.intellij.tasks.config.TaskSettings;
import com.intellij.util.net.HttpConfigurable;
@@ -20,7 +19,6 @@ import java.net.URLEncoder;
* @author Dmitry Avdeev
*/
public abstract class BaseRepositoryImpl extends BaseRepository {
- private static final Logger LOG = Logger.getInstance(BaseRepositoryImpl.class);
private final HttpClient myClient;
protected BaseRepositoryImpl() {
@@ -113,8 +111,7 @@ public abstract class BaseRepositoryImpl extends BaseRepository {
protected void configureHttpMethod(HttpMethod method) {
}
- public abstract class HttpTestConnection<T extends HttpMethod> extends CancellableConnection {
-
+ public abstract static class HttpTestConnection<T extends HttpMethod> extends CancellableConnection {
protected T myMethod;
public HttpTestConnection(T method) {
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskDialog.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskDialog.java
index 6fe1467b1b47..2cc241e4d8a1 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskDialog.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskDialog.java
@@ -28,7 +28,6 @@ import com.intellij.openapi.ui.ValidationInfo;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.vcs.AbstractVcs;
import com.intellij.openapi.vcs.VcsTaskHandler;
-import com.intellij.openapi.vcs.VcsType;
import com.intellij.tasks.*;
import com.intellij.tasks.impl.TaskManagerImpl;
import com.intellij.tasks.impl.TaskUtil;
@@ -106,7 +105,8 @@ public class OpenTaskDialog extends DialogWrapper {
myCreateBranch.addActionListener(listener);
myCreateChangelist.setSelected(manager.getState().createChangelist);
- if (vcs.getType() != VcsType.distributed) {
+ VcsTaskHandler[] handlers = VcsTaskHandler.getAllHandlers(project);
+ if (handlers.length == 0) {
myCreateBranch.setSelected(false);
myCreateBranch.setVisible(false);
myBranchName.setVisible(false);
@@ -114,7 +114,6 @@ public class OpenTaskDialog extends DialogWrapper {
myBranchFrom.setVisible(false);
}
else {
- VcsTaskHandler[] handlers = VcsTaskHandler.getAllHandlers(project);
for (VcsTaskHandler handler : handlers) {
VcsTaskHandler.TaskInfo[] tasks = handler.getCurrentTasks();
if (tasks.length > 0) {
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/httpclient/NewBaseRepositoryImpl.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/httpclient/NewBaseRepositoryImpl.java
index 8f14564c74b5..c1648fc8f490 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/httpclient/NewBaseRepositoryImpl.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/httpclient/NewBaseRepositoryImpl.java
@@ -1,6 +1,5 @@
package com.intellij.tasks.impl.httpclient;
-import com.intellij.openapi.diagnostic.Logger;
import com.intellij.tasks.TaskRepositoryType;
import com.intellij.tasks.config.TaskSettings;
import com.intellij.tasks.impl.BaseRepository;
@@ -34,7 +33,6 @@ import java.io.IOException;
* @author Mikhail Golubev
*/
public abstract class NewBaseRepositoryImpl extends BaseRepository {
- private static final Logger LOG = Logger.getInstance(NewBaseRepositoryImpl.class);
private static final AuthScope BASIC_AUTH_SCOPE =
new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM, AuthSchemes.BASIC);
// Provides preemptive authentication in HttpClient 4.x
diff --git a/plugins/tasks/tasks-tests/test/com/intellij/tasks/vcs/TaskVcsTest.java b/plugins/tasks/tasks-tests/test/com/intellij/tasks/vcs/TaskVcsTest.java
index d78c5c055b47..c08230becf46 100644
--- a/plugins/tasks/tasks-tests/test/com/intellij/tasks/vcs/TaskVcsTest.java
+++ b/plugins/tasks/tasks-tests/test/com/intellij/tasks/vcs/TaskVcsTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -493,6 +493,7 @@ public class TaskVcsTest extends CodeInsightFixtureTestCase {
finally {
myTaskManager = null;
myVcs = null;
+ myChangeListManager = null;
}
super.tearDown();
}
diff --git a/plugins/terminal/resources/META-INF/terminal.xml b/plugins/terminal/resources/META-INF/terminal.xml
index e85297f2b715..b41877f9db87 100644
--- a/plugins/terminal/resources/META-INF/terminal.xml
+++ b/plugins/terminal/resources/META-INF/terminal.xml
@@ -3,7 +3,7 @@
<toolWindow id="Terminal" anchor="bottom" icon="TerminalIcons.OpenTerminal_13x13"
factoryClass="org.jetbrains.plugins.terminal.TerminalToolWindowFactory" secondary="false"/>
- <projectConfigurable groupId="tools" displayName="Terminal" instance="org.jetbrains.plugins.terminal.TerminalOptionsConfigurable"/>
+ <projectConfigurable groupId="tools" groupWeight="130" displayName="Terminal" instance="org.jetbrains.plugins.terminal.TerminalOptionsConfigurable"/>
<fileEditorProvider implementation="org.jetbrains.plugins.terminal.vfs.TerminalSessionEditorProvider"/>
</extensions>
diff --git a/plugins/testng/src/META-INF/plugin.xml b/plugins/testng/src/META-INF/plugin.xml
index fff400d9f794..5fe0fb55b60f 100644
--- a/plugins/testng/src/META-INF/plugin.xml
+++ b/plugins/testng/src/META-INF/plugin.xml
@@ -46,6 +46,9 @@
<localInspection language="JAVA" shortName="MisorderedAssertEqualsArgumentsTestNG" displayName="Misordered 'assertEquals()' arguments"
groupName="TestNG" enabledByDefault="false" level="WARNING"
implementationClass="com.theoryinpractice.testng.inspection.MisorderedAssertEqualsArgumentsTestNGInspection"/>
+ <localInspection language="JAVA" shortName="TestNGMethodNamingConvention" displayName="TestNG test method naming convention"
+ groupName="TestNG" enabledByDefault="false" level="WARNING"
+ implementationClass="com.theoryinpractice.testng.inspection.TestNGMethodNamingConventionInspection"/>
<intentionAction>
<className>com.theoryinpractice.testng.intention.TestNGOrderEntryFix</className>
diff --git a/plugins/testng/src/com/theoryinpractice/testng/TestNGReferenceContributor.java b/plugins/testng/src/com/theoryinpractice/testng/TestNGReferenceContributor.java
index 0a9acf231499..6e483fb97c3d 100644
--- a/plugins/testng/src/com/theoryinpractice/testng/TestNGReferenceContributor.java
+++ b/plugins/testng/src/com/theoryinpractice/testng/TestNGReferenceContributor.java
@@ -170,7 +170,7 @@ public class TestNGReferenceContributor extends PsiReferenceContributor {
if (cls != null) {
PsiMethod[] methods = cls.findMethodsByName(methodName, true);
for (PsiMethod method : methods) {
- if (TestNGUtil.hasTest(method) || TestNGUtil.hasConfig(method)) {
+ if (TestNGUtil.hasTest(method, false) || TestNGUtil.hasConfig(method)) {
return method;
}
}
diff --git a/plugins/testng/src/com/theoryinpractice/testng/configuration/SearchingForTestsTask.java b/plugins/testng/src/com/theoryinpractice/testng/configuration/SearchingForTestsTask.java
index 413aceebf8d4..2258b16a7a2a 100644
--- a/plugins/testng/src/com/theoryinpractice/testng/configuration/SearchingForTestsTask.java
+++ b/plugins/testng/src/com/theoryinpractice/testng/configuration/SearchingForTestsTask.java
@@ -191,11 +191,22 @@ public class SearchingForTestsTask extends Task.Backgroundable {
private void composeTestSuiteFromClasses() {
Map<String, Collection<String>> map = new HashMap<String, Collection<String>>();
+
+ final boolean findTestMethodsForClass = shouldSearchForTestMethods();
+
for (final Map.Entry<PsiClass, Collection<PsiMethod>> entry : myClasses.entrySet()) {
- Collection<String> methods = new HashSet<String>(entry.getValue().size());
- for (PsiMethod method : entry.getValue()) {
+ final Collection<PsiMethod> depMethods = entry.getValue();
+ Collection<String> methods = new HashSet<String>(depMethods.size());
+ for (PsiMethod method : depMethods) {
methods.add(method.getName());
}
+ if (findTestMethodsForClass && depMethods.isEmpty()) {
+ for (PsiMethod method : entry.getKey().getMethods()) {
+ if (TestNGUtil.hasTest(method)) {
+ methods.add(method.getName());
+ }
+ }
+ }
map.put(ApplicationManager.getApplication().runReadAction(
new Computable<String>() {
@Nullable
@@ -243,6 +254,17 @@ public class SearchingForTestsTask extends Task.Backgroundable {
}
}
+ private boolean shouldSearchForTestMethods() {
+ boolean dependantMethods = false;
+ for (Collection<PsiMethod> methods : myClasses.values()) {
+ if (!methods.isEmpty()) {
+ dependantMethods = true;
+ break;
+ }
+ }
+ return dependantMethods;
+ }
+
private void composeTestSuiteFromXml() throws CantRunException {
final Map<String, String> buildTestParams = buildTestParameters();
try {
diff --git a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGRunnableState.java b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGRunnableState.java
index 21afb568e912..0c73ae5f5761 100644
--- a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGRunnableState.java
+++ b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGRunnableState.java
@@ -144,19 +144,6 @@ public class TestNGRunnableState extends JavaCommandLineState {
if (mySearchForTestIndicator != null && !mySearchForTestIndicator.isCanceled()) {
task.finish();
}
-
- final Runnable notificationRunnable = new Runnable() {
- public void run() {
- final Project project = config.getProject();
- if (project.isDisposed()) return;
-
- final TestConsoleProperties consoleProperties = console.getProperties();
- if (consoleProperties == null) return;
- final TestNGResults resultsView = console.getResultsView();
- TestsUIUtil.notifyByBalloon(project, myStarted, console.getResultsView().getRoot(), consoleProperties, "in " + resultsView.getTime());
- }
- };
- SwingUtilities.invokeLater(notificationRunnable);
}
@Override
@@ -175,7 +162,7 @@ public class TestNGRunnableState extends JavaCommandLineState {
public void processWillTerminate(ProcessEvent event, boolean willBeDestroyed) {
final TestNGResults resultsView = console.getResultsView();
if (resultsView != null) {
- resultsView.finish();
+ resultsView.finish(myStarted);
}
}
diff --git a/plugins/testng/src/com/theoryinpractice/testng/inspection/DependsOnMethodInspection.java b/plugins/testng/src/com/theoryinpractice/testng/inspection/DependsOnMethodInspection.java
index b8cf78a83d5d..aeda466432a2 100644
--- a/plugins/testng/src/com/theoryinpractice/testng/inspection/DependsOnMethodInspection.java
+++ b/plugins/testng/src/com/theoryinpractice/testng/inspection/DependsOnMethodInspection.java
@@ -18,14 +18,19 @@ package com.theoryinpractice.testng.inspection;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInspection.*;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.HashSet;
import com.theoryinpractice.testng.util.TestNGUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
+import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -35,7 +40,7 @@ import java.util.regex.Pattern;
public class DependsOnMethodInspection extends BaseJavaLocalInspectionTool
{
private static final Logger LOGGER = Logger.getInstance("TestNG Runner");
- private static final Pattern PATTERN = Pattern.compile("\"([a-zA-Z1-9_\\(\\)]*)\"");
+ private static final Pattern PATTERN = Pattern.compile("\"([a-zA-Z1-9_\\(\\)\\*]*)\"");
@NotNull
@Override
@@ -63,17 +68,13 @@ public class DependsOnMethodInspection extends BaseJavaLocalInspectionTool
@Nullable
public ProblemDescriptor[] checkClass(@NotNull PsiClass psiClass, @NotNull InspectionManager manager, boolean isOnTheFly) {
- //LOGGER.info("Looking for dependsOnMethods problems in " + psiClass.getName());
-
- if (!psiClass.getContainingFile().isWritable()) return null;
-
PsiAnnotation[] annotations = TestNGUtil.getTestNGAnnotations(psiClass);
if(annotations.length == 0) return ProblemDescriptor.EMPTY_ARRAY;
List<ProblemDescriptor> problemDescriptors = new ArrayList<ProblemDescriptor>();
for (PsiAnnotation annotation : annotations) {
final PsiAnnotationMemberValue value = annotation.findDeclaredAttributeValue("dependsOnMethods");
- if (value != null) {
+ if (value != null && !TestNGUtil.isDisabled(annotation)) {
String text = value.getText();
if (value instanceof PsiReferenceExpression) {
final PsiElement resolve = ((PsiReferenceExpression)value).resolve();
@@ -84,10 +85,25 @@ public class DependsOnMethodInspection extends BaseJavaLocalInspectionTool
}
}
}
- Matcher matcher = PATTERN.matcher(text);
+ final Set<String> names = new HashSet<String>();
+ final Matcher matcher = PATTERN.matcher(text);
+ int idx = 0;
while (matcher.find()) {
- String methodName = matcher.group(1);
+ String methodName = matcher.group(1);
+ if (!names.add(methodName)) {
+ PsiAnnotationMemberValue element2Highlight = value;
+ if (value instanceof PsiArrayInitializerMemberValue) {
+ final PsiAnnotationMemberValue[] initializers = ((PsiArrayInitializerMemberValue)value).getInitializers();
+ if (idx < initializers.length) {
+ element2Highlight = initializers[idx];
+ }
+ }
+ problemDescriptors.add(manager.createProblemDescriptor(element2Highlight, "Duplicated method name: " + methodName,
+ (LocalQuickFix)null, ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
+ isOnTheFly));
+ }
checkMethodNameDependency(manager, psiClass, methodName, value, problemDescriptors, isOnTheFly);
+ idx++;
}
}
}
@@ -111,7 +127,19 @@ public class DependsOnMethodInspection extends BaseJavaLocalInspectionTool
} else {
final String configAnnotation = TestNGUtil.getConfigAnnotation(PsiTreeUtil.getParentOfType(value, PsiMethod.class));
- PsiMethod[] foundMethods = psiClass.findMethodsByName(methodName, true);
+ final PsiMethod[] foundMethods;
+ if (methodName.endsWith("*")) {
+ final String methodNameMask = StringUtil.trimEnd(methodName, "*");
+ final List<PsiMethod> methods = ContainerUtil.filter(psiClass.getMethods(), new Condition<PsiMethod>() {
+ @Override
+ public boolean value(PsiMethod method) {
+ return method.getName().startsWith(methodNameMask);
+ }
+ });
+ foundMethods = methods.toArray(new PsiMethod[methods.size()]);
+ } else {
+ foundMethods = psiClass.findMethodsByName(methodName, true);
+ }
if (foundMethods.length == 0) {
LOGGER.debug("dependsOnMethods method doesn't exist:" + methodName);
ProblemDescriptor descriptor = manager.createProblemDescriptor(value,
diff --git a/plugins/testng/src/com/theoryinpractice/testng/inspection/TestNGMethodNamingConventionInspection.java b/plugins/testng/src/com/theoryinpractice/testng/inspection/TestNGMethodNamingConventionInspection.java
new file mode 100644
index 000000000000..2cc894faf064
--- /dev/null
+++ b/plugins/testng/src/com/theoryinpractice/testng/inspection/TestNGMethodNamingConventionInspection.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.theoryinpractice.testng.inspection;
+
+import com.intellij.psi.PsiIdentifier;
+import com.intellij.psi.PsiMethod;
+import com.siyeh.ig.BaseInspectionVisitor;
+import com.siyeh.ig.InspectionGadgetsFix;
+import com.siyeh.ig.fixes.RenameFix;
+import com.siyeh.ig.naming.ConventionInspection;
+import com.siyeh.ig.psiutils.LibraryUtil;
+import com.siyeh.ig.psiutils.MethodUtils;
+import com.theoryinpractice.testng.util.TestNGUtil;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class TestNGMethodNamingConventionInspection extends ConventionInspection {
+ @Nls
+ @NotNull
+ @Override
+ public String getDisplayName() {
+ return "TestNG test method naming convention";
+ }
+
+ @NotNull
+ @Override
+ protected String buildErrorString(Object... infos) {
+ final String methodName = (String)infos[0];
+ final int length = methodName.length();
+ if (length < getMinLength()) {
+ return "TestNG test method name <code>#ref</code> is too short (" + length + " < " + getMinLength() + ") #loc";
+ }
+ else if (length > getMaxLength()) {
+ return "TestNG test method name <code>#ref</code> is too long (" + length + " > " + getMaxLength() + ") #loc";
+ }
+ return "JUnit4 test method name <code>#ref</code> doesn't match regex '{0}' #loc";
+ }
+
+ @Override
+ protected String getDefaultRegex() {
+ return "[a-z][A-Za-z_\\d]*";
+ }
+
+ @Override
+ protected int getDefaultMinLength() {
+ return 4;
+ }
+
+ @Override
+ protected int getDefaultMaxLength() {
+ return 64;
+ }
+
+ @Override
+ protected InspectionGadgetsFix buildFix(Object... infos) {
+ return new RenameFix();
+ }
+
+ @Override
+ public BaseInspectionVisitor buildVisitor() {
+ return new TestNGMethodNamingConventionVisitor();
+ }
+
+ private class TestNGMethodNamingConventionVisitor extends BaseInspectionVisitor {
+
+ @Override
+ public void visitMethod(PsiMethod method) {
+ super.visitMethod(method);
+ if (!TestNGUtil.hasTest(method)) {
+ return;
+ }
+ final PsiIdentifier nameIdentifier = method.getNameIdentifier();
+ if (nameIdentifier == null) {
+ return;
+ }
+ final String name = method.getName();
+ if (isValid(name)) {
+ return;
+ }
+ if (!isOnTheFly() && MethodUtils.hasSuper(method)) {
+ return;
+ }
+ if (LibraryUtil.isOverrideOfLibraryMethod(method)) {
+ return;
+ }
+ registerMethodError(method, name);
+ }
+ }
+}
diff --git a/plugins/testng/src/com/theoryinpractice/testng/model/TestNGRemoteListener.java b/plugins/testng/src/com/theoryinpractice/testng/model/TestNGRemoteListener.java
index cf8598d8ae3f..b4e89b28a5c6 100644
--- a/plugins/testng/src/com/theoryinpractice/testng/model/TestNGRemoteListener.java
+++ b/plugins/testng/src/com/theoryinpractice/testng/model/TestNGRemoteListener.java
@@ -48,10 +48,6 @@ public class TestNGRemoteListener implements IRemoteSuiteListener, IRemoteTestLi
public void onFinish(SuiteMessage suiteMessage) {
unboundOutputRoot.flush();
console.finish();
- final TestNGResults view = console.getResultsView();
- if (view != null) {
- view.finish();
- }
}
public void onStart(TestMessage tm) {
diff --git a/plugins/testng/src/com/theoryinpractice/testng/ui/ResultTreeRenderer.java b/plugins/testng/src/com/theoryinpractice/testng/ui/ResultTreeRenderer.java
index ba30f43b66f0..9ea4429447fe 100644
--- a/plugins/testng/src/com/theoryinpractice/testng/ui/ResultTreeRenderer.java
+++ b/plugins/testng/src/com/theoryinpractice/testng/ui/ResultTreeRenderer.java
@@ -16,6 +16,7 @@
package com.theoryinpractice.testng.ui;
import com.intellij.execution.testframework.PoolOfTestIcons;
+import com.intellij.execution.testframework.TestFrameworkRunningModel;
import com.intellij.icons.AllIcons;
import com.intellij.ui.ColoredTreeCellRenderer;
import com.intellij.ui.SimpleTextAttributes;
@@ -34,10 +35,11 @@ import javax.swing.tree.DefaultMutableTreeNode;
*/
public class ResultTreeRenderer extends ColoredTreeCellRenderer
{
- private final TestNGConsoleProperties consoleProperties;
- public ResultTreeRenderer(TestNGConsoleProperties consoleProperties) {
- this.consoleProperties = consoleProperties;
+ private TestFrameworkRunningModel model;
+
+ public ResultTreeRenderer(TestFrameworkRunningModel model) {
+ this.model = model;
}
@Override
@@ -47,7 +49,7 @@ public class ResultTreeRenderer extends ColoredTreeCellRenderer
TestProxy proxy = ((TestNodeDescriptor) node.getUserObject()).getElement();
if (node == tree.getModel().getRoot()) {
TreeRootNode root = (TreeRootNode) proxy;
- if (node.getChildCount() == 0) {
+ if (node.getChildCount() == 0 && !((TestNGResults)model).hasFinishedTests()) {
if ((root.isStarted() && root.isInProgress()) || (root.isInProgress() && !root.isStarted())) {
setIcon(PoolOfTestIcons.NOT_RAN);
append("Instantiating tests... ", SimpleTextAttributes.REGULAR_ATTRIBUTES);
@@ -64,13 +66,13 @@ public class ResultTreeRenderer extends ColoredTreeCellRenderer
append(root.isInProgress() ? "Running tests..." : "Test Results", SimpleTextAttributes.REGULAR_ATTRIBUTES);
}
- if (consoleProperties.isPaused()) {
+ if (model.getProperties().isPaused()) {
setIcon(AllIcons.RunConfigurations.TestPaused);
}
} else {
if (proxy.getResultMessage() != null) {
final TestResultMessage result = proxy.getResultMessage();
- final String name = TestProxy.toDisplayText(result, consoleProperties.getProject());
+ final String name = TestProxy.toDisplayText(result, model.getProperties().getProject());
append(name, SimpleTextAttributes.REGULAR_ATTRIBUTES);
} else {
append(proxy.getName(), SimpleTextAttributes.REGULAR_ATTRIBUTES);
diff --git a/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java b/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java
index 442e03440ac5..78f980aea83d 100644
--- a/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java
+++ b/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java
@@ -378,7 +378,7 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn
rootNode.setStarted(true);
}
- public void finish() {
+ public void finish(final boolean started) {
if (start > 0) {
end = System.currentTimeMillis();
}
@@ -409,6 +409,7 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn
}
}
tree.repaint();
+ TestsUIUtil.notifyByBalloon(project, started, rootNode, getProperties(), "in " + getTime());
}
});
}
@@ -466,6 +467,10 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn
this.failedToStart = failedToStart;
}
+ public boolean hasFinishedTests() {
+ return count > 0;
+ }
+
private class OpenSourceSelectionListener implements TreeSelectionListener {
public void valueChanged(TreeSelectionEvent e) {
diff --git a/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGTestTreeView.java b/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGTestTreeView.java
index 48f252d828ee..7e5b7995af0c 100644
--- a/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGTestTreeView.java
+++ b/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGTestTreeView.java
@@ -33,7 +33,7 @@ import javax.swing.tree.TreeSelectionModel;
public class TestNGTestTreeView extends TestTreeView {
protected TreeCellRenderer getRenderer(final TestConsoleProperties properties) {
- return new ResultTreeRenderer((TestNGConsoleProperties)properties);
+ return new ResultTreeRenderer(getTestFrameworkRunningModel());
}
public TestProxy getSelectedTest(@NotNull TreePath treepath) {
diff --git a/plugins/testng/src/com/theoryinpractice/testng/ui/actions/RerunFailedTestsAction.java b/plugins/testng/src/com/theoryinpractice/testng/ui/actions/RerunFailedTestsAction.java
index a3538059b1db..597bb5983876 100644
--- a/plugins/testng/src/com/theoryinpractice/testng/ui/actions/RerunFailedTestsAction.java
+++ b/plugins/testng/src/com/theoryinpractice/testng/ui/actions/RerunFailedTestsAction.java
@@ -8,25 +8,26 @@ import com.intellij.execution.actions.JavaRerunFailedTestsAction;
import com.intellij.execution.configurations.RunProfileState;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.testframework.AbstractTestProxy;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComponentContainer;
+import com.intellij.openapi.util.Computable;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.util.containers.ContainerUtil;
import com.theoryinpractice.testng.configuration.SearchingForTestsTask;
import com.theoryinpractice.testng.configuration.TestNGConfiguration;
import com.theoryinpractice.testng.configuration.TestNGRunnableState;
+import com.theoryinpractice.testng.util.TestNGUtil;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.net.ServerSocket;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
public class RerunFailedTestsAction extends JavaRerunFailedTestsAction {
@@ -53,6 +54,19 @@ public class RerunFailedTestsAction extends JavaRerunFailedTestsAction {
return new SearchingForTestsTask(serverSocket, config, tempFile, client) {
@Override
protected void fillTestObjects(final Map<PsiClass, Collection<PsiMethod>> classes) throws CantRunException {
+ final HashMap<PsiClass, Collection<PsiMethod>> fullClassList = ContainerUtil.newHashMap();
+ super.fillTestObjects(fullClassList);
+ for (final PsiClass aClass : fullClassList.keySet()) {
+ if (!ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
+ @Override
+ public Boolean compute() {
+ return TestNGUtil.hasTest(aClass);
+ }
+ })) {
+ classes.put(aClass, fullClassList.get(aClass));
+ }
+ }
+
final GlobalSearchScope scope = config.getConfigurationModule().getSearchScope();
final Project project = config.getProject();
for (AbstractTestProxy proxy : failedTests) {
diff --git a/plugins/testng/src/com/theoryinpractice/testng/util/TestNGUtil.java b/plugins/testng/src/com/theoryinpractice/testng/util/TestNGUtil.java
index c707a5e86e4e..565af249a27f 100644
--- a/plugins/testng/src/com/theoryinpractice/testng/util/TestNGUtil.java
+++ b/plugins/testng/src/com/theoryinpractice/testng/util/TestNGUtil.java
@@ -113,25 +113,27 @@ public class TestNGUtil {
private static final String SUITE_TAG_NAME = "suite";
public static boolean hasConfig(PsiModifierListOwner element) {
- PsiMethod[] methods;
if (element instanceof PsiClass) {
- methods = ((PsiClass) element).getMethods();
+ for (PsiMethod method : ((PsiClass)element).getAllMethods()) {
+ if (isConfigMethod(method)) return true;
+ }
} else {
if (!(element instanceof PsiMethod)) return false;
- methods = new PsiMethod[] {(PsiMethod) element};
+ return isConfigMethod((PsiMethod)element);
}
+ return false;
+ }
- for (PsiMethod method : methods) {
- for (String fqn : CONFIG_ANNOTATIONS_FQN) {
- if (AnnotationUtil.isAnnotated(method, fqn, false)) return true;
- }
+ private static boolean isConfigMethod(PsiMethod method) {
+ for (String fqn : CONFIG_ANNOTATIONS_FQN) {
+ if (AnnotationUtil.isAnnotated(method, fqn, false)) return true;
+ }
- if (hasDocTagsSupport) {
- final PsiDocComment comment = method.getDocComment();
- if (comment != null) {
- for (String javadocTag : CONFIG_JAVADOC_TAGS) {
- if (comment.findTagByName(javadocTag) != null) return true;
- }
+ if (hasDocTagsSupport) {
+ final PsiDocComment comment = method.getDocComment();
+ if (comment != null) {
+ for (String javadocTag : CONFIG_JAVADOC_TAGS) {
+ if (comment.findTagByName(javadocTag) != null) return true;
}
}
}
@@ -178,13 +180,7 @@ public class TestNGUtil {
if (checkDisabled) {
PsiAnnotation annotation = AnnotationUtil.findAnnotation(element, true, TEST_ANNOTATION_FQN);
if (annotation != null) {
- PsiNameValuePair[] attribs = annotation.getParameterList().getAttributes();
- for (PsiNameValuePair attrib : attribs) {
- final String attribName = attrib.getName();
- final PsiAnnotationMemberValue attribValue = attrib.getValue();
- if (Comparing.strEqual(attribName, "enabled") && attribValue != null && attribValue.textMatches("false"))
- return false;
- }
+ if (isDisabled(annotation)) return false;
}
}
return true;
@@ -207,7 +203,7 @@ public class TestNGUtil {
if (AnnotationUtil.isAnnotated(psiClass, TEST_ANNOTATION_FQN, true, true)) {
//even if it has a global test, we ignore private methods
boolean isPrivate = element.hasModifierProperty(PsiModifier.PRIVATE);
- return !isPrivate;
+ return !isPrivate && !element.hasModifierProperty(PsiModifier.STATIC) && !hasConfig(element);
}
if (hasTestJavaDoc(psiClass, checkJavadoc)) return true;
}
@@ -215,6 +211,11 @@ public class TestNGUtil {
return false;
}
+ public static boolean isDisabled(PsiAnnotation annotation) {
+ final PsiAnnotationMemberValue attributeValue = annotation.findDeclaredAttributeValue("enabled");
+ return attributeValue != null && attributeValue.textMatches("false");
+ }
+
private static boolean hasTestJavaDoc(@NotNull PsiDocCommentOwner element, final boolean checkJavadoc) {
if (checkJavadoc) {
return getTextJavaDoc(element) != null;
diff --git a/plugins/testng/src/inspectionDescriptions/TestNGMethodNamingConvention.html b/plugins/testng/src/inspectionDescriptions/TestNGMethodNamingConvention.html
new file mode 100644
index 000000000000..2303a201c5d9
--- /dev/null
+++ b/plugins/testng/src/inspectionDescriptions/TestNGMethodNamingConvention.html
@@ -0,0 +1,13 @@
+<html>
+<body>
+Reports TestNG test methods whose names are either too short, too long, or do not follow the specified regular expression pattern.
+When this inspection is enabled, the <i>Instance method naming convention</i> inspection
+will ignore TestNG test methods automatically.
+<!-- tooltip end -->
+<p>
+ Use the fields below to specify minimum length, maximum length and regular expression expected for TestNG test method names.
+ Specify <b>0</b> to not check the length of names. Regular expressions are in standard <b>java.util.regex</b> format.
+<p>
+ <small>New in 14</small>
+</body>
+</html> \ No newline at end of file
diff --git a/plugins/testng/testData/inspection/dependsOn/Dependencies.java b/plugins/testng/testData/inspection/dependsOn/Dependencies.java
index 9111c74affd0..fc095a3ecd3d 100644
--- a/plugins/testng/testData/inspection/dependsOn/Dependencies.java
+++ b/plugins/testng/testData/inspection/dependsOn/Dependencies.java
@@ -14,6 +14,12 @@ import org.testng.annotations.*;
@BeforeMethod(dependsOnMethods = <warning descr="Method 'afterSuiteMethod' is not annotated with @org.testng.annotations.BeforeMethod">"afterSuiteMethod"</warning>)
public final void beforeMethod() throws Throwable {
}
-}
+
+ @Test(dependsOnMethods = <warning descr="Method 'foo*' unknown.">"foo*"</warning>)
+ public void testBar2() {}
+
+ @Test(dependsOnMethods = "testBa*")
+ public void testBar1() {}
+ }
diff --git a/plugins/ui-designer-core/src/com/intellij/designer/propertyTable/actions/ShowJavadoc.java b/plugins/ui-designer-core/src/com/intellij/designer/propertyTable/actions/ShowJavadoc.java
index 459d18ae2bab..6f42108cab9a 100644
--- a/plugins/ui-designer-core/src/com/intellij/designer/propertyTable/actions/ShowJavadoc.java
+++ b/plugins/ui-designer-core/src/com/intellij/designer/propertyTable/actions/ShowJavadoc.java
@@ -33,7 +33,6 @@ import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.ui.awt.RelativePoint;
-import com.intellij.ui.popup.NotLookupOrSearchCondition;
import java.awt.*;
@@ -101,7 +100,6 @@ public class ShowJavadoc extends AnAction implements IPropertyTableAction {
public void run() {
JBPopup hint =
JBPopupFactory.getInstance().createComponentPopupBuilder(component, component)
- .setRequestFocusCondition(project, NotLookupOrSearchCondition.INSTANCE)
.setProject(project)
.setDimensionServiceKey(project, DocumentationManager.JAVADOC_LOCATION_AND_SIZE, false)
.setResizable(true)
diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/actions/AbstractCreateFormAction.java b/plugins/ui-designer/src/com/intellij/uiDesigner/actions/AbstractCreateFormAction.java
index a5cd762fcf15..0377b72ea043 100644
--- a/plugins/ui-designer/src/com/intellij/uiDesigner/actions/AbstractCreateFormAction.java
+++ b/plugins/ui-designer/src/com/intellij/uiDesigner/actions/AbstractCreateFormAction.java
@@ -31,6 +31,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.JavaDirectoryService;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiNameHelper;
import com.intellij.uiDesigner.UIDesignerBundle;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NonNls;
@@ -104,7 +105,7 @@ public abstract class AbstractCreateFormAction extends CreateElementActionBase i
@Override
public boolean checkInput(String inputString) {
- return inputString.length() > 0 && JavaPsiFacade.getInstance(myProject).getNameHelper().isQualifiedName(inputString);
+ return inputString.length() > 0 && PsiNameHelper.getInstance(myProject).isQualifiedName(inputString);
}
}
} \ No newline at end of file
diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/actions/GenerateMainAction.java b/plugins/ui-designer/src/com/intellij/uiDesigner/actions/GenerateMainAction.java
index d698a076b891..a9996ba276d0 100644
--- a/plugins/ui-designer/src/com/intellij/uiDesigner/actions/GenerateMainAction.java
+++ b/plugins/ui-designer/src/com/intellij/uiDesigner/actions/GenerateMainAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,7 +21,6 @@ import com.intellij.codeInsight.generation.PsiGenerationInfo;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.diagnostic.Logger;
@@ -146,7 +145,7 @@ public class GenerateMainAction extends AnAction {
PsiClass psiClass = PsiTreeUtil.getParentOfType(element, PsiClass.class);
if (psiClass == null) return false;
if (PsiMethodUtil.findMainMethod(psiClass) != null) return false;
- if (FormClassIndex.findFormsBoundToClass(psiClass).isEmpty()) return false;
+ if (FormClassIndex.findFormsBoundToClass(project, psiClass).isEmpty()) return false;
return true;
}
}
diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/binding/BoundIconRenderer.java b/plugins/ui-designer/src/com/intellij/uiDesigner/binding/BoundIconRenderer.java
index 48816354893d..60f12b2489b6 100644
--- a/plugins/ui-designer/src/com/intellij/uiDesigner/binding/BoundIconRenderer.java
+++ b/plugins/ui-designer/src/com/intellij/uiDesigner/binding/BoundIconRenderer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -124,7 +124,7 @@ public class BoundIconRenderer extends GutterIconRenderer {
aClass = (PsiClass) myElement;
}
if (aClass != null && aClass.getQualifiedName() != null) {
- formFiles = FormClassIndex.findFormsBoundToClass(aClass);
+ formFiles = FormClassIndex.findFormsBoundToClass(aClass.getProject(), aClass);
}
return formFiles;
}
diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormClassAnnotator.java b/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormClassAnnotator.java
index 0733ad85c781..05c1bcb1b912 100644
--- a/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormClassAnnotator.java
+++ b/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormClassAnnotator.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -47,7 +47,7 @@ public class FormClassAnnotator implements Annotator {
}
else if (psiElement instanceof PsiClass) {
PsiClass aClass = (PsiClass) psiElement;
- final List<PsiFile> formsBoundToClass = FormClassIndex.findFormsBoundToClass(aClass);
+ final List<PsiFile> formsBoundToClass = FormClassIndex.findFormsBoundToClass(aClass.getProject(), aClass);
if (formsBoundToClass.size() > 0) {
Annotation boundClassAnnotation = holder.createInfoAnnotation(aClass.getNameIdentifier(), null);
boundClassAnnotation.setGutterIconRenderer(new BoundIconRenderer(aClass));
diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormClassIndex.java b/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormClassIndex.java
index 0bf86d73618b..000b63716ef4 100644
--- a/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormClassIndex.java
+++ b/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormClassIndex.java
@@ -127,15 +127,15 @@ public class FormClassIndex extends ScalarIndexExtension<String> {
});
}
- public static List<PsiFile> findFormsBoundToClass(@NotNull PsiClass psiClass) {
+ public static List<PsiFile> findFormsBoundToClass(Project project, @NotNull PsiClass psiClass) {
String qName = FormReferencesSearcher.getQualifiedName(psiClass);
if (qName == null) return Collections.emptyList();
- return findFormsBoundToClass(psiClass.getProject(), qName);
+ return findFormsBoundToClass(project, qName);
}
- public static List<PsiFile> findFormsBoundToClass(PsiClass psiClass, GlobalSearchScope scope) {
+ public static List<PsiFile> findFormsBoundToClass(Project project, PsiClass psiClass, GlobalSearchScope scope) {
String qName = FormReferencesSearcher.getQualifiedName(psiClass);
if (qName == null) return Collections.emptyList();
- return findFormsBoundToClass(psiClass.getProject(), qName, scope);
+ return findFormsBoundToClass(project, qName, scope);
}
}
diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormReferenceProvider.java b/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormReferenceProvider.java
index c0ef7a143a41..173ae3a3a7c1 100644
--- a/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormReferenceProvider.java
+++ b/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormReferenceProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -83,7 +83,7 @@ public class FormReferenceProvider extends PsiReferenceProvider {
public static PsiReference getFormReference(PsiField field) {
final PsiClass containingClass = field.getContainingClass();
if (containingClass != null && containingClass.getQualifiedName() != null) {
- final List<PsiFile> forms = FormClassIndex.findFormsBoundToClass(containingClass);
+ final List<PsiFile> forms = FormClassIndex.findFormsBoundToClass(containingClass.getProject(), containingClass);
for (PsiFile formFile : forms) {
final PsiReference[] refs = formFile.getReferences();
for (final PsiReference ref : refs) {
diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormReferencesSearcher.java b/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormReferencesSearcher.java
index 179f47d57a47..d40be21e1786 100644
--- a/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormReferencesSearcher.java
+++ b/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormReferencesSearcher.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.intellij.uiDesigner.binding;
import com.intellij.lang.properties.IProperty;
@@ -15,7 +30,6 @@ import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.NullableComputable;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
-import com.intellij.psi.impl.PsiManagerImpl;
import com.intellij.psi.impl.cache.CacheManager;
import com.intellij.psi.impl.search.PsiSearchHelperImpl;
import com.intellij.psi.search.*;
@@ -27,16 +41,19 @@ import com.intellij.util.QueryExecutor;
import com.intellij.util.text.CharArrayUtil;
import org.jetbrains.annotations.NotNull;
+import java.util.Arrays;
import java.util.List;
/**
* @author max
*/
public class FormReferencesSearcher implements QueryExecutor<PsiReference, ReferencesSearch.SearchParameters> {
+ @Override
public boolean execute(@NotNull final ReferencesSearch.SearchParameters p, @NotNull final Processor<PsiReference> consumer) {
if (!scopeCanContainForms(p.getScope())) return true;
final PsiElement refElement = p.getElementToSearch();
final PsiFile psiFile = ApplicationManager.getApplication().runReadAction(new Computable<PsiFile>() {
+ @Override
public PsiFile compute() {
if (!refElement.isValid()) return null;
return refElement.getContainingFile();
@@ -45,31 +62,38 @@ public class FormReferencesSearcher implements QueryExecutor<PsiReference, Refer
if (psiFile == null) return true;
final VirtualFile virtualFile = psiFile.getVirtualFile();
if (virtualFile == null) return true;
- Module module = ProjectRootManager.getInstance(refElement.getProject()).getFileIndex().getModuleForFile(virtualFile);
+ Project project = ApplicationManager.getApplication().runReadAction(new Computable<Project>() {
+ @Override
+ public Project compute() {
+ return psiFile.getProject();
+ }
+ });
+ Module module = ProjectRootManager.getInstance(project).getFileIndex().getModuleForFile(virtualFile);
if (module == null) return true;
final GlobalSearchScope scope = GlobalSearchScope.moduleWithDependenciesScope(module);
final LocalSearchScope filterScope = p.getScope() instanceof LocalSearchScope
? (LocalSearchScope) p.getScope()
: null;
+ PsiManager psiManager = PsiManager.getInstance(project);
if (refElement instanceof PsiPackage) {
//no need to do anything
//if (!UIFormUtil.processReferencesInUIForms(consumer, (PsiPackage)refElement, scope)) return false;
}
else if (refElement instanceof PsiClass) {
- if (!processReferencesInUIForms(consumer, (PsiClass)refElement, scope, filterScope)) return false;
+ if (!processReferencesInUIForms(consumer, psiManager,(PsiClass)refElement, scope, filterScope)) return false;
}
else if (refElement instanceof PsiEnumConstant) {
- if (!processReferencesInUIForms(consumer, (PsiEnumConstant)refElement, scope, filterScope)) return false;
+ if (!processReferencesInUIForms(consumer, psiManager, (PsiEnumConstant)refElement, scope, filterScope)) return false;
}
else if (refElement instanceof PsiField) {
- if (!processReferencesInUIForms(consumer, (PsiField)refElement, scope, filterScope)) return false;
+ if (!processReferencesInUIForms(consumer, psiManager, (PsiField)refElement, scope, filterScope)) return false;
}
else if (refElement instanceof IProperty) {
- if (!processReferencesInUIForms(consumer, (Property)refElement, scope, filterScope)) return false;
+ if (!processReferencesInUIForms(consumer, psiManager, (Property)refElement, scope, filterScope)) return false;
}
else if (refElement instanceof PropertiesFile) {
- if (!processReferencesInUIForms(consumer, (PropertiesFile)refElement, scope, filterScope)) return false;
+ if (!processReferencesInUIForms(consumer, psiManager, (PropertiesFile)refElement, scope, filterScope)) return false;
}
return true;
@@ -79,31 +103,37 @@ public class FormReferencesSearcher implements QueryExecutor<PsiReference, Refer
if (!(scope instanceof LocalSearchScope)) return true;
LocalSearchScope localSearchScope = (LocalSearchScope) scope;
final PsiElement[] elements = localSearchScope.getScope();
- for (PsiElement element : elements) {
+ for (final PsiElement element : elements) {
if (element instanceof PsiDirectory) return true;
- PsiFile file;
- if (element instanceof PsiFile) {
- file = (PsiFile) element;
- }
- else {
- if (!element.isValid()) continue;
- file = element.getContainingFile();
- }
- if (file.getFileType() == StdFileTypes.GUI_DESIGNER_FORM) return true;
+ boolean isForm = ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
+ @Override
+ public Boolean compute() {
+ PsiFile file;
+ if (element instanceof PsiFile) {
+ file = (PsiFile)element;
+ }
+ else {
+ if (!element.isValid()) return false;
+ file = element.getContainingFile();
+ }
+ return file.getFileType() == StdFileTypes.GUI_DESIGNER_FORM;
+ }
+ });
+ if (isForm) return true;
}
return false;
}
private static boolean processReferencesInUIForms(Processor<PsiReference> processor,
- final PsiClass aClass,
- GlobalSearchScope scope, final LocalSearchScope filterScope) {
- PsiManagerImpl manager = (PsiManagerImpl)aClass.getManager();
+ PsiManager psiManager, final PsiClass aClass,
+ GlobalSearchScope scope, final LocalSearchScope filterScope) {
String className = getQualifiedName(aClass);
- return className == null || processReferencesInUIFormsInner(className, aClass, processor, scope, manager, filterScope);
+ return className == null || processReferencesInUIFormsInner(className, aClass, processor, scope, psiManager, filterScope);
}
public static String getQualifiedName(final PsiClass aClass) {
return ApplicationManager.getApplication().runReadAction(new Computable<String>() {
+ @Override
public String compute() {
if (!aClass.isValid()) return null;
return aClass.getQualifiedName();
@@ -112,83 +142,56 @@ public class FormReferencesSearcher implements QueryExecutor<PsiReference, Refer
}
private static boolean processReferencesInUIForms(Processor<PsiReference> processor,
- final PsiEnumConstant enumConstant,
+ PsiManager psiManager, final PsiEnumConstant enumConstant,
GlobalSearchScope scope, final LocalSearchScope filterScope) {
- PsiManagerImpl manager = (PsiManagerImpl)enumConstant.getManager();
String className = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
@Override
public String compute() {
return enumConstant.getName();
}
});
- return className == null || processReferencesInUIFormsInner(className, enumConstant, processor, scope, manager, filterScope);
-
+ return className == null || processReferencesInUIFormsInner(className, enumConstant, processor, scope, psiManager, filterScope);
}
private static boolean processReferencesInUIFormsInner(String name,
PsiElement element,
Processor<PsiReference> processor,
GlobalSearchScope scope1,
- PsiManagerImpl manager,
+ PsiManager manager,
final LocalSearchScope filterScope) {
GlobalSearchScope scope = GlobalSearchScope.projectScope(manager.getProject()).intersectWith(scope1);
- manager.startBatchFilesProcessingMode();
-
- try {
- List<PsiFile> files = FormClassIndex.findFormsBoundToClass(manager.getProject(), name, scope);
-
- for (PsiFile file : files) {
- ProgressManager.checkCanceled();
+ List<PsiFile> files = FormClassIndex.findFormsBoundToClass(manager.getProject(), name, scope);
- if (file.getFileType() != StdFileTypes.GUI_DESIGNER_FORM) continue;
- if (!processReferences(processor, file, name, element, filterScope)) return false;
- }
- }
- finally {
- manager.finishBatchFilesProcessingMode();
- }
-
- return true;
+ return processReferencesInFiles(files, manager, name, element, filterScope, processor);
}
private static boolean processReferencesInUIForms(Processor<PsiReference> processor,
- PsiField field,
- GlobalSearchScope scope1,
- LocalSearchScope filterScope) {
- GlobalSearchScope scope = GlobalSearchScope.projectScope(field.getProject()).intersectWith(scope1);
- PsiManagerImpl manager = (PsiManagerImpl)field.getManager();
+ PsiManager psiManager,
+ PsiField field,
+ GlobalSearchScope scope1,
+ LocalSearchScope filterScope) {
+ GlobalSearchScope scope = GlobalSearchScope.projectScope(psiManager.getProject()).intersectWith(scope1);
+ final AccessToken token = ReadAction.start();
PsiClass containingClass = field.getContainingClass();
if (containingClass == null) return true;
String fieldName;
- final AccessToken token = ReadAction.start();
try {
fieldName = field.getName();
}
finally {
token.finish();
}
- manager.startBatchFilesProcessingMode();
-
- try {
- final List<PsiFile> files = FormClassIndex.findFormsBoundToClass(containingClass, scope);
-
- for (PsiFile file : files) {
- ProgressManager.checkCanceled();
-
- if (file.getFileType() != StdFileTypes.GUI_DESIGNER_FORM) continue;
- if (!processReferences(processor, file, fieldName, field, filterScope)) return false;
- }
- }
- finally {
- manager.finishBatchFilesProcessingMode();
- }
-
- return true;
+ final List<PsiFile> files = FormClassIndex.findFormsBoundToClass(psiManager.getProject(), containingClass, scope);
+ return processReferencesInFiles(files, psiManager, fieldName, field, filterScope, processor);
}
- private static boolean processReferences(final Processor<PsiReference> processor, final PsiFile file, String name, final PsiElement element,
+ private static boolean processReferences(final Processor<PsiReference> processor,
+ final PsiFile file,
+ String name,
+ final PsiElement element,
final LocalSearchScope filterScope) {
CharSequence chars = ApplicationManager.getApplication().runReadAction(new NullableComputable<CharSequence>() {
+ @Override
public CharSequence compute() {
if (filterScope != null) {
boolean isInScope = false;
@@ -211,6 +214,7 @@ public class FormReferencesSearcher implements QueryExecutor<PsiReference, Refer
if (index < 0) break;
final int finalIndex = index;
final Boolean searchDone = ApplicationManager.getApplication().runReadAction(new NullableComputable<Boolean>() {
+ @Override
public Boolean compute() {
final PsiReference ref = file.findReferenceAt(finalIndex + offset + 1);
if (ref != null && ref.isReferenceTo(element)) {
@@ -227,13 +231,13 @@ public class FormReferencesSearcher implements QueryExecutor<PsiReference, Refer
}
private static boolean processReferencesInUIForms(final Processor<PsiReference> processor,
- final Property property,
- final GlobalSearchScope globalSearchScope,
- final LocalSearchScope filterScope) {
+ PsiManager psiManager,
+ final Property property,
+ final GlobalSearchScope globalSearchScope,
+ final LocalSearchScope filterScope) {
+ final Project project = psiManager.getProject();
- final Project project = property.getProject();
final GlobalSearchScope scope = GlobalSearchScope.projectScope(project).intersectWith(globalSearchScope);
- final PsiManagerImpl manager = (PsiManagerImpl)property.getManager();
String name = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
@Override
public String compute() {
@@ -242,7 +246,7 @@ public class FormReferencesSearcher implements QueryExecutor<PsiReference, Refer
});
if (name == null) return true;
- manager.startBatchFilesProcessingMode();
+ psiManager.startBatchFilesProcessingMode();
try {
CommonProcessors.CollectProcessor<VirtualFile> collector = new CommonProcessors.CollectProcessor<VirtualFile>() {
@@ -268,34 +272,54 @@ public class FormReferencesSearcher implements QueryExecutor<PsiReference, Refer
}
}
finally {
- manager.finishBatchFilesProcessingMode();
+ psiManager.finishBatchFilesProcessingMode();
}
return true;
}
- private static boolean processReferencesInUIForms(final Processor<PsiReference> processor, final PropertiesFile propFile, final GlobalSearchScope globalSearchScope,
- final LocalSearchScope filterScope) {
- final Project project = propFile.getProject();
+ private static boolean processReferencesInUIForms(final Processor<PsiReference> processor,
+ PsiManager psiManager,
+ final PropertiesFile propFile,
+ final GlobalSearchScope globalSearchScope,
+ final LocalSearchScope filterScope) {
+ final Project project = psiManager.getProject();
GlobalSearchScope scope = GlobalSearchScope.projectScope(project).intersectWith(globalSearchScope);
- PsiManagerImpl manager = (PsiManagerImpl)propFile.getContainingFile().getManager();
- final String baseName = propFile.getResourceBundle().getBaseName();
- manager.startBatchFilesProcessingMode();
+ final String baseName = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
+ @Override
+ public String compute() {
+ return propFile.getResourceBundle().getBaseName();
+ }
+ });
+ PsiFile containingFile = ApplicationManager.getApplication().runReadAction(new Computable<PsiFile>() {
+ @Override
+ public PsiFile compute() {
+ return propFile.getContainingFile();
+ }
+ });
- try {
- PsiFile[] files = CacheManager.SERVICE.getInstance(project).getFilesWithWord(baseName, UsageSearchContext.IN_PLAIN_TEXT, scope, true);
+ List<PsiFile> files = Arrays.asList(CacheManager.SERVICE.getInstance(project).getFilesWithWord(baseName, UsageSearchContext.IN_PLAIN_TEXT, scope, true));
+ return processReferencesInFiles(files, psiManager, baseName, containingFile, filterScope, processor);
+ }
+ private static boolean processReferencesInFiles(List<PsiFile> files,
+ PsiManager psiManager, String baseName,
+ PsiElement element,
+ LocalSearchScope filterScope,
+ Processor<PsiReference> processor) {
+ psiManager.startBatchFilesProcessingMode();
+
+ try {
for (PsiFile file : files) {
ProgressManager.checkCanceled();
if (file.getFileType() != StdFileTypes.GUI_DESIGNER_FORM) continue;
- if (!processReferences(processor, file, baseName, propFile.getContainingFile(), filterScope)) return false;
+ if (!processReferences(processor, file, baseName, element, filterScope)) return false;
}
}
finally {
- manager.finishBatchFilesProcessingMode();
+ psiManager.finishBatchFilesProcessingMode();
}
-
return true;
}
}
diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormRelatedFilesProvider.java b/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormRelatedFilesProvider.java
index dbe28385666d..8de344a03f16 100644
--- a/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormRelatedFilesProvider.java
+++ b/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormRelatedFilesProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -42,7 +42,7 @@ public class FormRelatedFilesProvider extends GotoRelatedProvider {
PsiClass psiClass = PsiTreeUtil.getParentOfType(context, PsiClass.class, false);
if (psiClass != null) {
while (psiClass != null) {
- List<PsiFile> forms = FormClassIndex.findFormsBoundToClass(psiClass);
+ List<PsiFile> forms = FormClassIndex.findFormsBoundToClass(psiClass.getProject(), psiClass);
if (!forms.isEmpty()) {
return GotoRelatedItem.createItems(forms, "UI Forms");
}
diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormsRenamer.java b/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormsRenamer.java
index cafbb8d2bf73..796aced2a67d 100644
--- a/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormsRenamer.java
+++ b/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormsRenamer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,7 +39,7 @@ public class FormsRenamer extends AutomaticRenamer {
public FormsRenamer(PsiClass aClass, String newClassName) {
if (aClass.getQualifiedName() != null) {
- List<PsiFile> forms = FormClassIndex.findFormsBoundToClass(aClass);
+ List<PsiFile> forms = FormClassIndex.findFormsBoundToClass(aClass.getProject(), aClass);
myElements.addAll(forms);
suggestAllNames(aClass.getName(), newClassName);
}
diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormsRenamerFactory.java b/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormsRenamerFactory.java
index 7f719850834e..5ffca466a954 100644
--- a/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormsRenamerFactory.java
+++ b/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormsRenamerFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,7 +29,7 @@ import java.util.List;
public class FormsRenamerFactory implements AutomaticRenamerFactory {
public boolean isApplicable(final PsiElement element) {
if (!(element instanceof PsiClass)) return false;
- List<PsiFile> forms = FormClassIndex.findFormsBoundToClass((PsiClass) element);
+ List<PsiFile> forms = FormClassIndex.findFormsBoundToClass(element.getProject(), (PsiClass)element);
return forms.size() > 0;
}
diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/binding/ResourceBundleFileReference.java b/plugins/ui-designer/src/com/intellij/uiDesigner/binding/ResourceBundleFileReference.java
index f2a9bbb8316d..3064746e9cac 100644
--- a/plugins/ui-designer/src/com/intellij/uiDesigner/binding/ResourceBundleFileReference.java
+++ b/plugins/ui-designer/src/com/intellij/uiDesigner/binding/ResourceBundleFileReference.java
@@ -16,8 +16,8 @@
package com.intellij.uiDesigner.binding;
import com.intellij.lang.properties.PropertiesFileType;
-import com.intellij.lang.properties.PropertiesUtil;
import com.intellij.lang.properties.PropertiesUtilBase;
+import com.intellij.lang.properties.ResourceBundleManager;
import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
@@ -61,7 +61,7 @@ public final class ResourceBundleFileReference extends ReferenceInForm {
@Override
public boolean isReferenceTo(final PsiElement element) {
if (!(element instanceof PropertiesFile)) return false;
- String baseName = PropertiesUtil.getFullName((PropertiesFile) element);
+ String baseName = ResourceBundleManager.getInstance(element.getProject()).getFullName((PropertiesFile)element);
if (baseName == null) return false;
baseName = baseName.replace('.', '/');
final String rangeText = getRangeText();
diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/binding/ResourceBundleKeyReference.java b/plugins/ui-designer/src/com/intellij/uiDesigner/binding/ResourceBundleKeyReference.java
index e6f2bb5930c9..e440400dcbee 100644
--- a/plugins/ui-designer/src/com/intellij/uiDesigner/binding/ResourceBundleKeyReference.java
+++ b/plugins/ui-designer/src/com/intellij/uiDesigner/binding/ResourceBundleKeyReference.java
@@ -16,8 +16,8 @@
package com.intellij.uiDesigner.binding;
import com.intellij.lang.properties.IProperty;
-import com.intellij.lang.properties.PropertiesUtil;
import com.intellij.lang.properties.PropertiesUtilBase;
+import com.intellij.lang.properties.ResourceBundleManager;
import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
@@ -74,7 +74,7 @@ public final class ResourceBundleKeyReference extends ReferenceInForm {
return false;
}
IProperty property = (IProperty) element;
- String baseName = PropertiesUtil.getFullName(property.getPropertiesFile());
+ String baseName = ResourceBundleManager.getInstance(element.getProject()).getFullName(property.getPropertiesFile());
return baseName != null && myBundleName.equals(baseName.replace('.', '/')) && getRangeText().equals(property.getUnescapedKey());
}
}
diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/ComponentItemDialog.java b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/ComponentItemDialog.java
index 95be42a02d8b..a3d66a914304 100644
--- a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/ComponentItemDialog.java
+++ b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/ComponentItemDialog.java
@@ -325,13 +325,13 @@ public final class ComponentItemDialog extends DialogWrapper {
if (myDocument == null) { // why?
return false;
}
- final JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(myProject);
- if (!javaPsiFacade.getNameHelper().isQualifiedName(myDocument.getText())) {
+ if (!PsiNameHelper.getInstance(myProject).isQualifiedName(myDocument.getText())) {
if (myDocument.getTextLength() > 0) {
myErrorLabel.setText(UIDesignerBundle.message("add.component.error.qualified.name.required"));
}
return false;
}
+ final JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(myProject);
PsiClass psiClass = javaPsiFacade.findClass(myDocument.getText(), ProjectScope.getAllScope(myProject));
PsiClass componentClass = javaPsiFacade.findClass(JComponent.class.getName(), ProjectScope.getAllScope(myProject));
if (psiClass != null && componentClass != null && !InheritanceUtil.isInheritorOrSelf(psiClass, componentClass, true)) {
diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/projectView/Form.java b/plugins/ui-designer/src/com/intellij/uiDesigner/projectView/Form.java
index 473593be180e..1b3b00365d8f 100644
--- a/plugins/ui-designer/src/com/intellij/uiDesigner/projectView/Form.java
+++ b/plugins/ui-designer/src/com/intellij/uiDesigner/projectView/Form.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,7 +34,7 @@ public class Form implements Navigatable {
public Form(PsiClass classToBind) {
myClassToBind = classToBind;
- myFormFiles = FormClassIndex.findFormsBoundToClass(classToBind);
+ myFormFiles = FormClassIndex.findFormsBoundToClass(classToBind.getProject(), classToBind);
}
public Form(PsiClass classToBind, Collection<PsiFile> formFiles) {
diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/propertyInspector/properties/BindingProperty.java b/plugins/ui-designer/src/com/intellij/uiDesigner/propertyInspector/properties/BindingProperty.java
index d4ef25332a60..58306f72167a 100644
--- a/plugins/ui-designer/src/com/intellij/uiDesigner/propertyInspector/properties/BindingProperty.java
+++ b/plugins/ui-designer/src/com/intellij/uiDesigner/propertyInspector/properties/BindingProperty.java
@@ -97,7 +97,7 @@ public final class BindingProperty extends Property<RadComponent, String> {
return;
}
- if (value.length() > 0 && !JavaPsiFacade.getInstance(component.getProject()).getNameHelper().isIdentifier(value)) {
+ if (value.length() > 0 && !PsiNameHelper.getInstance(component.getProject()).isIdentifier(value)) {
throw new Exception("Value '" + value + "' is not a valid identifier");
}
diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/propertyInspector/properties/IdentifierValidator.java b/plugins/ui-designer/src/com/intellij/uiDesigner/propertyInspector/properties/IdentifierValidator.java
index 42372bd96104..2a698d3fc6e3 100644
--- a/plugins/ui-designer/src/com/intellij/uiDesigner/propertyInspector/properties/IdentifierValidator.java
+++ b/plugins/ui-designer/src/com/intellij/uiDesigner/propertyInspector/properties/IdentifierValidator.java
@@ -25,6 +25,7 @@ package com.intellij.uiDesigner.propertyInspector.properties;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.InputValidator;
import com.intellij.psi.JavaPsiFacade;
+import com.intellij.psi.PsiNameHelper;
public class IdentifierValidator implements InputValidator {
private final Project myProject;
@@ -34,7 +35,7 @@ public class IdentifierValidator implements InputValidator {
}
public boolean checkInput(String inputString) {
- return JavaPsiFacade.getInstance(myProject).getNameHelper().isIdentifier(inputString);
+ return PsiNameHelper.getInstance(myProject).isIdentifier(inputString);
}
public boolean canClose(String inputString) {
diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/wizard/BeanStep.java b/plugins/ui-designer/src/com/intellij/uiDesigner/wizard/BeanStep.java
index f273cd32106c..d963bb137aec 100644
--- a/plugins/ui-designer/src/com/intellij/uiDesigner/wizard/BeanStep.java
+++ b/plugins/ui-designer/src/com/intellij/uiDesigner/wizard/BeanStep.java
@@ -154,7 +154,7 @@ final class BeanStep extends StepAdapter{
throw new CommitStepException(UIDesignerBundle.message("error.please.specify.class.name.of.the.bean.to.be.created"));
}
final PsiManager psiManager = PsiManager.getInstance(myData.myProject);
- if(!JavaPsiFacade.getInstance(psiManager.getProject()).getNameHelper().isIdentifier(shortClassName)){
+ if(!PsiNameHelper.getInstance(psiManager.getProject()).isIdentifier(shortClassName)){
throw new CommitStepException(UIDesignerBundle.message("error.X.is.not.a.valid.class.name", shortClassName));
}
diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/wizard/BindToNewBeanStep.java b/plugins/ui-designer/src/com/intellij/uiDesigner/wizard/BindToNewBeanStep.java
index 0d88412ece9b..00a89febe8b0 100644
--- a/plugins/ui-designer/src/com/intellij/uiDesigner/wizard/BindToNewBeanStep.java
+++ b/plugins/ui-designer/src/com/intellij/uiDesigner/wizard/BindToNewBeanStep.java
@@ -93,7 +93,7 @@ final class BindToNewBeanStep extends StepAdapter{
}
// Check that all included fields are bound to valid bean properties
- final PsiNameHelper nameHelper = JavaPsiFacade.getInstance(myData.myProject).getNameHelper();
+ final PsiNameHelper nameHelper = PsiNameHelper.getInstance(myData.myProject);
for(int i = 0; i <myData.myBindings.length; i++){
final FormProperty2BeanProperty binding = myData.myBindings[i];
if(binding.myBeanProperty == null){
diff --git a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/XsltDebuggerRunner.java b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/XsltDebuggerRunner.java
index f573f9442e64..5fb6888ec1e2 100644
--- a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/XsltDebuggerRunner.java
+++ b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/XsltDebuggerRunner.java
@@ -8,7 +8,6 @@ import com.intellij.execution.runners.DefaultProgramRunner;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.ui.RunContentDescriptor;
import com.intellij.openapi.fileEditor.FileDocumentManager;
-import com.intellij.openapi.project.Project;
import com.intellij.xdebugger.XDebugProcess;
import com.intellij.xdebugger.XDebugProcessStarter;
import com.intellij.xdebugger.XDebugSession;
@@ -19,11 +18,6 @@ import org.intellij.plugins.xsltDebugger.impl.XsltDebugProcess;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
-/*
-* Created by IntelliJ IDEA.
-* User: sweinreuter
-* Date: 16.11.10
-*/
public class XsltDebuggerRunner extends DefaultProgramRunner {
static final ThreadLocal<Boolean> ACTIVE = new ThreadLocal<Boolean>();
@@ -43,26 +37,20 @@ public class XsltDebuggerRunner extends DefaultProgramRunner {
}
@Override
- protected RunContentDescriptor doExecute(@NotNull Project project,
- @NotNull RunProfileState state,
- RunContentDescriptor contentToReuse,
- @NotNull ExecutionEnvironment env) throws ExecutionException {
+ protected RunContentDescriptor doExecute(@NotNull RunProfileState state, @NotNull ExecutionEnvironment env) throws ExecutionException {
FileDocumentManager.getInstance().saveAllDocuments();
- return createContentDescriptor(project, state, contentToReuse, env);
+ return createContentDescriptor(state, env);
}
- protected RunContentDescriptor createContentDescriptor(Project project,
- final RunProfileState runProfileState,
- RunContentDescriptor contentToReuse,
- final ExecutionEnvironment executionEnvironment) throws ExecutionException {
+ protected RunContentDescriptor createContentDescriptor(final RunProfileState runProfileState, final ExecutionEnvironment environment) throws ExecutionException {
final XDebugSession debugSession =
- XDebuggerManager.getInstance(project).startSession(this, executionEnvironment, contentToReuse, new XDebugProcessStarter() {
+ XDebuggerManager.getInstance(environment.getProject()).startSession(environment, new XDebugProcessStarter() {
@NotNull
public XDebugProcess start(@NotNull final XDebugSession session) throws ExecutionException {
ACTIVE.set(Boolean.TRUE);
try {
final XsltCommandLineState c = (XsltCommandLineState)runProfileState;
- final ExecutionResult result = runProfileState.execute(executionEnvironment.getExecutor(), XsltDebuggerRunner.this);
+ final ExecutionResult result = runProfileState.execute(environment.getExecutor(), XsltDebuggerRunner.this);
return new XsltDebugProcess(session, result, c.getExtensionData().getUserData(XsltDebuggerExtension.VERSION));
} finally {
ACTIVE.remove();
diff --git a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltExecutionStack.java b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltExecutionStack.java
index 3f57574e175c..42d706ae927c 100644
--- a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltExecutionStack.java
+++ b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltExecutionStack.java
@@ -31,6 +31,7 @@ public class XsltExecutionStack extends XExecutionStack {
if (myDebuggerSession.getCurrentState() == Debugger.State.SUSPENDED) {
Debugger.Frame frame = myTopFrame.getFrame();
final List<XStackFrame> frames = new ArrayList<XStackFrame>();
+ frames.add(myTopFrame);
while (frame != null) {
frame = frame.getPrevious();
if (frame != null) {
@@ -38,7 +39,7 @@ public class XsltExecutionStack extends XExecutionStack {
}
}
if (firstFrameIndex <= frames.size()) {
- container.addStackFrames(frames.subList(firstFrameIndex - 1, frames.size()), true);
+ container.addStackFrames(frames.subList(firstFrameIndex, frames.size()), true);
} else {
container.addStackFrames(Collections.<XStackFrame>emptyList(), true);
}
diff --git a/python/build/pycharm_community_build.gant b/python/build/pycharm_community_build.gant
index cfaaf33f3bd0..0bb18ff38758 100644
--- a/python/build/pycharm_community_build.gant
+++ b/python/build/pycharm_community_build.gant
@@ -15,7 +15,7 @@ setProperty("pythonCommunityHome", "$home/python")
// load ApplicationInfo.xml properties
ant.xmlproperty(file: "$pythonCommunityHome/resources/idea/PyCharmCoreApplicationInfo.xml", collapseAttributes: "true")
-setProperty("system_selector", "PyCharm${p("component.version.major")}0")
+setProperty("system_selector", "PyCharmCE${p("component.version.major")}0")
setProperty("dryRun", false)
setProperty("jdk16", guessJdk())
diff --git a/python/edu/build/desktop.ini b/python/edu/build/desktop.ini
index f56d43c998bf..0ea32dec3569 100644
--- a/python/edu/build/desktop.ini
+++ b/python/edu/build/desktop.ini
@@ -28,7 +28,7 @@ Text=Choice Python version
[Field 4]
Type=RadioButton
Left=5
-Right=45
+Right=100
Top=50
Bottom=60
State=1
@@ -36,8 +36,8 @@ Text=Python 2
[Field 5]
Type=RadioButton
-Left=95
-Right=135
+Left=120
+Right=-1
Top=50
Bottom=60
State=0
diff --git a/python/edu/build/idea.nsi b/python/edu/build/idea.nsi
index d9903c94de5e..05c37577893b 100644
--- a/python/edu/build/idea.nsi
+++ b/python/edu/build/idea.nsi
@@ -23,6 +23,7 @@ RequestExecutionLevel user
;------------------------------------------------------------------------------
!include "MUI2.nsh"
!include "FileFunc.nsh"
+!include "TextFunc.nsh"
!include UAC.nsh
!include "InstallOptions.nsh"
!include StrFunc.nsh
@@ -32,6 +33,7 @@ ${UnStrStr}
${UnStrLoc}
${UnStrRep}
${StrRep}
+${StrTok}
ReserveFile "desktop.ini"
ReserveFile "DeleteSettings.ini"
@@ -700,49 +702,69 @@ command_exists:
'$INSTDIR\bin\${PRODUCT_EXE_FILE} "%1"'
FunctionEnd
+Function getPythonInfo
+ ClearErrors
+ FileOpen $3 $INSTDIR\python\python.txt r
+ IfErrors cantOpenFile ;file can not be open.
+ ;get python2 info
+ FileRead $3 $4
+ ${StrTok} $0 $4 " " "1" "1"
+ ${StrTok} $1 $4 " " "2" "1"
+ ;get python3 info
+ FileRead $3 $4
+ ${StrTok} $R0 $4 " " "1" "1"
+ ${StrTok} $R1 $4 " " "2" "1"
+ goto Done
+cantOpenFile:
+ MessageBox MB_OK|MB_ICONEXCLAMATION "python.txt is not exist. Python will not be downloaded."
+ StrCpy $0 "Error"
+Done:
+FunctionEnd
+
+
;------------------------------------------------------------------------------
; Installer sections
;------------------------------------------------------------------------------
Section "IDEA Files" CopyIdeaFiles
-; StrCpy $baseRegKey "HKCU"
-; !insertmacro INSTALLOPTIONS_READ $R2 "Desktop.ini" "Field 3" "State"
-; StrCmp $R2 1 continue_for_current_user
-; SetShellVarContext all
-; StrCpy $baseRegKey "HKLM"
-; continue_for_current_user:
-
-; create shortcuts
-
+ ${LineSum} "$INSTDIR\python\python.txt" $R0
+ IfErrors cantOpenFile
+ StrCmp $R0 "2" getPythonInfo ;info about 2 and 3 version of python
+cantOpenFile:
+ MessageBox MB_OK|MB_ICONEXCLAMATION "python.txt is invalid. Python will not be downloaded."
+ goto skip_python_download
+getPythonInfo:
+ Call getPythonInfo
+ StrCmp $0 "Error" skip_python_download
!insertmacro INSTALLOPTIONS_READ $R2 "Desktop.ini" "Field 4" "State"
StrCmp $R2 1 "" python3
- StrCpy $R2 "2.7"
+ StrCpy $R2 $0
+ StrCpy $R3 $1
goto check_python
python3:
- StrCpy $R2 "3.4"
+ StrCpy $R2 $R0
+ StrCpy $R3 $R1
check_python:
- ReadRegStr $1 "HKCU" "Software\Python\PythonCore\$R2\InstallPath" $0
+ ReadRegStr $1 "HKCU" "Software\Python\PythonCore\$R2\InstallPath" ""
StrCmp $1 "" installation_for_all_users
goto verefy_python_launcher
installation_for_all_users:
- ReadRegStr $1 "HKLM" "Software\Python\PythonCore\$R2\InstallPath" $0
+ ReadRegStr $1 "HKLM" "Software\Python\PythonCore\$R2\InstallPath" ""
StrCmp $1 "" get_python
verefy_python_launcher:
IfFileExists $1\python.exe python_exists get_python
-
-get_python:
- CreateDirectory "$INSTDIR\python"
- StrCmp $R2 "2.7" get_python2
- inetc::get "https://www.python.org/ftp/python/3.4.1/python-3.4.1.amd64.msi" "$INSTDIR\python\python_$R2.msi"
+get_python:
+ inetc::get "$R3" "$INSTDIR\python\python_$R2.msi"
goto validate_download
-get_python2:
- inetc::get "http://www.python.org/ftp/python/2.7.8/python-2.7.8.msi" "$INSTDIR\python\python_$R2.msi"
-validate_download:
+validate_download:
Pop $0
${If} $0 == "OK"
- ExecCmd::exec 'msiexec /i "$INSTDIR\python\python_$R2.msi" /quiet /qn /norestart /log "$INSTDIR\python\python_$R2_silent.log"'
+ ExecCmd::exec 'msiexec /i "$INSTDIR\python\python_$R2.msi" /quiet /qn /norestart'
+ ${Else}
+ MessageBox MB_OK|MB_ICONEXCLAMATION "The download is failed"
${EndIf}
-
python_exists:
+skip_python_download:
+; create shortcuts
!insertmacro INSTALLOPTIONS_READ $R2 "Desktop.ini" "Field 1" "State"
StrCmp $R2 1 "" skip_desktop_shortcut
CreateShortCut "$DESKTOP\${PRODUCT_FULL_NAME_WITH_VER}.lnk" \
@@ -882,6 +904,21 @@ Function ConfirmDesktopShortcut
${If} $0 == "1"
!insertmacro INSTALLOPTIONS_WRITE "Desktop.ini" "Field 2" "Flags" "DISABLED"
${EndIf}
+ CreateDirectory "$INSTDIR\python"
+ inetc::get "http://www.jetbrains.com/updates/python.txt" "$INSTDIR\python\python.txt"
+ ${LineSum} "$INSTDIR\python\python.txt" $R0
+ IfErrors cantOpenFile
+ StrCmp $R0 "2" getPythonInfo
+cantOpenFile:
+ MessageBox MB_OK|MB_ICONEXCLAMATION "python.txt is not exist. Python will not be downloaded."
+ goto association
+getPythonInfo:
+ Call getPythonInfo
+ StrCmp $0 "Error" association
+ !insertmacro INSTALLOPTIONS_WRITE "Desktop.ini" "Field 4" "Text" "Python $0"
+ !insertmacro INSTALLOPTIONS_WRITE "Desktop.ini" "Field 5" "Text" "Python $R0"
+
+association:
StrCmp "${ASSOCIATION}" "NoAssociation" skip_association
StrCpy $R0 6
push "${ASSOCIATION}"
diff --git a/python/edu/build/paths.nsi b/python/edu/build/paths.nsi
index 910f2b3555b7..d85492988c41 100644
--- a/python/edu/build/paths.nsi
+++ b/python/edu/build/paths.nsi
@@ -1,5 +1,5 @@
; Installer images
-!define IMAGES_LOCATION ${COMMUNITY_DIR}\python\build\resources
+!define IMAGES_LOCATION ${COMMUNITY_DIR}\python\edu\build\resources
;!define LICENSE_FILE ${BASE_DIR}\python\license\PyCharm_Preview_License
!define PRODUCT_PROPERTIES_FILE ${BASE_DIR}\out\pycharmEDU\layout\bin\idea.properties
!define PRODUCT_VM_OPTIONS_NAME pycharm.exe.vmoptions
diff --git a/python/edu/build/plugin-list.txt b/python/edu/build/plugin-list.txt
index bc4b94c9e7f4..60ecf3ff6f2d 100644
--- a/python/edu/build/plugin-list.txt
+++ b/python/edu/build/plugin-list.txt
@@ -4,4 +4,5 @@ remote-servers-git
github
IntelliLang
IntelliLang-python
-learn-python \ No newline at end of file
+learn-python
+course-creator \ No newline at end of file
diff --git a/python/edu/build/pycharm_edu_build.gant b/python/edu/build/pycharm_edu_build.gant
index 2ef0bed607a7..28d829e68b34 100644
--- a/python/edu/build/pycharm_edu_build.gant
+++ b/python/edu/build/pycharm_edu_build.gant
@@ -22,14 +22,17 @@ includeTargets << new File("$home/community/build/scripts/libLicenses.gant")
includeTargets << new File("$home/build/scripts/ultimate_utils.gant")
requireProperty("buildNumber", requireProperty("build.number", snapshot))
-setProperty("buildName", "PE-$buildNumber")
+setProperty("buildName", "EDU-$buildNumber")
setProperty("ch", "$home/community")
setProperty("pythonCommunityHome", "$ch/python")
setProperty("pythonEduHome", "$ch/python/edu")
+requireProperty("jdk_bundled_mac", "1.7")
+def jdk_bundled_version = p("jdk_bundled_mac") == "1.8" ? "jdk8_mac_redist.tar" : "jdk_mac_redist.tar"
+ant.copy(file: "${home}/build/jdk/${jdk_bundled_version}", tofile: "${home}/build/jdk/jdk_mac_redist_for_${buildNumber}.tar")
// load ApplicationInfo.xml properties
ant.xmlproperty(file: "$pythonEduHome/resources/idea/PyCharmEduApplicationInfo.xml", collapseAttributes: "true")
-setProperty("system_selector", "PyCharm${p("component.version.major")}0")
+setProperty("system_selector", "PyCharmEdu${p("component.version.major")}0")
setProperty("dryRun", false)
setProperty("jdk16", guessJdk())
@@ -89,7 +92,6 @@ class Paths {
}
setProperty("paths", new Paths(home))
-setProperty("buildName", "PE-$buildNumber")
target('default': "Build artifacts") {
@@ -196,12 +198,12 @@ public layoutEducational(String classesPath, Set usedJars) {
buildNSIS([paths.distAll, paths.distWin],
"$pythonEduHome/build/strings.nsi", "$pythonEduHome/build/paths.nsi",
- "pycharmPE-", false, true, ".py", system_selector)
+ "pycharmEDU-", false, true, ".py", system_selector)
- String tarRoot = isEap() ? "pycharm-pe-$buildNumber" : "pycharm-pe-${p("component.version.major")}.${p("component.version.minor")}"
+ String tarRoot = isEap() ? "pycharm-edu-$buildNumber" : "pycharm-edu-${p("component.version.major")}.${p("component.version.minor")}"
buildTarGz(tarRoot, "$paths.artifacts/pycharm${buildName}.tar", [paths.distAll, paths.distUnix])
- String macAppRoot = isEap() ? "PyCharm PE ${p("component.version.major")}.${p("component.version.minor")} EAP.app/Contents" : "PyCharm PE.app/Contents"
+ String macAppRoot = isEap() ? "PyCharm Educational ${p("component.version.major")}.${p("component.version.minor")} EAP.app/Contents" : "PyCharm Educational.app/Contents"
buildMacZip(macAppRoot, "${paths.artifacts}/pycharm${buildName}.sit", [paths.distAll], paths.distMac)
ant.copy(file: "${paths.artifacts}/pycharm${buildName}.sit", tofile: "${paths.artifacts}/pycharm${buildName}-jdk-bundled.sit")
ant.delete(file: "${paths.artifacts}/pycharm${buildName}.sit")
@@ -214,6 +216,7 @@ private layoutPlugins(layouts) {
fileset(dir: "$pythonEduHome/learn-python/resources/courses")
}
}
+ layouts.layoutPlugin("course-creator")
}
layouts.layoutCommunityPlugins(ch)
@@ -363,7 +366,7 @@ private layoutWin(Map args, String target) {
winScripts(target, ch, "pycharm.bat", args)
winVMOptions(target, null, "pycharm.exe")
- ant.copy(file: "$home/python/help/pycharmhelp.jar", todir: "$target/help", failonerror: false)
+ ant.copy(file: "$home/python/help/pycharm-eduhelp.jar", todir: "$target/help", failonerror: false)
}
private layoutUnix(Map args, String target) {
@@ -380,7 +383,7 @@ private layoutUnix(Map args, String target) {
unixScripts(target, ch, "pycharm.sh", args)
unixVMOptions(target, "pycharm")
- ant.copy(file: "$home/python/help/pycharmhelp.jar", todir: "$target/help", failonerror: false)
+ ant.copy(file: "$home/python/help/pycharm-eduhelp.jar", todir: "$target/help", failonerror: false)
}
private layoutMac(Map _args, String target) {
diff --git a/python/edu/build/python.txt b/python/edu/build/python.txt
new file mode 100644
index 000000000000..d6f247d29afb
--- /dev/null
+++ b/python/edu/build/python.txt
@@ -0,0 +1,2 @@
+python2 2.7 https://www.python.org/ftp/python/2.7.8/python-2.7.8.amd64.msi
+python3 3.4 https://www.python.org/ftp/python/3.4.1/python-3.4.1.amd64.msi \ No newline at end of file
diff --git a/python/edu/build/resources/logo.bmp b/python/edu/build/resources/logo.bmp
new file mode 100644
index 000000000000..9ff6698b8e36
--- /dev/null
+++ b/python/edu/build/resources/logo.bmp
Binary files differ
diff --git a/python/edu/build/resources/logo.png b/python/edu/build/resources/logo.png
deleted file mode 100644
index 1ccbc0773837..000000000000
--- a/python/edu/build/resources/logo.png
+++ /dev/null
Binary files differ
diff --git a/python/edu/build/upload_pythonInfo.xml b/python/edu/build/upload_pythonInfo.xml
new file mode 100644
index 000000000000..f8d9477d1a3f
--- /dev/null
+++ b/python/edu/build/upload_pythonInfo.xml
@@ -0,0 +1,32 @@
+<project name="Upload updates.xml to jetbrains.com. Effective in half an hour" default="bootstrap">
+ <property name="home" value="${basedir}/../../../.."/>
+ <target name="upload">
+ <xmlvalidate file="${home}/build/eap/updates.xml"/>
+
+ <property name="host" value="ftp.labs.intellij.net"/>
+ <property name="user" value="idea"/>
+ <property name="password" value="4pawoMauoJjjlxpIl3XG"/>
+
+ <ftp server="${host}" action="send" binary="false" remotedir="updates" userid="${user}" password="${password}">
+ <fileset file="${home}/community/python/edu/build/python.txt"/>
+ </ftp>
+ </target>
+
+ <target name="bootstrap">
+ <java failonerror="true" classname="org.apache.tools.ant.Main" fork="true">
+ <classpath>
+ <fileset dir="${home}/community/lib/ant/lib">
+ <include name="*.jar"/>
+ </fileset>
+ <fileset dir="${home}/community/lib">
+ <include name="commons-net-3.1.jar"/>
+ <include name="jsch-0.1.50.jar"/>
+ </fileset>
+ </classpath>
+
+ <arg value="-f"/>
+ <arg value="${ant.file}"/>
+ <arg value="upload"/>
+ </java>
+ </target>
+</project>
diff --git a/python/edu/course-creator/course-creator.iml b/python/edu/course-creator/course-creator.iml
new file mode 100644
index 000000000000..fc8c6a1462b1
--- /dev/null
+++ b/python/edu/course-creator/course-creator.iml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$">
+ <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module" module-name="python-community" />
+ <orderEntry type="module" module-name="lang-impl" />
+ <orderEntry type="library" name="gson" level="project" />
+ </component>
+</module>
+
diff --git a/python/edu/course-creator/resources/META-INF/plugin.xml b/python/edu/course-creator/resources/META-INF/plugin.xml
new file mode 100644
index 000000000000..6a9a9ea90276
--- /dev/null
+++ b/python/edu/course-creator/resources/META-INF/plugin.xml
@@ -0,0 +1,60 @@
+<idea-plugin version="2">
+ <id>org.jetbrains.plugins.coursecreator</id>
+ <name>Course Creator for PyCharm Educational</name>
+ <version>1.0</version>
+
+ <description><![CDATA[
+ Plugin allows you to create new course for PyCharm Education Edition.
+ ]]></description>
+
+ <change-notes><![CDATA[
+ ]]>
+ </change-notes>
+ <!-- please see http://confluence.jetbrains.com/display/IDEADEV/Build+Number+Ranges for description -->
+
+ <!-- please see http://confluence.jetbrains.com/display/IDEADEV/Plugin+Compatibility+with+IntelliJ+Platform+Products
+ on how to target different products -->
+ <!-- uncomment to enable plugin in all products
+ <depends>com.intellij.modules.lang</depends>
+ -->
+
+ <depends>com.intellij.modules.python</depends>
+
+ <extensions defaultExtensionNs="com.intellij">
+ <directoryProjectGenerator implementation="org.jetbrains.plugins.coursecreator.CCProjectGenerator"/>
+ <projectService serviceImplementation="org.jetbrains.plugins.coursecreator.CCProjectService"/>
+ <codeInsight.lineMarkerProvider language="Python"
+ implementationClass="org.jetbrains.plugins.coursecreator.highlighting.CCTaskLineMarkerProvider"/>
+ <treeStructureProvider implementation="org.jetbrains.plugins.coursecreator.projectView.CCTreeStructureProvider"/>
+ </extensions>
+
+ <application-components>
+ <!-- Add your application components here -->
+ </application-components>
+
+ <project-components>
+ <!-- Add your project components here -->
+ <component>
+ <implementation-class>org.jetbrains.plugins.coursecreator.CCProjectComponent</implementation-class>
+ </component>
+ </project-components>
+
+ <actions>
+ <action id="CreateLesson" class="org.jetbrains.plugins.coursecreator.actions.CreateLesson">
+ <add-to-group group-id="NewGroup" anchor="before" relative-to-action="NewFile"/>
+ </action>
+ <action id="CreateTaskFile" class="org.jetbrains.plugins.coursecreator.actions.CreateTaskFile">
+ <add-to-group group-id="NewGroup" anchor="before" relative-to-action="NewFile"/>
+ </action>
+ <action id="CreateTask" class="org.jetbrains.plugins.coursecreator.actions.CreateTask">
+ <add-to-group group-id="NewGroup" anchor="before" relative-to-action="NewFile"/>
+ </action>
+ <action id="AddTaskWindow" class="org.jetbrains.plugins.coursecreator.actions.AddTaskWindow">
+ <add-to-group group-id="EditorPopupMenu" anchor="before" relative-to-action="CopyReference"/>
+ </action>
+ <action id="PackCourse" class="org.jetbrains.plugins.coursecreator.actions.CreateCourseArchive">
+ <add-to-group group-id="MainToolBar" anchor="last" />
+ </action>
+ </actions>
+
+</idea-plugin> \ No newline at end of file
diff --git a/python/edu/course-creator/resources/fileTemplates/internal/task.html.ft b/python/edu/course-creator/resources/fileTemplates/internal/task.html.ft
new file mode 100644
index 000000000000..f6833496d1c1
--- /dev/null
+++ b/python/edu/course-creator/resources/fileTemplates/internal/task.html.ft
@@ -0,0 +1,4 @@
+<html>
+Write your task text here.
+<br>
+</html> \ No newline at end of file
diff --git a/python/edu/course-creator/resources/fileTemplates/internal/task.py.ft b/python/edu/course-creator/resources/fileTemplates/internal/task.py.ft
new file mode 100644
index 000000000000..0256e108786c
--- /dev/null
+++ b/python/edu/course-creator/resources/fileTemplates/internal/task.py.ft
@@ -0,0 +1 @@
+# TODO: type solution here \ No newline at end of file
diff --git a/python/edu/course-creator/resources/fileTemplates/internal/test_helper.py.ft b/python/edu/course-creator/resources/fileTemplates/internal/test_helper.py.ft
new file mode 100644
index 000000000000..1182b7815c06
--- /dev/null
+++ b/python/edu/course-creator/resources/fileTemplates/internal/test_helper.py.ft
@@ -0,0 +1,127 @@
+import sys
+
+def get_file_text(path):
+ """ get file text by path"""
+ file_io = open(path, "r")
+ text = file_io.read()
+ file_io.close()
+ return text
+
+def get_file_output(path):
+ # TODO: get file output by path
+ return ""
+
+def test_file_importable():
+ """ tests there is no obvious syntax errors"""
+ path = sys.argv[-1]
+ try:
+ import_file(path)
+ except ImportError:
+ failed("File contains syntax errors")
+ return
+ except SyntaxError:
+ failed("File contains syntax errors")
+ return
+ except NameError:
+ failed("File contains syntax errors")
+ return
+
+ passed()
+
+def import_file(path):
+ """ returns imported file """
+ import imp
+ tmp = imp.load_source('tmp', path)
+ return tmp
+
+def import_task_file():
+ """ returns imported file """
+ path = sys.argv[-1]
+ return import_file(path)
+
+def test_is_not_empty():
+ path = sys.argv[-1]
+ file_text = get_file_text(path)
+
+ if len(file_text) > 0:
+ passed()
+ else:
+ failed("The file is empty. Please, reload the task and try again.")
+
+def test_is_initial_text(error_text="You should modify the file"):
+ path = sys.argv[-1]
+ text = get_initial_text(path)
+ file_text = get_file_text(path)
+
+ if file_text.strip() == text:
+ failed(error_text)
+ else:
+ passed()
+
+def get_initial_text(path):
+ course_lib = sys.argv[-2]
+
+ import os
+ # path format is "project_root/lessonX/taskY/file.py"
+ task_index = path.rfind(os.sep, 0, path.rfind(os.sep))
+ index = path.rfind(os.sep, 0, task_index)
+ relative_path = path[index+1:]
+ initial_file_path = os.path.join(course_lib, relative_path)
+ return get_file_text(initial_file_path)
+
+
+def test_text_equals(text, error_text):
+ path = sys.argv[-1]
+ file_text = get_file_text(path)
+
+ if file_text.strip() == text:
+ passed()
+ else:
+ failed(error_text)
+
+def test_window_text_deleted(error_text="Don't just delete task text"):
+ windows = get_task_windows()
+
+ for window in windows:
+ if len(window) == 0:
+ failed(error_text)
+ return
+ passed()
+
+
+def failed(message="Please, reload the task and try again."):
+ print("#study_plugin FAILED + " + message)
+
+def passed():
+ print("#study_plugin test OK")
+
+def get_task_windows():
+ prefix = "#study_plugin_window = "
+ path = sys.argv[-1]
+ import os
+ windows_path = os.path.splitext(path)[0] + "_windows"
+ windows = []
+ f = open(windows_path, "r")
+ window_text = ""
+ first = True
+ for line in f.readlines():
+ if line.startswith(prefix):
+ if not first:
+ windows.append(window_text.strip())
+ else:
+ first = False
+ window_text = line[len(prefix):]
+ else:
+ window_text += line
+
+ if window_text:
+ windows.append(window_text.strip())
+
+ f.close()
+ return windows
+
+def run_common_tests(error_text="Please, reload file and try again"):
+ test_file_importable()
+ test_is_not_empty()
+ test_is_initial_text(error_text)
+ test_window_text_deleted(error_text) \ No newline at end of file
diff --git a/python/edu/course-creator/resources/fileTemplates/internal/tests.py.ft b/python/edu/course-creator/resources/fileTemplates/internal/tests.py.ft
new file mode 100644
index 000000000000..2e6fd4c78eed
--- /dev/null
+++ b/python/edu/course-creator/resources/fileTemplates/internal/tests.py.ft
@@ -0,0 +1,17 @@
+from test_helper import run_common_tests, failed, passed, get_task_windows
+
+
+def test_task_windows():
+ windows = get_task_windows()
+ window = windows[0]
+ if window != "": # TODO: your condition here
+ passed()
+ else:
+ failed()
+
+
+if __name__ == '__main__':
+ run_common_tests()
+ test_task_windows()
+
+
diff --git a/python/edu/course-creator/resources/icons/gutter.png b/python/edu/course-creator/resources/icons/gutter.png
new file mode 100644
index 000000000000..244e6ca045c5
--- /dev/null
+++ b/python/edu/course-creator/resources/icons/gutter.png
Binary files differ
diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCEditorFactoryListener.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCEditorFactoryListener.java
new file mode 100644
index 000000000000..1eb8690aad22
--- /dev/null
+++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCEditorFactoryListener.java
@@ -0,0 +1,80 @@
+package org.jetbrains.plugins.coursecreator;
+
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.event.EditorFactoryEvent;
+import com.intellij.openapi.editor.event.EditorFactoryListener;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.coursecreator.format.*;
+
+public class CCEditorFactoryListener implements EditorFactoryListener {
+ @Override
+ public void editorCreated(@NotNull EditorFactoryEvent event) {
+ Editor editor = event.getEditor();
+ Project project = editor.getProject();
+ if (project == null) {
+ return;
+ }
+ VirtualFile virtualFile = FileDocumentManager.getInstance().getFile(editor.getDocument());
+ if (virtualFile == null) {
+ return;
+ }
+ Course course = CCProjectService.getInstance(project).getCourse();
+ if (course == null) {
+ return;
+ }
+ final VirtualFile taskDir = virtualFile.getParent();
+ if (taskDir == null || !taskDir.getName().contains("task")) {
+ return;
+ }
+ final VirtualFile lessonDir = taskDir.getParent();
+ if (lessonDir == null) return;
+ final Lesson lesson = course.getLesson(lessonDir.getName());
+ final Task task = lesson.getTask(taskDir.getName());
+ final TaskFile taskFile = task.getTaskFile(virtualFile.getName());
+ TaskFileModificationListener listener = new TaskFileModificationListener(taskFile);
+ CCProjectService.addDocumentListener(editor.getDocument(), listener);
+ editor.getDocument().addDocumentListener(listener);
+ CCProjectService.drawTaskWindows(virtualFile, editor, course);
+ }
+
+ @Override
+ public void editorReleased(@NotNull EditorFactoryEvent event) {
+ Editor editor = event.getEditor();
+ Document document = editor.getDocument();
+ StudyDocumentListener listener = CCProjectService.getListener(document);
+ if (listener != null) {
+ document.removeDocumentListener(listener);
+ CCProjectService.removeListener(document);
+ }
+ editor.getMarkupModel().removeAllHighlighters();
+ editor.getSelectionModel().removeSelection();
+ }
+
+ private class TaskFileModificationListener extends StudyDocumentListener {
+
+ private final TaskFile myTaskFile;
+
+ public TaskFileModificationListener(TaskFile taskFile) {
+ super(taskFile);
+ myTaskFile = taskFile;
+ }
+
+ @Override
+ protected void updateTaskWindowLength(CharSequence fragment, TaskWindow taskWindow, int change) {
+ int newLength = taskWindow.getReplacementLength() + change;
+ taskWindow.setReplacementLength(newLength <= 0 ? 0 : newLength);
+ if (fragment.equals("\n")) {
+ taskWindow.setReplacementLength(taskWindow.getLength() + 1);
+ }
+ }
+
+ @Override
+ protected boolean needModify() {
+ return myTaskFile.isTrackChanges();
+ }
+ }
+}
diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCProjectComponent.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCProjectComponent.java
new file mode 100644
index 000000000000..34de943d2ad0
--- /dev/null
+++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCProjectComponent.java
@@ -0,0 +1,58 @@
+package org.jetbrains.plugins.coursecreator;
+
+import com.intellij.openapi.components.ProjectComponent;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.EditorFactory;
+import com.intellij.openapi.editor.event.EditorFactoryEvent;
+import com.intellij.openapi.editor.impl.EditorFactoryImpl;
+import com.intellij.openapi.fileEditor.FileEditor;
+import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.fileEditor.impl.text.PsiAwareTextEditorImpl;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectManager;
+import com.intellij.openapi.startup.StartupManager;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.coursecreator.format.Course;
+
+public class CCProjectComponent implements ProjectComponent {
+ private final Project myProject;
+
+ public CCProjectComponent(Project project) {
+ myProject = project;
+ }
+
+ public void initComponent() {
+ }
+
+ public void disposeComponent() {
+ }
+
+ @NotNull
+ public String getComponentName() {
+ return "CCProjectComponent";
+ }
+
+ public void projectOpened() {
+ StartupManager.getInstance(myProject).runWhenProjectIsInitialized(new Runnable() {
+ @Override
+ public void run() {
+ Course course = CCProjectService.getInstance(myProject).getCourse();
+ if (course != null) {
+ EditorFactory.getInstance().addEditorFactoryListener(new CCEditorFactoryListener(), myProject);
+ VirtualFile[] files = FileEditorManager.getInstance(myProject).getOpenFiles();
+ for (VirtualFile file : files) {
+ FileEditor fileEditor = FileEditorManager.getInstance(myProject).getSelectedEditor(file);
+ if (fileEditor instanceof PsiAwareTextEditorImpl) {
+ Editor editor = ((PsiAwareTextEditorImpl)fileEditor).getEditor();
+ new CCEditorFactoryListener().editorCreated(new EditorFactoryEvent(new EditorFactoryImpl(ProjectManager.getInstance()), editor ));
+ }
+ }
+ }
+ }
+ });
+ }
+
+ public void projectClosed() {
+ }
+}
diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCProjectGenerator.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCProjectGenerator.java
new file mode 100644
index 000000000000..dbaa7265f5c1
--- /dev/null
+++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCProjectGenerator.java
@@ -0,0 +1,101 @@
+package org.jetbrains.plugins.coursecreator;
+
+import com.intellij.facet.ui.FacetEditorValidator;
+import com.intellij.facet.ui.FacetValidatorsManager;
+import com.intellij.facet.ui.ValidationResult;
+import com.intellij.ide.fileTemplates.FileTemplate;
+import com.intellij.ide.fileTemplates.FileTemplateManager;
+import com.intellij.ide.fileTemplates.FileTemplateUtil;
+import com.intellij.ide.util.DirectoryUtil;
+import com.intellij.openapi.command.WriteCommandAction;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.progress.ProcessCanceledException;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.platform.DirectoryProjectGenerator;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiManager;
+import com.jetbrains.python.newProject.PythonProjectGenerator;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.coursecreator.format.Course;
+import org.jetbrains.plugins.coursecreator.ui.CCNewProjectPanel;
+
+import javax.swing.*;
+
+
+public class CCProjectGenerator extends PythonProjectGenerator implements DirectoryProjectGenerator {
+ private CCNewProjectPanel mySettingsPanel;
+
+ @Nls
+ @NotNull
+ @Override
+ public String getName() {
+ return "Course creation";
+ }
+
+ @Nullable
+ @Override
+ public Object showGenerationSettings(VirtualFile baseDir) throws ProcessCanceledException {
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public Icon getLogo() {
+ return null;
+ }
+
+
+ @Override
+ public void generateProject(@NotNull final Project project, @NotNull final VirtualFile baseDir,
+ @Nullable Object settings, @NotNull Module module) {
+
+ final CCProjectService service = CCProjectService.getInstance(project);
+ final Course course = new Course(mySettingsPanel.getName(), mySettingsPanel.getAuthor(), mySettingsPanel.getDescription());
+ service.setCourse(course);
+
+ final PsiDirectory projectDir = PsiManager.getInstance(project).findDirectory(baseDir);
+ if (projectDir == null) return;
+ new WriteCommandAction.Simple(project) {
+ @Override
+ protected void run() throws Throwable {
+ final FileTemplate template = FileTemplateManager.getInstance().getInternalTemplate("test_helper");
+ try {
+ FileTemplateUtil.createFromTemplate(template, "test_helper.py", null, projectDir);
+ }
+ catch (Exception ignored) {
+ }
+ DirectoryUtil.createSubdirectories("hints", projectDir, "\\/");
+ }
+ }.execute();
+
+ }
+
+ @NotNull
+ @Override
+ public ValidationResult validate(@NotNull String s) {
+ String message = "";
+ message = mySettingsPanel.getDescription().equals("") ? "Enter description" : message;
+ message = mySettingsPanel.getAuthor().equals("") ? "Enter author name" : message;
+ message = mySettingsPanel.getName().equals("") ? "Enter course name" : message;
+ return message.equals("")? ValidationResult.OK : new ValidationResult(message) ;
+ }
+
+ @Nullable
+ @Override
+ public JPanel extendBasePanel() throws ProcessCanceledException {
+ mySettingsPanel = new CCNewProjectPanel();
+ mySettingsPanel.registerValidators(new FacetValidatorsManager() {
+ public void registerValidator(FacetEditorValidator validator, JComponent... componentsToWatch) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void validate() {
+ fireStateChanged();
+ }
+ });
+ return mySettingsPanel.getMainPanel();
+ }
+}
diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCProjectService.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCProjectService.java
new file mode 100644
index 000000000000..1e38bab865cb
--- /dev/null
+++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCProjectService.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.coursecreator;
+
+import com.intellij.ide.projectView.ProjectView;
+import com.intellij.openapi.components.PersistentStateComponent;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.components.State;
+import com.intellij.openapi.components.Storage;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileManager;
+import com.intellij.util.xmlb.XmlSerializer;
+import org.jdom.Element;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.coursecreator.format.*;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@State(name = "CCProjectService",
+ storages = {
+ @Storage(file = "$PROJECT_CONFIG_DIR$/course_service.xml")
+ }
+)
+public class CCProjectService implements PersistentStateComponent<Element> {
+
+ private static final Logger LOG = Logger.getInstance(CCProjectService.class.getName());
+ public Course myCourse;
+ public static final String COURSE_ELEMENT = "course";
+ private static final Map<Document, StudyDocumentListener> myDocumentListeners = new HashMap<Document, StudyDocumentListener>();
+
+ public void setCourse(@NotNull final Course course) {
+ myCourse = course;
+ }
+
+ public Course getCourse() {
+ return myCourse;
+ }
+
+ @Override
+ public Element getState() {
+ final Element el = new Element("CCProjectService");
+ if (myCourse != null) {
+ Element courseElement = new Element(COURSE_ELEMENT);
+ XmlSerializer.serializeInto(myCourse, courseElement);
+ el.addContent(courseElement);
+ }
+ return el;
+ }
+
+ @Override
+ public void loadState(Element el) {
+ myCourse = XmlSerializer.deserialize(el.getChild(COURSE_ELEMENT), Course.class);
+ }
+
+ public static CCProjectService getInstance(@NotNull Project project) {
+ return ServiceManager.getService(project, CCProjectService.class);
+ }
+
+ public static void deleteProjectFile(File file, @NotNull final Project project) {
+ if (!file.delete()) {
+ LOG.info("Failed to delete file " + file.getPath());
+ }
+ VirtualFileManager.getInstance().refreshWithoutFileWatcher(true);
+ ProjectView.getInstance(project).refresh();
+ }
+
+ public static void drawTaskWindows(@NotNull final VirtualFile virtualFile, @NotNull final Editor editor, @NotNull final Course course) {
+ VirtualFile taskDir = virtualFile.getParent();
+ if (taskDir == null) {
+ return;
+ }
+ String taskDirName = taskDir.getName();
+ if (!taskDirName.contains("task")) {
+ return;
+ }
+ VirtualFile lessonDir = taskDir.getParent();
+ if (lessonDir == null) {
+ return;
+ }
+ String lessonDirName = lessonDir.getName();
+ if (!lessonDirName.contains("lesson")) {
+ return;
+ }
+ Lesson lesson = course.getLessonsMap().get(lessonDirName);
+ if (lesson == null) {
+ return;
+ }
+ Task task = lesson.getTask(taskDirName);
+ if (task == null) {
+ return;
+ }
+ TaskFile taskFile = task.getTaskFile(virtualFile.getName());
+ if (taskFile == null) {
+ return;
+ }
+ List<TaskWindow> taskWindows = taskFile.getTaskWindows();
+ for (TaskWindow taskWindow : taskWindows) {
+ taskWindow.drawHighlighter(editor);
+ }
+ }
+
+ public static void addDocumentListener(Document document, StudyDocumentListener listener) {
+ myDocumentListeners.put(document, listener);
+ }
+
+ public static StudyDocumentListener getListener(Document document) {
+ return myDocumentListeners.get(document);
+ }
+
+ public static void removeListener(Document document) {
+ myDocumentListeners.remove(document);
+ }
+
+ public static boolean indexIsValid(int index, List<TaskWindow> collection) {
+ int size = collection.size();
+ return index >= 0 && index < size;
+ }
+}
diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/StudyDocumentListener.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/StudyDocumentListener.java
new file mode 100644
index 000000000000..d803e0e8fd97
--- /dev/null
+++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/StudyDocumentListener.java
@@ -0,0 +1,71 @@
+package org.jetbrains.plugins.coursecreator;
+
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.LogicalPosition;
+import com.intellij.openapi.editor.event.DocumentAdapter;
+import com.intellij.openapi.editor.event.DocumentEvent;
+import com.intellij.openapi.editor.impl.event.DocumentEventImpl;
+import org.jetbrains.plugins.coursecreator.format.TaskFile;
+import org.jetbrains.plugins.coursecreator.format.TaskWindow;
+
+/**
+ * author: liana
+ * data: 7/16/14.
+ * Listens changes in study files and updates
+ * coordinates of all the windows in current task file
+ */
+public abstract class StudyDocumentListener extends DocumentAdapter {
+ private final TaskFile myTaskFile;
+ private int oldLine;
+ private int oldLineStartOffset;
+ private TaskWindow myTaskWindow;
+
+ public StudyDocumentListener(TaskFile taskFile) {
+ myTaskFile = taskFile;
+ }
+
+
+ //remembering old end before document change because of problems
+ // with fragments containing "\n"
+ @Override
+ public void beforeDocumentChange(DocumentEvent e) {
+ int offset = e.getOffset();
+ int oldEnd = offset + e.getOldLength();
+ Document document = e.getDocument();
+ oldLine = document.getLineNumber(oldEnd);
+ oldLineStartOffset = document.getLineStartOffset(oldLine);
+ int line = document.getLineNumber(offset);
+ int offsetInLine = offset - document.getLineStartOffset(line);
+ LogicalPosition pos = new LogicalPosition(line, offsetInLine);
+ myTaskWindow = myTaskFile.getTaskWindow(document, pos);
+
+ }
+
+ @Override
+ public void documentChanged(DocumentEvent e) {
+ if (e instanceof DocumentEventImpl) {
+ if (!needModify()) {
+ return;
+ }
+ DocumentEventImpl event = (DocumentEventImpl)e;
+ Document document = e.getDocument();
+ int offset = e.getOffset();
+ int change = event.getNewLength() - event.getOldLength();
+ if (myTaskWindow != null) {
+ updateTaskWindowLength(e.getNewFragment(), myTaskWindow, change);
+ }
+ int newEnd = offset + event.getNewLength();
+ int newLine = document.getLineNumber(newEnd);
+ int lineChange = newLine - oldLine;
+ myTaskFile.incrementLines(oldLine + 1, lineChange);
+ int newEndOffsetInLine = offset + e.getNewLength() - document.getLineStartOffset(newLine);
+ int oldEndOffsetInLine = offset + e.getOldLength() - oldLineStartOffset;
+ myTaskFile.updateLine(lineChange, oldLine, newEndOffsetInLine, oldEndOffsetInLine);
+ }
+ }
+
+ protected abstract void updateTaskWindowLength(CharSequence fragment, TaskWindow taskWindow, int change);
+
+ protected abstract boolean needModify();
+}
+
diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/AddTaskWindow.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/AddTaskWindow.java
new file mode 100644
index 000000000000..ff88cea5fd42
--- /dev/null
+++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/AddTaskWindow.java
@@ -0,0 +1,105 @@
+package org.jetbrains.plugins.coursecreator.actions;
+
+import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.actionSystem.Presentation;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.SelectionModel;
+import com.intellij.openapi.project.DumbAwareAction;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiFile;
+import org.jetbrains.plugins.coursecreator.CCProjectService;
+import org.jetbrains.plugins.coursecreator.format.*;
+import org.jetbrains.plugins.coursecreator.ui.CreateTaskWindowDialog;
+
+public class AddTaskWindow extends DumbAwareAction {
+ public AddTaskWindow() {
+ super("Add task window","Add task window", null);
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ final Project project = e.getData(CommonDataKeys.PROJECT);
+ if (project == null) {
+ return;
+ }
+ final PsiFile file = CommonDataKeys.PSI_FILE.getData(e.getDataContext());
+ if (file == null) return;
+ final Editor editor = CommonDataKeys.EDITOR.getData(e.getDataContext());
+ if (editor == null) return;
+
+ final SelectionModel model = editor.getSelectionModel();
+ final Document document = PsiDocumentManager.getInstance(project).getDocument(file);
+ if (document == null) return;
+ final int start = model.getSelectionStart();
+ final int end = model.getSelectionEnd();
+ final int lineNumber = document.getLineNumber(start);
+ final int length = end - start;
+ int realStart = start - document.getLineStartOffset(lineNumber);
+
+ final CCProjectService service = CCProjectService.getInstance(project);
+ final Course course = service.getCourse();
+ final PsiDirectory taskDir = file.getContainingDirectory();
+ final PsiDirectory lessonDir = taskDir.getParent();
+ if (lessonDir == null) return;
+
+ final Lesson lesson = course.getLesson(lessonDir.getName());
+ final Task task = lesson.getTask(taskDir.getName());
+ final TaskFile taskFile = task.getTaskFile(file.getName());
+ final TaskWindow taskWindow = new TaskWindow(lineNumber, realStart, length, model.getSelectedText());
+ CreateTaskWindowDialog dlg = new CreateTaskWindowDialog(project, taskWindow, lesson.getIndex(), task.getIndex(), file.getVirtualFile().getNameWithoutExtension(), taskFile.getTaskWindows().size() + 1);
+ dlg.show();
+ if (dlg.getExitCode() != DialogWrapper.OK_EXIT_CODE) {
+ return;
+ }
+ int index = taskFile.getTaskWindows().size() + 1;
+ taskFile.addTaskWindow(taskWindow, index);
+ taskWindow.drawHighlighter(editor);
+ DaemonCodeAnalyzerImpl.getInstance(project).restart(file);
+ }
+
+ @Override
+ public void update(AnActionEvent event) {
+ final Presentation presentation = event.getPresentation();
+ final Project project = event.getData(CommonDataKeys.PROJECT);
+ if (project == null) {
+ presentation.setVisible(false);
+ presentation.setEnabled(false);
+ return;
+ }
+ final Editor editor = CommonDataKeys.EDITOR.getData(event.getDataContext());
+ final PsiFile file = CommonDataKeys.PSI_FILE.getData(event.getDataContext());
+ if (editor == null || file == null) {
+ presentation.setVisible(false);
+ presentation.setEnabled(false);
+ return;
+ }
+ if (!editor.getSelectionModel().hasSelection()) {
+ presentation.setVisible(false);
+ presentation.setEnabled(false);
+ return;
+ }
+
+ final CCProjectService service = CCProjectService.getInstance(project);
+ final Course course = service.getCourse();
+ final PsiDirectory taskDir = file.getContainingDirectory();
+ final PsiDirectory lessonDir = taskDir.getParent();
+ if (lessonDir == null) return;
+
+ final Lesson lesson = course.getLesson(lessonDir.getName());
+ final Task task = lesson.getTask(taskDir.getName());
+ if (task == null) {
+ presentation.setVisible(false);
+ presentation.setEnabled(false);
+ return;
+ }
+ presentation.setVisible(true);
+ presentation.setEnabled(true);
+
+ }
+} \ No newline at end of file
diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CreateCourseArchive.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CreateCourseArchive.java
new file mode 100644
index 000000000000..05428f4e82d1
--- /dev/null
+++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CreateCourseArchive.java
@@ -0,0 +1,198 @@
+package org.jetbrains.plugins.coursecreator.actions;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.projectView.ProjectView;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.command.CommandProcessor;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.project.DumbAwareAction;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileManager;
+import com.intellij.util.io.ZipUtil;
+import org.jetbrains.plugins.coursecreator.CCProjectService;
+import org.jetbrains.plugins.coursecreator.StudyDocumentListener;
+import org.jetbrains.plugins.coursecreator.format.*;
+import org.jetbrains.plugins.coursecreator.ui.CreateCourseArchiveDialog;
+
+import java.io.*;
+import java.util.*;
+import java.util.zip.ZipOutputStream;
+
+public class CreateCourseArchive extends DumbAwareAction {
+ private static final Logger LOG = Logger.getInstance(CreateCourseArchive.class.getName());
+ String myZipName;
+ String myLocationDir;
+
+ public void setZipName(String zipName) {
+ myZipName = zipName;
+ }
+
+ public void setLocationDir(String locationDir) {
+ myLocationDir = locationDir;
+ }
+
+ public CreateCourseArchive() {
+ super("Generate course archive", "Generate course archive", AllIcons.FileTypes.Archive);
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ final Project project = e.getData(CommonDataKeys.PROJECT);
+ if (project == null) {
+ return;
+ }
+ final CCProjectService service = CCProjectService.getInstance(project);
+ final Course course = service.getCourse();
+ if (course == null) return;
+ CreateCourseArchiveDialog dlg = new CreateCourseArchiveDialog(project, this);
+ dlg.show();
+ if (dlg.getExitCode() != DialogWrapper.OK_EXIT_CODE) {
+ return;
+ }
+ final VirtualFile baseDir = project.getBaseDir();
+ final Map<String, Lesson> lessons = course.getLessonsMap();
+ //List<FileEditor> editorList = new ArrayList<FileEditor>();
+ Map<VirtualFile, TaskFile> taskFiles = new HashMap<VirtualFile, TaskFile>();
+ for (Map.Entry<String, Lesson> lesson : lessons.entrySet()) {
+ final VirtualFile lessonDir = baseDir.findChild(lesson.getKey());
+ if (lessonDir == null) continue;
+ for (Map.Entry<String, Task> task : lesson.getValue().myTasksMap.entrySet()) {
+ final VirtualFile taskDir = lessonDir.findChild(task.getKey());
+ if (taskDir == null) continue;
+ for (Map.Entry<String, TaskFile> entry : task.getValue().task_files.entrySet()) {
+ final VirtualFile file = taskDir.findChild(entry.getKey());
+ if (file == null) continue;
+ final Document document = FileDocumentManager.getInstance().getDocument(file);
+ if (document == null) continue;
+ final TaskFile taskFile = entry.getValue();
+ document.addDocumentListener(new InsertionListener(taskFile));
+ taskFiles.put(file, taskFile);
+ taskFile.setTrackChanges(false);
+ Collections.sort(taskFile.getTaskWindows());
+ for (int i = taskFile.getTaskWindows().size() - 1; i >=0 ; i--) {
+ final TaskWindow taskWindow = taskFile.getTaskWindows().get(i);
+ final String taskText = taskWindow.getTaskText();
+ final int lineStartOffset = document.getLineStartOffset(taskWindow.line);
+ final int offset = lineStartOffset + taskWindow.start;
+ CommandProcessor.getInstance().executeCommand(project, new Runnable() {
+ @Override
+ public void run() {
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ document.replaceString(offset, offset + taskWindow.getReplacementLength(), taskText);
+ FileDocumentManager.getInstance().saveDocument(document);
+ }
+ });
+ }
+ }, "x", "qwe");
+ }
+ }
+ }
+ }
+ generateJson(project);
+ try {
+ File zipFile = new File(myLocationDir, myZipName + ".zip");
+ ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFile)));
+
+ for (Map.Entry<String, Lesson> entry : lessons.entrySet()) {
+ final VirtualFile lessonDir = baseDir.findChild(entry.getKey());
+ if (lessonDir == null) continue;
+
+ ZipUtil.addFileOrDirRecursively(zos, null, new File(lessonDir.getPath()), lessonDir.getName(), null, null);
+ }
+ ZipUtil.addFileOrDirRecursively(zos, null, new File(baseDir.getPath(), "hints"), "hints", null, null);
+ ZipUtil.addFileOrDirRecursively(zos, null, new File(baseDir.getPath(), "course.json"), "course.json", null, null);
+ ZipUtil.addFileOrDirRecursively(zos, null, new File(baseDir.getPath(), "test_helper.py"), "test_helper.py", null, null);
+ zos.close();
+ Messages.showInfoMessage("Course archive was saved to " + zipFile.getPath(), "Course Archive Was Created Successfully");
+ }
+ catch (IOException e1) {
+ LOG.error(e1);
+ }
+
+ for (Map.Entry<VirtualFile, TaskFile> entry: taskFiles.entrySet()) {
+ TaskFile value = entry.getValue();
+ final Document document = FileDocumentManager.getInstance().getDocument(entry.getKey());
+ if (document == null) {
+ continue;
+ }
+ for (final TaskWindow taskWindow : value.getTaskWindows()){
+ final int lineStartOffset = document.getLineStartOffset(taskWindow.line);
+ final int offset = lineStartOffset + taskWindow.start;
+ CommandProcessor.getInstance().executeCommand(project, new Runnable() {
+ @Override
+ public void run() {
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ document.replaceString(offset, offset + taskWindow.length, taskWindow.getPossibleAnswer());
+ FileDocumentManager.getInstance().saveDocument(document);
+ }
+ });
+ }
+ }, "x", "qwe");
+ }
+ value.setTrackChanges(true);
+ }
+ VirtualFileManager.getInstance().refreshWithoutFileWatcher(true);
+ ProjectView.getInstance(project).refresh();
+ }
+
+ private void generateJson(Project project) {
+ final CCProjectService service = CCProjectService.getInstance(project);
+ final Course course = service.getCourse();
+ final Gson gson = new GsonBuilder().setPrettyPrinting().excludeFieldsWithoutExposeAnnotation().create();
+ final String json = gson.toJson(course);
+ final File courseJson = new File(project.getBasePath(), "course.json");
+ FileWriter writer = null;
+ try {
+ writer = new FileWriter(courseJson);
+ writer.write(json);
+ }
+ catch (IOException e) {
+ Messages.showErrorDialog(e.getMessage(), "Failed to Generate Json");
+ LOG.info(e);
+ }
+ catch (Exception e) {
+ Messages.showErrorDialog(e.getMessage(), "Failed to Generate Json");
+ LOG.info(e);
+ }
+ finally {
+ try {
+ if (writer != null) {
+ writer.close();
+ }
+ }
+ catch (IOException e1) {
+ //close silently
+ }
+ }
+ }
+
+ private class InsertionListener extends StudyDocumentListener {
+
+ public InsertionListener(TaskFile taskFile) {
+ super(taskFile);
+ }
+
+ @Override
+ protected void updateTaskWindowLength(CharSequence fragment, TaskWindow taskWindow, int change) {
+ //we don't need to update task window length
+ }
+
+ @Override
+ protected boolean needModify() {
+ return true;
+ }
+ }
+} \ No newline at end of file
diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CreateLesson.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CreateLesson.java
new file mode 100644
index 000000000000..15d9f8367db9
--- /dev/null
+++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CreateLesson.java
@@ -0,0 +1,89 @@
+package org.jetbrains.plugins.coursecreator.actions;
+
+import com.intellij.ide.IdeView;
+import com.intellij.ide.util.DirectoryChooserUtil;
+import com.intellij.ide.util.DirectoryUtil;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.actionSystem.LangDataKeys;
+import com.intellij.openapi.actionSystem.Presentation;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.project.DumbAwareAction;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.util.PlatformIcons;
+import org.jetbrains.plugins.coursecreator.CCProjectService;
+import org.jetbrains.plugins.coursecreator.format.Course;
+import org.jetbrains.plugins.coursecreator.format.Lesson;
+
+public class CreateLesson extends DumbAwareAction {
+ public CreateLesson() {
+ super("Lesson", "Create new Lesson", PlatformIcons.DIRECTORY_CLOSED_ICON);
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ final IdeView view = e.getData(LangDataKeys.IDE_VIEW);
+ final Project project = e.getData(CommonDataKeys.PROJECT);
+
+ if (view == null || project == null) {
+ return;
+ }
+ final PsiDirectory directory = DirectoryChooserUtil.getOrChooseDirectory(view);
+ if (directory == null) return;
+
+ final CCProjectService service = CCProjectService.getInstance(project);
+ final Course course = service.getCourse();
+ final int size = course.getLessons().size();
+ final String lessonName = Messages.showInputDialog("Name:", "Lesson Name", null, "lesson" + (size+1), null);
+ if (lessonName == null) return;
+
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ final PsiDirectory lessonDirectory = DirectoryUtil.createSubdirectories("lesson" + (size+1), directory, "\\/");
+ if (lessonDirectory != null) {
+ view.selectElement(lessonDirectory);
+ final Lesson lesson = new Lesson(lessonName);
+ lesson.setIndex(size + 1);
+ course.addLesson(lesson, lessonDirectory);
+ }
+ }
+ });
+ }
+
+ @Override
+ public void update(AnActionEvent event) {
+ final Presentation presentation = event.getPresentation();
+ final Project project = event.getData(CommonDataKeys.PROJECT);
+ if (project == null) {
+ presentation.setVisible(false);
+ presentation.setEnabled(false);
+ return;
+ }
+
+ final IdeView view = event.getData(LangDataKeys.IDE_VIEW);
+ if (view == null) {
+ presentation.setVisible(false);
+ presentation.setEnabled(false);
+ return;
+ }
+
+ final PsiDirectory[] directories = view.getDirectories();
+ if (directories.length == 0) {
+ presentation.setVisible(false);
+ presentation.setEnabled(false);
+ return;
+ }
+ final PsiDirectory directory = DirectoryChooserUtil.getOrChooseDirectory(view);
+ if (directory != null && !project.getBaseDir().equals(directory.getVirtualFile())) {
+ presentation.setVisible(false);
+ presentation.setEnabled(false);
+ return;
+ }
+ presentation.setVisible(true);
+ presentation.setEnabled(true);
+
+ }
+} \ No newline at end of file
diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CreateTask.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CreateTask.java
new file mode 100644
index 000000000000..0940135b97be
--- /dev/null
+++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CreateTask.java
@@ -0,0 +1,122 @@
+package org.jetbrains.plugins.coursecreator.actions;
+
+import com.intellij.ide.IdeView;
+import com.intellij.ide.fileTemplates.FileTemplate;
+import com.intellij.ide.fileTemplates.FileTemplateManager;
+import com.intellij.ide.fileTemplates.FileTemplateUtil;
+import com.intellij.ide.util.DirectoryChooserUtil;
+import com.intellij.ide.util.DirectoryUtil;
+import com.intellij.ide.util.EditorHelper;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.actionSystem.LangDataKeys;
+import com.intellij.openapi.actionSystem.Presentation;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.project.DumbAwareAction;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiElement;
+import com.intellij.util.PlatformIcons;
+import org.jetbrains.plugins.coursecreator.CCProjectService;
+import org.jetbrains.plugins.coursecreator.format.Course;
+import org.jetbrains.plugins.coursecreator.format.Lesson;
+import org.jetbrains.plugins.coursecreator.format.Task;
+
+public class CreateTask extends DumbAwareAction {
+ public CreateTask() {
+ super("Task", "Create new Task", PlatformIcons.DIRECTORY_CLOSED_ICON);
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ final IdeView view = e.getData(LangDataKeys.IDE_VIEW);
+ final Project project = e.getData(CommonDataKeys.PROJECT);
+
+ if (view == null || project == null) {
+ return;
+ }
+ final PsiDirectory directory = DirectoryChooserUtil.getOrChooseDirectory(view);
+
+ if (directory == null) return;
+ final CCProjectService service = CCProjectService.getInstance(project);
+ final Course course = service.getCourse();
+ final Lesson lesson = course.getLesson(directory.getName());
+ final int size = lesson.getTasklist().size();
+
+ final String taskName = Messages.showInputDialog("Name:", "Task Name", null, "task" + (size + 1), null);
+ if (taskName == null) return;
+
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ final PsiDirectory taskDirectory = DirectoryUtil.createSubdirectories("task" + (size + 1), directory, "\\/");
+ if (taskDirectory != null) {
+ final FileTemplate template = FileTemplateManager.getInstance().getInternalTemplate("task.html");
+ final FileTemplate testsTemplate = FileTemplateManager.getInstance().getInternalTemplate("tests");
+ final FileTemplate taskTemplate = FileTemplateManager.getInstance().getInternalTemplate("task.py");
+ try {
+ final PsiElement taskFile = FileTemplateUtil.createFromTemplate(template, "task.html", null, taskDirectory);
+ final PsiElement testsFile = FileTemplateUtil.createFromTemplate(testsTemplate, "tests.py", null, taskDirectory);
+ final PsiElement taskPyFile = FileTemplateUtil.createFromTemplate(taskTemplate, "file1" + ".py", null, taskDirectory);
+
+ final Task task = new Task(taskName);
+ task.addTaskFile(taskPyFile.getContainingFile().getName(), size + 1);
+ task.setIndex(size + 1);
+ lesson.addTask(task, taskDirectory);
+
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ EditorHelper.openInEditor(testsFile, false);
+ EditorHelper.openInEditor(taskPyFile, false);
+ view.selectElement(taskFile);
+ }
+ });
+ }
+ catch (Exception ignored) {
+ }
+
+
+ }
+ }
+ });
+ }
+
+ @Override
+ public void update(AnActionEvent event) {
+ final Presentation presentation = event.getPresentation();
+ final Project project = event.getData(CommonDataKeys.PROJECT);
+ if (project == null) {
+ presentation.setVisible(false);
+ presentation.setEnabled(false);
+ return;
+ }
+
+ final IdeView view = event.getData(LangDataKeys.IDE_VIEW);
+ if (view == null) {
+ presentation.setVisible(false);
+ presentation.setEnabled(false);
+ return;
+ }
+
+ final PsiDirectory[] directories = view.getDirectories();
+ if (directories.length == 0) {
+ presentation.setVisible(false);
+ presentation.setEnabled(false);
+ return;
+ }
+ final PsiDirectory directory = DirectoryChooserUtil.getOrChooseDirectory(view);
+ final CCProjectService service = CCProjectService.getInstance(project);
+ final Course course = service.getCourse();
+ if (course != null && directory != null && course.getLesson(directory.getName()) == null) {
+ presentation.setVisible(false);
+ presentation.setEnabled(false);
+ return;
+ }
+
+ presentation.setVisible(true);
+ presentation.setEnabled(true);
+
+ }
+} \ No newline at end of file
diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CreateTaskFile.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CreateTaskFile.java
new file mode 100644
index 000000000000..5aafcebefd6e
--- /dev/null
+++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CreateTaskFile.java
@@ -0,0 +1,110 @@
+package org.jetbrains.plugins.coursecreator.actions;
+
+import com.intellij.ide.IdeView;
+import com.intellij.ide.fileTemplates.FileTemplate;
+import com.intellij.ide.fileTemplates.FileTemplateManager;
+import com.intellij.ide.fileTemplates.FileTemplateUtil;
+import com.intellij.ide.util.DirectoryChooserUtil;
+import com.intellij.ide.util.EditorHelper;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.actionSystem.LangDataKeys;
+import com.intellij.openapi.actionSystem.Presentation;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.project.DumbAwareAction;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiElement;
+import icons.PythonPsiApiIcons;
+import org.jetbrains.plugins.coursecreator.CCProjectService;
+import org.jetbrains.plugins.coursecreator.format.Course;
+import org.jetbrains.plugins.coursecreator.format.Lesson;
+import org.jetbrains.plugins.coursecreator.format.Task;
+
+public class CreateTaskFile extends DumbAwareAction {
+
+ public CreateTaskFile() {
+ super("Task File", "Create new Task File", PythonPsiApiIcons.PythonFile);
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ final IdeView view = e.getData(LangDataKeys.IDE_VIEW);
+ final Project project = e.getData(CommonDataKeys.PROJECT);
+
+ if (view == null || project == null) {
+ return;
+ }
+ final PsiDirectory taskDir = DirectoryChooserUtil.getOrChooseDirectory(view);
+ if (taskDir == null) return;
+ PsiDirectory lessonDir = taskDir.getParent();
+ if (lessonDir == null) {
+ return;
+ }
+ final CCProjectService service = CCProjectService.getInstance(project);
+ final Course course = service.getCourse();
+ final Lesson lesson = course.getLesson(lessonDir.getName());
+ final Task task = lesson.getTask(taskDir.getName());
+
+ final int index = task.getTaskFiles().size() + 1;
+ String generatedName = "file" + index;
+ final String taskFileName = Messages.showInputDialog("Name:", "Task File Name", null, generatedName, null);
+ if (taskFileName == null) return;
+
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ final FileTemplate taskTemplate = FileTemplateManager.getInstance().getInternalTemplate("task.py");
+ try {
+ final PsiElement taskPyFile = FileTemplateUtil.createFromTemplate(taskTemplate, taskFileName + ".py", null, taskDir);
+ task.addTaskFile(taskPyFile.getContainingFile().getName(), index);
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ EditorHelper.openInEditor(taskPyFile, false);
+ view.selectElement(taskPyFile);
+ }
+ });
+ }
+ catch (Exception ignored) {
+ }
+ }
+ });
+ }
+
+ @Override
+ public void update(AnActionEvent event) {
+ final Presentation presentation = event.getPresentation();
+ final Project project = event.getData(CommonDataKeys.PROJECT);
+ if (project == null) {
+ presentation.setVisible(false);
+ presentation.setEnabled(false);
+ return;
+ }
+
+ final IdeView view = event.getData(LangDataKeys.IDE_VIEW);
+ if (view == null) {
+ presentation.setVisible(false);
+ presentation.setEnabled(false);
+ return;
+ }
+
+ final PsiDirectory[] directories = view.getDirectories();
+ if (directories.length == 0) {
+ presentation.setVisible(false);
+ presentation.setEnabled(false);
+ return;
+ }
+ final PsiDirectory directory = DirectoryChooserUtil.getOrChooseDirectory(view);
+ final CCProjectService service = CCProjectService.getInstance(project);
+ final Course course = service.getCourse();
+ if (course != null && directory != null && !directory.getName().contains("task")) {
+ presentation.setVisible(false);
+ presentation.setEnabled(false);
+ return;
+ }
+ presentation.setVisible(true);
+ presentation.setEnabled(true);
+ }
+}
diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/DeleteTaskWindow.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/DeleteTaskWindow.java
new file mode 100644
index 000000000000..2724759a8c4f
--- /dev/null
+++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/DeleteTaskWindow.java
@@ -0,0 +1,62 @@
+package org.jetbrains.plugins.coursecreator.actions;
+
+import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.actionSystem.PlatformDataKeys;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.DumbAwareAction;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.coursecreator.CCProjectService;
+import org.jetbrains.plugins.coursecreator.format.*;
+
+import java.util.List;
+
+@SuppressWarnings("ComponentNotRegistered")
+public class DeleteTaskWindow extends DumbAwareAction {
+ @NotNull
+ private final TaskWindow myTaskWindow;
+
+ public DeleteTaskWindow(@NotNull final TaskWindow taskWindow) {
+ super("Delete task window","Delete task window", null);
+ myTaskWindow = taskWindow;
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ final Project project = e.getData(PlatformDataKeys.PROJECT);
+ if (project == null) return;
+ final PsiFile file = CommonDataKeys.PSI_FILE.getData(e.getDataContext());
+ if (file == null) return;
+ final Editor editor = CommonDataKeys.EDITOR.getData(e.getDataContext());
+ if (editor == null) {
+ return;
+ }
+ final Document document = PsiDocumentManager.getInstance(project).getDocument(file);
+ if (document == null) return;
+
+ final CCProjectService service = CCProjectService.getInstance(project);
+ final Course course = service.getCourse();
+ final PsiDirectory taskDir = file.getContainingDirectory();
+ final PsiDirectory lessonDir = taskDir.getParent();
+ if (lessonDir == null) return;
+
+ final Lesson lesson = course.getLesson(lessonDir.getName());
+ final Task task = lesson.getTask(taskDir.getName());
+ final TaskFile taskFile = task.getTaskFile(file.getName());
+ final List<TaskWindow> taskWindows = taskFile.getTaskWindows();
+ if (taskWindows.contains(myTaskWindow)) {
+ myTaskWindow.removeResources(project);
+ taskWindows.remove(myTaskWindow);
+ editor.getMarkupModel().removeAllHighlighters();
+ CCProjectService.drawTaskWindows(file.getVirtualFile(), editor, course);
+ DaemonCodeAnalyzerImpl.getInstance(project).restart(file);
+ }
+ }
+
+} \ No newline at end of file
diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/ShowTaskWindowText.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/ShowTaskWindowText.java
new file mode 100644
index 000000000000..7c7e7fa727b8
--- /dev/null
+++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/ShowTaskWindowText.java
@@ -0,0 +1,44 @@
+package org.jetbrains.plugins.coursecreator.actions;
+
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.actionSystem.PlatformDataKeys;
+import com.intellij.openapi.project.DumbAwareAction;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.coursecreator.CCProjectService;
+import org.jetbrains.plugins.coursecreator.format.*;
+import org.jetbrains.plugins.coursecreator.ui.CreateTaskWindowDialog;
+
+@SuppressWarnings("ComponentNotRegistered")
+public class ShowTaskWindowText extends DumbAwareAction {
+ @NotNull
+ private final TaskWindow myTaskWindow;
+
+ public ShowTaskWindowText(@NotNull final TaskWindow taskWindow) {
+ super("Add task window","Add task window", null);
+ myTaskWindow = taskWindow;
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ final Project project = e.getData(PlatformDataKeys.PROJECT);
+ if (project == null) return;
+ final PsiFile file = CommonDataKeys.PSI_FILE.getData(e.getDataContext());
+ if (file == null) return;
+ final CCProjectService service = CCProjectService.getInstance(project);
+ final Course course = service.getCourse();
+ final PsiDirectory taskDir = file.getContainingDirectory();
+ final PsiDirectory lessonDir = taskDir.getParent();
+ if (lessonDir == null) return;
+
+ final Lesson lesson = course.getLesson(lessonDir.getName());
+ final Task task = lesson.getTask(taskDir.getName());
+ final TaskFile taskFile = task.getTaskFile(file.getName());
+ //TODO: copy task window and return if modification canceled
+ CreateTaskWindowDialog dlg = new CreateTaskWindowDialog(project, myTaskWindow, lesson.getIndex(), task.getIndex(), file.getVirtualFile().getNameWithoutExtension(), taskFile.getTaskWindows().size() + 1);
+ dlg.show();
+ }
+} \ No newline at end of file
diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/Course.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/Course.java
new file mode 100644
index 000000000000..eb62d59cd9b1
--- /dev/null
+++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/Course.java
@@ -0,0 +1,55 @@
+package org.jetbrains.plugins.coursecreator.format;
+
+import com.google.gson.annotations.Expose;
+import com.intellij.psi.PsiDirectory;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class Course {
+ @Expose public List<Lesson> lessons = new ArrayList<Lesson>();
+ @Expose public String description;
+
+ @Expose public String name;
+ @Expose public String author;
+
+ public Map<String, Lesson> myLessonsMap = new HashMap<String, Lesson>();
+
+ public Map<String, Lesson> getLessonsMap() {
+ return myLessonsMap;
+ }
+
+ public Lesson getLesson(@NotNull final String name) {
+ return myLessonsMap.get(name);
+ }
+
+
+ public Course() {
+ }
+
+ public Course(@NotNull final String name, @NotNull final String author, @NotNull final String description) {
+ this.description = description;
+ this.name = name;
+ this.author = author;
+ }
+
+ public List<Lesson> getLessons() {
+ return lessons;
+ }
+
+ public void addLesson(@NotNull final Lesson lesson, @NotNull final PsiDirectory directory) {
+ lessons.add(lesson);
+ myLessonsMap.put(directory.getName(), lesson);
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+}
diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/Lesson.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/Lesson.java
new file mode 100644
index 000000000000..38720140caf1
--- /dev/null
+++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/Lesson.java
@@ -0,0 +1,45 @@
+package org.jetbrains.plugins.coursecreator.format;
+
+import com.google.gson.annotations.Expose;
+import com.intellij.psi.PsiDirectory;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class Lesson {
+ @Expose public String name;
+ @Expose public List<Task> task_list = new ArrayList<Task>();
+
+ public int myIndex;
+ public Map<String, Task> myTasksMap = new HashMap<String, Task>();
+
+ public Lesson() {}
+
+ public Lesson(@NotNull final String name) {
+ this.name = name;
+ }
+
+ public void addTask(@NotNull final Task task, PsiDirectory taskDirectory) {
+ myTasksMap.put(taskDirectory.getName(), task);
+ task_list.add(task);
+ }
+
+ public Task getTask(@NotNull final String name) {
+ return myTasksMap.get(name);
+ }
+
+ public List<Task> getTasklist() {
+ return task_list;
+ }
+
+ public void setIndex(int index) {
+ myIndex = index;
+ }
+
+ public int getIndex() {
+ return myIndex;
+ }
+}
diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/Task.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/Task.java
new file mode 100644
index 000000000000..e6c085b5d6a1
--- /dev/null
+++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/Task.java
@@ -0,0 +1,41 @@
+package org.jetbrains.plugins.coursecreator.format;
+
+import com.google.gson.annotations.Expose;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class Task {
+ @Expose public String name;
+ @Expose public Map<String, TaskFile> task_files = new HashMap<String, TaskFile>();
+ public int myIndex;
+
+ public Task() {}
+
+ public Task(@NotNull final String name) {
+ this.name = name;
+ }
+
+ public int getIndex() {
+ return myIndex;
+ }
+
+ public void addTaskFile(@NotNull final String name, int index) {
+ TaskFile taskFile = new TaskFile();
+ taskFile.setIndex(index);
+ task_files.put(name, taskFile);
+ }
+
+ public TaskFile getTaskFile(@NotNull final String name) {
+ return task_files.get(name);
+ }
+
+ public void setIndex(int index) {
+ myIndex = index;
+ }
+
+ public Map<String, TaskFile> getTaskFiles() {
+ return task_files;
+ }
+}
diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/TaskFile.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/TaskFile.java
new file mode 100644
index 000000000000..85f0d91983f2
--- /dev/null
+++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/TaskFile.java
@@ -0,0 +1,111 @@
+package org.jetbrains.plugins.coursecreator.format;
+
+import com.google.gson.annotations.Expose;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.LogicalPosition;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.coursecreator.CCProjectService;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TaskFile {
+ @Expose public List<TaskWindow> task_windows = new ArrayList<TaskWindow>();
+ public int myIndex;
+ public boolean myTrackChanges = true;
+
+ public boolean isTrackChanges() {
+ return myTrackChanges;
+ }
+
+ public void setTrackChanges(boolean trackChanges) {
+ myTrackChanges = trackChanges;
+ }
+
+ public TaskFile() {}
+
+ public void addTaskWindow(@NotNull final TaskWindow taskWindow, int index) {
+ taskWindow.setIndex(index);
+ task_windows.add(taskWindow);
+ }
+
+ public List<TaskWindow> getTaskWindows() {
+ return task_windows;
+ }
+
+ public void setIndex(int index) {
+ myIndex = index;
+ }
+
+
+ /**
+ * @param pos position in editor
+ * @return task window located in specified position or null if there is no task window in this position
+ */
+ @Nullable
+ public TaskWindow getTaskWindow(@NotNull final Document document, @NotNull final LogicalPosition pos) {
+ int line = pos.line;
+ if (line >= document.getLineCount()) {
+ return null;
+ }
+ int column = pos.column;
+ int offset = document.getLineStartOffset(line) + column;
+ for (TaskWindow tw : task_windows) {
+ if (tw.getLine() <= line) {
+ int twStartOffset = tw.getRealStartOffset(document);
+ final int length = tw.getReplacementLength() > 0 ? tw.getReplacementLength() : 0;
+ int twEndOffset = twStartOffset + length;
+ if (twStartOffset <= offset && offset <= twEndOffset) {
+ return tw;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Updates task window lines
+ *
+ * @param startLine lines greater than this line and including this line will be updated
+ * @param change change to be added to line numbers
+ */
+ public void incrementLines(int startLine, int change) {
+ for (TaskWindow taskTaskWindow : task_windows) {
+ if (taskTaskWindow.getLine() >= startLine) {
+ taskTaskWindow.setLine(taskTaskWindow.getLine() + change);
+ }
+ }
+ }
+
+ /**
+ * Updates windows in specific line
+ *
+ * @param lineChange change in line number
+ * @param line line to be updated
+ * @param newEndOffsetInLine distance from line start to end of inserted fragment
+ * @param oldEndOffsetInLine distance from line start to end of changed fragment
+ */
+ public void updateLine(int lineChange, int line, int newEndOffsetInLine, int oldEndOffsetInLine) {
+ for (TaskWindow w : task_windows) {
+ if ((w.getLine() == line) && (w.getStart() >= oldEndOffsetInLine)) {
+ int distance = w.getStart() - oldEndOffsetInLine;
+ boolean coveredByPrevTW = false;
+ int prevIndex = w.getIndex() - 1;
+ if (CCProjectService.indexIsValid(prevIndex, task_windows)) {
+ TaskWindow prevTW = task_windows.get(prevIndex);
+ if (prevTW.getLine() == line) {
+ int endOffset = prevTW.getStart() + prevTW.getLength();
+ if (endOffset >= newEndOffsetInLine) {
+ coveredByPrevTW = true;
+ }
+ }
+ }
+ if (lineChange != 0 || newEndOffsetInLine <= w.getStart() || coveredByPrevTW) {
+ w.setStart(distance + newEndOffsetInLine);
+ w.setLine(line + lineChange);
+ }
+ }
+ }
+ }
+}
diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/TaskWindow.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/TaskWindow.java
new file mode 100644
index 000000000000..cb6418ec75d7
--- /dev/null
+++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/format/TaskWindow.java
@@ -0,0 +1,133 @@
+package org.jetbrains.plugins.coursecreator.format;
+
+import com.google.gson.annotations.Expose;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.colors.EditorColors;
+import com.intellij.openapi.editor.colors.EditorColorsManager;
+import com.intellij.openapi.editor.markup.HighlighterLayer;
+import com.intellij.openapi.editor.markup.HighlighterTargetArea;
+import com.intellij.openapi.editor.markup.RangeHighlighter;
+import com.intellij.openapi.editor.markup.TextAttributes;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.coursecreator.CCProjectService;
+
+import java.io.File;
+
+public class TaskWindow implements Comparable{
+
+ @Expose public int line;
+ @Expose public int start;
+ @Expose public String hint;
+ @Expose public String possible_answer;
+ @Expose public int length;
+ public String myTaskText;
+ public int myReplacementLength;
+ public int myIndex;
+
+ public TaskWindow() {}
+
+ public TaskWindow(int line, int start, int length, String selectedText) {
+ this.line = line;
+ this.start = start;
+ myReplacementLength = length;
+ this.possible_answer = selectedText;
+ }
+
+ public void setTaskText(@NotNull final String taskText) {
+ myTaskText = taskText;
+ length = myTaskText.length();
+ }
+
+ public String getTaskText() {
+ return myTaskText;
+ }
+
+ public int getReplacementLength() {
+ return myReplacementLength;
+ }
+
+ public void setHint(String hint) {
+ this.hint = hint;
+ }
+
+ public String getHintName() {
+ return hint;
+ }
+
+ public void removeResources(@NotNull final Project project) {
+ if (hint != null) {
+ VirtualFile hints = project.getBaseDir().findChild("hints");
+ if (hints == null) {
+ return;
+ }
+ File hintFile = new File(hints.getPath(), hint);
+ CCProjectService.deleteProjectFile(hintFile, project);
+ }
+ }
+
+ public void drawHighlighter(@NotNull final Editor editor) {
+ int startOffset = editor.getDocument().getLineStartOffset(line) + start;
+ int endOffset = startOffset + myReplacementLength;
+ TextAttributes defaultTestAttributes =
+ EditorColorsManager.getInstance().getGlobalScheme().getAttributes(EditorColors.LIVE_TEMPLATE_ATTRIBUTES);
+ RangeHighlighter highlighter =
+ editor.getMarkupModel().addRangeHighlighter(startOffset, endOffset, HighlighterLayer.LAST + 1, defaultTestAttributes,
+ HighlighterTargetArea.EXACT_RANGE);
+ highlighter.setGreedyToLeft(true);
+ highlighter.setGreedyToRight(true);
+ }
+
+ public int getIndex() {
+ return myIndex;
+ }
+
+ public void setIndex(int index) {
+
+ myIndex = index;
+ }
+
+ public void setReplacementLength(int replacementLength) {
+ myReplacementLength = replacementLength;
+ }
+
+ public int getLine() {
+ return line;
+ }
+
+ public int getRealStartOffset(Document document) {
+ return document.getLineStartOffset(line) + start;
+ }
+
+ public void setLine(int line) {
+ this.line = line;
+ }
+
+ public int getStart() {
+ return start;
+ }
+
+ public void setStart(int start) {
+ this.start = start;
+ }
+
+ @Override
+ public int compareTo(Object o) {
+ TaskWindow taskWindow = (TaskWindow)o;
+ int lineDiff = line - taskWindow.line;
+ if (lineDiff == 0) {
+ return start - taskWindow.start;
+ }
+ return lineDiff;
+ }
+
+ public String getPossibleAnswer() {
+ return possible_answer;
+ }
+
+ public int getLength() {
+ return length;
+ }
+} \ No newline at end of file
diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/highlighting/CCTaskLineMarkerProvider.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/highlighting/CCTaskLineMarkerProvider.java
new file mode 100644
index 000000000000..1818b658ddfc
--- /dev/null
+++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/highlighting/CCTaskLineMarkerProvider.java
@@ -0,0 +1,75 @@
+package org.jetbrains.plugins.coursecreator.highlighting;
+
+import com.intellij.codeHighlighting.Pass;
+import com.intellij.codeInsight.daemon.LineMarkerInfo;
+import com.intellij.codeInsight.daemon.LineMarkerProvider;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.markup.GutterIconRenderer;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.IconLoader;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.coursecreator.CCProjectService;
+import org.jetbrains.plugins.coursecreator.format.*;
+
+import java.util.Collection;
+import java.util.List;
+
+public class CCTaskLineMarkerProvider implements LineMarkerProvider {
+ private static final Logger LOG = Logger.getInstance(CCTaskLineMarkerProvider.class.getName());
+
+ @Nullable
+ @Override
+ public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement element) {
+ return null;
+ }
+
+ @Override
+ public void collectSlowLineMarkers(@NotNull List<PsiElement> elements, @NotNull final Collection<LineMarkerInfo> result) {
+ for (PsiElement element : elements) {
+ if (element instanceof PsiFile) {
+ final Project project = element.getProject();
+ final Course course = CCProjectService.getInstance(project).getCourse();
+ if (course == null) return;
+ final String taskFileName = ((PsiFile) element).getName();
+ final PsiDirectory taskDir = ((PsiFile) element).getParent();
+ if (taskDir == null) continue;
+ final String taskDirName = taskDir.getName();
+ final PsiDirectory lessonDir = taskDir.getParentDirectory();
+ if (lessonDir == null) continue;
+ final String lessonDirName = lessonDir.getName();
+ final Lesson lesson = course.getLesson(lessonDirName);
+ if (lesson == null) continue;
+ final Task task = lesson.getTask(taskDirName);
+ final TaskFile taskFile = task.getTaskFile(taskFileName);
+ if (taskFile == null) continue;
+ final Document document = PsiDocumentManager.getInstance(project).getDocument((PsiFile) element);
+ if (document == null) continue;
+ for (final TaskWindow taskWindow : taskFile.getTaskWindows()) {
+ if (taskWindow.line > document.getLineCount()) continue;
+ final int lineStartOffset = document.getLineStartOffset(taskWindow.line);
+ final int offset = lineStartOffset + taskWindow.start;
+ if (offset > document.getTextLength()) continue;
+ final TextRange textRange = TextRange.create(offset, offset + taskWindow.getReplacementLength());
+ @SuppressWarnings("unchecked")
+ final LineMarkerInfo info = new LineMarkerInfo(element, textRange,
+ IconLoader.getIcon("/icons/gutter.png"), Pass.UPDATE_OVERRIDEN_MARKERS,
+ null, null, GutterIconRenderer.Alignment.CENTER) {
+ @Nullable
+ @Override
+ public GutterIconRenderer createGutterRenderer() {
+ return new TaskTextGutter(taskWindow, this);
+ }
+ };
+ result.add(info);
+ }
+ }
+ }
+ }
+}
diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/highlighting/TaskTextGutter.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/highlighting/TaskTextGutter.java
new file mode 100644
index 000000000000..80b267485192
--- /dev/null
+++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/highlighting/TaskTextGutter.java
@@ -0,0 +1,60 @@
+package org.jetbrains.plugins.coursecreator.highlighting;
+
+import com.intellij.codeInsight.daemon.LineMarkerInfo;
+import com.intellij.openapi.actionSystem.ActionGroup;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.DefaultActionGroup;
+import com.intellij.openapi.util.IconLoader;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.coursecreator.actions.DeleteTaskWindow;
+import org.jetbrains.plugins.coursecreator.actions.ShowTaskWindowText;
+import org.jetbrains.plugins.coursecreator.format.TaskWindow;
+
+import javax.swing.*;
+
+public class TaskTextGutter extends LineMarkerInfo.LineMarkerGutterIconRenderer {
+ @NotNull
+ private final TaskWindow myTaskWindow;
+
+ public TaskTextGutter(@NotNull final TaskWindow taskWindow, LineMarkerInfo lineMarkerInfo) {
+ super(lineMarkerInfo);
+ myTaskWindow = taskWindow;
+ }
+
+ @NotNull
+ @Override
+ public Icon getIcon() {
+ return IconLoader.getIcon("/icons/gutter.png");
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return this == o || o instanceof TaskTextGutter
+ && myTaskWindow.getTaskText().equals(((TaskTextGutter) o).getTaskWindow().getTaskText());
+ }
+
+ @NotNull
+ public TaskWindow getTaskWindow() {
+ return myTaskWindow;
+ }
+
+ @Override
+ public int hashCode() {
+ return myTaskWindow.hashCode();
+ }
+
+ @Nullable
+ @Override
+ public AnAction getClickAction() {
+ return new ShowTaskWindowText(myTaskWindow);
+ }
+
+ @Nullable
+ @Override
+ public ActionGroup getPopupMenuActions() {
+ DefaultActionGroup group = new DefaultActionGroup();
+ group.add(new DeleteTaskWindow(myTaskWindow));
+ return group;
+ }
+}
diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/projectView/CCDirectoryNode.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/projectView/CCDirectoryNode.java
new file mode 100644
index 000000000000..1a7304123f0a
--- /dev/null
+++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/projectView/CCDirectoryNode.java
@@ -0,0 +1,63 @@
+package org.jetbrains.plugins.coursecreator.projectView;
+
+import com.intellij.ide.projectView.PresentationData;
+import com.intellij.ide.projectView.ViewSettings;
+import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.ui.SimpleTextAttributes;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.coursecreator.CCProjectService;
+import org.jetbrains.plugins.coursecreator.format.Course;
+import org.jetbrains.plugins.coursecreator.format.Lesson;
+import org.jetbrains.plugins.coursecreator.format.Task;
+
+public class CCDirectoryNode extends PsiDirectoryNode {
+ private final PsiDirectory myValue;
+ private final Project myProject;
+
+ public CCDirectoryNode(@NotNull final Project project,
+ PsiDirectory value,
+ ViewSettings viewSettings) {
+ super(project, value, viewSettings);
+ myValue = value;
+ myProject = project;
+ }
+
+ @Override
+ protected void updateImpl(PresentationData data) {
+ String valueName = myValue.getName();
+ final Course course = CCProjectService.getInstance(myProject).getCourse();
+ if (course == null) return;
+ if (myProject.getBaseDir().equals(myValue.getVirtualFile())) {
+ data.clearText();
+ data.addText(valueName, SimpleTextAttributes.REGULAR_ATTRIBUTES);
+ data.addText(" (" + course.getName() + ")", SimpleTextAttributes.GRAYED_ATTRIBUTES);
+ return;
+ }
+ final Lesson lesson = course.getLesson(valueName);
+ if (lesson != null) {
+ data.clearText();
+ data.addText(valueName, SimpleTextAttributes.REGULAR_ATTRIBUTES);
+ data.addText(" (" + lesson.name + ")", SimpleTextAttributes.GRAYED_ATTRIBUTES);
+ return;
+ }
+ else {
+ final PsiDirectory parentDir = myValue.getParentDirectory();
+ if (parentDir != null) {
+ final Lesson parentLesson = course.getLesson(parentDir.getName());
+ if (parentLesson != null) {
+ final Task task = parentLesson.getTask(valueName);
+ if (task != null) {
+ data.clearText();
+ data.addText(valueName, SimpleTextAttributes.REGULAR_ATTRIBUTES);
+ data.addText(" (" + task.name + ")", SimpleTextAttributes.GRAYED_ATTRIBUTES);
+ return;
+ }
+ }
+ }
+ }
+ data.setPresentableText(valueName);
+ }
+
+}
diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/projectView/CCTreeStructureProvider.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/projectView/CCTreeStructureProvider.java
new file mode 100644
index 000000000000..69b78ec9a92b
--- /dev/null
+++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/projectView/CCTreeStructureProvider.java
@@ -0,0 +1,55 @@
+package org.jetbrains.plugins.coursecreator.projectView;
+
+import com.intellij.ide.projectView.TreeStructureProvider;
+import com.intellij.ide.projectView.ViewSettings;
+import com.intellij.ide.util.treeView.AbstractTreeNode;
+import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiDirectory;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.coursecreator.CCProjectService;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+public class CCTreeStructureProvider implements TreeStructureProvider, DumbAware {
+ @NotNull
+ @Override
+ public Collection<AbstractTreeNode> modify(@NotNull AbstractTreeNode parent,
+ @NotNull Collection<AbstractTreeNode> children,
+ ViewSettings settings) {
+ if (!needModify(parent)) {
+ return children;
+ }
+ Collection<AbstractTreeNode> nodes = new ArrayList<AbstractTreeNode>();
+ for (AbstractTreeNode node : children) {
+ Project project = node.getProject();
+ if (project != null) {
+ if (node.getValue() instanceof PsiDirectory) {
+ PsiDirectory directory = (PsiDirectory) node.getValue();
+ nodes.add(new CCDirectoryNode(project, directory, settings));
+ } else {
+ nodes.add(node);
+ }
+ }
+ }
+ return nodes;
+ }
+
+ private static boolean needModify(@NotNull final AbstractTreeNode parent) {
+ Project project = parent.getProject();
+ if (project != null) {
+ if (CCProjectService.getInstance(project).getCourse() == null) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Nullable
+ @Override
+ public Object getData(Collection<AbstractTreeNode> selected, String dataName) {
+ return null;
+ }
+}
diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CCNewProjectPanel.form b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CCNewProjectPanel.form
new file mode 100644
index 000000000000..71e27857a2ee
--- /dev/null
+++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CCNewProjectPanel.form
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.plugins.coursecreator.ui.CCNewProjectPanel">
+ <grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="3" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <margin top="0" left="0" bottom="0" right="0"/>
+ <constraints>
+ <xy x="20" y="20" width="500" height="400"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <component id="fd520" class="javax.swing.JLabel">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false">
+ <preferred-size width="95" height="-1"/>
+ </grid>
+ </constraints>
+ <properties>
+ <text value="Name:"/>
+ </properties>
+ </component>
+ <component id="7e88" class="javax.swing.JTextField" binding="myName">
+ <constraints>
+ <grid row="0" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+ <preferred-size width="150" height="-1"/>
+ </grid>
+ </constraints>
+ <properties/>
+ </component>
+ <component id="ec56c" class="javax.swing.JLabel">
+ <constraints>
+ <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value="Description"/>
+ </properties>
+ </component>
+ <component id="2e2d7" class="javax.swing.JLabel">
+ <constraints>
+ <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false">
+ <preferred-size width="95" height="-1"/>
+ </grid>
+ </constraints>
+ <properties>
+ <text value="Author:"/>
+ </properties>
+ </component>
+ <component id="41fe6" class="javax.swing.JTextField" binding="myAuthorField">
+ <constraints>
+ <grid row="1" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+ <preferred-size width="150" height="-1"/>
+ </grid>
+ </constraints>
+ <properties/>
+ </component>
+ <grid id="12f06" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <margin top="0" left="0" bottom="0" right="0"/>
+ <constraints>
+ <grid row="2" column="1" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ <border type="line">
+ <color color="-6709600"/>
+ </border>
+ <children>
+ <component id="389a7" class="javax.swing.JTextArea" binding="myDescription">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="6" anchor="0" fill="3" indent="0" use-parent-layout="false">
+ <preferred-size width="150" height="50"/>
+ </grid>
+ </constraints>
+ <properties/>
+ </component>
+ </children>
+ </grid>
+ </children>
+ </grid>
+</form>
diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CCNewProjectPanel.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CCNewProjectPanel.java
new file mode 100644
index 000000000000..83a3458576b6
--- /dev/null
+++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CCNewProjectPanel.java
@@ -0,0 +1,59 @@
+package org.jetbrains.plugins.coursecreator.ui;
+
+import com.intellij.facet.ui.FacetValidatorsManager;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.ui.DocumentAdapter;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import javax.swing.event.DocumentEvent;
+
+public class CCNewProjectPanel {
+ private JPanel myPanel;
+ private JTextArea myDescription;
+ private JTextField myName;
+ private JTextField myAuthorField;
+ private FacetValidatorsManager myValidationManager;
+
+
+ public CCNewProjectPanel() {
+ final String userName = System.getProperty("user.name");
+ if (userName != null) {
+ myAuthorField.setText(userName);
+ }
+ myName.getDocument().addDocumentListener(new MyValidator());
+ myDescription.getDocument().addDocumentListener(new MyValidator());
+ myAuthorField.getDocument().addDocumentListener(new MyValidator());
+ }
+
+ public JPanel getMainPanel() {
+ return myPanel;
+ }
+
+ @NotNull
+ public String getName() {
+ return StringUtil.notNullize(myName.getText());
+ }
+
+ @NotNull
+ public String getDescription() {
+ return StringUtil.notNullize(myDescription.getText());
+ }
+
+ @NotNull
+ public String getAuthor() {
+ return StringUtil.notNullize(myAuthorField.getText());
+ }
+
+ public void registerValidators(FacetValidatorsManager manager) {
+ myValidationManager = manager;
+ }
+
+ private class MyValidator extends DocumentAdapter {
+
+ @Override
+ protected void textChanged(DocumentEvent e) {
+ myValidationManager.validate();
+ }
+ }
+}
diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateCourseArchiveDialog.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateCourseArchiveDialog.java
new file mode 100644
index 000000000000..d6c3bdb24af3
--- /dev/null
+++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateCourseArchiveDialog.java
@@ -0,0 +1,40 @@
+package org.jetbrains.plugins.coursecreator.ui;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogWrapper;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.coursecreator.actions.CreateCourseArchive;
+
+import javax.swing.*;
+
+public class CreateCourseArchiveDialog extends DialogWrapper {
+
+ private CreateCourseArchivePanel myPanel;
+ private CreateCourseArchive myAction;
+
+ public CreateCourseArchiveDialog(@NotNull final Project project, CreateCourseArchive action) {
+ super(project);
+ setTitle("Create Course Archive");
+ myPanel = new CreateCourseArchivePanel(project, this);
+ myAction = action;
+ init();
+ }
+
+ @Nullable
+ @Override
+ protected JComponent createCenterPanel() {
+ return myPanel;
+ }
+
+ public void enableOKAction(boolean isEnabled) {
+ myOKAction.setEnabled(isEnabled);
+ }
+
+ @Override
+ protected void doOKAction() {
+ myAction.setZipName(myPanel.getZipName());
+ myAction.setLocationDir(myPanel.getLocationPath());
+ super.doOKAction();
+ }
+}
diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateCourseArchivePanel.form b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateCourseArchivePanel.form
new file mode 100644
index 000000000000..920dcb9494a7
--- /dev/null
+++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateCourseArchivePanel.form
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.plugins.coursecreator.ui.CreateCourseArchivePanel">
+ <grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <margin top="0" left="0" bottom="0" right="0"/>
+ <constraints>
+ <xy x="20" y="20" width="500" height="400"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <grid id="a3b77" layout-manager="GridLayoutManager" row-count="4" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <margin top="0" left="0" bottom="0" right="0"/>
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <component id="786af" class="javax.swing.JLabel">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value="Name:"/>
+ </properties>
+ </component>
+ <component id="160bb" class="javax.swing.JTextField" binding="myNameField" default-binding="true">
+ <constraints>
+ <grid row="0" column="1" row-span="2" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+ <preferred-size width="150" height="-1"/>
+ </grid>
+ </constraints>
+ <properties/>
+ </component>
+ <component id="628ab" class="javax.swing.JLabel">
+ <constraints>
+ <grid row="1" column="0" row-span="2" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value="Location:"/>
+ </properties>
+ </component>
+ <component id="aab8" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myLocationField">
+ <constraints>
+ <grid row="2" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ </component>
+ <grid id="29be7" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <margin top="0" left="0" bottom="0" right="0"/>
+ <constraints>
+ <grid row="3" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <component id="4fa15" class="javax.swing.JLabel" binding="myErrorIcon">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value=""/>
+ </properties>
+ </component>
+ <component id="4bdcf" class="javax.swing.JLabel" binding="myErrorLabel">
+ <constraints>
+ <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value=""/>
+ </properties>
+ </component>
+ </children>
+ </grid>
+ </children>
+ </grid>
+ </children>
+ </grid>
+</form>
diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateCourseArchivePanel.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateCourseArchivePanel.java
new file mode 100644
index 000000000000..4e7deedf7e47
--- /dev/null
+++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateCourseArchivePanel.java
@@ -0,0 +1,65 @@
+package org.jetbrains.plugins.coursecreator.ui;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.fileChooser.FileChooserDescriptor;
+import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.TextFieldWithBrowseButton;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+
+public class CreateCourseArchivePanel extends JPanel {
+ private JPanel myPanel;
+ private JTextField myNameField;
+ private TextFieldWithBrowseButton myLocationField;
+ private JLabel myErrorIcon;
+ private JLabel myErrorLabel;
+ private CreateCourseArchiveDialog myDlg;
+
+ public CreateCourseArchivePanel(@NotNull final Project project, CreateCourseArchiveDialog dlg) {
+ setLayout(new BorderLayout());
+ add(myPanel, BorderLayout.CENTER);
+ myErrorIcon.setIcon(AllIcons.Actions.Lightning);
+ setState(false);
+ myDlg = dlg;
+ myNameField.setText("course");
+ myLocationField.setText(project.getBasePath());
+ FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor();
+ myLocationField.addBrowseFolderListener("Choose location folder", null, project, descriptor);
+ myLocationField.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ String location = myLocationField.getText();
+ File file = new File(location);
+ if (!file.exists() || !file.isDirectory()) {
+ myDlg.enableOKAction(false);
+ setError("Invalid location");
+ }
+ myDlg.enableOKAction(true);
+ }
+ });
+ }
+
+ private void setState(boolean isVisible) {
+ myErrorIcon.setVisible(isVisible);
+ myErrorLabel.setVisible(isVisible);
+ }
+
+ private void setError(String message) {
+ myErrorLabel.setText(message);
+ setState(true);
+ }
+
+ public String getZipName() {
+ return myNameField.getText();
+ }
+
+ public String getLocationPath() {
+ return myLocationField.getText();
+ }
+}
diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateTaskWindowDialog.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateTaskWindowDialog.java
new file mode 100644
index 000000000000..c7e8f715672c
--- /dev/null
+++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateTaskWindowDialog.java
@@ -0,0 +1,153 @@
+package org.jetbrains.plugins.coursecreator.ui;
+
+import com.intellij.ide.projectView.ProjectView;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.ui.ValidationInfo;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileManager;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.coursecreator.CCProjectService;
+import org.jetbrains.plugins.coursecreator.format.TaskWindow;
+
+import javax.swing.*;
+import java.io.*;
+
+public class CreateTaskWindowDialog extends DialogWrapper {
+
+ public static final String TITLE = "New Task Window";
+ private static final Logger LOG = Logger.getInstance(CreateTaskWindowDialog.class.getName());
+ private final TaskWindow myTaskWindow;
+ private final CreateTaskWindowPanel myPanel;
+ private final Project myProject;
+
+ public Project getProject() {
+ return myProject;
+ }
+
+ public CreateTaskWindowDialog(@NotNull final Project project, @NotNull final TaskWindow taskWindow, int lessonIndex,
+ int taskIndex, String taskFileName, int taskWindowIndex) {
+ super(project, true);
+ setTitle(TITLE);
+ myTaskWindow = taskWindow;
+ myPanel = new CreateTaskWindowPanel(this);
+ String generatedHintName = "lesson" + lessonIndex + "task" + taskIndex + taskFileName + "_" + taskWindowIndex;
+ myPanel.setGeneratedHintName(generatedHintName);
+ if (taskWindow.getHintName() != null) {
+ setHintText(project, taskWindow);
+ }
+ myProject = project;
+ String taskWindowTaskText = taskWindow.getTaskText();
+ myPanel.setTaskWindowText(taskWindowTaskText != null ? taskWindowTaskText : "");
+ String hintName = taskWindow.getHintName();
+ myPanel.setHintName(hintName != null ? hintName : "");
+ init();
+ initValidation();
+ }
+
+ private void setHintText(Project project, TaskWindow taskWindow) {
+ VirtualFile hints = project.getBaseDir().findChild("hints");
+ if (hints != null) {
+ File file = new File(hints.getPath(), taskWindow.getHintName());
+ StringBuilder hintText = new StringBuilder();
+ if (file.exists()) {
+ try {
+ BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
+ String line;
+ while ((line = bufferedReader.readLine()) != null) {
+ hintText.append(line).append("\n");
+ }
+ myPanel.doClick();
+ //myPanel.enableHint(true);
+ myPanel.setHintText(hintText.toString());
+ }
+ catch (FileNotFoundException e) {
+ LOG.error("created hint was not found", e);
+ }
+ catch (IOException e) {
+ LOG.error(e);
+ }
+ }
+ }
+ }
+
+ @Override
+ protected void doOKAction() {
+ String taskWindowText = myPanel.getTaskWindowText();
+ myTaskWindow.setTaskText(StringUtil.notNullize(taskWindowText));
+ if (myPanel.createHint()) {
+ String hintName = myPanel.getHintName();
+ myTaskWindow.setHint(hintName);
+ String hintText = myPanel.getHintText();
+ createHint(hintName, hintText);
+ }
+ super.doOKAction();
+ }
+
+ private void createHint(String hintName, String hintText) {
+ VirtualFile hintsDir = myProject.getBaseDir().findChild("hints");
+ if (hintsDir != null) {
+ File hintFile = new File(hintsDir.getPath(), hintName);
+ PrintWriter printWriter = null;
+ try {
+ printWriter = new PrintWriter(hintFile);
+ printWriter.print(hintText);
+ }
+ catch (FileNotFoundException e) {
+ //TODO:show error in UI
+ return;
+ }
+ finally {
+ if (printWriter != null) {
+ printWriter.close();
+ }
+ }
+ }
+ VirtualFileManager.getInstance().refreshWithoutFileWatcher(true);
+ ProjectView.getInstance(myProject).refresh();
+ }
+
+ public void deleteHint() {
+ VirtualFile hintsDir = myProject.getBaseDir().findChild("hints");
+ if (hintsDir != null) {
+ String hintName = myTaskWindow.getHintName();
+ if (hintName == null) {
+ return;
+ }
+ File hintFile = new File(hintsDir.getPath(), hintName);
+ if (hintFile.exists()) {
+ CCProjectService.deleteProjectFile(hintFile, myProject);
+ myTaskWindow.setHint(null);
+ myPanel.resetHint();
+ }
+ }
+ }
+
+ @Nullable
+ @Override
+ protected JComponent createCenterPanel() {
+ return myPanel;
+ }
+
+ @Nullable
+ @Override
+ public ValidationInfo doValidate() {
+ String name = myPanel.getHintName();
+ VirtualFile hintsDir = myProject.getBaseDir().findChild("hints");
+ if (hintsDir == null) {
+ return null;
+ }
+ VirtualFile child = hintsDir.findChild(name);
+ if (child == null) {
+ return null;
+ }
+ return myTaskWindow.getHintName() != null ? null : new ValidationInfo("Hint file with such filename already exists");
+ }
+
+ public void validateInput() {
+ super.initValidation();
+ }
+}
diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateTaskWindowPanel.form b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateTaskWindowPanel.form
new file mode 100644
index 000000000000..ccd91e4154b0
--- /dev/null
+++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateTaskWindowPanel.form
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.plugins.coursecreator.ui.CreateTaskWindowPanel">
+ <grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="4" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <margin top="0" left="0" bottom="0" right="0"/>
+ <constraints>
+ <xy x="20" y="20" width="500" height="400"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <component id="aaa28" class="javax.swing.JLabel">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <labelFor value="b712"/>
+ <text value="Text:"/>
+ </properties>
+ </component>
+ <component id="d2e2f" class="javax.swing.JLabel" binding="myHintNameLabel">
+ <constraints>
+ <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <enabled value="true"/>
+ <labelFor value="ddeb1"/>
+ <text value="Hint name:"/>
+ </properties>
+ </component>
+ <component id="ddeb1" class="javax.swing.JTextField" binding="myHintName">
+ <constraints>
+ <grid row="2" column="1" row-span="1" col-span="3" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+ <preferred-size width="150" height="-1"/>
+ </grid>
+ </constraints>
+ <properties>
+ <text value=""/>
+ </properties>
+ </component>
+ <component id="d322a" class="javax.swing.JLabel" binding="myHintTextLabel">
+ <constraints>
+ <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <labelFor value="d0efc"/>
+ <text value="Hint text:"/>
+ </properties>
+ </component>
+ <grid id="51a63" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <margin top="0" left="0" bottom="0" right="0"/>
+ <constraints>
+ <grid row="3" column="1" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ <border type="line">
+ <color color="-6709600"/>
+ </border>
+ <children>
+ <component id="d0efc" class="javax.swing.JTextArea" binding="myHintText">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="6" anchor="0" fill="3" indent="0" use-parent-layout="false">
+ <preferred-size width="300" height="100"/>
+ </grid>
+ </constraints>
+ <properties/>
+ </component>
+ </children>
+ </grid>
+ <grid id="cbc70" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <margin top="0" left="0" bottom="0" right="0"/>
+ <constraints>
+ <grid row="0" column="1" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
+ <minimum-size width="150" height="-1"/>
+ <preferred-size width="150" height="-1"/>
+ </grid>
+ </constraints>
+ <properties/>
+ <border type="line">
+ <color color="-6709600"/>
+ </border>
+ <children>
+ <component id="b712" class="javax.swing.JTextArea" binding="myTaskWindowText">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="6" anchor="0" fill="3" indent="0" use-parent-layout="false">
+ <preferred-size width="300" height="100"/>
+ </grid>
+ </constraints>
+ <properties/>
+ </component>
+ </children>
+ </grid>
+ <component id="f86b4" class="javax.swing.JCheckBox" binding="myCreateHintCheckBox" default-binding="true">
+ <constraints>
+ <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value="Create hint"/>
+ </properties>
+ </component>
+ </children>
+ </grid>
+</form>
diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateTaskWindowPanel.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateTaskWindowPanel.java
new file mode 100644
index 000000000000..21a7eb063c63
--- /dev/null
+++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateTaskWindowPanel.java
@@ -0,0 +1,96 @@
+package org.jetbrains.plugins.coursecreator.ui;
+
+import com.intellij.ui.DocumentAdapter;
+
+import javax.swing.*;
+import javax.swing.event.DocumentEvent;
+import java.awt.*;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+
+public class CreateTaskWindowPanel extends JPanel {
+
+ private final CreateTaskWindowDialog myDialog;
+ private JPanel myPanel;
+ private JTextArea myTaskWindowText;
+ private JTextField myHintName;
+ private JTextArea myHintText;
+ private JCheckBox myCreateHintCheckBox;
+ private JLabel myHintNameLabel;
+ private JLabel myHintTextLabel;
+ private String myGeneratedHintName = "";
+
+ public CreateTaskWindowPanel(CreateTaskWindowDialog dialog) {
+ super(new BorderLayout());
+ add(myPanel, BorderLayout.CENTER);
+ myDialog = dialog;
+ enableHint(false);
+ myCreateHintCheckBox.addItemListener(new ItemListener() {
+ @Override
+ public void itemStateChanged(ItemEvent e) {
+ int state = e.getStateChange();
+ // 1 for checked
+ enableHint(state == 1);
+ if (state == 2) {
+ myDialog.deleteHint();
+ }
+ }
+ });
+
+ myHintName.getDocument().addDocumentListener(new DocumentAdapter() {
+ @Override
+ protected void textChanged(DocumentEvent e) {
+ myDialog.validateInput();
+ }
+ });
+ }
+
+ public void enableHint(boolean isEnable) {
+ myHintName.setEnabled(isEnable);
+ myHintText.setEnabled(isEnable);
+ myHintNameLabel.setEnabled(isEnable);
+ myHintTextLabel.setEnabled(isEnable);
+ myHintName.setText(myGeneratedHintName);
+ }
+
+ public void setTaskWindowText(String taskWindowText) {
+ myTaskWindowText.setText(taskWindowText);
+ }
+
+ public void setHintName(String hintName) {
+ myHintName.setText(hintName);
+ }
+
+ public void setHintText(String hintText) {
+ myHintText.setText(hintText);
+ }
+
+ public String getTaskWindowText() {
+ return myTaskWindowText.getText();
+ }
+
+ public String getHintName() {
+ return myHintName.getText();
+ }
+
+ public String getHintText() {
+ return myHintText.getText();
+ }
+
+ public boolean createHint() {
+ return myHintName.isEnabled();
+ }
+
+ public void doClick() {
+ myCreateHintCheckBox.doClick();
+ }
+
+ public void resetHint() {
+ myHintName.setText("");
+ myHintText.setText("");
+ }
+
+ public void setGeneratedHintName(String generatedHintName) {
+ myGeneratedHintName = generatedHintName;
+ }
+}
diff --git a/python/edu/learn-python/gen/icons/StudyIcons.java b/python/edu/learn-python/gen/icons/StudyIcons.java
index 28409103ea00..04ae98da1672 100644
--- a/python/edu/learn-python/gen/icons/StudyIcons.java
+++ b/python/edu/learn-python/gen/icons/StudyIcons.java
@@ -13,17 +13,15 @@ public class StudyIcons {
return IconLoader.getIcon(path, StudyIcons.class);
}
- public static final Icon Add = load("/icons/com/jetbrains/python/edu/add.png"); // 16x16
- public static final Icon Checked = load("/icons/com/jetbrains/python/edu/checked.png"); // 32x32
- public static final Icon Failed = load("/icons/com/jetbrains/python/edu/failed.png"); // 32x32
- public static final Icon Next = load("/icons/com/jetbrains/python/edu/next.png"); // 24x24
- public static final Icon Playground = load("/icons/com/jetbrains/python/edu/playground.png"); // 32x28
- public static final Icon Prev = load("/icons/com/jetbrains/python/edu/prev.png"); // 24x24
- public static final Icon Refresh = load("/icons/com/jetbrains/python/edu/refresh.png"); // 16x16
- public static final Icon Refresh24 = load("/icons/com/jetbrains/python/edu/refresh24.png"); // 24x24
- public static final Icon Resolve = load("/icons/com/jetbrains/python/edu/resolve.png"); // 24x24
- public static final Icon Run = load("/icons/com/jetbrains/python/edu/Run.png"); // 24x24
+ public static final Icon EducationalProjectType = load("/icons/com/jetbrains/python/edu/EducationalProjectType.png"); // 32x32
+ public static final Icon Lesson = load("/icons/com/jetbrains/python/edu/Lesson.png"); // 16x16
+ public static final Icon LessonCompl = load("/icons/com/jetbrains/python/edu/LessonCompl.png"); // 16x16
+ public static final Icon Playground = load("/icons/com/jetbrains/python/edu/Playground.png"); // 16x16
+ public static final Icon Prev = load("/icons/com/jetbrains/python/edu/prev.png"); // 16x16
+ public static final Icon Resolve = load("/icons/com/jetbrains/python/edu/resolve.png"); // 16x16
public static final Icon ShowHint = load("/icons/com/jetbrains/python/edu/showHint.png"); // 24x24
- public static final Icon Unchecked = load("/icons/com/jetbrains/python/edu/unchecked.png"); // 32x32
+ public static final Icon Task = load("/icons/com/jetbrains/python/edu/Task.png"); // 16x16
+ public static final Icon TaskCompl = load("/icons/com/jetbrains/python/edu/TaskCompl.png"); // 16x16
+ public static final Icon TaskProbl = load("/icons/com/jetbrains/python/edu/TaskProbl.png"); // 16x16
public static final Icon WatchInput = load("/icons/com/jetbrains/python/edu/WatchInput.png"); // 24x24
}
diff --git a/python/edu/learn-python/learn-python.iml b/python/edu/learn-python/learn-python.iml
index bd539d1e2147..613d67594a7a 100644
--- a/python/edu/learn-python/learn-python.iml
+++ b/python/edu/learn-python/learn-python.iml
@@ -15,6 +15,7 @@
<orderEntry type="module" module-name="lang-impl" />
<orderEntry type="library" name="gson" level="project" />
<orderEntry type="library" name="JUnit4" level="project" />
+ <orderEntry type="module" module-name="python-ide-community" />
</component>
</module>
diff --git a/python/edu/learn-python/resources/META-INF/plugin.xml b/python/edu/learn-python/resources/META-INF/plugin.xml
index ec828eb44d59..8e8bddcce5e5 100644
--- a/python/edu/learn-python/resources/META-INF/plugin.xml
+++ b/python/edu/learn-python/resources/META-INF/plugin.xml
@@ -50,7 +50,7 @@
<action id="NextTaskAction" class="com.jetbrains.python.edu.actions.StudyNextStudyTaskAction" text="NextTaskAction" description="Next Task"/>
<action id="PreviousTaskAction" class="com.jetbrains.python.edu.actions.StudyPreviousStudyTaskAction" text="PreviousTaskAction"
description="Previous Task"/>
- <action id="RefreshTaskAction" class="com.jetbrains.python.edu.actions.StudyRefreshTaskAction" text="RefreshTaskAction"
+ <action id="RefreshTaskAction" class="com.jetbrains.python.edu.actions.StudyRefreshTaskFileAction" text="RefreshTaskAction"
description="Refresh current task"/>
<action id="WatchInputAction" class="com.jetbrains.python.edu.actions.StudyEditInputAction" text="WatchInputAction"
description="watch input"/>
@@ -59,6 +59,11 @@
description="show hint">
<add-to-group group-id="MainToolBar" anchor="last"/>
</action>
+
+ <action id="WelcomeScreen.LearnPython" class="com.jetbrains.python.edu.actions.StudyNewProject" icon="StudyIcons.EducationalProjectType">
+ <add-to-group group-id="WelcomeScreen.QuickStart" anchor="first"/>
+ </action>
+
</actions>
<extensions defaultExtensionNs="com.intellij">
@@ -70,4 +75,7 @@
<applicationService serviceInterface="com.intellij.openapi.fileEditor.impl.EditorEmptyTextPainter"
serviceImplementation="com.jetbrains.python.edu.StudyInstructionPainter" overrides="true"/>
</extensions>
+ <extensions defaultExtensionNs="Pythonid">
+ <visitorFilter language="Python" implementationClass="com.jetbrains.python.edu.highlighting.StudyVisitorFilter"/>
+ </extensions>
</idea-plugin> \ No newline at end of file
diff --git a/python/edu/learn-python/resources/courses/introduction_course.zip b/python/edu/learn-python/resources/courses/introduction_course.zip
index f3b24f24b1e2..c39695e0c380 100644
--- a/python/edu/learn-python/resources/courses/introduction_course.zip
+++ b/python/edu/learn-python/resources/courses/introduction_course.zip
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/EducationalProjectType.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/EducationalProjectType.png
new file mode 100644
index 000000000000..6340e89b1f3f
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/EducationalProjectType.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/EducationalProjectType_dark.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/EducationalProjectType_dark.png
new file mode 100644
index 000000000000..d9ec6dc45b0c
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/EducationalProjectType_dark.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Lesson.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Lesson.png
new file mode 100644
index 000000000000..9cc8a4f84f06
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Lesson.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Lesson@2x.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Lesson@2x.png
new file mode 100644
index 000000000000..2b0c0b83271b
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Lesson@2x.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/LessonComp@2x.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/LessonComp@2x.png
new file mode 100644
index 000000000000..e18c6391d0ac
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/LessonComp@2x.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/LessonCompl.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/LessonCompl.png
new file mode 100644
index 000000000000..bacc7ded6755
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/LessonCompl.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Playground.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Playground.png
new file mode 100644
index 000000000000..10867103374a
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Playground.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Playground@2x.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Playground@2x.png
new file mode 100644
index 000000000000..58665fa41a1b
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Playground@2x.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Run.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Run.png
deleted file mode 100644
index 27a6e362cded..000000000000
--- a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Run.png
+++ /dev/null
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Task.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Task.png
new file mode 100644
index 000000000000..b678c649b303
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Task.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Task@2x.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Task@2x.png
new file mode 100644
index 000000000000..4abb95ce7c9e
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Task@2x.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Task@2x_dark.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Task@2x_dark.png
new file mode 100644
index 000000000000..78af6914c933
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Task@2x_dark.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskCompl.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskCompl.png
new file mode 100644
index 000000000000..a7f8f7792823
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskCompl.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskCompl@2x.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskCompl@2x.png
new file mode 100644
index 000000000000..d657aa68f7df
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskCompl@2x.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskCompl@2x_dark.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskCompl@2x_dark.png
new file mode 100644
index 000000000000..f5f29ee3e68e
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskCompl@2x_dark.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskCompl_dark.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskCompl_dark.png
new file mode 100644
index 000000000000..481e9cd2fbbd
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskCompl_dark.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskProbl.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskProbl.png
new file mode 100644
index 000000000000..6173d6423385
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskProbl.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskProbl@2x.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskProbl@2x.png
new file mode 100644
index 000000000000..44aba9d1c6fb
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskProbl@2x.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskProbl@2x_dark.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskProbl@2x_dark.png
new file mode 100644
index 000000000000..f74c9de5398c
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskProbl@2x_dark.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskProbl_dark.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskProbl_dark.png
new file mode 100644
index 000000000000..0133a7f75505
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/TaskProbl_dark.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Task_dark.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Task_dark.png
new file mode 100644
index 000000000000..2ff286dd28f6
--- /dev/null
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/Task_dark.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/add.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/add.png
deleted file mode 100644
index 9494f2d0c72e..000000000000
--- a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/add.png
+++ /dev/null
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/checked.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/checked.png
deleted file mode 100644
index 4105a01f1353..000000000000
--- a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/checked.png
+++ /dev/null
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/failed.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/failed.png
deleted file mode 100644
index e2aaa556056e..000000000000
--- a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/failed.png
+++ /dev/null
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/icon.jpg b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/icon.jpg
deleted file mode 100644
index 3a9716e4e1fb..000000000000
--- a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/icon.jpg
+++ /dev/null
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/next.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/next.png
deleted file mode 100644
index dd1a5d9aebf3..000000000000
--- a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/next.png
+++ /dev/null
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/playground.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/playground.png
deleted file mode 100644
index d12a751c0c40..000000000000
--- a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/playground.png
+++ /dev/null
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/prev.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/prev.png
index 0656f81eee83..fc51cb5861b1 100644
--- a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/prev.png
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/prev.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/refresh.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/refresh.png
deleted file mode 100644
index d595f6b42f56..000000000000
--- a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/refresh.png
+++ /dev/null
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/refresh24.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/refresh24.png
deleted file mode 100644
index 218f075d0c18..000000000000
--- a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/refresh24.png
+++ /dev/null
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/resolve.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/resolve.png
index 7ef960bcf244..78290f936f68 100644
--- a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/resolve.png
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/resolve.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/resolve_dark.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/resolve_dark.png
index 99aaa1d20a32..b988adc56843 100644
--- a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/resolve_dark.png
+++ b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/resolve_dark.png
Binary files differ
diff --git a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/unchecked.png b/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/unchecked.png
deleted file mode 100644
index 2145982cf2be..000000000000
--- a/python/edu/learn-python/resources/icons/com/jetbrains/python/edu/unchecked.png
+++ /dev/null
Binary files differ
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDirectoryProjectGenerator.java b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDirectoryProjectGenerator.java
index d4831d93e367..59bd8bc2ea7c 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDirectoryProjectGenerator.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDirectoryProjectGenerator.java
@@ -53,7 +53,7 @@ public class StudyDirectoryProjectGenerator extends PythonProjectGenerator imple
@NotNull
@Override
public String getName() {
- return "Study project";
+ return "Learn Python";
}
@@ -137,7 +137,7 @@ public class StudyDirectoryProjectGenerator extends PythonProjectGenerator imple
@Nullable
@Override
public Icon getLogo() {
- return StudyIcons.Playground;
+ return StudyIcons.EducationalProjectType;
}
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDocumentListener.java b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDocumentListener.java
index 9fdcf704a29b..6ce1d0991dff 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDocumentListener.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDocumentListener.java
@@ -52,6 +52,9 @@ public class StudyDocumentListener extends DocumentAdapter {
if (myTaskWindow != null) {
int newLength = myTaskWindow.getLength() + change;
myTaskWindow.setLength(newLength <= 0 ? 0 : newLength);
+ if (e.getNewFragment().equals("\n")) {
+ myTaskWindow.setLength(myTaskWindow.getLength() + 1);
+ }
}
int newEnd = offset + event.getNewLength();
int newLine = document.getLineNumber(newEnd);
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyInstructionPainter.java b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyInstructionPainter.java
index 4f34bfb92fab..96a44b2ee66a 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyInstructionPainter.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyInstructionPainter.java
@@ -8,7 +8,6 @@ import com.intellij.ui.JBColor;
import com.intellij.util.PairFunction;
import com.intellij.util.ui.GraphicsUtil;
import com.intellij.util.ui.UIUtil;
-import com.jetbrains.python.edu.ui.StudyCondition;
import java.awt.*;
@@ -19,10 +18,6 @@ import java.awt.*;
public class StudyInstructionPainter extends EditorEmptyTextPainter {
@Override
public void paintEmptyText(final EditorsSplitters splitters, Graphics g) {
- if (!StudyCondition.VALUE) {
- super.paintEmptyText(splitters, g);
- return;
- }
boolean isDarkBackground = UIUtil.isUnderDarcula();
UIUtil.applyRenderingHints(g);
GraphicsUtil.setupAntialiasing(g, true, false);
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyState.java b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyState.java
new file mode 100644
index 000000000000..96dc3d906472
--- /dev/null
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyState.java
@@ -0,0 +1,52 @@
+package com.jetbrains.python.edu;
+
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.jetbrains.python.edu.course.Task;
+import com.jetbrains.python.edu.course.TaskFile;
+import com.jetbrains.python.edu.editor.StudyEditor;
+
+public class StudyState {
+ private final StudyEditor myStudyEditor;
+ private final Editor myEditor;
+ private final TaskFile myTaskFile;
+ private final VirtualFile myVirtualFile;
+ private final Task myTask;
+ private final VirtualFile myTaskDir;
+
+ public StudyState(final StudyEditor studyEditor) {
+ myStudyEditor = studyEditor;
+ myEditor = studyEditor != null ? studyEditor.getEditor() : null;
+ myTaskFile = studyEditor != null ? studyEditor.getTaskFile() : null;
+ myVirtualFile = myEditor != null ? FileDocumentManager.getInstance().getFile(myEditor.getDocument()) : null;
+ myTaskDir = myVirtualFile != null ? myVirtualFile.getParent() : null;
+ myTask = myTaskFile != null ? myTaskFile.getTask() : null;
+ }
+
+ public Editor getEditor() {
+ return myEditor;
+ }
+
+ public TaskFile getTaskFile() {
+ return myTaskFile;
+ }
+
+ public VirtualFile getVirtualFile() {
+ return myVirtualFile;
+ }
+
+ public Task getTask() {
+ return myTask;
+ }
+
+ public VirtualFile getTaskDir() {
+ return myTaskDir;
+ }
+
+ public boolean isValid() {
+ return myStudyEditor != null && myEditor != null &&
+ myTaskFile != null && myVirtualFile != null &&
+ myTask != null && myTaskDir != null;
+ }
+}
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyTaskManager.java b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyTaskManager.java
index 213c1f7601f0..3013fbcb05d3 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyTaskManager.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyTaskManager.java
@@ -109,21 +109,29 @@ public class StudyTaskManager implements ProjectComponent, PersistentStateCompon
StartupManager.getInstance(myProject).runWhenProjectIsInitialized(new Runnable() {
@Override
public void run() {
- ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.PROJECT_VIEW).show(null);
- FileEditor[] editors = FileEditorManager.getInstance(myProject).getSelectedEditors();
- if (editors.length > 0) {
- JComponent focusedComponent = editors[0].getPreferredFocusedComponent();
- if (focusedComponent != null) {
- IdeFocusManager.getInstance(myProject).requestFocus(focusedComponent, true);
+ ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.PROJECT_VIEW).show(new Runnable() {
+ @Override
+ public void run() {
+ FileEditor[] editors = FileEditorManager.getInstance(myProject).getSelectedEditors();
+ if (editors.length > 0) {
+ final JComponent focusedComponent = editors[0].getPreferredFocusedComponent();
+ if (focusedComponent != null) {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ IdeFocusManager.getInstance(myProject).requestFocus(focusedComponent, true);
+ }
+ });
+ }
+ }
}
- }
+ });
}
});
UISettings.getInstance().HIDE_TOOL_STRIPES = false;
UISettings.getInstance().fireUISettingsChanged();
ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(myProject);
String toolWindowId = StudyToolWindowFactory.STUDY_TOOL_WINDOW;
- //TODO:decide smth with tool window position
try {
Method method = toolWindowManager.getClass().getDeclaredMethod("registerToolWindow", String.class,
JComponent.class,
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyTestRunner.java b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyTestRunner.java
new file mode 100644
index 000000000000..b0cd5ba89fed
--- /dev/null
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyTestRunner.java
@@ -0,0 +1,76 @@
+package com.jetbrains.python.edu;
+
+import com.intellij.execution.ExecutionException;
+import com.intellij.execution.configurations.GeneralCommandLine;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.jetbrains.python.edu.course.Course;
+import com.jetbrains.python.edu.course.Task;
+import com.jetbrains.python.sdk.PythonSdkType;
+
+import java.io.*;
+import java.util.Map;
+
+public class StudyTestRunner {
+ public static final String TEST_OK = "#study_plugin test OK";
+ private static final String TEST_FAILED = "#study_plugin FAILED + ";
+ private static final String PYTHONPATH = "PYTHONPATH";
+ private static final Logger LOG = Logger.getInstance(StudyTestRunner.class);
+ private final Task myTask;
+ private final VirtualFile myTaskDir;
+
+ public StudyTestRunner(Task task, VirtualFile taskDir) {
+ myTask = task;
+ myTaskDir = taskDir;
+ }
+
+ public Process launchTests(Project project, String executablePath) throws ExecutionException {
+ Sdk sdk = PythonSdkType.findPythonSdk(ModuleManager.getInstance(project).getModules()[0]);
+ File testRunner = new File(myTaskDir.getPath(), myTask.getTestFile());
+ GeneralCommandLine commandLine = new GeneralCommandLine();
+ commandLine.setWorkDirectory(myTaskDir.getPath());
+ final Map<String, String> env = commandLine.getEnvironment();
+ final VirtualFile courseDir = project.getBaseDir();
+ if (courseDir != null) {
+ env.put(PYTHONPATH, courseDir.getPath());
+ }
+ if (sdk != null) {
+ String pythonPath = sdk.getHomePath();
+ if (pythonPath != null) {
+ commandLine.setExePath(pythonPath);
+ commandLine.addParameter(testRunner.getPath());
+ final Course course = StudyTaskManager.getInstance(project).getCourse();
+ assert course != null;
+ commandLine.addParameter(new File(course.getResourcePath()).getParent());
+ commandLine.addParameter(FileUtil.toSystemDependentName(executablePath));
+ return commandLine.createProcess();
+ }
+ }
+ return null;
+ }
+
+
+ public String getPassedTests(Process p) {
+ InputStream testOutput = p.getInputStream();
+ BufferedReader testOutputReader = new BufferedReader(new InputStreamReader(testOutput));
+ String line;
+ try {
+ while ((line = testOutputReader.readLine()) != null) {
+ if (line.contains(TEST_FAILED)) {
+ return line.substring(TEST_FAILED.length(), line.length());
+ }
+ }
+ }
+ catch (IOException e) {
+ LOG.error(e);
+ }
+ finally {
+ StudyUtils.closeSilently(testOutputReader);
+ }
+ return TEST_OK;
+ }
+}
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyUtils.java b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyUtils.java
index d3ac1dadf98e..5d9bb139db09 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyUtils.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyUtils.java
@@ -3,6 +3,7 @@ package com.jetbrains.python.edu;
import com.intellij.ide.SaveAndSyncHandlerImpl;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.Presentation;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.FileDocumentManager;
@@ -10,12 +11,12 @@ import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.util.ui.UIUtil;
-import com.jetbrains.python.edu.course.TaskFile;
-import com.jetbrains.python.edu.course.TaskWindow;
+import com.jetbrains.python.edu.course.*;
import com.jetbrains.python.edu.editor.StudyEditor;
import com.jetbrains.python.edu.ui.StudyToolWindowFactory;
import org.jetbrains.annotations.NotNull;
@@ -70,7 +71,7 @@ public class StudyUtils {
return wrapHTML ? UIUtil.toHtml(taskText.toString()) : taskText.toString();
}
catch (IOException e) {
- LOG.error("Failed to get file text from file " + fileName, e);
+ LOG.info("Failed to get file text from file " + fileName, e);
}
finally {
closeSilently(reader);
@@ -119,14 +120,18 @@ public class StudyUtils {
}
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
- public static VirtualFile flushWindows(Document document, TaskFile taskFile, VirtualFile file) {
+ public static VirtualFile flushWindows(TaskFile taskFile, VirtualFile file) {
VirtualFile taskDir = file.getParent();
VirtualFile fileWindows = null;
+ final Document document = FileDocumentManager.getInstance().getDocument(file);
+ if (document == null) {
+ LOG.debug("Couldn't flush windows");
+ return null;
+ }
if (taskDir != null) {
String name = file.getNameWithoutExtension() + "_windows";
PrintWriter printWriter = null;
try {
-
fileWindows = taskDir.createChildData(taskFile, name);
printWriter = new PrintWriter(new FileOutputStream(fileWindows.getPath()));
for (TaskWindow taskWindow : taskFile.getTaskWindows()) {
@@ -137,6 +142,12 @@ public class StudyUtils {
String windowDescription = document.getText(new TextRange(start, start + taskWindow.getLength()));
printWriter.println("#study_plugin_window = " + windowDescription);
}
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ FileDocumentManager.getInstance().saveDocument(document);
+ }
+ });
}
catch (IOException e) {
LOG.error(e);
@@ -148,4 +159,27 @@ public class StudyUtils {
}
return fileWindows;
}
+
+ public static void deleteFile(VirtualFile file) {
+ try {
+ file.delete(StudyUtils.class);
+ }
+ catch (IOException e) {
+ LOG.error(e);
+ }
+ }
+
+ public static File copyResourceFile(String sourceName, String copyName, Project project, Task task)
+ throws IOException {
+ StudyTaskManager taskManager = StudyTaskManager.getInstance(project);
+ Course course = taskManager.getCourse();
+ int taskNum = task.getIndex() + 1;
+ int lessonNum = task.getLesson().getIndex() + 1;
+ assert course != null;
+ String pathToResource =
+ FileUtil.join(new File(course.getResourcePath()).getParent(), Lesson.LESSON_DIR + lessonNum, Task.TASK_DIR + taskNum);
+ File resourceFile = new File(pathToResource, copyName);
+ FileUtil.copy(new File(pathToResource, sourceName), resourceFile);
+ return resourceFile;
+ }
}
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyCheckAction.java b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyCheckAction.java
index f8e10c9c4521..5d02f7149aab 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyCheckAction.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyCheckAction.java
@@ -1,7 +1,6 @@
package com.jetbrains.python.edu.actions;
import com.intellij.execution.ExecutionException;
-import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.ide.projectView.ProjectView;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.AnActionEvent;
@@ -13,93 +12,81 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.FileEditorManager;
-import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.ui.popup.BalloonBuilder;
import com.intellij.openapi.ui.popup.JBPopupFactory;
-import com.intellij.openapi.util.TextRange;
-import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.ui.JBColor;
+import com.intellij.openapi.wm.IdeFocusManager;
import com.jetbrains.python.edu.StudyDocumentListener;
-import com.jetbrains.python.edu.StudyTaskManager;
+import com.jetbrains.python.edu.StudyState;
+import com.jetbrains.python.edu.StudyTestRunner;
import com.jetbrains.python.edu.StudyUtils;
-import com.jetbrains.python.edu.course.*;
+import com.jetbrains.python.edu.course.StudyStatus;
+import com.jetbrains.python.edu.course.Task;
+import com.jetbrains.python.edu.course.TaskFile;
+import com.jetbrains.python.edu.course.TaskWindow;
import com.jetbrains.python.edu.editor.StudyEditor;
-import com.jetbrains.python.sdk.PythonSdkType;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
-import java.io.*;
-import java.util.*;
-import java.util.List;
+import java.io.IOException;
+import java.util.Map;
public class StudyCheckAction extends DumbAwareAction {
private static final Logger LOG = Logger.getInstance(StudyCheckAction.class.getName());
- public static final String PYTHONPATH = "PYTHONPATH";
+ private static final String ANSWERS_POSTFIX = "_answers.py";
- static class StudyTestRunner {
- public static final String TEST_OK = "#study_plugin test OK";
- private static final String TEST_FAILED = "#study_plugin FAILED + ";
- private final Task myTask;
- private final VirtualFile myTaskDir;
- StudyTestRunner(Task task, VirtualFile taskDir) {
- myTask = task;
- myTaskDir = taskDir;
+ private static void flushWindows(@NotNull final Task task, @NotNull final VirtualFile taskDir) {
+ for (Map.Entry<String, TaskFile> entry : task.getTaskFiles().entrySet()) {
+ String name = entry.getKey();
+ TaskFile taskFile = entry.getValue();
+ VirtualFile virtualFile = taskDir.findChild(name);
+ if (virtualFile == null) {
+ continue;
+ }
+ StudyUtils.flushWindows(taskFile, virtualFile);
}
+ }
- Process launchTests(Project project, String executablePath) throws ExecutionException {
- Sdk sdk = PythonSdkType.findPythonSdk(ModuleManager.getInstance(project).getModules()[0]);
- File testRunner = new File(myTaskDir.getPath(), myTask.getTestFile());
- GeneralCommandLine commandLine = new GeneralCommandLine();
- commandLine.setWorkDirectory(myTaskDir.getPath());
- final Map<String, String> env = commandLine.getEnvironment();
- final VirtualFile courseDir = project.getBaseDir();
- if (courseDir != null)
- env.put(PYTHONPATH, courseDir.getPath());
- if (sdk != null) {
- String pythonPath = sdk.getHomePath();
- if (pythonPath != null) {
- commandLine.setExePath(pythonPath);
- commandLine.addParameter(testRunner.getPath());
- final Course course = StudyTaskManager.getInstance(project).getCourse();
- assert course != null;
- commandLine.addParameter(new File(course.getResourcePath()).getParent());
- commandLine.addParameter(FileUtil.toSystemDependentName(executablePath));
- return commandLine.createProcess();
- }
+ private static void deleteWindowDescriptions(@NotNull final Task task, @NotNull final VirtualFile taskDir) {
+ for (Map.Entry<String, TaskFile> entry : task.getTaskFiles().entrySet()) {
+ String name = entry.getKey();
+ VirtualFile virtualFile = taskDir.findChild(name);
+ if (virtualFile == null) {
+ continue;
+ }
+ String windowsFileName = virtualFile.getNameWithoutExtension() + "_windows";
+ VirtualFile windowsFile = taskDir.findChild(windowsFileName);
+ if (windowsFile != null) {
+ StudyUtils.deleteFile(windowsFile);
}
- return null;
}
+ }
-
- String getPassedTests(Process p) {
- InputStream testOutput = p.getInputStream();
- BufferedReader testOutputReader = new BufferedReader(new InputStreamReader(testOutput));
- String line;
- try {
- while ((line = testOutputReader.readLine()) != null) {
- if (line.contains(TEST_FAILED)) {
- return line.substring(TEST_FAILED.length(), line.length());
- }
- }
- }
- catch (IOException e) {
- LOG.error(e);
+ private static void drawAllTaskWindows(@NotNull final Project project, @NotNull final Task task, @NotNull final VirtualFile taskDir) {
+ for (Map.Entry<String, TaskFile> entry : task.getTaskFiles().entrySet()) {
+ String name = entry.getKey();
+ TaskFile taskFile = entry.getValue();
+ VirtualFile virtualFile = taskDir.findChild(name);
+ if (virtualFile == null) {
+ continue;
}
- finally {
- StudyUtils.closeSilently(testOutputReader);
+ FileEditor fileEditor = FileEditorManager.getInstance(project).getSelectedEditor(virtualFile);
+ if (fileEditor instanceof StudyEditor) {
+ StudyEditor studyEditor = (StudyEditor)fileEditor;
+ taskFile.drawAllWindows(studyEditor.getEditor());
}
- return TEST_OK;
}
}
+
public void check(@NotNull final Project project) {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
@@ -107,188 +94,138 @@ public class StudyCheckAction extends DumbAwareAction {
CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() {
@Override
public void run() {
- final Editor selectedEditor = StudyEditor.getSelectedEditor(project);
- if (selectedEditor != null) {
- final FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance();
- final VirtualFile openedFile = fileDocumentManager.getFile(selectedEditor.getDocument());
- if (openedFile != null) {
- StudyTaskManager taskManager = StudyTaskManager.getInstance(project);
- final TaskFile selectedTaskFile = taskManager.getTaskFile(openedFile);
- List<VirtualFile> filesToDelete = new ArrayList<VirtualFile>();
- if (selectedTaskFile != null) {
- final VirtualFile taskDir = openedFile.getParent();
- Task currentTask = selectedTaskFile.getTask();
- StudyStatus oldStatus = currentTask.getStatus();
- Map<String, TaskFile> taskFiles = selectedTaskFile.getTask().getTaskFiles();
+ final StudyEditor selectedEditor = StudyEditor.getSelectedStudyEditor(project);
+ final StudyState studyState = new StudyState(selectedEditor);
+ if (!studyState.isValid()) {
+ LOG.error("StudyCheckAction was invokes outside study editor");
+ return;
+ }
+ Task task = studyState.getTask();
+ StudyStatus oldStatus = task.getStatus();
+ Map<String, TaskFile> taskFiles = task.getTaskFiles();
+ VirtualFile taskDir = studyState.getTaskDir();
+ flushWindows(task, taskDir);
+ StudyRunAction runAction = (StudyRunAction)ActionManager.getInstance().getAction(StudyRunAction.ACTION_ID);
+ if (runAction != null && taskFiles.size() == 1) {
+ runAction.run(project);
+ }
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ IdeFocusManager.getInstance(project).requestFocus(studyState.getEditor().getComponent(), true);
+ }
+ });
+ final StudyTestRunner testRunner = new StudyTestRunner(task, taskDir);
+ Process testProcess = null;
+ try {
+ testProcess = testRunner.launchTests(project, studyState.getVirtualFile().getPath());
+ }
+ catch (ExecutionException e) {
+ LOG.error(e);
+ }
+ if (testProcess == null) {
+ return;
+ }
+ String failedMessage = testRunner.getPassedTests(testProcess);
+ if (failedMessage.equals(StudyTestRunner.TEST_OK)) {
+ task.setStatus(StudyStatus.Solved, oldStatus);
+ createTestResultPopUp("Congratulations!", MessageType.INFO.getPopupBackground(), project);
+ }
+ else {
+ task.setStatus(StudyStatus.Failed, oldStatus);
for (Map.Entry<String, TaskFile> entry : taskFiles.entrySet()) {
String name = entry.getKey();
TaskFile taskFile = entry.getValue();
- VirtualFile virtualFile = taskDir.findChild(name);
- if (virtualFile == null) {
+ if (taskFile.getTaskWindows().size() < 2) {
+ taskFile.setStatus(StudyStatus.Failed, StudyStatus.Unchecked);
continue;
}
- VirtualFile windowFile = StudyUtils.flushWindows(FileDocumentManager.getInstance().getDocument(virtualFile), taskFile, virtualFile);
- filesToDelete.add(windowFile);
- FileDocumentManager.getInstance().saveAllDocuments();
- }
-
- StudyRunAction runAction = (StudyRunAction)ActionManager.getInstance().getAction(StudyRunAction.ACTION_ID);
- if (runAction != null && currentTask.getTaskFiles().size() == 1) {
- runAction.run(project);
- }
- final StudyTestRunner testRunner = new StudyTestRunner(currentTask, taskDir);
- Process testProcess = null;
- try {
- testProcess = testRunner.launchTests(project, openedFile.getPath());
- }
- catch (ExecutionException e) {
- LOG.error(e);
- }
- if (testProcess != null) {
- String failedMessage = testRunner.getPassedTests(testProcess);
- if (failedMessage.equals(StudyTestRunner.TEST_OK)) {
- currentTask.setStatus(StudyStatus.Solved, oldStatus);
- StudyUtils.updateStudyToolWindow(project);
- selectedTaskFile.drawAllWindows(selectedEditor);
- ProjectView.getInstance(project).refresh();
- for (VirtualFile file:filesToDelete) {
- try {
- file.delete(this);
- }
- catch (IOException e) {
- LOG.error(e);
- }
- }
- createTestResultPopUp("Congratulations!", JBColor.GREEN, project);
- return;
- }
- for (Map.Entry<String, TaskFile> entry : taskFiles.entrySet()) {
- String name = entry.getKey();
- TaskFile taskFile = entry.getValue();
- TaskFile answerTaskFile = new TaskFile();
- VirtualFile virtualFile = taskDir.findChild(name);
- if (virtualFile == null) {
- continue;
- }
- VirtualFile answerFile = getCopyWithAnswers(taskDir, virtualFile, taskFile, answerTaskFile);
- for (TaskWindow taskWindow : answerTaskFile.getTaskWindows()) {
- Document document = FileDocumentManager.getInstance().getDocument(virtualFile);
- if (document == null) {
- continue;
- }
- if (!taskWindow.isValid(document)) {
- continue;
- }
- check(project, taskWindow, answerFile, answerTaskFile, taskFile, document, testRunner, virtualFile);
- }
- FileEditor fileEditor = FileEditorManager.getInstance(project).getSelectedEditor(virtualFile);
- Editor editor = null;
- if (fileEditor instanceof StudyEditor) {
- StudyEditor studyEditor = (StudyEditor) fileEditor;
- editor = studyEditor.getEditor();
- }
-
- if (editor != null) {
- taskFile.drawAllWindows(editor);
- StudyUtils.synchronize();
- }
- try {
- answerFile.delete(this);
- }
- catch (IOException e) {
- LOG.error(e);
- }
- }
- for (VirtualFile file:filesToDelete) {
- try {
- file.delete(this);
- }
- catch (IOException e) {
- LOG.error(e);
- }
- }
- currentTask.setStatus(StudyStatus.Failed, oldStatus);
- StudyUtils.updateStudyToolWindow(project);
- createTestResultPopUp(failedMessage, JBColor.RED, project);
+ runSmartTestProcess(taskDir, testRunner, name, taskFile, project);
}
+ createTestResultPopUp(failedMessage, MessageType.ERROR.getPopupBackground(), project);
+ navigateToFailedTaskWindow(studyState, task, taskDir, project);
}
+ StudyUtils.updateStudyToolWindow(project);
+ drawAllTaskWindows(project, task, taskDir);
+ ProjectView.getInstance(project).refresh();
+ deleteWindowDescriptions(task, taskDir);
}
- }
-
- }
- });
+ });
}
});
}
- private void check(Project project,
- TaskWindow taskWindow,
- VirtualFile answerFile,
- TaskFile answerTaskFile,
- TaskFile usersTaskFile,
- Document usersDocument,
- StudyTestRunner testRunner,
- VirtualFile openedFile) {
-
- try {
- VirtualFile windowCopy = answerFile.copy(this, answerFile.getParent(), answerFile.getNameWithoutExtension() + "_window" + taskWindow.getIndex() + ".py");
- final FileDocumentManager documentManager = FileDocumentManager.getInstance();
- final Document windowDocument = documentManager.getDocument(windowCopy);
- if (windowDocument != null) {
- StudyTaskManager taskManager = StudyTaskManager.getInstance(project);
- Course course = taskManager.getCourse();
- Task task = usersTaskFile.getTask();
- int taskNum = task.getIndex() + 1;
- int lessonNum = task.getLesson().getIndex() + 1;
- assert course != null;
- String pathToResource = FileUtil.join(new File(course.getResourcePath()).getParent(), Lesson.LESSON_DIR + lessonNum, Task.TASK_DIR + taskNum);
- File resourceFile = new File(pathToResource, windowCopy.getName());
- FileUtil.copy(new File(pathToResource, openedFile.getName()), resourceFile);
- TaskFile windowTaskFile = new TaskFile();
- TaskFile.copy(answerTaskFile, windowTaskFile);
- StudyDocumentListener listener = new StudyDocumentListener(windowTaskFile);
- windowDocument.addDocumentListener(listener);
- int start = taskWindow.getRealStartOffset(windowDocument);
- int end = start + taskWindow.getLength();
- TaskWindow userTaskWindow = usersTaskFile.getTaskWindows().get(taskWindow.getIndex());
- int userStart = userTaskWindow.getRealStartOffset(usersDocument);
- int userEnd = userStart + userTaskWindow.getLength();
- String text = usersDocument.getText(new TextRange(userStart, userEnd));
- windowDocument.replaceString(start, end, text);
- ApplicationManager.getApplication().runWriteAction(new Runnable() {
- @Override
- public void run() {
- documentManager.saveDocument(windowDocument);
+ private static void navigateToFailedTaskWindow(@NotNull final StudyState studyState,
+ @NotNull final Task task,
+ @NotNull final VirtualFile taskDir,
+ @NotNull final Project project) {
+ TaskFile selectedTaskFile = studyState.getTaskFile();
+ Editor editor = studyState.getEditor();
+ TaskFile taskFileToNavigate = selectedTaskFile;
+ VirtualFile fileToNavigate = studyState.getVirtualFile();
+ if (!selectedTaskFile.hasFailedTaskWindows()) {
+ for (Map.Entry<String, TaskFile> entry : task.getTaskFiles().entrySet()) {
+ String name = entry.getKey();
+ TaskFile taskFile = entry.getValue();
+ if (taskFile.hasFailedTaskWindows()) {
+ taskFileToNavigate = taskFile;
+ VirtualFile virtualFile = taskDir.findChild(name);
+ if (virtualFile == null) {
+ continue;
}
- });
- VirtualFile fileWindows = StudyUtils.flushWindows(windowDocument, windowTaskFile, windowCopy);
- Process smartTestProcess = testRunner.launchTests(project, windowCopy.getPath());
- boolean res = testRunner.getPassedTests(smartTestProcess).equals(StudyTestRunner.TEST_OK);
- userTaskWindow.setStatus(res ? StudyStatus.Solved : StudyStatus.Failed, StudyStatus.Unchecked);
- windowCopy.delete(this);
- fileWindows.delete(this);
- if (!resourceFile.delete()) {
- LOG.error("failed to delete", resourceFile.getPath());
+ FileEditor fileEditor = FileEditorManager.getInstance(project).getSelectedEditor(virtualFile);
+ if (fileEditor instanceof StudyEditor) {
+ StudyEditor studyEditor = (StudyEditor)fileEditor;
+ editor = studyEditor.getEditor();
+ }
+ fileToNavigate = virtualFile;
+ break;
}
}
}
- catch (IOException e) {
- LOG.error(e);
+ FileEditorManager.getInstance(project).openFile(fileToNavigate, true);
+ final Editor editorToNavigate = editor;
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ IdeFocusManager.getInstance(project).requestFocus(editorToNavigate.getContentComponent(), true);
+ }
+ });
+ taskFileToNavigate.navigateToFirstFailedTaskWindow(editor);
+ }
+
+ private void runSmartTestProcess(@NotNull final VirtualFile taskDir,
+ @NotNull final StudyTestRunner testRunner,
+ final String taskFileName,
+ @NotNull final TaskFile taskFile,
+ @NotNull final Project project) {
+ TaskFile answerTaskFile = new TaskFile();
+ VirtualFile virtualFile = taskDir.findChild(taskFileName);
+ if (virtualFile == null) {
+ return;
}
- catch (ExecutionException e) {
- LOG.error(e);
+ VirtualFile answerFile = getCopyWithAnswers(taskDir, virtualFile, taskFile, answerTaskFile);
+ for (TaskWindow taskWindow : answerTaskFile.getTaskWindows()) {
+ Document document = FileDocumentManager.getInstance().getDocument(virtualFile);
+ if (document == null) {
+ continue;
+ }
+ if (!taskWindow.isValid(document)) {
+ continue;
+ }
+ taskWindow.smartCheck(project, answerFile, answerTaskFile, taskFile, testRunner, virtualFile, document);
}
+ StudyUtils.deleteFile(answerFile);
}
-
- private VirtualFile getCopyWithAnswers(final VirtualFile taskDir,
- final VirtualFile file,
- final TaskFile source,
- TaskFile target) {
+ private VirtualFile getCopyWithAnswers(@NotNull final VirtualFile taskDir,
+ @NotNull final VirtualFile file,
+ @NotNull final TaskFile source,
+ @NotNull final TaskFile target) {
VirtualFile copy = null;
try {
- copy = file.copy(this, taskDir, file.getNameWithoutExtension() +"_answers.py");
+ copy = file.copy(this, taskDir, file.getNameWithoutExtension() + ANSWERS_POSTFIX);
final FileDocumentManager documentManager = FileDocumentManager.getInstance();
final Document document = documentManager.getDocument(copy);
if (document != null) {
@@ -315,19 +252,18 @@ public class StudyCheckAction extends DumbAwareAction {
catch (IOException e) {
LOG.error(e);
}
-
-
return copy;
}
private static void createTestResultPopUp(final String text, Color color, @NotNull final Project project) {
BalloonBuilder balloonBuilder =
JBPopupFactory.getInstance().createHtmlTextBalloonBuilder(text, null, color, null);
- Balloon balloon = balloonBuilder.createBalloon();
+ final Balloon balloon = balloonBuilder.createBalloon();
StudyEditor studyEditor = StudyEditor.getSelectedStudyEditor(project);
assert studyEditor != null;
JButton checkButton = studyEditor.getCheckButton();
balloon.showInCenterOf(checkButton);
+ Disposer.register(project, balloon);
}
@Override
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyEditInputAction.java b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyEditInputAction.java
index 5b9a6fef23ac..72660fc9c2c6 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyEditInputAction.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyEditInputAction.java
@@ -19,6 +19,7 @@ import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.ui.tabs.TabInfo;
import com.intellij.ui.tabs.TabsListener;
import com.intellij.ui.tabs.impl.JBEditorTabs;
+import com.intellij.util.PlatformIcons;
import com.jetbrains.python.edu.StudyTaskManager;
import com.jetbrains.python.edu.StudyUtils;
import com.jetbrains.python.edu.course.Task;
@@ -26,7 +27,6 @@ import com.jetbrains.python.edu.course.TaskFile;
import com.jetbrains.python.edu.course.UserTest;
import com.jetbrains.python.edu.editor.StudyEditor;
import com.jetbrains.python.edu.ui.StudyTestContentPanel;
-import icons.StudyIcons;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -92,7 +92,7 @@ public class StudyEditInputAction extends DumbAwareAction {
i++;
}
TabInfo plusTab = new TabInfo(new JPanel());
- plusTab.setIcon(StudyIcons.Add);
+ plusTab.setIcon(PlatformIcons.ADD_ICON);
tabbedPane.addTabSilently(plusTab, tabbedPane.getTabCount());
final JBPopup hint =
JBPopupFactory.getInstance().createComponentPopupBuilder(tabbedPane.getComponent(), tabbedPane.getComponent())
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNewProject.java b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNewProject.java
new file mode 100644
index 000000000000..0b75c4bc01c4
--- /dev/null
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNewProject.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jetbrains.python.edu.actions;
+
+import com.jetbrains.python.edu.StudyDirectoryProjectGenerator;
+import com.jetbrains.python.newProject.actions.GenerateProjectCallback;
+import com.jetbrains.python.newProject.actions.ProjectSpecificAction;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class StudyNewProject extends ProjectSpecificAction {
+
+ public StudyNewProject(@NotNull final String name, @Nullable final Runnable runnable) {
+ super(new GenerateProjectCallback(runnable), new StudyDirectoryProjectGenerator(), name, true);
+ }
+
+ public StudyNewProject() {
+ this("Learn Python", null);
+ }
+
+}
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNextStudyTaskAction.java b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNextStudyTaskAction.java
index 81818a95c044..3c971c3fe15e 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNextStudyTaskAction.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNextStudyTaskAction.java
@@ -2,13 +2,14 @@ package com.jetbrains.python.edu.actions;
import com.jetbrains.python.edu.editor.StudyEditor;
import com.jetbrains.python.edu.course.Task;
+import org.jetbrains.annotations.NotNull;
import javax.swing.*;
public class StudyNextStudyTaskAction extends StudyTaskNavigationAction {
@Override
- protected JButton getButton(StudyEditor selectedStudyEditor) {
+ protected JButton getButton(@NotNull final StudyEditor selectedStudyEditor) {
return selectedStudyEditor.getNextTaskButton();
}
@@ -18,7 +19,7 @@ public class StudyNextStudyTaskAction extends StudyTaskNavigationAction {
}
@Override
- protected Task getTargetTask(Task sourceTask) {
+ protected Task getTargetTask(@NotNull final Task sourceTask) {
return sourceTask.next();
}
} \ No newline at end of file
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNextWindowAction.java b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNextWindowAction.java
index 595aeeff42e3..fcf9ef40c7d4 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNextWindowAction.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNextWindowAction.java
@@ -1,8 +1,8 @@
package com.jetbrains.python.edu.actions;
+import com.intellij.icons.AllIcons;
import com.jetbrains.python.edu.StudyUtils;
import com.jetbrains.python.edu.course.TaskWindow;
-import icons.StudyIcons;
import org.jetbrains.annotations.NotNull;
import java.util.List;
@@ -16,7 +16,7 @@ public class StudyNextWindowAction extends StudyWindowNavigationAction {
public static final String SHORTCUT2 = "ctrl pressed ENTER";
public StudyNextWindowAction() {
- super("NextWindowAction", "Select next window", StudyIcons.Next);
+ super("NextWindowAction", "Select next window", AllIcons.Actions.Forward);
}
@Override
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyPreviousStudyTaskAction.java b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyPreviousStudyTaskAction.java
index bc26c28cfabd..f6da6a067894 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyPreviousStudyTaskAction.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyPreviousStudyTaskAction.java
@@ -3,13 +3,14 @@ package com.jetbrains.python.edu.actions;
import com.jetbrains.python.edu.editor.StudyEditor;
import com.jetbrains.python.edu.course.Task;
+import org.jetbrains.annotations.NotNull;
import javax.swing.*;
public class StudyPreviousStudyTaskAction extends StudyTaskNavigationAction {
@Override
- protected JButton getButton(StudyEditor selectedStudyEditor) {
+ protected JButton getButton(@NotNull final StudyEditor selectedStudyEditor) {
return selectedStudyEditor.getPrevTaskButton();
}
@@ -19,7 +20,7 @@ public class StudyPreviousStudyTaskAction extends StudyTaskNavigationAction {
}
@Override
- protected Task getTargetTask(Task sourceTask) {
+ protected Task getTargetTask(@NotNull final Task sourceTask) {
return sourceTask.prev();
}
} \ No newline at end of file
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyRefreshTaskAction.java b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyRefreshTaskFileAction.java
index f8abb0b63365..a9448ddea0e3 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyRefreshTaskAction.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyRefreshTaskFileAction.java
@@ -14,6 +14,7 @@ import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.ui.popup.BalloonBuilder;
import com.intellij.openapi.ui.popup.JBPopupFactory;
+import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.IdeFocusManager;
import com.jetbrains.python.edu.StudyDocumentListener;
@@ -24,8 +25,8 @@ import com.jetbrains.python.edu.editor.StudyEditor;
import java.io.*;
-public class StudyRefreshTaskAction extends DumbAwareAction {
- private static final Logger LOG = Logger.getInstance(StudyRefreshTaskAction.class.getName());
+public class StudyRefreshTaskFileAction extends DumbAwareAction {
+ private static final Logger LOG = Logger.getInstance(StudyRefreshTaskFileAction.class.getName());
public void refresh(final Project project) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@@ -92,14 +93,20 @@ public class StudyRefreshTaskAction extends DumbAwareAction {
document.addDocumentListener(listener);
}
selectedTaskFile.drawAllWindows(editor);
- IdeFocusManager.getInstance(project).requestFocus(editor.getContentComponent(), true);
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ IdeFocusManager.getInstance(project).requestFocus(editor.getContentComponent(), true);
+ }
+ });
selectedTaskFile.navigateToFirstTaskWindow(editor);
BalloonBuilder balloonBuilder =
JBPopupFactory.getInstance().createHtmlTextBalloonBuilder("You can now start again", MessageType.INFO, null);
- Balloon balloon = balloonBuilder.createBalloon();
+ final Balloon balloon = balloonBuilder.createBalloon();
StudyEditor selectedStudyEditor = StudyEditor.getSelectedStudyEditor(project);
assert selectedStudyEditor != null;
balloon.showInCenterOf(selectedStudyEditor.getRefreshButton());
+ Disposer.register(project, balloon);
}
catch (FileNotFoundException e1) {
LOG.error(e1);
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyShowHintAction.java b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyShowHintAction.java
index 1efa90889449..2952486274cf 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyShowHintAction.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyShowHintAction.java
@@ -5,19 +5,18 @@ import com.intellij.codeInsight.documentation.DocumentationManager;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.LogicalPosition;
-import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.JBPopupFactory;
-import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.util.Disposer;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
+import com.jetbrains.python.edu.StudyState;
import com.jetbrains.python.edu.StudyTaskManager;
import com.jetbrains.python.edu.StudyUtils;
import com.jetbrains.python.edu.course.Course;
-import com.jetbrains.python.edu.course.TaskFile;
import com.jetbrains.python.edu.course.TaskWindow;
import com.jetbrains.python.edu.editor.StudyEditor;
import icons.StudyIcons;
@@ -33,58 +32,56 @@ public class StudyShowHintAction extends DumbAwareAction {
}
public void actionPerformed(AnActionEvent e) {
- Project project = e.getProject();
- if (project != null) {
+ final Project project = e.getProject();
+ if (project == null) {
+ return;
+ }
+ Course course = StudyTaskManager.getInstance(project).getCourse();
+ if (course == null) {
+ return;
+ }
+ StudyState studyState = new StudyState(StudyEditor.getSelectedStudyEditor(project));
+ if (!studyState.isValid()) {
+ return;
+ }
+ PsiFile file = PsiManager.getInstance(project).findFile(studyState.getVirtualFile());
+ final Editor editor = studyState.getEditor();
+ LogicalPosition pos = editor.getCaretModel().getLogicalPosition();
+ TaskWindow taskWindow = studyState.getTaskFile().getTaskWindow(editor.getDocument(), pos);
+ if (file == null || taskWindow == null) {
+ return;
+ }
+ String hint = taskWindow.getHint();
+ if (hint == null) {
+ return;
+ }
+ File resourceFile = new File(course.getResourcePath());
+ File resourceRoot = resourceFile.getParentFile();
+ if (resourceRoot == null || !resourceRoot.exists()) {
+ return;
+ }
+ File hintsDir = new File(resourceRoot, Course.HINTS_DIR);
+ if (hintsDir.exists()) {
+ String hintText = StudyUtils.getFileText(hintsDir.getAbsolutePath(), hint, true);
+ int offset = editor.getDocument().getLineStartOffset(pos.line) + pos.column;
+ PsiElement element = file.findElementAt(offset);
+ if (hintText == null || element == null) {
+ return;
+ }
+
DocumentationManager documentationManager = DocumentationManager.getInstance(project);
DocumentationComponent component = new DocumentationComponent(documentationManager);
- Editor selectedEditor = StudyEditor.getSelectedEditor(project);
- FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance();
- assert selectedEditor != null;
- VirtualFile openedFile = fileDocumentManager.getFile(selectedEditor.getDocument());
- if (openedFile != null) {
- StudyTaskManager taskManager = StudyTaskManager.getInstance(e.getProject());
- TaskFile taskFile = taskManager.getTaskFile(openedFile);
- if (taskFile != null) {
- PsiFile file = PsiManager.getInstance(project).findFile(openedFile);
- if (file != null) {
- LogicalPosition pos = selectedEditor.getCaretModel().getLogicalPosition();
- TaskWindow taskWindow = taskFile.getTaskWindow(selectedEditor.getDocument(), pos);
- if (taskWindow != null) {
- String hint = taskWindow.getHint();
- if (hint == null) {
- return;
- }
- Course course = taskManager.getCourse();
- if (course != null) {
- File resourceFile = new File(course.getResourcePath());
- File resourceRoot = resourceFile.getParentFile();
- if (resourceRoot != null && resourceRoot.exists()) {
- File hintsDir = new File(resourceRoot, Course.HINTS_DIR);
- if (hintsDir.exists()) {
- String hintText = StudyUtils.getFileText(hintsDir.getAbsolutePath(), hint, true);
- if (hintText != null) {
- int offset = selectedEditor.getDocument().getLineStartOffset(pos.line) + pos.column;
- PsiElement element = file.findElementAt(offset);
- if (element != null) {
- component.setData(element, hintText, true, null);
- final JBPopup popup =
- JBPopupFactory.getInstance().createComponentPopupBuilder(component, component)
- .setDimensionServiceKey(project, DocumentationManager.JAVADOC_LOCATION_AND_SIZE, false)
- .setResizable(true)
- .setMovable(true)
- .setRequestFocus(true)
- .createPopup();
- component.setHint(popup);
- popup.showInBestPositionFor(selectedEditor);
- }
- }
- }
- }
- }
- }
- }
- }
- }
+ component.setData(element, hintText, true, null);
+ final JBPopup popup =
+ JBPopupFactory.getInstance().createComponentPopupBuilder(component, component)
+ .setDimensionServiceKey(project, DocumentationManager.JAVADOC_LOCATION_AND_SIZE, false)
+ .setResizable(true)
+ .setMovable(true)
+ .setRequestFocus(true)
+ .createPopup();
+ component.setHint(popup);
+ popup.showInBestPositionFor(editor);
+ Disposer.dispose(component);
}
}
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyTaskNavigationAction.java b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyTaskNavigationAction.java
index b781e7da8849..46c0981cb964 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyTaskNavigationAction.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyTaskNavigationAction.java
@@ -1,8 +1,6 @@
package com.jetbrains.python.edu.actions;
import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
@@ -11,37 +9,34 @@ import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.ui.popup.BalloonBuilder;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.vfs.VirtualFile;
-import com.jetbrains.python.edu.StudyTaskManager;
+import com.intellij.openapi.wm.ToolWindow;
+import com.intellij.openapi.wm.ToolWindowId;
+import com.intellij.openapi.wm.ToolWindowManager;
+import com.jetbrains.python.edu.StudyState;
import com.jetbrains.python.edu.course.Lesson;
import com.jetbrains.python.edu.course.Task;
import com.jetbrains.python.edu.course.TaskFile;
import com.jetbrains.python.edu.editor.StudyEditor;
+import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.Map;
-/**
- * author: liana
- * data: 7/21/14.
- */
+
abstract public class StudyTaskNavigationAction extends DumbAwareAction {
- public void navigateTask(Project project) {
- Editor selectedEditor = StudyEditor.getSelectedEditor(project);
- FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance();
- assert selectedEditor != null;
- VirtualFile openedFile = fileDocumentManager.getFile(selectedEditor.getDocument());
- StudyTaskManager taskManager = StudyTaskManager.getInstance(project);
- assert openedFile != null;
- TaskFile selectedTaskFile = taskManager.getTaskFile(openedFile);
- assert selectedTaskFile != null;
- Task currentTask = selectedTaskFile.getTask();
- Task nextTask = getTargetTask(currentTask);
+ public void navigateTask(@NotNull final Project project) {
+ StudyEditor studyEditor = StudyEditor.getSelectedStudyEditor(project);
+ StudyState studyState = new StudyState(studyEditor);
+ if (!studyState.isValid()) {
+ return;
+ }
+ Task nextTask = getTargetTask(studyState.getTask());
if (nextTask == null) {
BalloonBuilder balloonBuilder =
JBPopupFactory.getInstance().createHtmlTextBalloonBuilder(getNavigationFinishedMessage(), MessageType.INFO, null);
Balloon balloon = balloonBuilder.createBalloon();
- StudyEditor selectedStudyEditor = StudyEditor.getSelectedStudyEditor(project);
- balloon.showInCenterOf(getButton(selectedStudyEditor));
+ assert studyEditor != null;
+ balloon.showInCenterOf(getButton(studyEditor));
return;
}
for (VirtualFile file : FileEditorManager.getInstance(project).getOpenFiles()) {
@@ -82,16 +77,24 @@ abstract public class StudyTaskNavigationAction extends DumbAwareAction {
if (shouldBeActive != null) {
FileEditorManager.getInstance(project).openFile(shouldBeActive, true);
}
+ ToolWindow runToolWindow = ToolWindowManager.getInstance(project).getToolWindow(ToolWindowId.RUN);
+ if (runToolWindow != null) {
+ runToolWindow.hide(null);
+ }
}
- protected abstract JButton getButton(StudyEditor selectedStudyEditor);
+ protected abstract JButton getButton(@NotNull final StudyEditor selectedStudyEditor);
@Override
public void actionPerformed(AnActionEvent e) {
- navigateTask(e.getProject());
+ Project project = e.getProject();
+ if (project == null) {
+ return;
+ }
+ navigateTask(project);
}
protected abstract String getNavigationFinishedMessage();
- protected abstract Task getTargetTask(Task sourceTask);
+ protected abstract Task getTargetTask(@NotNull final Task sourceTask);
}
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/course/TaskFile.java b/python/edu/learn-python/src/com/jetbrains/python/edu/course/TaskFile.java
index 4f17fc0d27f3..c46c4f56f937 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/course/TaskFile.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/course/TaskFile.java
@@ -21,7 +21,7 @@ import java.util.List;
* which is visible to student in project view
*/
-public class TaskFile implements Stateful{
+public class TaskFile implements Stateful {
public List<TaskWindow> taskWindows = new ArrayList<TaskWindow>();
private Task myTask;
@Transient
@@ -173,7 +173,18 @@ public class TaskFile implements Stateful{
for (TaskWindow w : taskWindows) {
if ((w.getLine() == line) && (w.getStart() >= oldEndOffsetInLine)) {
int distance = w.getStart() - oldEndOffsetInLine;
- if (lineChange != 0 || newEndOffsetInLine <= w.getStart()) {
+ boolean coveredByPrevTW = false;
+ int prevIndex = w.getIndex() - 1;
+ if (StudyUtils.indexIsValid(prevIndex, taskWindows)) {
+ TaskWindow prevTW = taskWindows.get(prevIndex);
+ if (prevTW.getLine() == line) {
+ int endOffset = prevTW.getStart() + prevTW.getLength();
+ if (endOffset >= newEndOffsetInLine) {
+ coveredByPrevTW = true;
+ }
+ }
+ }
+ if (lineChange != 0 || newEndOffsetInLine <= w.getStart() || coveredByPrevTW) {
w.setStart(distance + newEndOffsetInLine);
w.setLine(line + lineChange);
}
@@ -217,12 +228,33 @@ public class TaskFile implements Stateful{
public void navigateToFirstTaskWindow(@NotNull final Editor editor) {
if (!taskWindows.isEmpty()) {
TaskWindow firstTaskWindow = StudyUtils.getFirst(taskWindows);
- mySelectedTaskWindow = firstTaskWindow;
- LogicalPosition taskWindowStart = new LogicalPosition(firstTaskWindow.getLine(), firstTaskWindow.getStart());
- editor.getCaretModel().moveToLogicalPosition(taskWindowStart);
- int startOffset = firstTaskWindow.getRealStartOffset(editor.getDocument());
- int endOffset = startOffset + firstTaskWindow.getLength();
- editor.getSelectionModel().setSelection(startOffset, endOffset);
+ navigateToTaskWindow(editor, firstTaskWindow);
+ }
+ }
+
+ private void navigateToTaskWindow(@NotNull final Editor editor, @NotNull final TaskWindow firstTaskWindow) {
+ if (!firstTaskWindow.isValid(editor.getDocument())) {
+ return;
}
+ mySelectedTaskWindow = firstTaskWindow;
+ LogicalPosition taskWindowStart = new LogicalPosition(firstTaskWindow.getLine(), firstTaskWindow.getStart());
+ editor.getCaretModel().moveToLogicalPosition(taskWindowStart);
+ int startOffset = firstTaskWindow.getRealStartOffset(editor.getDocument());
+ int endOffset = startOffset + firstTaskWindow.getLength();
+ editor.getSelectionModel().setSelection(startOffset, endOffset);
+ }
+
+ public void navigateToFirstFailedTaskWindow(@NotNull final Editor editor) {
+ for (TaskWindow taskWindow : taskWindows) {
+ if (taskWindow.getStatus() != StudyStatus.Failed) {
+ continue;
+ }
+ navigateToTaskWindow(editor, taskWindow);
+ break;
+ }
+ }
+
+ public boolean hasFailedTaskWindows() {
+ return taskWindows.size() > 0 && getStatus() == StudyStatus.Failed;
}
}
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/course/TaskWindow.java b/python/edu/learn-python/src/com/jetbrains/python/edu/course/TaskWindow.java
index 4fb112cc1f9b..dc4a75a800ce 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/course/TaskWindow.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/course/TaskWindow.java
@@ -1,5 +1,8 @@
package com.jetbrains.python.edu.course;
+import com.intellij.execution.ExecutionException;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.colors.EditorColors;
@@ -8,16 +11,27 @@ import com.intellij.openapi.editor.markup.HighlighterLayer;
import com.intellij.openapi.editor.markup.HighlighterTargetArea;
import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.editor.markup.TextAttributes;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.JBColor;
+import com.jetbrains.python.edu.StudyDocumentListener;
+import com.jetbrains.python.edu.StudyTestRunner;
+import com.jetbrains.python.edu.StudyUtils;
import org.jetbrains.annotations.NotNull;
+import java.io.File;
+import java.io.IOException;
+
/**
* Implementation of windows which user should type in
*/
public class TaskWindow implements Comparable, Stateful {
-
+ private static final String WINDOW_POSTFIX = "_window.py";
+ private static final Logger LOG = Logger.getInstance(TaskWindow.class);
public int line = 0;
public int start = 0;
public String hint = "";
@@ -174,4 +188,55 @@ public class TaskWindow implements Comparable, Stateful {
public int getIndex() {
return myIndex;
}
+
+ public void smartCheck(@NotNull final Project project,
+ @NotNull final VirtualFile answerFile,
+ @NotNull final TaskFile answerTaskFile,
+ @NotNull final TaskFile usersTaskFile,
+ @NotNull final StudyTestRunner testRunner,
+ @NotNull final VirtualFile virtualFile,
+ @NotNull final Document usersDocument) {
+
+ try {
+ VirtualFile windowCopy =
+ answerFile.copy(this, answerFile.getParent(), answerFile.getNameWithoutExtension() + WINDOW_POSTFIX);
+ final FileDocumentManager documentManager = FileDocumentManager.getInstance();
+ final Document windowDocument = documentManager.getDocument(windowCopy);
+ if (windowDocument != null) {
+ File resourceFile = StudyUtils.copyResourceFile(virtualFile.getName(), windowCopy.getName(), project, usersTaskFile.getTask());
+ TaskFile windowTaskFile = new TaskFile();
+ TaskFile.copy(answerTaskFile, windowTaskFile);
+ StudyDocumentListener listener = new StudyDocumentListener(windowTaskFile);
+ windowDocument.addDocumentListener(listener);
+ int start = getRealStartOffset(windowDocument);
+ int end = start + getLength();
+ TaskWindow userTaskWindow = usersTaskFile.getTaskWindows().get(getIndex());
+ int userStart = userTaskWindow.getRealStartOffset(usersDocument);
+ int userEnd = userStart + userTaskWindow.getLength();
+ String text = usersDocument.getText(new TextRange(userStart, userEnd));
+ windowDocument.replaceString(start, end, text);
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ documentManager.saveDocument(windowDocument);
+ }
+ });
+ VirtualFile fileWindows = StudyUtils.flushWindows(windowTaskFile, windowCopy);
+ Process smartTestProcess = testRunner.launchTests(project, windowCopy.getPath());
+ boolean res = testRunner.getPassedTests(smartTestProcess).equals(StudyTestRunner.TEST_OK);
+ userTaskWindow.setStatus(res ? StudyStatus.Solved : StudyStatus.Failed, StudyStatus.Unchecked);
+ StudyUtils.deleteFile(windowCopy);
+ StudyUtils.deleteFile(fileWindows);
+ if (!resourceFile.delete()) {
+ LOG.error("failed to delete", resourceFile.getPath());
+ }
+ }
+ }
+ catch (ExecutionException e) {
+ LOG.error(e);
+ }
+ catch (IOException e) {
+ LOG.error(e);
+ }
+ }
} \ No newline at end of file
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/editor/StudyEditor.java b/python/edu/learn-python/src/com/jetbrains/python/edu/editor/StudyEditor.java
index 69c5acc5f127..6b27c4a406db 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/editor/StudyEditor.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/editor/StudyEditor.java
@@ -1,8 +1,10 @@
package com.jetbrains.python.edu.editor;
import com.intellij.codeHighlighting.BackgroundEditorHighlighter;
+import com.intellij.icons.AllIcons;
import com.intellij.ide.structureView.StructureViewBuilder;
import com.intellij.openapi.actionSystem.ActionManager;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
@@ -17,9 +19,15 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.wm.IdeFocusManager;
+import com.intellij.openapi.wm.ToolWindow;
+import com.intellij.openapi.wm.ToolWindowId;
+import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.pom.Navigatable;
+import com.intellij.ui.BrowserHyperlinkListener;
import com.intellij.ui.HideableTitledPanel;
import com.intellij.ui.JBColor;
+import com.intellij.util.ui.EmptyClipboardOwner;
import com.intellij.util.ui.UIUtil;
import com.jetbrains.python.edu.StudyDocumentListener;
import com.jetbrains.python.edu.StudyTaskManager;
@@ -36,8 +44,8 @@ import javax.swing.text.MutableAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
+import java.awt.datatransfer.StringSelection;
+import java.awt.event.*;
import java.beans.PropertyChangeListener;
import java.util.HashMap;
import java.util.Map;
@@ -50,12 +58,13 @@ public class StudyEditor implements TextEditor {
private static final String TASK_TEXT_HEADER = "Task Text";
private final FileEditor myDefaultEditor;
private final JComponent myComponent;
+ private final TaskFile myTaskFile;
private JButton myCheckButton;
private JButton myNextTaskButton;
private JButton myPrevTaskButton;
private JButton myRefreshButton;
private static final Map<Document, StudyDocumentListener> myDocumentListeners = new HashMap<Document, StudyDocumentListener>();
- private Project myProject;
+ private final Project myProject;
public JButton getCheckButton() {
return myCheckButton;
@@ -65,6 +74,10 @@ public class StudyEditor implements TextEditor {
return myPrevTaskButton;
}
+ public TaskFile getTaskFile() {
+ return myTaskFile;
+ }
+
private static JButton addButton(@NotNull final JComponent parentComponent, String toolTipText, Icon icon) {
JButton newButton = new JButton();
newButton.setToolTipText(toolTipText);
@@ -89,26 +102,72 @@ public class StudyEditor implements TextEditor {
myComponent = myDefaultEditor.getComponent();
JPanel studyPanel = new JPanel();
studyPanel.setLayout(new BoxLayout(studyPanel, BoxLayout.Y_AXIS));
- TaskFile taskFile = StudyTaskManager.getInstance(myProject).getTaskFile(file);
- if (taskFile != null) {
- Task currentTask = taskFile.getTask();
+ myTaskFile = StudyTaskManager.getInstance(myProject).getTaskFile(file);
+ if (myTaskFile != null) {
+ Task currentTask = myTaskFile.getTask();
String taskText = currentTask.getResourceText(project, currentTask.getText(), false);
initializeTaskText(studyPanel, taskText);
JPanel studyButtonPanel = new JPanel(new GridLayout(1, 2));
JPanel taskActionsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
studyButtonPanel.add(taskActionsPanel);
studyButtonPanel.add(new JPanel());
- initializeButtons(taskActionsPanel, taskFile);
+ initializeButtons(taskActionsPanel, myTaskFile);
studyPanel.add(studyButtonPanel);
myComponent.add(studyPanel, BorderLayout.NORTH);
}
}
- private static void initializeTaskText(JPanel studyPanel, @Nullable String taskText) {
+ class CopyListener extends MouseAdapter {
+ final JTextPane myTextPane;
+
+ public CopyListener(JTextPane textPane) {
+ myTextPane = textPane;
+ }
+
+ @Override
+ public void mouseReleased(MouseEvent e) {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ ToolWindow projectView = ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.PROJECT_VIEW);
+ if (projectView == null) {
+ return;
+ }
+ final Component focusComponent = projectView.getComponent();
+ IdeFocusManager.getInstance(myProject).requestFocus(focusComponent, true);
+ final String text = myTextPane.getSelectedText();
+ if (text == null) {
+ return;
+ }
+ KeyAdapter keyAdapter = new KeyAdapter() {
+ @Override
+ public void keyPressed(KeyEvent ev) {
+ if (ev.getKeyCode() == KeyEvent.VK_C
+ && ev.getModifiers() == InputEvent.CTRL_MASK) {
+ StringSelection selection = new StringSelection(text);
+ Toolkit.getDefaultToolkit().getSystemClipboard().setContents(selection, EmptyClipboardOwner.INSTANCE);
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ IdeFocusManager.getInstance(myProject).requestFocus(myDefaultEditor.getComponent(), true);
+ }
+ });
+ }
+ }
+ };
+ focusComponent.addKeyListener(keyAdapter);
+ }
+ });
+ }
+ }
+
+ private void initializeTaskText(JPanel studyPanel, @Nullable String taskText) {
JTextPane taskTextPane = new JTextPane();
+ taskTextPane.addMouseListener(new CopyListener(taskTextPane));
taskTextPane.setContentType("text/html");
taskTextPane.setEditable(false);
taskTextPane.setText(taskText);
+ taskTextPane.addHyperlinkListener(new BrowserHyperlinkListener());
EditorColorsScheme editorColorsScheme = EditorColorsManager.getInstance().getGlobalScheme();
int fontSize = editorColorsScheme.getEditorFontSize();
String fontName = editorColorsScheme.getEditorFontName();
@@ -134,10 +193,10 @@ public class StudyEditor implements TextEditor {
private void initializeButtons(@NotNull final JPanel taskActionsPanel, @NotNull final TaskFile taskFile) {
myCheckButton = addButton(taskActionsPanel, "Check task", StudyIcons.Resolve);
myPrevTaskButton = addButton(taskActionsPanel, "Prev Task", StudyIcons.Prev);
- myNextTaskButton = addButton(taskActionsPanel, "Next Task", StudyIcons.Next);
- myRefreshButton = addButton(taskActionsPanel, "Start task again", StudyIcons.Refresh24);
+ myNextTaskButton = addButton(taskActionsPanel, "Next Task", AllIcons.Actions.Forward);
+ myRefreshButton = addButton(taskActionsPanel, "Start task again", AllIcons.Actions.Refresh);
if (!taskFile.getTask().getUserTests().isEmpty()) {
- JButton runButton = addButton(taskActionsPanel, "Run", StudyIcons.Run);
+ JButton runButton = addButton(taskActionsPanel, "Run", AllIcons.General.Run);
runButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
@@ -149,7 +208,8 @@ public class StudyEditor implements TextEditor {
watchInputButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
- StudyEditInputAction studyEditInputAction = (StudyEditInputAction)ActionManager.getInstance().getAction("WatchInputAction");
+ StudyEditInputAction studyEditInputAction =
+ (StudyEditInputAction)ActionManager.getInstance().getAction("WatchInputAction");
studyEditInputAction.showInput(myProject);
}
});
@@ -165,7 +225,8 @@ public class StudyEditor implements TextEditor {
myNextTaskButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
- StudyNextStudyTaskAction studyNextTaskAction = (StudyNextStudyTaskAction)ActionManager.getInstance().getAction("NextTaskAction");
+ StudyNextStudyTaskAction studyNextTaskAction =
+ (StudyNextStudyTaskAction)ActionManager.getInstance().getAction("NextTaskAction");
studyNextTaskAction.navigateTask(myProject);
}
});
@@ -180,7 +241,8 @@ public class StudyEditor implements TextEditor {
myRefreshButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
- StudyRefreshTaskAction studyRefreshTaskAction = (StudyRefreshTaskAction)ActionManager.getInstance().getAction("RefreshTaskAction");
+ StudyRefreshTaskFileAction studyRefreshTaskAction =
+ (StudyRefreshTaskFileAction)ActionManager.getInstance().getAction("RefreshTaskAction");
studyRefreshTaskAction.refresh(myProject);
}
});
@@ -300,7 +362,8 @@ public class StudyEditor implements TextEditor {
if (fileEditor instanceof StudyEditor) {
return (StudyEditor)fileEditor;
}
- } catch (Exception e) {
+ }
+ catch (Exception e) {
return null;
}
return null;
@@ -325,8 +388,9 @@ public class StudyEditor implements TextEditor {
@NotNull
@Override
public Editor getEditor() {
- if (myDefaultEditor instanceof TextEditor)
+ if (myDefaultEditor instanceof TextEditor) {
return ((TextEditor)myDefaultEditor).getEditor();
+ }
return EditorFactory.getInstance().createViewer(new DocumentImpl(""), myProject);
}
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/highlighting/StudyVisitorFilter.java b/python/edu/learn-python/src/com/jetbrains/python/edu/highlighting/StudyVisitorFilter.java
new file mode 100644
index 000000000000..dc7495adb16e
--- /dev/null
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/highlighting/StudyVisitorFilter.java
@@ -0,0 +1,18 @@
+package com.jetbrains.python.edu.highlighting;
+
+import com.intellij.psi.PsiFile;
+import com.jetbrains.python.edu.StudyTaskManager;
+import com.jetbrains.python.inspections.PythonVisitorFilter;
+import com.jetbrains.python.inspections.unresolvedReference.PyUnresolvedReferencesInspection;
+import org.jetbrains.annotations.NotNull;
+
+public class StudyVisitorFilter implements PythonVisitorFilter {
+ @Override
+ public boolean isSupported(@NotNull final Class visitorClass, @NotNull final PsiFile file) {
+ if (StudyTaskManager.getInstance(file.getProject()).getCourse() == null) return true;
+ if (visitorClass == PyUnresolvedReferencesInspection.class) {
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/projectView/StudyDirectoryNode.java b/python/edu/learn-python/src/com/jetbrains/python/edu/projectView/StudyDirectoryNode.java
index abf648c5c82a..2f80dba12695 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/projectView/StudyDirectoryNode.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/projectView/StudyDirectoryNode.java
@@ -32,7 +32,7 @@ public class StudyDirectoryNode extends PsiDirectoryNode {
@Override
protected void updateImpl(PresentationData data) {
- data.setIcon(StudyIcons.Unchecked);
+ data.setIcon(StudyIcons.Task);
String valueName = myValue.getName();
StudyTaskManager studyTaskManager = StudyTaskManager.getInstance(myProject);
Course course = studyTaskManager.getCourse();
@@ -41,7 +41,7 @@ public class StudyDirectoryNode extends PsiDirectoryNode {
}
if (valueName.equals(myProject.getName())) {
data.clearText();
- data.addText(course.getName(), new SimpleTextAttributes(SimpleTextAttributes.STYLE_BOLD, JBColor.BLUE));
+ data.addText(course.getName(), new SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN, JBColor.BLACK));
data.addText(" (" + valueName + ")", SimpleTextAttributes.GRAYED_ATTRIBUTES);
return;
}
@@ -91,15 +91,16 @@ public class StudyDirectoryNode extends PsiDirectoryNode {
StudyStatus taskStatus = stateful.getStatus();
switch (taskStatus) {
case Unchecked: {
- updatePresentation(data, additionalName, JBColor.blue, StudyIcons.Unchecked);
+ updatePresentation(data, additionalName, JBColor.BLACK, stateful instanceof Lesson ? StudyIcons.Lesson : StudyIcons.Task);
break;
}
case Solved: {
- updatePresentation(data, additionalName, new JBColor(new Color(0, 134, 0), new Color(98, 150, 85)), StudyIcons.Checked);
+ updatePresentation(data, additionalName, new JBColor(new Color(0, 134, 0), new Color(98, 150, 85)),
+ stateful instanceof Lesson ? StudyIcons.LessonCompl : StudyIcons.TaskCompl);
break;
}
case Failed: {
- updatePresentation(data, additionalName, JBColor.RED, StudyIcons.Failed);
+ updatePresentation(data, additionalName, JBColor.RED, stateful instanceof Lesson ? StudyIcons.Lesson : StudyIcons.TaskProbl);
}
}
}
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyNewProjectPanel.form b/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyNewProjectPanel.form
index 133c38d4e8f8..8dd6506d710c 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyNewProjectPanel.form
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyNewProjectPanel.form
@@ -39,11 +39,9 @@
</component>
</children>
</grid>
- <component id="6c40c" class="javax.swing.JLabel">
+ <component id="6c40c" class="javax.swing.JLabel" binding="myLabel">
<constraints>
- <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false">
- <preferred-size width="81" height="-1"/>
- </grid>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<font/>
@@ -67,9 +65,7 @@
</component>
<component id="f1e10" class="javax.swing.JButton" binding="myRefreshButton">
<constraints>
- <grid row="0" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false">
- <minimum-size width="30" height="23"/>
- </grid>
+ <grid row="0" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<hideActionText value="false"/>
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyNewProjectPanel.java b/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyNewProjectPanel.java
index 0f1ec08a8856..6edad63586f0 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyNewProjectPanel.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyNewProjectPanel.java
@@ -2,6 +2,7 @@ package com.jetbrains.python.edu.ui;
import com.intellij.facet.ui.FacetValidatorsManager;
import com.intellij.facet.ui.ValidationResult;
+import com.intellij.icons.AllIcons;
import com.intellij.openapi.fileChooser.FileChooser;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.vfs.VirtualFile;
@@ -9,7 +10,6 @@ import com.intellij.util.Consumer;
import com.jetbrains.python.edu.StudyDirectoryProjectGenerator;
import com.jetbrains.python.edu.StudyUtils;
import com.jetbrains.python.edu.course.CourseInfo;
-import icons.StudyIcons;
import javax.swing.*;
import java.awt.event.ActionEvent;
@@ -32,6 +32,7 @@ public class StudyNewProjectPanel{
private JPanel myContentPanel;
private JLabel myAuthorLabel;
private JLabel myDescriptionLabel;
+ private JLabel myLabel;
private final StudyDirectoryProjectGenerator myGenerator;
private static final String CONNECTION_ERROR = "<html>Failed to download courses.<br>Check your Internet connection.</html>";
private static final String INVALID_COURSE = "Selected course is invalid";
@@ -56,7 +57,9 @@ public class StudyNewProjectPanel{
}
initListeners();
myRefreshButton.setVisible(true);
- myRefreshButton.setIcon(StudyIcons.Refresh);
+ myRefreshButton.setIcon(AllIcons.Actions.Refresh);
+
+ myLabel.setPreferredSize(new JLabel("Project name").getPreferredSize());
}
private void initListeners() {
diff --git a/python/edu/main_pycharm_edu.iml b/python/edu/main_pycharm_edu.iml
index 12efe9b350d1..17f1d67a39da 100644
--- a/python/edu/main_pycharm_edu.iml
+++ b/python/edu/main_pycharm_edu.iml
@@ -16,6 +16,7 @@
<orderEntry type="module" module-name="ShortcutPromoter" />
<orderEntry type="module" module-name="python-educational" />
<orderEntry type="module" module-name="learn-python" />
+ <orderEntry type="module" module-name="course-creator" />
</component>
</module>
diff --git a/python/edu/resources/idea/PyCharmEduApplicationInfo.xml b/python/edu/resources/idea/PyCharmEduApplicationInfo.xml
index 0fdf0d48fd08..eed232dcd3c7 100644
--- a/python/edu/resources/idea/PyCharmEduApplicationInfo.xml
+++ b/python/edu/resources/idea/PyCharmEduApplicationInfo.xml
@@ -19,5 +19,5 @@
<feedback eap-url="http://www.jetbrains.com/feedback/feedback.jsp?product=PyCharm&amp;build=$BUILD&amp;timezone=$TIMEZONE&amp;eval=$EVAL"
release-url="http://www.jetbrains.com/feedback/feedback.jsp?product=PyCharm&amp;build=$BUILD&amp;timezone=$TIMEZONE&amp;eval=$EVAL"/>
- <help file="pycharmhelp.jar" root="pycharm"/>
+ <help file="pycharm-eduhelp.jar" root="pycharm"/>
</component>
diff --git a/python/edu/src/META-INF/PyCharmEduPlugin.xml b/python/edu/src/META-INF/PyCharmEduPlugin.xml
index d5b2fdfe8c28..87739a948968 100644
--- a/python/edu/src/META-INF/PyCharmEduPlugin.xml
+++ b/python/edu/src/META-INF/PyCharmEduPlugin.xml
@@ -19,6 +19,10 @@
</component>
</application-components>
+ <extensions defaultExtensionNs="com.intellij">
+ <codeInsight.lineMarkerProvider language="Python" implementationClass="com.jetbrains.python.edu.PyExecuteFileLineMarkerProvider"/>
+ </extensions>
+
<actions>
<group overrides="true" class="com.intellij.openapi.actionSystem.EmptyActionGroup" id="ToolsMenu"/>
@@ -38,5 +42,11 @@
<action overrides="true" class="com.intellij.openapi.actionSystem.EmptyAction" id="NewHtmlFile"/>
+ <group id="PyRunMenu">
+ <action id="runCurrentFile" class="com.jetbrains.python.edu.PyRunCurrentFileAction"/>
+ <add-to-group group-id="RunMenu" anchor="first"/>
+ </group>
+
+
</actions>
</idea-plugin>
diff --git a/python/edu/src/com/intellij/openapi/application/PyCharmEduConfigImportSettings.java b/python/edu/src/com/intellij/openapi/application/PyCharmEduConfigImportSettings.java
new file mode 100644
index 000000000000..989c750681f3
--- /dev/null
+++ b/python/edu/src/com/intellij/openapi/application/PyCharmEduConfigImportSettings.java
@@ -0,0 +1,12 @@
+package com.intellij.openapi.application;
+
+import com.intellij.ide.plugins.PluginManagerCore;
+
+// see com.intellij.openapi.application.ConfigImportHelper.getConfigImportSettings
+@SuppressWarnings("UnusedDeclaration")
+public class PyCharmEduConfigImportSettings extends ConfigImportSettings {
+ public PyCharmEduConfigImportSettings() {
+ PluginManagerCore.disablePlugin("org.jetbrains.plugins.coursecreator");
+ }
+
+}
diff --git a/python/edu/src/com/jetbrains/python/edu/PyCharmEduInitialConfigurator.java b/python/edu/src/com/jetbrains/python/edu/PyCharmEduInitialConfigurator.java
index ecf3d79a6424..2954f7c5b706 100644
--- a/python/edu/src/com/jetbrains/python/edu/PyCharmEduInitialConfigurator.java
+++ b/python/edu/src/com/jetbrains/python/edu/PyCharmEduInitialConfigurator.java
@@ -35,14 +35,15 @@ import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.keymap.Keymap;
import com.intellij.openapi.keymap.ex.KeymapManagerEx;
import com.intellij.openapi.keymap.impl.KeymapImpl;
+import com.intellij.openapi.project.DumbAwareRunnable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.project.ProjectManagerAdapter;
import com.intellij.openapi.project.ex.ProjectManagerEx;
+import com.intellij.openapi.startup.StartupManager;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.VfsUtil;
-import com.intellij.openapi.wm.ToolWindowEP;
-import com.intellij.openapi.wm.ToolWindowId;
-import com.intellij.openapi.wm.WindowManager;
+import com.intellij.openapi.wm.*;
import com.intellij.platform.DirectoryProjectConfigurator;
import com.intellij.platform.PlatformProjectViewOpener;
import com.intellij.psi.codeStyle.CodeStyleSettings;
@@ -62,9 +63,9 @@ import java.util.Set;
*/
@SuppressWarnings({"UtilityClassWithoutPrivateConstructor", "UtilityClassWithPublicConstructor"})
public class PyCharmEduInitialConfigurator {
- @NonNls private static final String DISPLAYED_PROPERTY = "PyCharm.initialConfigurationShown";
+ @NonNls private static final String DISPLAYED_PROPERTY = "PyCharmEDU.initialConfigurationShown";
- @NonNls private static final String CONFIGURED = "PyCharm.InitialConfiguration";
+ @NonNls private static final String CONFIGURED = "PyCharmEDU.InitialConfiguration";
public static class First {
@@ -93,6 +94,8 @@ public class PyCharmEduInitialConfigurator {
uiSettings.SHOW_MAIN_TOOLBAR = false;
codeInsightSettings.REFORMAT_ON_PASTE = CodeInsightSettings.NO_REFORMAT;
+ Registry.get("ide.new.settings.dialog").setValue(true);
+
GeneralSettings.getInstance().setShowTipsOnStartup(false);
EditorSettingsExternalizable.getInstance().setVirtualSpace(false);
@@ -113,7 +116,7 @@ public class PyCharmEduInitialConfigurator {
});
}
});
- PyCodeInsightSettings.getInstance().SHOW_IMPORT_POPUP = true;
+ PyCodeInsightSettings.getInstance().SHOW_IMPORT_POPUP = false;
}
if (!propertiesComponent.isValueSet(DISPLAYED_PROPERTY)) {
@@ -147,6 +150,29 @@ public class PyCharmEduInitialConfigurator {
}
patchProjectAreaExtensions(project);
+
+ StartupManager.getInstance(project).runWhenProjectIsInitialized(new DumbAwareRunnable() {
+ @Override
+ public void run() {
+ if (project.isDisposed()) return;
+
+ ToolWindowManager.getInstance(project).invokeLater(new Runnable() {
+ int count = 0;
+
+ public void run() {
+ if (project.isDisposed()) return;
+ if (count++ < 3) { // we need to call this after ToolWindowManagerImpl.registerToolWindowsFromBeans
+ ToolWindowManager.getInstance(project).invokeLater(this);
+ return;
+ }
+ ToolWindow toolWindow = ToolWindowManager.getInstance(project).getToolWindow("Project");
+ if (toolWindow.getType() != ToolWindowType.SLIDING) {
+ toolWindow.activate(null);
+ }
+ }
+ });
+ }
+ });
}
});
}
@@ -205,6 +231,11 @@ public class PyCharmEduInitialConfigurator {
private static void showInitialConfigurationDialog() {
final JFrame frame = WindowManager.getInstance().findVisibleFrame();
- new InitialConfigurationDialog(frame, "Python").show();
+ new InitialConfigurationDialog(frame, "Python") {
+ @Override
+ protected boolean canCreateLauncherScript() {
+ return false;
+ }
+ }.show();
}
}
diff --git a/python/edu/src/com/jetbrains/python/edu/PyExecuteFileLineMarkerProvider.java b/python/edu/src/com/jetbrains/python/edu/PyExecuteFileLineMarkerProvider.java
new file mode 100644
index 000000000000..03522bb8cf8a
--- /dev/null
+++ b/python/edu/src/com/jetbrains/python/edu/PyExecuteFileLineMarkerProvider.java
@@ -0,0 +1,91 @@
+package com.jetbrains.python.edu;
+
+import com.intellij.codeHighlighting.Pass;
+import com.intellij.codeInsight.daemon.GutterIconNavigationHandler;
+import com.intellij.codeInsight.daemon.LineMarkerInfo;
+import com.intellij.codeInsight.daemon.LineMarkerProvider;
+import com.intellij.execution.actions.ConfigurationContext;
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.DataManager;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.markup.GutterIconRenderer;
+import com.intellij.psi.PsiComment;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiWhiteSpace;
+import com.intellij.psi.util.PsiUtilBase;
+import com.intellij.util.Function;
+import com.jetbrains.python.psi.PyFile;
+import com.jetbrains.python.psi.PyImportStatement;
+import com.jetbrains.python.psi.PyStatement;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.awt.event.MouseEvent;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * @author traff
+ */
+public class PyExecuteFileLineMarkerProvider implements LineMarkerProvider {
+ @Nullable
+ @Override
+ public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement element) {
+ return null;
+ }
+
+ @Override
+ public void collectSlowLineMarkers(@NotNull List<PsiElement> elements, @NotNull Collection<LineMarkerInfo> result) {
+ for (PsiElement element : elements) {
+ if (isFirstCodeLine(element)) {
+ result.add(new LineMarkerInfo<PsiElement>(
+ element, element.getTextRange(), AllIcons.Actions.Execute, Pass.UPDATE_OVERRIDEN_MARKERS,
+ new Function<PsiElement, String>() {
+ @Override
+ public String fun(PsiElement e) {
+ return "Execute '" + e.getContainingFile().getName() + "'";
+ }
+ },
+ new GutterIconNavigationHandler<PsiElement>() {
+ @Override
+ public void navigate(MouseEvent e, PsiElement elt) {
+ executeCurrentScript(elt);
+ }
+ },
+ GutterIconRenderer.Alignment.RIGHT));
+ }
+ }
+ }
+
+ private static void executeCurrentScript(PsiElement elt) {
+ Editor editor = PsiUtilBase.findEditor(elt);
+ assert editor != null;
+
+ final ConfigurationContext context =
+ ConfigurationContext.getFromContext(DataManager.getInstance().getDataContext(editor.getComponent()));
+ PyRunCurrentFileAction.run(context);
+ }
+
+ private static boolean isFirstCodeLine(PsiElement element) {
+ return element instanceof PyStatement &&
+ element.getParent() instanceof PyFile &&
+ !isNothing(element) &&
+ nothingBefore(element);
+ }
+
+ private static boolean nothingBefore(PsiElement element) {
+ element = element.getPrevSibling();
+ while (element != null) {
+ if (!isNothing(element)) {
+ return false;
+ }
+ element = element.getPrevSibling();
+ }
+
+ return true;
+ }
+
+ private static boolean isNothing(PsiElement element) {
+ return (element instanceof PsiComment) || (element instanceof PyImportStatement) || (element instanceof PsiWhiteSpace);
+ }
+}
diff --git a/python/edu/src/com/jetbrains/python/edu/PyRunCurrentFileAction.java b/python/edu/src/com/jetbrains/python/edu/PyRunCurrentFileAction.java
new file mode 100644
index 000000000000..4d30fa29a3b3
--- /dev/null
+++ b/python/edu/src/com/jetbrains/python/edu/PyRunCurrentFileAction.java
@@ -0,0 +1,56 @@
+package com.jetbrains.python.edu;
+
+import com.intellij.execution.Location;
+import com.intellij.execution.RunManagerEx;
+import com.intellij.execution.RunnerAndConfigurationSettings;
+import com.intellij.execution.actions.ConfigurationContext;
+import com.intellij.execution.executors.DefaultRunExecutor;
+import com.intellij.execution.runners.ExecutionUtil;
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.Presentation;
+import com.jetbrains.python.PythonFileType;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author traff
+ */
+public class PyRunCurrentFileAction extends AnAction {
+ public PyRunCurrentFileAction() {
+ getTemplatePresentation().setIcon(AllIcons.Actions.Execute);
+ }
+
+ @Override
+ public void update(AnActionEvent e) {
+ Presentation presentation = e.getPresentation();
+ final ConfigurationContext context = ConfigurationContext.getFromContext(e.getDataContext());
+ Location location = context.getLocation();
+ if (location != null && location.getPsiElement().getContainingFile() != null && location.getPsiElement().getContainingFile().getFileType() == PythonFileType.INSTANCE) {
+ presentation.setEnabled(true);
+ presentation.setText("Run '" + location.getPsiElement().getContainingFile().getName() + "'");
+ }
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ final ConfigurationContext context = ConfigurationContext.getFromContext(e.getDataContext());
+
+ run(context);
+ }
+
+ public static void run(@NotNull ConfigurationContext context) {
+ RunnerAndConfigurationSettings configuration = context.findExisting();
+ final RunManagerEx runManager = (RunManagerEx)context.getRunManager();
+ if (configuration == null) {
+ configuration = context.getConfiguration();
+ if (configuration == null) {
+ return;
+ }
+ runManager.setTemporaryConfiguration(configuration);
+ }
+ runManager.setSelectedConfiguration(configuration);
+
+ ExecutionUtil.runConfiguration(configuration, DefaultRunExecutor.getRunExecutorInstance());
+ }
+}
diff --git a/python/helpers/pycharm/_bdd_utils.py b/python/helpers/pycharm/_bdd_utils.py
index 300feb286051..eea1bebf1654 100644
--- a/python/helpers/pycharm/_bdd_utils.py
+++ b/python/helpers/pycharm/_bdd_utils.py
@@ -15,6 +15,20 @@ import tcmessages
__author__ = 'Ilya.Kazakevich'
+def fix_win_drive(feature_path):
+ """
+ Workaround to fix issues like http://bugs.python.org/issue7195 on windows.
+ Pass feature dir or file path as argument.
+ This function does nothing on non-windows platforms, so it could be run safely.
+
+ :param feature_path: path to feature (c:/fe.feature or /my/features)
+ """
+ current_disk = (os.path.splitdrive(os.getcwd()))[0]
+ feature_disk = (os.path.splitdrive(feature_path))[0]
+ if current_disk and feature_disk and current_disk != feature_disk:
+ os.chdir(feature_disk)
+
+
def get_path_by_args(arguments):
"""
:type arguments list
diff --git a/python/helpers/pycharm/behave_runner.py b/python/helpers/pycharm/behave_runner.py
index 0ad83137adb6..2ec649ea7c1d 100644
--- a/python/helpers/pycharm/behave_runner.py
+++ b/python/helpers/pycharm/behave_runner.py
@@ -228,6 +228,8 @@ if __name__ == "__main__":
pass
command_args = list(filter(None, sys.argv[1:]))
+ if command_args:
+ _bdd_utils.fix_win_drive(command_args[0])
my_config = configuration.Configuration(command_args=command_args)
formatters.register_as(_Null, "com.intellij.python.null")
my_config.format = ["com.intellij.python.null"] # To prevent output to stdout
diff --git a/python/helpers/pycharm/lettuce_runner.py b/python/helpers/pycharm/lettuce_runner.py
index 3cd112540e5f..f0a4b5dbb873 100644
--- a/python/helpers/pycharm/lettuce_runner.py
+++ b/python/helpers/pycharm/lettuce_runner.py
@@ -109,4 +109,5 @@ class _LettuceRunner(_bdd_utils.BddRunner):
if __name__ == "__main__":
(base_dir, what_to_run) = _bdd_utils.get_path_by_args(sys.argv)
+ _bdd_utils.fix_win_drive(what_to_run)
_LettuceRunner(base_dir, what_to_run).run() \ No newline at end of file
diff --git a/python/helpers/pydev/README.md b/python/helpers/pydev/README.md
index 7b221164e66f..17df01ca8113 100644
--- a/python/helpers/pydev/README.md
+++ b/python/helpers/pydev/README.md
@@ -1,2 +1,9 @@
PyDev.Debugger
==============
+
+[![Build Status](https://travis-ci.org/fabioz/PyDev.Debugger.png)](https://travis-ci.org/fabioz/PyDev.Debugger)
+
+This repository contains the sources for the Debugger used in PyDev & PyCharm.
+
+It should be compatible with Python 2.4 onwards (as well as Jython 2.2.1, IronPython and PyPy -- and any
+other variant which properly supports the Python structure for debuggers -- i.e.: sys.settrace/threading.settrace). \ No newline at end of file
diff --git a/python/helpers/pydev/__init__.py b/python/helpers/pydev/__init__.py
deleted file mode 100644
index e69de29bb2d1..000000000000
--- a/python/helpers/pydev/__init__.py
+++ /dev/null
diff --git a/python/helpers/pydev/_pydev_BaseHTTPServer.py b/python/helpers/pydev/_pydev_BaseHTTPServer.py
deleted file mode 100644
index 1dcef2eeb67d..000000000000
--- a/python/helpers/pydev/_pydev_BaseHTTPServer.py
+++ /dev/null
@@ -1,604 +0,0 @@
-"""HTTP server base class.
-
-Note: the class in this module doesn't implement any HTTP request; see
-SimpleHTTPServer for simple implementations of GET, HEAD and POST
-(including CGI scripts). It does, however, optionally implement HTTP/1.1
-persistent connections, as of version 0.3.
-
-Contents:
-
-- BaseHTTPRequestHandler: HTTP request handler base class
-- test: test function
-
-XXX To do:
-
-- log requests even later (to capture byte count)
-- log user-agent header and other interesting goodies
-- send error log to separate file
-"""
-
-
-# See also:
-#
-# HTTP Working Group T. Berners-Lee
-# INTERNET-DRAFT R. T. Fielding
-# <draft-ietf-http-v10-spec-00.txt> H. Frystyk Nielsen
-# Expires September 8, 1995 March 8, 1995
-#
-# URL: http://www.ics.uci.edu/pub/ietf/http/draft-ietf-http-v10-spec-00.txt
-#
-# and
-#
-# Network Working Group R. Fielding
-# Request for Comments: 2616 et al
-# Obsoletes: 2068 June 1999
-# Category: Standards Track
-#
-# URL: http://www.faqs.org/rfcs/rfc2616.html
-
-# Log files
-# ---------
-#
-# Here's a quote from the NCSA httpd docs about log file format.
-#
-# | The logfile format is as follows. Each line consists of:
-# |
-# | host rfc931 authuser [DD/Mon/YYYY:hh:mm:ss] "request" ddd bbbb
-# |
-# | host: Either the DNS name or the IP number of the remote client
-# | rfc931: Any information returned by identd for this person,
-# | - otherwise.
-# | authuser: If user sent a userid for authentication, the user name,
-# | - otherwise.
-# | DD: Day
-# | Mon: Month (calendar name)
-# | YYYY: Year
-# | hh: hour (24-hour format, the machine's timezone)
-# | mm: minutes
-# | ss: seconds
-# | request: The first line of the HTTP request as sent by the client.
-# | ddd: the status code returned by the server, - if not available.
-# | bbbb: the total number of bytes sent,
-# | *not including the HTTP/1.0 header*, - if not available
-# |
-# | You can determine the name of the file accessed through request.
-#
-# (Actually, the latter is only true if you know the server configuration
-# at the time the request was made!)
-
-__version__ = "0.3"
-
-__all__ = ["HTTPServer", "BaseHTTPRequestHandler"]
-
-import sys
-import _pydev_time as time
-import _pydev_socket as socket # For gethostbyaddr()
-from warnings import filterwarnings, catch_warnings
-with catch_warnings():
- if sys.py3kwarning:
- filterwarnings("ignore", ".*mimetools has been removed",
- DeprecationWarning)
- import mimetools
-
-import _pydev_SocketServer as SocketServer
-
-# Default error message template
-DEFAULT_ERROR_MESSAGE = """\
-<head>
-<title>Error response</title>
-</head>
-<body>
-<h1>Error response</h1>
-<p>Error code %(code)d.
-<p>Message: %(message)s.
-<p>Error code explanation: %(code)s = %(explain)s.
-</body>
-"""
-
-DEFAULT_ERROR_CONTENT_TYPE = "text/html"
-
-def _quote_html(html):
- return html.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")
-
-class HTTPServer(SocketServer.TCPServer):
-
- allow_reuse_address = 1 # Seems to make sense in testing environment
-
- def server_bind(self):
- """Override server_bind to store the server name."""
- SocketServer.TCPServer.server_bind(self)
- host, port = self.socket.getsockname()[:2]
- self.server_name = socket.getfqdn(host)
- self.server_port = port
-
-
-class BaseHTTPRequestHandler(SocketServer.StreamRequestHandler):
-
- """HTTP request handler base class.
-
- The following explanation of HTTP serves to guide you through the
- code as well as to expose any misunderstandings I may have about
- HTTP (so you don't need to read the code to figure out I'm wrong
- :-).
-
- HTTP (HyperText Transfer Protocol) is an extensible protocol on
- top of a reliable stream transport (e.g. TCP/IP). The protocol
- recognizes three parts to a request:
-
- 1. One line identifying the request type and path
- 2. An optional set of RFC-822-style headers
- 3. An optional data part
-
- The headers and data are separated by a blank line.
-
- The first line of the request has the form
-
- <command> <path> <version>
-
- where <command> is a (case-sensitive) keyword such as GET or POST,
- <path> is a string containing path information for the request,
- and <version> should be the string "HTTP/1.0" or "HTTP/1.1".
- <path> is encoded using the URL encoding scheme (using %xx to signify
- the ASCII character with hex code xx).
-
- The specification specifies that lines are separated by CRLF but
- for compatibility with the widest range of clients recommends
- servers also handle LF. Similarly, whitespace in the request line
- is treated sensibly (allowing multiple spaces between components
- and allowing trailing whitespace).
-
- Similarly, for output, lines ought to be separated by CRLF pairs
- but most clients grok LF characters just fine.
-
- If the first line of the request has the form
-
- <command> <path>
-
- (i.e. <version> is left out) then this is assumed to be an HTTP
- 0.9 request; this form has no optional headers and data part and
- the reply consists of just the data.
-
- The reply form of the HTTP 1.x protocol again has three parts:
-
- 1. One line giving the response code
- 2. An optional set of RFC-822-style headers
- 3. The data
-
- Again, the headers and data are separated by a blank line.
-
- The response code line has the form
-
- <version> <responsecode> <responsestring>
-
- where <version> is the protocol version ("HTTP/1.0" or "HTTP/1.1"),
- <responsecode> is a 3-digit response code indicating success or
- failure of the request, and <responsestring> is an optional
- human-readable string explaining what the response code means.
-
- This server parses the request and the headers, and then calls a
- function specific to the request type (<command>). Specifically,
- a request SPAM will be handled by a method do_SPAM(). If no
- such method exists the server sends an error response to the
- client. If it exists, it is called with no arguments:
-
- do_SPAM()
-
- Note that the request name is case sensitive (i.e. SPAM and spam
- are different requests).
-
- The various request details are stored in instance variables:
-
- - client_address is the client IP address in the form (host,
- port);
-
- - command, path and version are the broken-down request line;
-
- - headers is an instance of mimetools.Message (or a derived
- class) containing the header information;
-
- - rfile is a file object open for reading positioned at the
- start of the optional input data part;
-
- - wfile is a file object open for writing.
-
- IT IS IMPORTANT TO ADHERE TO THE PROTOCOL FOR WRITING!
-
- The first thing to be written must be the response line. Then
- follow 0 or more header lines, then a blank line, and then the
- actual data (if any). The meaning of the header lines depends on
- the command executed by the server; in most cases, when data is
- returned, there should be at least one header line of the form
-
- Content-type: <type>/<subtype>
-
- where <type> and <subtype> should be registered MIME types,
- e.g. "text/html" or "text/plain".
-
- """
-
- # The Python system version, truncated to its first component.
- sys_version = "Python/" + sys.version.split()[0]
-
- # The server software version. You may want to override this.
- # The format is multiple whitespace-separated strings,
- # where each string is of the form name[/version].
- server_version = "BaseHTTP/" + __version__
-
- # The default request version. This only affects responses up until
- # the point where the request line is parsed, so it mainly decides what
- # the client gets back when sending a malformed request line.
- # Most web servers default to HTTP 0.9, i.e. don't send a status line.
- default_request_version = "HTTP/0.9"
-
- def parse_request(self):
- """Parse a request (internal).
-
- The request should be stored in self.raw_requestline; the results
- are in self.command, self.path, self.request_version and
- self.headers.
-
- Return True for success, False for failure; on failure, an
- error is sent back.
-
- """
- self.command = None # set in case of error on the first line
- self.request_version = version = self.default_request_version
- self.close_connection = 1
- requestline = self.raw_requestline
- requestline = requestline.rstrip('\r\n')
- self.requestline = requestline
- words = requestline.split()
- if len(words) == 3:
- command, path, version = words
- if version[:5] != 'HTTP/':
- self.send_error(400, "Bad request version (%r)" % version)
- return False
- try:
- base_version_number = version.split('/', 1)[1]
- version_number = base_version_number.split(".")
- # RFC 2145 section 3.1 says there can be only one "." and
- # - major and minor numbers MUST be treated as
- # separate integers;
- # - HTTP/2.4 is a lower version than HTTP/2.13, which in
- # turn is lower than HTTP/12.3;
- # - Leading zeros MUST be ignored by recipients.
- if len(version_number) != 2:
- raise ValueError
- version_number = int(version_number[0]), int(version_number[1])
- except (ValueError, IndexError):
- self.send_error(400, "Bad request version (%r)" % version)
- return False
- if version_number >= (1, 1) and self.protocol_version >= "HTTP/1.1":
- self.close_connection = 0
- if version_number >= (2, 0):
- self.send_error(505,
- "Invalid HTTP Version (%s)" % base_version_number)
- return False
- elif len(words) == 2:
- command, path = words
- self.close_connection = 1
- if command != 'GET':
- self.send_error(400,
- "Bad HTTP/0.9 request type (%r)" % command)
- return False
- elif not words:
- return False
- else:
- self.send_error(400, "Bad request syntax (%r)" % requestline)
- return False
- self.command, self.path, self.request_version = command, path, version
-
- # Examine the headers and look for a Connection directive
- self.headers = self.MessageClass(self.rfile, 0)
-
- conntype = self.headers.get('Connection', "")
- if conntype.lower() == 'close':
- self.close_connection = 1
- elif (conntype.lower() == 'keep-alive' and
- self.protocol_version >= "HTTP/1.1"):
- self.close_connection = 0
- return True
-
- def handle_one_request(self):
- """Handle a single HTTP request.
-
- You normally don't need to override this method; see the class
- __doc__ string for information on how to handle specific HTTP
- commands such as GET and POST.
-
- """
- try:
- self.raw_requestline = self.rfile.readline(65537)
- if len(self.raw_requestline) > 65536:
- self.requestline = ''
- self.request_version = ''
- self.command = ''
- self.send_error(414)
- return
- if not self.raw_requestline:
- self.close_connection = 1
- return
- if not self.parse_request():
- # An error code has been sent, just exit
- return
- mname = 'do_' + self.command
- if not hasattr(self, mname):
- self.send_error(501, "Unsupported method (%r)" % self.command)
- return
- method = getattr(self, mname)
- method()
- self.wfile.flush() #actually send the response if not already done.
- except socket.timeout:
- #a read or a write timed out. Discard this connection
- self.log_error("Request timed out: %r", sys.exc_info()[1])
- self.close_connection = 1
- return
-
- def handle(self):
- """Handle multiple requests if necessary."""
- self.close_connection = 1
-
- self.handle_one_request()
- while not self.close_connection:
- self.handle_one_request()
-
- def send_error(self, code, message=None):
- """Send and log an error reply.
-
- Arguments are the error code, and a detailed message.
- The detailed message defaults to the short entry matching the
- response code.
-
- This sends an error response (so it must be called before any
- output has been generated), logs the error, and finally sends
- a piece of HTML explaining the error to the user.
-
- """
-
- try:
- short, long = self.responses[code]
- except KeyError:
- short, long = '???', '???'
- if message is None:
- message = short
- explain = long
- self.log_error("code %d, message %s", code, message)
- # using _quote_html to prevent Cross Site Scripting attacks (see bug #1100201)
- content = (self.error_message_format %
- {'code': code, 'message': _quote_html(message), 'explain': explain})
- self.send_response(code, message)
- self.send_header("Content-Type", self.error_content_type)
- self.send_header('Connection', 'close')
- self.end_headers()
- if self.command != 'HEAD' and code >= 200 and code not in (204, 304):
- self.wfile.write(content)
-
- error_message_format = DEFAULT_ERROR_MESSAGE
- error_content_type = DEFAULT_ERROR_CONTENT_TYPE
-
- def send_response(self, code, message=None):
- """Send the response header and log the response code.
-
- Also send two standard headers with the server software
- version and the current date.
-
- """
- self.log_request(code)
- if message is None:
- if code in self.responses:
- message = self.responses[code][0]
- else:
- message = ''
- if self.request_version != 'HTTP/0.9':
- self.wfile.write("%s %d %s\r\n" %
- (self.protocol_version, code, message))
- # print (self.protocol_version, code, message)
- self.send_header('Server', self.version_string())
- self.send_header('Date', self.date_time_string())
-
- def send_header(self, keyword, value):
- """Send a MIME header."""
- if self.request_version != 'HTTP/0.9':
- self.wfile.write("%s: %s\r\n" % (keyword, value))
-
- if keyword.lower() == 'connection':
- if value.lower() == 'close':
- self.close_connection = 1
- elif value.lower() == 'keep-alive':
- self.close_connection = 0
-
- def end_headers(self):
- """Send the blank line ending the MIME headers."""
- if self.request_version != 'HTTP/0.9':
- self.wfile.write("\r\n")
-
- def log_request(self, code='-', size='-'):
- """Log an accepted request.
-
- This is called by send_response().
-
- """
-
- self.log_message('"%s" %s %s',
- self.requestline, str(code), str(size))
-
- def log_error(self, format, *args):
- """Log an error.
-
- This is called when a request cannot be fulfilled. By
- default it passes the message on to log_message().
-
- Arguments are the same as for log_message().
-
- XXX This should go to the separate error log.
-
- """
-
- self.log_message(format, *args)
-
- def log_message(self, format, *args):
- """Log an arbitrary message.
-
- This is used by all other logging functions. Override
- it if you have specific logging wishes.
-
- The first argument, FORMAT, is a format string for the
- message to be logged. If the format string contains
- any % escapes requiring parameters, they should be
- specified as subsequent arguments (it's just like
- printf!).
-
- The client host and current date/time are prefixed to
- every message.
-
- """
-
- sys.stderr.write("%s - - [%s] %s\n" %
- (self.address_string(),
- self.log_date_time_string(),
- format%args))
-
- def version_string(self):
- """Return the server software version string."""
- return self.server_version + ' ' + self.sys_version
-
- def date_time_string(self, timestamp=None):
- """Return the current date and time formatted for a message header."""
- if timestamp is None:
- timestamp = time.time()
- year, month, day, hh, mm, ss, wd, y, z = time.gmtime(timestamp)
- s = "%s, %02d %3s %4d %02d:%02d:%02d GMT" % (
- self.weekdayname[wd],
- day, self.monthname[month], year,
- hh, mm, ss)
- return s
-
- def log_date_time_string(self):
- """Return the current time formatted for logging."""
- now = time.time()
- year, month, day, hh, mm, ss, x, y, z = time.localtime(now)
- s = "%02d/%3s/%04d %02d:%02d:%02d" % (
- day, self.monthname[month], year, hh, mm, ss)
- return s
-
- weekdayname = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
-
- monthname = [None,
- 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
- 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
-
- def address_string(self):
- """Return the client address formatted for logging.
-
- This version looks up the full hostname using gethostbyaddr(),
- and tries to find a name that contains at least one dot.
-
- """
-
- host, port = self.client_address[:2]
- return socket.getfqdn(host)
-
- # Essentially static class variables
-
- # The version of the HTTP protocol we support.
- # Set this to HTTP/1.1 to enable automatic keepalive
- protocol_version = "HTTP/1.0"
-
- # The Message-like class used to parse headers
- MessageClass = mimetools.Message
-
- # Table mapping response codes to messages; entries have the
- # form {code: (shortmessage, longmessage)}.
- # See RFC 2616.
- responses = {
- 100: ('Continue', 'Request received, please continue'),
- 101: ('Switching Protocols',
- 'Switching to new protocol; obey Upgrade header'),
-
- 200: ('OK', 'Request fulfilled, document follows'),
- 201: ('Created', 'Document created, URL follows'),
- 202: ('Accepted',
- 'Request accepted, processing continues off-line'),
- 203: ('Non-Authoritative Information', 'Request fulfilled from cache'),
- 204: ('No Content', 'Request fulfilled, nothing follows'),
- 205: ('Reset Content', 'Clear input form for further input.'),
- 206: ('Partial Content', 'Partial content follows.'),
-
- 300: ('Multiple Choices',
- 'Object has several resources -- see URI list'),
- 301: ('Moved Permanently', 'Object moved permanently -- see URI list'),
- 302: ('Found', 'Object moved temporarily -- see URI list'),
- 303: ('See Other', 'Object moved -- see Method and URL list'),
- 304: ('Not Modified',
- 'Document has not changed since given time'),
- 305: ('Use Proxy',
- 'You must use proxy specified in Location to access this '
- 'resource.'),
- 307: ('Temporary Redirect',
- 'Object moved temporarily -- see URI list'),
-
- 400: ('Bad Request',
- 'Bad request syntax or unsupported method'),
- 401: ('Unauthorized',
- 'No permission -- see authorization schemes'),
- 402: ('Payment Required',
- 'No payment -- see charging schemes'),
- 403: ('Forbidden',
- 'Request forbidden -- authorization will not help'),
- 404: ('Not Found', 'Nothing matches the given URI'),
- 405: ('Method Not Allowed',
- 'Specified method is invalid for this resource.'),
- 406: ('Not Acceptable', 'URI not available in preferred format.'),
- 407: ('Proxy Authentication Required', 'You must authenticate with '
- 'this proxy before proceeding.'),
- 408: ('Request Timeout', 'Request timed out; try again later.'),
- 409: ('Conflict', 'Request conflict.'),
- 410: ('Gone',
- 'URI no longer exists and has been permanently removed.'),
- 411: ('Length Required', 'Client must specify Content-Length.'),
- 412: ('Precondition Failed', 'Precondition in headers is false.'),
- 413: ('Request Entity Too Large', 'Entity is too large.'),
- 414: ('Request-URI Too Long', 'URI is too long.'),
- 415: ('Unsupported Media Type', 'Entity body in unsupported format.'),
- 416: ('Requested Range Not Satisfiable',
- 'Cannot satisfy request range.'),
- 417: ('Expectation Failed',
- 'Expect condition could not be satisfied.'),
-
- 500: ('Internal Server Error', 'Server got itself in trouble'),
- 501: ('Not Implemented',
- 'Server does not support this operation'),
- 502: ('Bad Gateway', 'Invalid responses from another server/proxy.'),
- 503: ('Service Unavailable',
- 'The server cannot process the request due to a high load'),
- 504: ('Gateway Timeout',
- 'The gateway server did not receive a timely response'),
- 505: ('HTTP Version Not Supported', 'Cannot fulfill request.'),
- }
-
-
-def test(HandlerClass = BaseHTTPRequestHandler,
- ServerClass = HTTPServer, protocol="HTTP/1.0"):
- """Test the HTTP request handler class.
-
- This runs an HTTP server on port 8000 (or the first command line
- argument).
-
- """
-
- if sys.argv[1:]:
- port = int(sys.argv[1])
- else:
- port = 8000
- server_address = ('', port)
-
- HandlerClass.protocol_version = protocol
- httpd = ServerClass(server_address, HandlerClass)
-
- sa = httpd.socket.getsockname()
- print ("Serving HTTP on", sa[0], "port", sa[1], "...")
- httpd.serve_forever()
-
-
-if __name__ == '__main__':
- test()
diff --git a/python/helpers/pydev/_pydev_Queue.py b/python/helpers/pydev/_pydev_Queue.py
deleted file mode 100644
index cc32ea6932d6..000000000000
--- a/python/helpers/pydev/_pydev_Queue.py
+++ /dev/null
@@ -1,244 +0,0 @@
-"""A multi-producer, multi-consumer queue."""
-
-from _pydev_time import time as _time
-try:
- import _pydev_threading as _threading
-except ImportError:
- import dummy_threading as _threading
-from collections import deque
-import heapq
-
-__all__ = ['Empty', 'Full', 'Queue', 'PriorityQueue', 'LifoQueue']
-
-class Empty(Exception):
- "Exception raised by Queue.get(block=0)/get_nowait()."
- pass
-
-class Full(Exception):
- "Exception raised by Queue.put(block=0)/put_nowait()."
- pass
-
-class Queue:
- """Create a queue object with a given maximum size.
-
- If maxsize is <= 0, the queue size is infinite.
- """
- def __init__(self, maxsize=0):
- self.maxsize = maxsize
- self._init(maxsize)
- # mutex must be held whenever the queue is mutating. All methods
- # that acquire mutex must release it before returning. mutex
- # is shared between the three conditions, so acquiring and
- # releasing the conditions also acquires and releases mutex.
- self.mutex = _threading.Lock()
- # Notify not_empty whenever an item is added to the queue; a
- # thread waiting to get is notified then.
- self.not_empty = _threading.Condition(self.mutex)
- # Notify not_full whenever an item is removed from the queue;
- # a thread waiting to put is notified then.
- self.not_full = _threading.Condition(self.mutex)
- # Notify all_tasks_done whenever the number of unfinished tasks
- # drops to zero; thread waiting to join() is notified to resume
- self.all_tasks_done = _threading.Condition(self.mutex)
- self.unfinished_tasks = 0
-
- def task_done(self):
- """Indicate that a formerly enqueued task is complete.
-
- Used by Queue consumer threads. For each get() used to fetch a task,
- a subsequent call to task_done() tells the queue that the processing
- on the task is complete.
-
- If a join() is currently blocking, it will resume when all items
- have been processed (meaning that a task_done() call was received
- for every item that had been put() into the queue).
-
- Raises a ValueError if called more times than there were items
- placed in the queue.
- """
- self.all_tasks_done.acquire()
- try:
- unfinished = self.unfinished_tasks - 1
- if unfinished <= 0:
- if unfinished < 0:
- raise ValueError('task_done() called too many times')
- self.all_tasks_done.notify_all()
- self.unfinished_tasks = unfinished
- finally:
- self.all_tasks_done.release()
-
- def join(self):
- """Blocks until all items in the Queue have been gotten and processed.
-
- The count of unfinished tasks goes up whenever an item is added to the
- queue. The count goes down whenever a consumer thread calls task_done()
- to indicate the item was retrieved and all work on it is complete.
-
- When the count of unfinished tasks drops to zero, join() unblocks.
- """
- self.all_tasks_done.acquire()
- try:
- while self.unfinished_tasks:
- self.all_tasks_done.wait()
- finally:
- self.all_tasks_done.release()
-
- def qsize(self):
- """Return the approximate size of the queue (not reliable!)."""
- self.mutex.acquire()
- n = self._qsize()
- self.mutex.release()
- return n
-
- def empty(self):
- """Return True if the queue is empty, False otherwise (not reliable!)."""
- self.mutex.acquire()
- n = not self._qsize()
- self.mutex.release()
- return n
-
- def full(self):
- """Return True if the queue is full, False otherwise (not reliable!)."""
- self.mutex.acquire()
- n = 0 < self.maxsize == self._qsize()
- self.mutex.release()
- return n
-
- def put(self, item, block=True, timeout=None):
- """Put an item into the queue.
-
- If optional args 'block' is true and 'timeout' is None (the default),
- block if necessary until a free slot is available. If 'timeout' is
- a positive number, it blocks at most 'timeout' seconds and raises
- the Full exception if no free slot was available within that time.
- Otherwise ('block' is false), put an item on the queue if a free slot
- is immediately available, else raise the Full exception ('timeout'
- is ignored in that case).
- """
- self.not_full.acquire()
- try:
- if self.maxsize > 0:
- if not block:
- if self._qsize() == self.maxsize:
- raise Full
- elif timeout is None:
- while self._qsize() == self.maxsize:
- self.not_full.wait()
- elif timeout < 0:
- raise ValueError("'timeout' must be a positive number")
- else:
- endtime = _time() + timeout
- while self._qsize() == self.maxsize:
- remaining = endtime - _time()
- if remaining <= 0.0:
- raise Full
- self.not_full.wait(remaining)
- self._put(item)
- self.unfinished_tasks += 1
- self.not_empty.notify()
- finally:
- self.not_full.release()
-
- def put_nowait(self, item):
- """Put an item into the queue without blocking.
-
- Only enqueue the item if a free slot is immediately available.
- Otherwise raise the Full exception.
- """
- return self.put(item, False)
-
- def get(self, block=True, timeout=None):
- """Remove and return an item from the queue.
-
- If optional args 'block' is true and 'timeout' is None (the default),
- block if necessary until an item is available. If 'timeout' is
- a positive number, it blocks at most 'timeout' seconds and raises
- the Empty exception if no item was available within that time.
- Otherwise ('block' is false), return an item if one is immediately
- available, else raise the Empty exception ('timeout' is ignored
- in that case).
- """
- self.not_empty.acquire()
- try:
- if not block:
- if not self._qsize():
- raise Empty
- elif timeout is None:
- while not self._qsize():
- self.not_empty.wait()
- elif timeout < 0:
- raise ValueError("'timeout' must be a positive number")
- else:
- endtime = _time() + timeout
- while not self._qsize():
- remaining = endtime - _time()
- if remaining <= 0.0:
- raise Empty
- self.not_empty.wait(remaining)
- item = self._get()
- self.not_full.notify()
- return item
- finally:
- self.not_empty.release()
-
- def get_nowait(self):
- """Remove and return an item from the queue without blocking.
-
- Only get an item if one is immediately available. Otherwise
- raise the Empty exception.
- """
- return self.get(False)
-
- # Override these methods to implement other queue organizations
- # (e.g. stack or priority queue).
- # These will only be called with appropriate locks held
-
- # Initialize the queue representation
- def _init(self, maxsize):
- self.queue = deque()
-
- def _qsize(self, len=len):
- return len(self.queue)
-
- # Put a new item in the queue
- def _put(self, item):
- self.queue.append(item)
-
- # Get an item from the queue
- def _get(self):
- return self.queue.popleft()
-
-
-class PriorityQueue(Queue):
- '''Variant of Queue that retrieves open entries in priority order (lowest first).
-
- Entries are typically tuples of the form: (priority number, data).
- '''
-
- def _init(self, maxsize):
- self.queue = []
-
- def _qsize(self, len=len):
- return len(self.queue)
-
- def _put(self, item, heappush=heapq.heappush):
- heappush(self.queue, item)
-
- def _get(self, heappop=heapq.heappop):
- return heappop(self.queue)
-
-
-class LifoQueue(Queue):
- '''Variant of Queue that retrieves most recently added entries first.'''
-
- def _init(self, maxsize):
- self.queue = []
-
- def _qsize(self, len=len):
- return len(self.queue)
-
- def _put(self, item):
- self.queue.append(item)
-
- def _get(self):
- return self.queue.pop()
diff --git a/python/helpers/pydev/_pydev_SimpleXMLRPCServer.py b/python/helpers/pydev/_pydev_SimpleXMLRPCServer.py
deleted file mode 100644
index c7da5b7fecdf..000000000000
--- a/python/helpers/pydev/_pydev_SimpleXMLRPCServer.py
+++ /dev/null
@@ -1,610 +0,0 @@
-#Just a copy of the version in python 2.5 to be used if it's not available in jython 2.1
-
-"""Simple XML-RPC Server.
-
-This module can be used to create simple XML-RPC servers
-by creating a server and either installing functions, a
-class instance, or by extending the SimpleXMLRPCServer
-class.
-
-It can also be used to handle XML-RPC requests in a CGI
-environment using CGIXMLRPCRequestHandler.
-
-A list of possible usage patterns follows:
-
-1. Install functions:
-
-server = SimpleXMLRPCServer(("localhost", 8000))
-server.register_function(pow)
-server.register_function(lambda x,y: x+y, 'add')
-server.serve_forever()
-
-2. Install an instance:
-
-class MyFuncs:
- def __init__(self):
- # make all of the string functions available through
- # string.func_name
- import string
- self.string = string
- def _listMethods(self):
- # implement this method so that system.listMethods
- # knows to advertise the strings methods
- return list_public_methods(self) + \
- ['string.' + method for method in list_public_methods(self.string)]
- def pow(self, x, y): return pow(x, y)
- def add(self, x, y) : return x + y
-
-server = SimpleXMLRPCServer(("localhost", 8000))
-server.register_introspection_functions()
-server.register_instance(MyFuncs())
-server.serve_forever()
-
-3. Install an instance with custom dispatch method:
-
-class Math:
- def _listMethods(self):
- # this method must be present for system.listMethods
- # to work
- return ['add', 'pow']
- def _methodHelp(self, method):
- # this method must be present for system.methodHelp
- # to work
- if method == 'add':
- return "add(2,3) => 5"
- elif method == 'pow':
- return "pow(x, y[, z]) => number"
- else:
- # By convention, return empty
- # string if no help is available
- return ""
- def _dispatch(self, method, params):
- if method == 'pow':
- return pow(*params)
- elif method == 'add':
- return params[0] + params[1]
- else:
- raise 'bad method'
-
-server = SimpleXMLRPCServer(("localhost", 8000))
-server.register_introspection_functions()
-server.register_instance(Math())
-server.serve_forever()
-
-4. Subclass SimpleXMLRPCServer:
-
-class MathServer(SimpleXMLRPCServer):
- def _dispatch(self, method, params):
- try:
- # We are forcing the 'export_' prefix on methods that are
- # callable through XML-RPC to prevent potential security
- # problems
- func = getattr(self, 'export_' + method)
- except AttributeError:
- raise Exception('method "%s" is not supported' % method)
- else:
- return func(*params)
-
- def export_add(self, x, y):
- return x + y
-
-server = MathServer(("localhost", 8000))
-server.serve_forever()
-
-5. CGI script:
-
-server = CGIXMLRPCRequestHandler()
-server.register_function(pow)
-server.handle_request()
-"""
-
-# Written by Brian Quinlan (brian@sweetapp.com).
-# Based on code written by Fredrik Lundh.
-
-try:
- True
- False
-except:
- import __builtin__
- setattr(__builtin__, 'True', 1) #Python 3.0 does not accept __builtin__.True = 1 in its syntax
- setattr(__builtin__, 'False', 0)
-
-
-import _pydev_xmlrpclib as xmlrpclib
-from _pydev_xmlrpclib import Fault
-import _pydev_SocketServer as SocketServer
-import _pydev_BaseHTTPServer as BaseHTTPServer
-import sys
-import os
-try:
- import fcntl
-except ImportError:
- fcntl = None
-
-def resolve_dotted_attribute(obj, attr, allow_dotted_names=True):
- """resolve_dotted_attribute(a, 'b.c.d') => a.b.c.d
-
- Resolves a dotted attribute name to an object. Raises
- an AttributeError if any attribute in the chain starts with a '_'.
-
- If the optional allow_dotted_names argument is false, dots are not
- supported and this function operates similar to getattr(obj, attr).
- """
-
- if allow_dotted_names:
- attrs = attr.split('.')
- else:
- attrs = [attr]
-
- for i in attrs:
- if i.startswith('_'):
- raise AttributeError(
- 'attempt to access private attribute "%s"' % i
- )
- else:
- obj = getattr(obj, i)
- return obj
-
-def list_public_methods(obj):
- """Returns a list of attribute strings, found in the specified
- object, which represent callable attributes"""
-
- return [member for member in dir(obj)
- if not member.startswith('_') and
- callable(getattr(obj, member))]
-
-def remove_duplicates(lst):
- """remove_duplicates([2,2,2,1,3,3]) => [3,1,2]
-
- Returns a copy of a list without duplicates. Every list
- item must be hashable and the order of the items in the
- resulting list is not defined.
- """
- u = {}
- for x in lst:
- u[x] = 1
-
- return u.keys()
-
-class SimpleXMLRPCDispatcher:
- """Mix-in class that dispatches XML-RPC requests.
-
- This class is used to register XML-RPC method handlers
- and then to dispatch them. There should never be any
- reason to instantiate this class directly.
- """
-
- def __init__(self, allow_none, encoding):
- self.funcs = {}
- self.instance = None
- self.allow_none = allow_none
- self.encoding = encoding
-
- def register_instance(self, instance, allow_dotted_names=False):
- """Registers an instance to respond to XML-RPC requests.
-
- Only one instance can be installed at a time.
-
- If the registered instance has a _dispatch method then that
- method will be called with the name of the XML-RPC method and
- its parameters as a tuple
- e.g. instance._dispatch('add',(2,3))
-
- If the registered instance does not have a _dispatch method
- then the instance will be searched to find a matching method
- and, if found, will be called. Methods beginning with an '_'
- are considered private and will not be called by
- SimpleXMLRPCServer.
-
- If a registered function matches a XML-RPC request, then it
- will be called instead of the registered instance.
-
- If the optional allow_dotted_names argument is true and the
- instance does not have a _dispatch method, method names
- containing dots are supported and resolved, as long as none of
- the name segments start with an '_'.
-
- *** SECURITY WARNING: ***
-
- Enabling the allow_dotted_names options allows intruders
- to access your module's global variables and may allow
- intruders to execute arbitrary code on your machine. Only
- use this option on a secure, closed network.
-
- """
-
- self.instance = instance
- self.allow_dotted_names = allow_dotted_names
-
- def register_function(self, function, name=None):
- """Registers a function to respond to XML-RPC requests.
-
- The optional name argument can be used to set a Unicode name
- for the function.
- """
-
- if name is None:
- name = function.__name__
- self.funcs[name] = function
-
- def register_introspection_functions(self):
- """Registers the XML-RPC introspection methods in the system
- namespace.
-
- see http://xmlrpc.usefulinc.com/doc/reserved.html
- """
-
- self.funcs.update({'system.listMethods' : self.system_listMethods,
- 'system.methodSignature' : self.system_methodSignature,
- 'system.methodHelp' : self.system_methodHelp})
-
- def register_multicall_functions(self):
- """Registers the XML-RPC multicall method in the system
- namespace.
-
- see http://www.xmlrpc.com/discuss/msgReader$1208"""
-
- self.funcs.update({'system.multicall' : self.system_multicall})
-
- def _marshaled_dispatch(self, data, dispatch_method=None):
- """Dispatches an XML-RPC method from marshalled (XML) data.
-
- XML-RPC methods are dispatched from the marshalled (XML) data
- using the _dispatch method and the result is returned as
- marshalled data. For backwards compatibility, a dispatch
- function can be provided as an argument (see comment in
- SimpleXMLRPCRequestHandler.do_POST) but overriding the
- existing method through subclassing is the prefered means
- of changing method dispatch behavior.
- """
- try:
- params, method = xmlrpclib.loads(data)
-
- # generate response
- if dispatch_method is not None:
- response = dispatch_method(method, params)
- else:
- response = self._dispatch(method, params)
- # wrap response in a singleton tuple
- response = (response,)
- response = xmlrpclib.dumps(response, methodresponse=1,
- allow_none=self.allow_none, encoding=self.encoding)
- except Fault, fault:
- response = xmlrpclib.dumps(fault, allow_none=self.allow_none,
- encoding=self.encoding)
- except:
- # report exception back to server
- response = xmlrpclib.dumps(
- xmlrpclib.Fault(1, "%s:%s" % (sys.exc_type, sys.exc_value)), #@UndefinedVariable exc_value only available when we actually have an exception
- encoding=self.encoding, allow_none=self.allow_none,
- )
-
- return response
-
- def system_listMethods(self):
- """system.listMethods() => ['add', 'subtract', 'multiple']
-
- Returns a list of the methods supported by the server."""
-
- methods = self.funcs.keys()
- if self.instance is not None:
- # Instance can implement _listMethod to return a list of
- # methods
- if hasattr(self.instance, '_listMethods'):
- methods = remove_duplicates(
- methods + self.instance._listMethods()
- )
- # if the instance has a _dispatch method then we
- # don't have enough information to provide a list
- # of methods
- elif not hasattr(self.instance, '_dispatch'):
- methods = remove_duplicates(
- methods + list_public_methods(self.instance)
- )
- methods.sort()
- return methods
-
- def system_methodSignature(self, method_name):
- """system.methodSignature('add') => [double, int, int]
-
- Returns a list describing the signature of the method. In the
- above example, the add method takes two integers as arguments
- and returns a double result.
-
- This server does NOT support system.methodSignature."""
-
- # See http://xmlrpc.usefulinc.com/doc/sysmethodsig.html
-
- return 'signatures not supported'
-
- def system_methodHelp(self, method_name):
- """system.methodHelp('add') => "Adds two integers together"
-
- Returns a string containing documentation for the specified method."""
-
- method = None
- if self.funcs.has_key(method_name):
- method = self.funcs[method_name]
- elif self.instance is not None:
- # Instance can implement _methodHelp to return help for a method
- if hasattr(self.instance, '_methodHelp'):
- return self.instance._methodHelp(method_name)
- # if the instance has a _dispatch method then we
- # don't have enough information to provide help
- elif not hasattr(self.instance, '_dispatch'):
- try:
- method = resolve_dotted_attribute(
- self.instance,
- method_name,
- self.allow_dotted_names
- )
- except AttributeError:
- pass
-
- # Note that we aren't checking that the method actually
- # be a callable object of some kind
- if method is None:
- return ""
- else:
- try:
- import pydoc
- except ImportError:
- return "" #not there for jython
- else:
- return pydoc.getdoc(method)
-
- def system_multicall(self, call_list):
- """system.multicall([{'methodName': 'add', 'params': [2, 2]}, ...]) => \
-[[4], ...]
-
- Allows the caller to package multiple XML-RPC calls into a single
- request.
-
- See http://www.xmlrpc.com/discuss/msgReader$1208
- """
-
- results = []
- for call in call_list:
- method_name = call['methodName']
- params = call['params']
-
- try:
- # XXX A marshalling error in any response will fail the entire
- # multicall. If someone cares they should fix this.
- results.append([self._dispatch(method_name, params)])
- except Fault, fault:
- results.append(
- {'faultCode' : fault.faultCode,
- 'faultString' : fault.faultString}
- )
- except:
- results.append(
- {'faultCode' : 1,
- 'faultString' : "%s:%s" % (sys.exc_type, sys.exc_value)} #@UndefinedVariable exc_value only available when we actually have an exception
- )
- return results
-
- def _dispatch(self, method, params):
- """Dispatches the XML-RPC method.
-
- XML-RPC calls are forwarded to a registered function that
- matches the called XML-RPC method name. If no such function
- exists then the call is forwarded to the registered instance,
- if available.
-
- If the registered instance has a _dispatch method then that
- method will be called with the name of the XML-RPC method and
- its parameters as a tuple
- e.g. instance._dispatch('add',(2,3))
-
- If the registered instance does not have a _dispatch method
- then the instance will be searched to find a matching method
- and, if found, will be called.
-
- Methods beginning with an '_' are considered private and will
- not be called.
- """
-
- func = None
- try:
- # check to see if a matching function has been registered
- func = self.funcs[method]
- except KeyError:
- if self.instance is not None:
- # check for a _dispatch method
- if hasattr(self.instance, '_dispatch'):
- return self.instance._dispatch(method, params)
- else:
- # call instance method directly
- try:
- func = resolve_dotted_attribute(
- self.instance,
- method,
- self.allow_dotted_names
- )
- except AttributeError:
- pass
-
- if func is not None:
- return func(*params)
- else:
- raise Exception('method "%s" is not supported' % method)
-
-class SimpleXMLRPCRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
- """Simple XML-RPC request handler class.
-
- Handles all HTTP POST requests and attempts to decode them as
- XML-RPC requests.
- """
-
- # Class attribute listing the accessible path components;
- # paths not on this list will result in a 404 error.
- rpc_paths = ('/', '/RPC2')
-
- def is_rpc_path_valid(self):
- if self.rpc_paths:
- return self.path in self.rpc_paths
- else:
- # If .rpc_paths is empty, just assume all paths are legal
- return True
-
- def do_POST(self):
- """Handles the HTTP POST request.
-
- Attempts to interpret all HTTP POST requests as XML-RPC calls,
- which are forwarded to the server's _dispatch method for handling.
- """
-
- # Check that the path is legal
- if not self.is_rpc_path_valid():
- self.report_404()
- return
-
- try:
- # Get arguments by reading body of request.
- # We read this in chunks to avoid straining
- # socket.read(); around the 10 or 15Mb mark, some platforms
- # begin to have problems (bug #792570).
- max_chunk_size = 10 * 1024 * 1024
- size_remaining = int(self.headers["content-length"])
- L = []
- while size_remaining:
- chunk_size = min(size_remaining, max_chunk_size)
- L.append(self.rfile.read(chunk_size))
- size_remaining -= len(L[-1])
- data = ''.join(L)
-
- # In previous versions of SimpleXMLRPCServer, _dispatch
- # could be overridden in this class, instead of in
- # SimpleXMLRPCDispatcher. To maintain backwards compatibility,
- # check to see if a subclass implements _dispatch and dispatch
- # using that method if present.
- response = self.server._marshaled_dispatch(
- data, getattr(self, '_dispatch', None)
- )
- except: # This should only happen if the module is buggy
- # internal error, report as HTTP server error
- self.send_response(500)
- self.end_headers()
- else:
- # got a valid XML RPC response
- self.send_response(200)
- self.send_header("Content-type", "text/xml")
- self.send_header("Content-length", str(len(response)))
- self.end_headers()
- self.wfile.write(response)
-
- # shut down the connection
- self.wfile.flush()
- self.connection.shutdown(1)
-
- def report_404 (self):
- # Report a 404 error
- self.send_response(404)
- response = 'No such page'
- self.send_header("Content-type", "text/plain")
- self.send_header("Content-length", str(len(response)))
- self.end_headers()
- self.wfile.write(response)
- # shut down the connection
- self.wfile.flush()
- self.connection.shutdown(1)
-
- def log_request(self, code='-', size='-'):
- """Selectively log an accepted request."""
-
- if self.server.logRequests:
- BaseHTTPServer.BaseHTTPRequestHandler.log_request(self, code, size)
-
-class SimpleXMLRPCServer(SocketServer.TCPServer,
- SimpleXMLRPCDispatcher):
- """Simple XML-RPC server.
-
- Simple XML-RPC server that allows functions and a single instance
- to be installed to handle requests. The default implementation
- attempts to dispatch XML-RPC calls to the functions or instance
- installed in the server. Override the _dispatch method inhereted
- from SimpleXMLRPCDispatcher to change this behavior.
- """
-
- allow_reuse_address = True
-
- def __init__(self, addr, requestHandler=SimpleXMLRPCRequestHandler,
- logRequests=True, allow_none=False, encoding=None):
- self.logRequests = logRequests
-
- SimpleXMLRPCDispatcher.__init__(self, allow_none, encoding)
- SocketServer.TCPServer.__init__(self, addr, requestHandler)
-
- # [Bug #1222790] If possible, set close-on-exec flag; if a
- # method spawns a subprocess, the subprocess shouldn't have
- # the listening socket open.
- if fcntl is not None and hasattr(fcntl, 'FD_CLOEXEC'):
- flags = fcntl.fcntl(self.fileno(), fcntl.F_GETFD)
- flags |= fcntl.FD_CLOEXEC
- fcntl.fcntl(self.fileno(), fcntl.F_SETFD, flags)
-
-class CGIXMLRPCRequestHandler(SimpleXMLRPCDispatcher):
- """Simple handler for XML-RPC data passed through CGI."""
-
- def __init__(self, allow_none=False, encoding=None):
- SimpleXMLRPCDispatcher.__init__(self, allow_none, encoding)
-
- def handle_xmlrpc(self, request_text):
- """Handle a single XML-RPC request"""
-
- response = self._marshaled_dispatch(request_text)
-
- sys.stdout.write('Content-Type: text/xml\n')
- sys.stdout.write('Content-Length: %d\n' % len(response))
- sys.stdout.write('\n')
-
- sys.stdout.write(response)
-
- def handle_get(self):
- """Handle a single HTTP GET request.
-
- Default implementation indicates an error because
- XML-RPC uses the POST method.
- """
-
- code = 400
- message, explain = \
- BaseHTTPServer.BaseHTTPRequestHandler.responses[code]
-
- response = BaseHTTPServer.DEFAULT_ERROR_MESSAGE % { #@UndefinedVariable
- 'code' : code,
- 'message' : message,
- 'explain' : explain
- }
- sys.stdout.write('Status: %d %s\n' % (code, message))
- sys.stdout.write('Content-Type: text/html\n')
- sys.stdout.write('Content-Length: %d\n' % len(response))
- sys.stdout.write('\n')
-
- sys.stdout.write(response)
-
- def handle_request(self, request_text=None):
- """Handle a single XML-RPC request passed through a CGI post method.
-
- If no XML data is given then it is read from stdin. The resulting
- XML-RPC response is printed to stdout along with the correct HTTP
- headers.
- """
-
- if request_text is None and \
- os.environ.get('REQUEST_METHOD', None) == 'GET':
- self.handle_get()
- else:
- # POST data is normally available through stdin
- if request_text is None:
- request_text = sys.stdin.read()
-
- self.handle_xmlrpc(request_text)
-
-if __name__ == '__main__':
- sys.stdout.write('Running XML-RPC server on port 8000\n')
- server = SimpleXMLRPCServer(("localhost", 8000))
- server.register_function(pow)
- server.register_function(lambda x, y: x + y, 'add')
- server.serve_forever()
diff --git a/python/helpers/pydev/_pydev_SocketServer.py b/python/helpers/pydev/_pydev_SocketServer.py
deleted file mode 100644
index c61112613a84..000000000000
--- a/python/helpers/pydev/_pydev_SocketServer.py
+++ /dev/null
@@ -1,715 +0,0 @@
-"""Generic socket server classes.
-
-This module tries to capture the various aspects of defining a server:
-
-For socket-based servers:
-
-- address family:
- - AF_INET{,6}: IP (Internet Protocol) sockets (default)
- - AF_UNIX: Unix domain sockets
- - others, e.g. AF_DECNET are conceivable (see <socket.h>
-- socket type:
- - SOCK_STREAM (reliable stream, e.g. TCP)
- - SOCK_DGRAM (datagrams, e.g. UDP)
-
-For request-based servers (including socket-based):
-
-- client address verification before further looking at the request
- (This is actually a hook for any processing that needs to look
- at the request before anything else, e.g. logging)
-- how to handle multiple requests:
- - synchronous (one request is handled at a time)
- - forking (each request is handled by a new process)
- - threading (each request is handled by a new thread)
-
-The classes in this module favor the server type that is simplest to
-write: a synchronous TCP/IP server. This is bad class design, but
-save some typing. (There's also the issue that a deep class hierarchy
-slows down method lookups.)
-
-There are five classes in an inheritance diagram, four of which represent
-synchronous servers of four types:
-
- +------------+
- | BaseServer |
- +------------+
- |
- v
- +-----------+ +------------------+
- | TCPServer |------->| UnixStreamServer |
- +-----------+ +------------------+
- |
- v
- +-----------+ +--------------------+
- | UDPServer |------->| UnixDatagramServer |
- +-----------+ +--------------------+
-
-Note that UnixDatagramServer derives from UDPServer, not from
-UnixStreamServer -- the only difference between an IP and a Unix
-stream server is the address family, which is simply repeated in both
-unix server classes.
-
-Forking and threading versions of each type of server can be created
-using the ForkingMixIn and ThreadingMixIn mix-in classes. For
-instance, a threading UDP server class is created as follows:
-
- class ThreadingUDPServer(ThreadingMixIn, UDPServer): pass
-
-The Mix-in class must come first, since it overrides a method defined
-in UDPServer! Setting the various member variables also changes
-the behavior of the underlying server mechanism.
-
-To implement a service, you must derive a class from
-BaseRequestHandler and redefine its handle() method. You can then run
-various versions of the service by combining one of the server classes
-with your request handler class.
-
-The request handler class must be different for datagram or stream
-services. This can be hidden by using the request handler
-subclasses StreamRequestHandler or DatagramRequestHandler.
-
-Of course, you still have to use your head!
-
-For instance, it makes no sense to use a forking server if the service
-contains state in memory that can be modified by requests (since the
-modifications in the child process would never reach the initial state
-kept in the parent process and passed to each child). In this case,
-you can use a threading server, but you will probably have to use
-locks to avoid two requests that come in nearly simultaneous to apply
-conflicting changes to the server state.
-
-On the other hand, if you are building e.g. an HTTP server, where all
-data is stored externally (e.g. in the file system), a synchronous
-class will essentially render the service "deaf" while one request is
-being handled -- which may be for a very long time if a client is slow
-to read all the data it has requested. Here a threading or forking
-server is appropriate.
-
-In some cases, it may be appropriate to process part of a request
-synchronously, but to finish processing in a forked child depending on
-the request data. This can be implemented by using a synchronous
-server and doing an explicit fork in the request handler class
-handle() method.
-
-Another approach to handling multiple simultaneous requests in an
-environment that supports neither threads nor fork (or where these are
-too expensive or inappropriate for the service) is to maintain an
-explicit table of partially finished requests and to use select() to
-decide which request to work on next (or whether to handle a new
-incoming request). This is particularly important for stream services
-where each client can potentially be connected for a long time (if
-threads or subprocesses cannot be used).
-
-Future work:
-- Standard classes for Sun RPC (which uses either UDP or TCP)
-- Standard mix-in classes to implement various authentication
- and encryption schemes
-- Standard framework for select-based multiplexing
-
-XXX Open problems:
-- What to do with out-of-band data?
-
-BaseServer:
-- split generic "request" functionality out into BaseServer class.
- Copyright (C) 2000 Luke Kenneth Casson Leighton <lkcl@samba.org>
-
- example: read entries from a SQL database (requires overriding
- get_request() to return a table entry from the database).
- entry is processed by a RequestHandlerClass.
-
-"""
-
-# Author of the BaseServer patch: Luke Kenneth Casson Leighton
-
-# XXX Warning!
-# There is a test suite for this module, but it cannot be run by the
-# standard regression test.
-# To run it manually, run Lib/test/test_socketserver.py.
-
-__version__ = "0.4"
-
-
-import _pydev_socket as socket
-import _pydev_select as select
-import sys
-import os
-try:
- import _pydev_threading as threading
-except ImportError:
- import dummy_threading as threading
-
-__all__ = ["TCPServer","UDPServer","ForkingUDPServer","ForkingTCPServer",
- "ThreadingUDPServer","ThreadingTCPServer","BaseRequestHandler",
- "StreamRequestHandler","DatagramRequestHandler",
- "ThreadingMixIn", "ForkingMixIn"]
-if hasattr(socket, "AF_UNIX"):
- __all__.extend(["UnixStreamServer","UnixDatagramServer",
- "ThreadingUnixStreamServer",
- "ThreadingUnixDatagramServer"])
-
-class BaseServer:
-
- """Base class for server classes.
-
- Methods for the caller:
-
- - __init__(server_address, RequestHandlerClass)
- - serve_forever(poll_interval=0.5)
- - shutdown()
- - handle_request() # if you do not use serve_forever()
- - fileno() -> int # for select()
-
- Methods that may be overridden:
-
- - server_bind()
- - server_activate()
- - get_request() -> request, client_address
- - handle_timeout()
- - verify_request(request, client_address)
- - server_close()
- - process_request(request, client_address)
- - shutdown_request(request)
- - close_request(request)
- - handle_error()
-
- Methods for derived classes:
-
- - finish_request(request, client_address)
-
- Class variables that may be overridden by derived classes or
- instances:
-
- - timeout
- - address_family
- - socket_type
- - allow_reuse_address
-
- Instance variables:
-
- - RequestHandlerClass
- - socket
-
- """
-
- timeout = None
-
- def __init__(self, server_address, RequestHandlerClass):
- """Constructor. May be extended, do not override."""
- self.server_address = server_address
- self.RequestHandlerClass = RequestHandlerClass
- self.__is_shut_down = threading.Event()
- self.__shutdown_request = False
-
- def server_activate(self):
- """Called by constructor to activate the server.
-
- May be overridden.
-
- """
- pass
-
- def serve_forever(self, poll_interval=0.5):
- """Handle one request at a time until shutdown.
-
- Polls for shutdown every poll_interval seconds. Ignores
- self.timeout. If you need to do periodic tasks, do them in
- another thread.
- """
- self.__is_shut_down.clear()
- try:
- while not self.__shutdown_request:
- # XXX: Consider using another file descriptor or
- # connecting to the socket to wake this up instead of
- # polling. Polling reduces our responsiveness to a
- # shutdown request and wastes cpu at all other times.
- r, w, e = select.select([self], [], [], poll_interval)
- if self in r:
- self._handle_request_noblock()
- finally:
- self.__shutdown_request = False
- self.__is_shut_down.set()
-
- def shutdown(self):
- """Stops the serve_forever loop.
-
- Blocks until the loop has finished. This must be called while
- serve_forever() is running in another thread, or it will
- deadlock.
- """
- self.__shutdown_request = True
- self.__is_shut_down.wait()
-
- # The distinction between handling, getting, processing and
- # finishing a request is fairly arbitrary. Remember:
- #
- # - handle_request() is the top-level call. It calls
- # select, get_request(), verify_request() and process_request()
- # - get_request() is different for stream or datagram sockets
- # - process_request() is the place that may fork a new process
- # or create a new thread to finish the request
- # - finish_request() instantiates the request handler class;
- # this constructor will handle the request all by itself
-
- def handle_request(self):
- """Handle one request, possibly blocking.
-
- Respects self.timeout.
- """
- # Support people who used socket.settimeout() to escape
- # handle_request before self.timeout was available.
- timeout = self.socket.gettimeout()
- if timeout is None:
- timeout = self.timeout
- elif self.timeout is not None:
- timeout = min(timeout, self.timeout)
- fd_sets = select.select([self], [], [], timeout)
- if not fd_sets[0]:
- self.handle_timeout()
- return
- self._handle_request_noblock()
-
- def _handle_request_noblock(self):
- """Handle one request, without blocking.
-
- I assume that select.select has returned that the socket is
- readable before this function was called, so there should be
- no risk of blocking in get_request().
- """
- try:
- request, client_address = self.get_request()
- except socket.error:
- return
- if self.verify_request(request, client_address):
- try:
- self.process_request(request, client_address)
- except:
- self.handle_error(request, client_address)
- self.shutdown_request(request)
-
- def handle_timeout(self):
- """Called if no new request arrives within self.timeout.
-
- Overridden by ForkingMixIn.
- """
- pass
-
- def verify_request(self, request, client_address):
- """Verify the request. May be overridden.
-
- Return True if we should proceed with this request.
-
- """
- return True
-
- def process_request(self, request, client_address):
- """Call finish_request.
-
- Overridden by ForkingMixIn and ThreadingMixIn.
-
- """
- self.finish_request(request, client_address)
- self.shutdown_request(request)
-
- def server_close(self):
- """Called to clean-up the server.
-
- May be overridden.
-
- """
- pass
-
- def finish_request(self, request, client_address):
- """Finish one request by instantiating RequestHandlerClass."""
- self.RequestHandlerClass(request, client_address, self)
-
- def shutdown_request(self, request):
- """Called to shutdown and close an individual request."""
- self.close_request(request)
-
- def close_request(self, request):
- """Called to clean up an individual request."""
- pass
-
- def handle_error(self, request, client_address):
- """Handle an error gracefully. May be overridden.
-
- The default is to print a traceback and continue.
-
- """
- print '-'*40
- print 'Exception happened during processing of request from',
- print client_address
- import traceback
- traceback.print_exc() # XXX But this goes to stderr!
- print '-'*40
-
-
-class TCPServer(BaseServer):
-
- """Base class for various socket-based server classes.
-
- Defaults to synchronous IP stream (i.e., TCP).
-
- Methods for the caller:
-
- - __init__(server_address, RequestHandlerClass, bind_and_activate=True)
- - serve_forever(poll_interval=0.5)
- - shutdown()
- - handle_request() # if you don't use serve_forever()
- - fileno() -> int # for select()
-
- Methods that may be overridden:
-
- - server_bind()
- - server_activate()
- - get_request() -> request, client_address
- - handle_timeout()
- - verify_request(request, client_address)
- - process_request(request, client_address)
- - shutdown_request(request)
- - close_request(request)
- - handle_error()
-
- Methods for derived classes:
-
- - finish_request(request, client_address)
-
- Class variables that may be overridden by derived classes or
- instances:
-
- - timeout
- - address_family
- - socket_type
- - request_queue_size (only for stream sockets)
- - allow_reuse_address
-
- Instance variables:
-
- - server_address
- - RequestHandlerClass
- - socket
-
- """
-
- address_family = socket.AF_INET
-
- socket_type = socket.SOCK_STREAM
-
- request_queue_size = 5
-
- allow_reuse_address = False
-
- def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True):
- """Constructor. May be extended, do not override."""
- BaseServer.__init__(self, server_address, RequestHandlerClass)
- self.socket = socket.socket(self.address_family,
- self.socket_type)
- if bind_and_activate:
- self.server_bind()
- self.server_activate()
-
- def server_bind(self):
- """Called by constructor to bind the socket.
-
- May be overridden.
-
- """
- if self.allow_reuse_address:
- self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
- self.socket.bind(self.server_address)
- self.server_address = self.socket.getsockname()
-
- def server_activate(self):
- """Called by constructor to activate the server.
-
- May be overridden.
-
- """
- self.socket.listen(self.request_queue_size)
-
- def server_close(self):
- """Called to clean-up the server.
-
- May be overridden.
-
- """
- self.socket.close()
-
- def fileno(self):
- """Return socket file number.
-
- Interface required by select().
-
- """
- return self.socket.fileno()
-
- def get_request(self):
- """Get the request and client address from the socket.
-
- May be overridden.
-
- """
- return self.socket.accept()
-
- def shutdown_request(self, request):
- """Called to shutdown and close an individual request."""
- try:
- #explicitly shutdown. socket.close() merely releases
- #the socket and waits for GC to perform the actual close.
- request.shutdown(socket.SHUT_WR)
- except socket.error:
- pass #some platforms may raise ENOTCONN here
- self.close_request(request)
-
- def close_request(self, request):
- """Called to clean up an individual request."""
- request.close()
-
-
-class UDPServer(TCPServer):
-
- """UDP server class."""
-
- allow_reuse_address = False
-
- socket_type = socket.SOCK_DGRAM
-
- max_packet_size = 8192
-
- def get_request(self):
- data, client_addr = self.socket.recvfrom(self.max_packet_size)
- return (data, self.socket), client_addr
-
- def server_activate(self):
- # No need to call listen() for UDP.
- pass
-
- def shutdown_request(self, request):
- # No need to shutdown anything.
- self.close_request(request)
-
- def close_request(self, request):
- # No need to close anything.
- pass
-
-class ForkingMixIn:
-
- """Mix-in class to handle each request in a new process."""
-
- timeout = 300
- active_children = None
- max_children = 40
-
- def collect_children(self):
- """Internal routine to wait for children that have exited."""
- if self.active_children is None: return
- while len(self.active_children) >= self.max_children:
- # XXX: This will wait for any child process, not just ones
- # spawned by this library. This could confuse other
- # libraries that expect to be able to wait for their own
- # children.
- try:
- pid, status = os.waitpid(0, 0)
- except os.error:
- pid = None
- if pid not in self.active_children: continue
- self.active_children.remove(pid)
-
- # XXX: This loop runs more system calls than it ought
- # to. There should be a way to put the active_children into a
- # process group and then use os.waitpid(-pgid) to wait for any
- # of that set, but I couldn't find a way to allocate pgids
- # that couldn't collide.
- for child in self.active_children:
- try:
- pid, status = os.waitpid(child, os.WNOHANG)
- except os.error:
- pid = None
- if not pid: continue
- try:
- self.active_children.remove(pid)
- except ValueError, e:
- raise ValueError('%s. x=%d and list=%r' % (e.message, pid,
- self.active_children))
-
- def handle_timeout(self):
- """Wait for zombies after self.timeout seconds of inactivity.
-
- May be extended, do not override.
- """
- self.collect_children()
-
- def process_request(self, request, client_address):
- """Fork a new subprocess to process the request."""
- self.collect_children()
- pid = os.fork()
- if pid:
- # Parent process
- if self.active_children is None:
- self.active_children = []
- self.active_children.append(pid)
- self.close_request(request) #close handle in parent process
- return
- else:
- # Child process.
- # This must never return, hence os._exit()!
- try:
- self.finish_request(request, client_address)
- self.shutdown_request(request)
- os._exit(0)
- except:
- try:
- self.handle_error(request, client_address)
- self.shutdown_request(request)
- finally:
- os._exit(1)
-
-
-class ThreadingMixIn:
- """Mix-in class to handle each request in a new thread."""
-
- # Decides how threads will act upon termination of the
- # main process
- daemon_threads = False
-
- def process_request_thread(self, request, client_address):
- """Same as in BaseServer but as a thread.
-
- In addition, exception handling is done here.
-
- """
- try:
- self.finish_request(request, client_address)
- self.shutdown_request(request)
- except:
- self.handle_error(request, client_address)
- self.shutdown_request(request)
-
- def process_request(self, request, client_address):
- """Start a new thread to process the request."""
- t = threading.Thread(target = self.process_request_thread,
- args = (request, client_address))
- t.daemon = self.daemon_threads
- t.start()
-
-
-class ForkingUDPServer(ForkingMixIn, UDPServer): pass
-class ForkingTCPServer(ForkingMixIn, TCPServer): pass
-
-class ThreadingUDPServer(ThreadingMixIn, UDPServer): pass
-class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass
-
-if hasattr(socket, 'AF_UNIX'):
-
- class UnixStreamServer(TCPServer):
- address_family = socket.AF_UNIX
-
- class UnixDatagramServer(UDPServer):
- address_family = socket.AF_UNIX
-
- class ThreadingUnixStreamServer(ThreadingMixIn, UnixStreamServer): pass
-
- class ThreadingUnixDatagramServer(ThreadingMixIn, UnixDatagramServer): pass
-
-class BaseRequestHandler:
-
- """Base class for request handler classes.
-
- This class is instantiated for each request to be handled. The
- constructor sets the instance variables request, client_address
- and server, and then calls the handle() method. To implement a
- specific service, all you need to do is to derive a class which
- defines a handle() method.
-
- The handle() method can find the request as self.request, the
- client address as self.client_address, and the server (in case it
- needs access to per-server information) as self.server. Since a
- separate instance is created for each request, the handle() method
- can define arbitrary other instance variariables.
-
- """
-
- def __init__(self, request, client_address, server):
- self.request = request
- self.client_address = client_address
- self.server = server
- self.setup()
- try:
- self.handle()
- finally:
- self.finish()
-
- def setup(self):
- pass
-
- def handle(self):
- pass
-
- def finish(self):
- pass
-
-
-# The following two classes make it possible to use the same service
-# class for stream or datagram servers.
-# Each class sets up these instance variables:
-# - rfile: a file object from which receives the request is read
-# - wfile: a file object to which the reply is written
-# When the handle() method returns, wfile is flushed properly
-
-
-class StreamRequestHandler(BaseRequestHandler):
-
- """Define self.rfile and self.wfile for stream sockets."""
-
- # Default buffer sizes for rfile, wfile.
- # We default rfile to buffered because otherwise it could be
- # really slow for large data (a getc() call per byte); we make
- # wfile unbuffered because (a) often after a write() we want to
- # read and we need to flush the line; (b) big writes to unbuffered
- # files are typically optimized by stdio even when big reads
- # aren't.
- rbufsize = -1
- wbufsize = 0
-
- # A timeout to apply to the request socket, if not None.
- timeout = None
-
- # Disable nagle algorithm for this socket, if True.
- # Use only when wbufsize != 0, to avoid small packets.
- disable_nagle_algorithm = False
-
- def setup(self):
- self.connection = self.request
- if self.timeout is not None:
- self.connection.settimeout(self.timeout)
- if self.disable_nagle_algorithm:
- self.connection.setsockopt(socket.IPPROTO_TCP,
- socket.TCP_NODELAY, True)
- self.rfile = self.connection.makefile('rb', self.rbufsize)
- self.wfile = self.connection.makefile('wb', self.wbufsize)
-
- def finish(self):
- if not self.wfile.closed:
- self.wfile.flush()
- self.wfile.close()
- self.rfile.close()
-
-
-class DatagramRequestHandler(BaseRequestHandler):
-
- # XXX Regrettably, I cannot get this working on Linux;
- # s.recvfrom() doesn't return a meaningful client address.
-
- """Define self.rfile and self.wfile for datagram sockets."""
-
- def setup(self):
- try:
- from cStringIO import StringIO
- except ImportError:
- from StringIO import StringIO
- self.packet, self.socket = self.request
- self.rfile = StringIO(self.packet)
- self.wfile = StringIO()
-
- def finish(self):
- self.socket.sendto(self.wfile.getvalue(), self.client_address)
diff --git a/python/helpers/pydev/_pydev_imps/_pydev_Queue.py b/python/helpers/pydev/_pydev_imps/_pydev_Queue.py
index d351b505a3e0..52e83b0de290 100644
--- a/python/helpers/pydev/_pydev_imps/_pydev_Queue.py
+++ b/python/helpers/pydev/_pydev_imps/_pydev_Queue.py
@@ -1,6 +1,7 @@
"""A multi-producer, multi-consumer queue."""
from _pydev_imps._pydev_time import time as _time
+from _pydev_imps import _pydev_thread
try:
import _pydev_threading as _threading
except ImportError:
@@ -30,7 +31,7 @@ class Queue:
# that acquire mutex must release it before returning. mutex
# is shared between the three conditions, so acquiring and
# releasing the conditions also acquires and releases mutex.
- self.mutex = _threading.Lock()
+ self.mutex = _pydev_thread.allocate_lock()
# Notify not_empty whenever an item is added to the queue; a
# thread waiting to get is notified then.
self.not_empty = _threading.Condition(self.mutex)
diff --git a/python/helpers/pydev/_pydev_imps/_pydev_inspect.py b/python/helpers/pydev/_pydev_imps/_pydev_inspect.py
index 57147644e769..5fd33d876c1b 100644
--- a/python/helpers/pydev/_pydev_imps/_pydev_inspect.py
+++ b/python/helpers/pydev/_pydev_imps/_pydev_inspect.py
@@ -27,13 +27,7 @@ Here are some of the useful functions provided by this module:
__author__ = 'Ka-Ping Yee <ping@lfw.org>'
__date__ = '1 Jan 2001'
-import sys
-import os
-import types
-import string
-import re
-import imp
-import tokenize
+import sys, os, types, string, re, imp, tokenize
# ----------------------------------------------------------- type-checking
def ismodule(object):
diff --git a/python/helpers/pydev/_pydev_imps/_pydev_select.py b/python/helpers/pydev/_pydev_imps/_pydev_select.py
index b8dad03cc984..c031f3d8177f 100644
--- a/python/helpers/pydev/_pydev_imps/_pydev_select.py
+++ b/python/helpers/pydev/_pydev_imps/_pydev_select.py
@@ -1 +1,9 @@
-from select import * \ No newline at end of file
+from select import *
+
+try:
+ from gevent import monkey
+ saved = monkey.saved['select']
+ for key, val in saved.items():
+ globals()[key] = val
+except:
+ pass \ No newline at end of file
diff --git a/python/helpers/pydev/_pydev_imps/_pydev_socket.py b/python/helpers/pydev/_pydev_imps/_pydev_socket.py
index 9e96e800876c..3d74e3b54ab4 100644
--- a/python/helpers/pydev/_pydev_imps/_pydev_socket.py
+++ b/python/helpers/pydev/_pydev_imps/_pydev_socket.py
@@ -1 +1,9 @@
-from socket import * \ No newline at end of file
+from socket import *
+
+try:
+ from gevent import monkey
+ saved = monkey.saved['socket']
+ for key, val in saved.items():
+ globals()[key] = val
+except:
+ pass \ No newline at end of file
diff --git a/python/helpers/pydev/_pydev_imps/_pydev_thread.py b/python/helpers/pydev/_pydev_imps/_pydev_thread.py
index 4d2fd5d8cf91..7b46c8ed3f05 100644
--- a/python/helpers/pydev/_pydev_imps/_pydev_thread.py
+++ b/python/helpers/pydev/_pydev_imps/_pydev_thread.py
@@ -2,3 +2,11 @@ try:
from thread import *
except:
from _thread import * #Py3k
+
+try:
+ from gevent import monkey
+ saved = monkey.saved['thread']
+ for key, val in saved.items():
+ globals()[key] = val
+except:
+ pass
diff --git a/python/helpers/pydev/_pydev_imps/_pydev_time.py b/python/helpers/pydev/_pydev_imps/_pydev_time.py
index 72705db20bdc..f53b94c0d0ad 100644
--- a/python/helpers/pydev/_pydev_imps/_pydev_time.py
+++ b/python/helpers/pydev/_pydev_imps/_pydev_time.py
@@ -1 +1,9 @@
from time import *
+
+try:
+ from gevent import monkey
+ saved = monkey.saved['time']
+ for key, val in saved.items():
+ globals()[key] = val
+except:
+ pass
diff --git a/python/helpers/pydev/_pydev_inspect.py b/python/helpers/pydev/_pydev_inspect.py
deleted file mode 100644
index 5fd33d876c1b..000000000000
--- a/python/helpers/pydev/_pydev_inspect.py
+++ /dev/null
@@ -1,788 +0,0 @@
-"""Get useful information from live Python objects.
-
-This module encapsulates the interface provided by the internal special
-attributes (func_*, co_*, im_*, tb_*, etc.) in a friendlier fashion.
-It also provides some help for examining source code and class layout.
-
-Here are some of the useful functions provided by this module:
-
- ismodule(), isclass(), ismethod(), isfunction(), istraceback(),
- isframe(), iscode(), isbuiltin(), isroutine() - check object types
- getmembers() - get members of an object that satisfy a given condition
-
- getfile(), getsourcefile(), getsource() - find an object's source code
- getdoc(), getcomments() - get documentation on an object
- getmodule() - determine the module that an object came from
- getclasstree() - arrange classes so as to represent their hierarchy
-
- getargspec(), getargvalues() - get info about function arguments
- formatargspec(), formatargvalues() - format an argument spec
- getouterframes(), getinnerframes() - get info about frames
- currentframe() - get the current stack frame
- stack(), trace() - get info about frames on the stack or in a traceback
-"""
-
-# This module is in the public domain. No warranties.
-
-__author__ = 'Ka-Ping Yee <ping@lfw.org>'
-__date__ = '1 Jan 2001'
-
-import sys, os, types, string, re, imp, tokenize
-
-# ----------------------------------------------------------- type-checking
-def ismodule(object):
- """Return true if the object is a module.
-
- Module objects provide these attributes:
- __doc__ documentation string
- __file__ filename (missing for built-in modules)"""
- return isinstance(object, types.ModuleType)
-
-def isclass(object):
- """Return true if the object is a class.
-
- Class objects provide these attributes:
- __doc__ documentation string
- __module__ name of module in which this class was defined"""
- return isinstance(object, types.ClassType) or hasattr(object, '__bases__')
-
-def ismethod(object):
- """Return true if the object is an instance method.
-
- Instance method objects provide these attributes:
- __doc__ documentation string
- __name__ name with which this method was defined
- im_class class object in which this method belongs
- im_func function object containing implementation of method
- im_self instance to which this method is bound, or None"""
- return isinstance(object, types.MethodType)
-
-def ismethoddescriptor(object):
- """Return true if the object is a method descriptor.
-
- But not if ismethod() or isclass() or isfunction() are true.
-
- This is new in Python 2.2, and, for example, is true of int.__add__.
- An object passing this test has a __get__ attribute but not a __set__
- attribute, but beyond that the set of attributes varies. __name__ is
- usually sensible, and __doc__ often is.
-
- Methods implemented via descriptors that also pass one of the other
- tests return false from the ismethoddescriptor() test, simply because
- the other tests promise more -- you can, e.g., count on having the
- im_func attribute (etc) when an object passes ismethod()."""
- return (hasattr(object, "__get__")
- and not hasattr(object, "__set__") # else it's a data descriptor
- and not ismethod(object) # mutual exclusion
- and not isfunction(object)
- and not isclass(object))
-
-def isfunction(object):
- """Return true if the object is a user-defined function.
-
- Function objects provide these attributes:
- __doc__ documentation string
- __name__ name with which this function was defined
- func_code code object containing compiled function bytecode
- func_defaults tuple of any default values for arguments
- func_doc (same as __doc__)
- func_globals global namespace in which this function was defined
- func_name (same as __name__)"""
- return isinstance(object, types.FunctionType)
-
-def istraceback(object):
- """Return true if the object is a traceback.
-
- Traceback objects provide these attributes:
- tb_frame frame object at this level
- tb_lasti index of last attempted instruction in bytecode
- tb_lineno current line number in Python source code
- tb_next next inner traceback object (called by this level)"""
- return isinstance(object, types.TracebackType)
-
-def isframe(object):
- """Return true if the object is a frame object.
-
- Frame objects provide these attributes:
- f_back next outer frame object (this frame's caller)
- f_builtins built-in namespace seen by this frame
- f_code code object being executed in this frame
- f_exc_traceback traceback if raised in this frame, or None
- f_exc_type exception type if raised in this frame, or None
- f_exc_value exception value if raised in this frame, or None
- f_globals global namespace seen by this frame
- f_lasti index of last attempted instruction in bytecode
- f_lineno current line number in Python source code
- f_locals local namespace seen by this frame
- f_restricted 0 or 1 if frame is in restricted execution mode
- f_trace tracing function for this frame, or None"""
- return isinstance(object, types.FrameType)
-
-def iscode(object):
- """Return true if the object is a code object.
-
- Code objects provide these attributes:
- co_argcount number of arguments (not including * or ** args)
- co_code string of raw compiled bytecode
- co_consts tuple of constants used in the bytecode
- co_filename name of file in which this code object was created
- co_firstlineno number of first line in Python source code
- co_flags bitmap: 1=optimized | 2=newlocals | 4=*arg | 8=**arg
- co_lnotab encoded mapping of line numbers to bytecode indices
- co_name name with which this code object was defined
- co_names tuple of names of local variables
- co_nlocals number of local variables
- co_stacksize virtual machine stack space required
- co_varnames tuple of names of arguments and local variables"""
- return isinstance(object, types.CodeType)
-
-def isbuiltin(object):
- """Return true if the object is a built-in function or method.
-
- Built-in functions and methods provide these attributes:
- __doc__ documentation string
- __name__ original name of this function or method
- __self__ instance to which a method is bound, or None"""
- return isinstance(object, types.BuiltinFunctionType)
-
-def isroutine(object):
- """Return true if the object is any kind of function or method."""
- return (isbuiltin(object)
- or isfunction(object)
- or ismethod(object)
- or ismethoddescriptor(object))
-
-def getmembers(object, predicate=None):
- """Return all members of an object as (name, value) pairs sorted by name.
- Optionally, only return members that satisfy a given predicate."""
- results = []
- for key in dir(object):
- value = getattr(object, key)
- if not predicate or predicate(value):
- results.append((key, value))
- results.sort()
- return results
-
-def classify_class_attrs(cls):
- """Return list of attribute-descriptor tuples.
-
- For each name in dir(cls), the return list contains a 4-tuple
- with these elements:
-
- 0. The name (a string).
-
- 1. The kind of attribute this is, one of these strings:
- 'class method' created via classmethod()
- 'static method' created via staticmethod()
- 'property' created via property()
- 'method' any other flavor of method
- 'data' not a method
-
- 2. The class which defined this attribute (a class).
-
- 3. The object as obtained directly from the defining class's
- __dict__, not via getattr. This is especially important for
- data attributes: C.data is just a data object, but
- C.__dict__['data'] may be a data descriptor with additional
- info, like a __doc__ string.
- """
-
- mro = getmro(cls)
- names = dir(cls)
- result = []
- for name in names:
- # Get the object associated with the name.
- # Getting an obj from the __dict__ sometimes reveals more than
- # using getattr. Static and class methods are dramatic examples.
- if name in cls.__dict__:
- obj = cls.__dict__[name]
- else:
- obj = getattr(cls, name)
-
- # Figure out where it was defined.
- homecls = getattr(obj, "__objclass__", None)
- if homecls is None:
- # search the dicts.
- for base in mro:
- if name in base.__dict__:
- homecls = base
- break
-
- # Get the object again, in order to get it from the defining
- # __dict__ instead of via getattr (if possible).
- if homecls is not None and name in homecls.__dict__:
- obj = homecls.__dict__[name]
-
- # Also get the object via getattr.
- obj_via_getattr = getattr(cls, name)
-
- # Classify the object.
- if isinstance(obj, staticmethod):
- kind = "static method"
- elif isinstance(obj, classmethod):
- kind = "class method"
- elif isinstance(obj, property):
- kind = "property"
- elif (ismethod(obj_via_getattr) or
- ismethoddescriptor(obj_via_getattr)):
- kind = "method"
- else:
- kind = "data"
-
- result.append((name, kind, homecls, obj))
-
- return result
-
-# ----------------------------------------------------------- class helpers
-def _searchbases(cls, accum):
- # Simulate the "classic class" search order.
- if cls in accum:
- return
- accum.append(cls)
- for base in cls.__bases__:
- _searchbases(base, accum)
-
-def getmro(cls):
- "Return tuple of base classes (including cls) in method resolution order."
- if hasattr(cls, "__mro__"):
- return cls.__mro__
- else:
- result = []
- _searchbases(cls, result)
- return tuple(result)
-
-# -------------------------------------------------- source code extraction
-def indentsize(line):
- """Return the indent size, in spaces, at the start of a line of text."""
- expline = string.expandtabs(line)
- return len(expline) - len(string.lstrip(expline))
-
-def getdoc(object):
- """Get the documentation string for an object.
-
- All tabs are expanded to spaces. To clean up docstrings that are
- indented to line up with blocks of code, any whitespace than can be
- uniformly removed from the second line onwards is removed."""
- try:
- doc = object.__doc__
- except AttributeError:
- return None
- if not isinstance(doc, (str, unicode)):
- return None
- try:
- lines = string.split(string.expandtabs(doc), '\n')
- except UnicodeError:
- return None
- else:
- margin = None
- for line in lines[1:]:
- content = len(string.lstrip(line))
- if not content: continue
- indent = len(line) - content
- if margin is None: margin = indent
- else: margin = min(margin, indent)
- if margin is not None:
- for i in range(1, len(lines)): lines[i] = lines[i][margin:]
- return string.join(lines, '\n')
-
-def getfile(object):
- """Work out which source or compiled file an object was defined in."""
- if ismodule(object):
- if hasattr(object, '__file__'):
- return object.__file__
- raise TypeError, 'arg is a built-in module'
- if isclass(object):
- object = sys.modules.get(object.__module__)
- if hasattr(object, '__file__'):
- return object.__file__
- raise TypeError, 'arg is a built-in class'
- if ismethod(object):
- object = object.im_func
- if isfunction(object):
- object = object.func_code
- if istraceback(object):
- object = object.tb_frame
- if isframe(object):
- object = object.f_code
- if iscode(object):
- return object.co_filename
- raise TypeError, 'arg is not a module, class, method, ' \
- 'function, traceback, frame, or code object'
-
-def getmoduleinfo(path):
- """Get the module name, suffix, mode, and module type for a given file."""
- filename = os.path.basename(path)
- suffixes = map(lambda (suffix, mode, mtype):
- (-len(suffix), suffix, mode, mtype), imp.get_suffixes())
- suffixes.sort() # try longest suffixes first, in case they overlap
- for neglen, suffix, mode, mtype in suffixes:
- if filename[neglen:] == suffix:
- return filename[:neglen], suffix, mode, mtype
-
-def getmodulename(path):
- """Return the module name for a given file, or None."""
- info = getmoduleinfo(path)
- if info: return info[0]
-
-def getsourcefile(object):
- """Return the Python source file an object was defined in, if it exists."""
- filename = getfile(object)
- if string.lower(filename[-4:]) in ['.pyc', '.pyo']:
- filename = filename[:-4] + '.py'
- for suffix, mode, kind in imp.get_suffixes():
- if 'b' in mode and string.lower(filename[-len(suffix):]) == suffix:
- # Looks like a binary file. We want to only return a text file.
- return None
- if os.path.exists(filename):
- return filename
-
-def getabsfile(object):
- """Return an absolute path to the source or compiled file for an object.
-
- The idea is for each object to have a unique origin, so this routine
- normalizes the result as much as possible."""
- return os.path.normcase(
- os.path.abspath(getsourcefile(object) or getfile(object)))
-
-modulesbyfile = {}
-
-def getmodule(object):
- """Return the module an object was defined in, or None if not found."""
- if ismodule(object):
- return object
- if isclass(object):
- return sys.modules.get(object.__module__)
- try:
- file = getabsfile(object)
- except TypeError:
- return None
- if modulesbyfile.has_key(file):
- return sys.modules[modulesbyfile[file]]
- for module in sys.modules.values():
- if hasattr(module, '__file__'):
- modulesbyfile[getabsfile(module)] = module.__name__
- if modulesbyfile.has_key(file):
- return sys.modules[modulesbyfile[file]]
- main = sys.modules['__main__']
- if hasattr(main, object.__name__):
- mainobject = getattr(main, object.__name__)
- if mainobject is object:
- return main
- builtin = sys.modules['__builtin__']
- if hasattr(builtin, object.__name__):
- builtinobject = getattr(builtin, object.__name__)
- if builtinobject is object:
- return builtin
-
-def findsource(object):
- """Return the entire source file and starting line number for an object.
-
- The argument may be a module, class, method, function, traceback, frame,
- or code object. The source code is returned as a list of all the lines
- in the file and the line number indexes a line in that list. An IOError
- is raised if the source code cannot be retrieved."""
- try:
- file = open(getsourcefile(object))
- except (TypeError, IOError):
- raise IOError, 'could not get source code'
- lines = file.readlines()
- file.close()
-
- if ismodule(object):
- return lines, 0
-
- if isclass(object):
- name = object.__name__
- pat = re.compile(r'^\s*class\s*' + name + r'\b')
- for i in range(len(lines)):
- if pat.match(lines[i]): return lines, i
- else: raise IOError, 'could not find class definition'
-
- if ismethod(object):
- object = object.im_func
- if isfunction(object):
- object = object.func_code
- if istraceback(object):
- object = object.tb_frame
- if isframe(object):
- object = object.f_code
- if iscode(object):
- if not hasattr(object, 'co_firstlineno'):
- raise IOError, 'could not find function definition'
- lnum = object.co_firstlineno - 1
- pat = re.compile(r'^(\s*def\s)|(.*\slambda(:|\s))')
- while lnum > 0:
- if pat.match(lines[lnum]): break
- lnum = lnum - 1
- return lines, lnum
- raise IOError, 'could not find code object'
-
-def getcomments(object):
- """Get lines of comments immediately preceding an object's source code."""
- try: lines, lnum = findsource(object)
- except IOError: return None
-
- if ismodule(object):
- # Look for a comment block at the top of the file.
- start = 0
- if lines and lines[0][:2] == '#!': start = 1
- while start < len(lines) and string.strip(lines[start]) in ['', '#']:
- start = start + 1
- if start < len(lines) and lines[start][:1] == '#':
- comments = []
- end = start
- while end < len(lines) and lines[end][:1] == '#':
- comments.append(string.expandtabs(lines[end]))
- end = end + 1
- return string.join(comments, '')
-
- # Look for a preceding block of comments at the same indentation.
- elif lnum > 0:
- indent = indentsize(lines[lnum])
- end = lnum - 1
- if end >= 0 and string.lstrip(lines[end])[:1] == '#' and \
- indentsize(lines[end]) == indent:
- comments = [string.lstrip(string.expandtabs(lines[end]))]
- if end > 0:
- end = end - 1
- comment = string.lstrip(string.expandtabs(lines[end]))
- while comment[:1] == '#' and indentsize(lines[end]) == indent:
- comments[:0] = [comment]
- end = end - 1
- if end < 0: break
- comment = string.lstrip(string.expandtabs(lines[end]))
- while comments and string.strip(comments[0]) == '#':
- comments[:1] = []
- while comments and string.strip(comments[-1]) == '#':
- comments[-1:] = []
- return string.join(comments, '')
-
-class ListReader:
- """Provide a readline() method to return lines from a list of strings."""
- def __init__(self, lines):
- self.lines = lines
- self.index = 0
-
- def readline(self):
- i = self.index
- if i < len(self.lines):
- self.index = i + 1
- return self.lines[i]
- else: return ''
-
-class EndOfBlock(Exception): pass
-
-class BlockFinder:
- """Provide a tokeneater() method to detect the end of a code block."""
- def __init__(self):
- self.indent = 0
- self.started = 0
- self.last = 0
-
- def tokeneater(self, type, token, (srow, scol), (erow, ecol), line):
- if not self.started:
- if type == tokenize.NAME: self.started = 1
- elif type == tokenize.NEWLINE:
- self.last = srow
- elif type == tokenize.INDENT:
- self.indent = self.indent + 1
- elif type == tokenize.DEDENT:
- self.indent = self.indent - 1
- if self.indent == 0: raise EndOfBlock, self.last
- elif type == tokenize.NAME and scol == 0:
- raise EndOfBlock, self.last
-
-def getblock(lines):
- """Extract the block of code at the top of the given list of lines."""
- try:
- tokenize.tokenize(ListReader(lines).readline, BlockFinder().tokeneater)
- except EndOfBlock, eob:
- return lines[:eob.args[0]]
- # Fooling the indent/dedent logic implies a one-line definition
- return lines[:1]
-
-def getsourcelines(object):
- """Return a list of source lines and starting line number for an object.
-
- The argument may be a module, class, method, function, traceback, frame,
- or code object. The source code is returned as a list of the lines
- corresponding to the object and the line number indicates where in the
- original source file the first line of code was found. An IOError is
- raised if the source code cannot be retrieved."""
- lines, lnum = findsource(object)
-
- if ismodule(object): return lines, 0
- else: return getblock(lines[lnum:]), lnum + 1
-
-def getsource(object):
- """Return the text of the source code for an object.
-
- The argument may be a module, class, method, function, traceback, frame,
- or code object. The source code is returned as a single string. An
- IOError is raised if the source code cannot be retrieved."""
- lines, lnum = getsourcelines(object)
- return string.join(lines, '')
-
-# --------------------------------------------------- class tree extraction
-def walktree(classes, children, parent):
- """Recursive helper function for getclasstree()."""
- results = []
- classes.sort(lambda a, b: cmp(a.__name__, b.__name__))
- for c in classes:
- results.append((c, c.__bases__))
- if children.has_key(c):
- results.append(walktree(children[c], children, c))
- return results
-
-def getclasstree(classes, unique=0):
- """Arrange the given list of classes into a hierarchy of nested lists.
-
- Where a nested list appears, it contains classes derived from the class
- whose entry immediately precedes the list. Each entry is a 2-tuple
- containing a class and a tuple of its base classes. If the 'unique'
- argument is true, exactly one entry appears in the returned structure
- for each class in the given list. Otherwise, classes using multiple
- inheritance and their descendants will appear multiple times."""
- children = {}
- roots = []
- for c in classes:
- if c.__bases__:
- for parent in c.__bases__:
- if not children.has_key(parent):
- children[parent] = []
- children[parent].append(c)
- if unique and parent in classes: break
- elif c not in roots:
- roots.append(c)
- for parent in children.keys():
- if parent not in classes:
- roots.append(parent)
- return walktree(roots, children, None)
-
-# ------------------------------------------------ argument list extraction
-# These constants are from Python's compile.h.
-CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS = 1, 2, 4, 8
-
-def getargs(co):
- """Get information about the arguments accepted by a code object.
-
- Three things are returned: (args, varargs, varkw), where 'args' is
- a list of argument names (possibly containing nested lists), and
- 'varargs' and 'varkw' are the names of the * and ** arguments or None."""
- if not iscode(co): raise TypeError, 'arg is not a code object'
-
- nargs = co.co_argcount
- names = co.co_varnames
- args = list(names[:nargs])
- step = 0
-
- # The following acrobatics are for anonymous (tuple) arguments.
- if not sys.platform.startswith('java'):#Jython doesn't have co_code
- code = co.co_code
- import dis
- for i in range(nargs):
- if args[i][:1] in ['', '.']:
- stack, remain, count = [], [], []
- while step < len(code):
- op = ord(code[step])
- step = step + 1
- if op >= dis.HAVE_ARGUMENT:
- opname = dis.opname[op]
- value = ord(code[step]) + ord(code[step + 1]) * 256
- step = step + 2
- if opname in ['UNPACK_TUPLE', 'UNPACK_SEQUENCE']:
- remain.append(value)
- count.append(value)
- elif opname == 'STORE_FAST':
- stack.append(names[value])
- remain[-1] = remain[-1] - 1
- while remain[-1] == 0:
- remain.pop()
- size = count.pop()
- stack[-size:] = [stack[-size:]]
- if not remain: break
- remain[-1] = remain[-1] - 1
- if not remain: break
- args[i] = stack[0]
-
- varargs = None
- if co.co_flags & CO_VARARGS:
- varargs = co.co_varnames[nargs]
- nargs = nargs + 1
- varkw = None
- if co.co_flags & CO_VARKEYWORDS:
- varkw = co.co_varnames[nargs]
- return args, varargs, varkw
-
-def getargspec(func):
- """Get the names and default values of a function's arguments.
-
- A tuple of four things is returned: (args, varargs, varkw, defaults).
- 'args' is a list of the argument names (it may contain nested lists).
- 'varargs' and 'varkw' are the names of the * and ** arguments or None.
- 'defaults' is an n-tuple of the default values of the last n arguments."""
- if ismethod(func):
- func = func.im_func
- if not isfunction(func): raise TypeError, 'arg is not a Python function'
- args, varargs, varkw = getargs(func.func_code)
- return args, varargs, varkw, func.func_defaults
-
-def getargvalues(frame):
- """Get information about arguments passed into a particular frame.
-
- A tuple of four things is returned: (args, varargs, varkw, locals).
- 'args' is a list of the argument names (it may contain nested lists).
- 'varargs' and 'varkw' are the names of the * and ** arguments or None.
- 'locals' is the locals dictionary of the given frame."""
- args, varargs, varkw = getargs(frame.f_code)
- return args, varargs, varkw, frame.f_locals
-
-def joinseq(seq):
- if len(seq) == 1:
- return '(' + seq[0] + ',)'
- else:
- return '(' + string.join(seq, ', ') + ')'
-
-def strseq(object, convert, join=joinseq):
- """Recursively walk a sequence, stringifying each element."""
- if type(object) in [types.ListType, types.TupleType]:
- return join(map(lambda o, c=convert, j=join: strseq(o, c, j), object))
- else:
- return convert(object)
-
-def formatargspec(args, varargs=None, varkw=None, defaults=None,
- formatarg=str,
- formatvarargs=lambda name: '*' + name,
- formatvarkw=lambda name: '**' + name,
- formatvalue=lambda value: '=' + repr(value),
- join=joinseq):
- """Format an argument spec from the 4 values returned by getargspec.
-
- The first four arguments are (args, varargs, varkw, defaults). The
- other four arguments are the corresponding optional formatting functions
- that are called to turn names and values into strings. The ninth
- argument is an optional function to format the sequence of arguments."""
- specs = []
- if defaults:
- firstdefault = len(args) - len(defaults)
- for i in range(len(args)):
- spec = strseq(args[i], formatarg, join)
- if defaults and i >= firstdefault:
- spec = spec + formatvalue(defaults[i - firstdefault])
- specs.append(spec)
- if varargs:
- specs.append(formatvarargs(varargs))
- if varkw:
- specs.append(formatvarkw(varkw))
- return '(' + string.join(specs, ', ') + ')'
-
-def formatargvalues(args, varargs, varkw, locals,
- formatarg=str,
- formatvarargs=lambda name: '*' + name,
- formatvarkw=lambda name: '**' + name,
- formatvalue=lambda value: '=' + repr(value),
- join=joinseq):
- """Format an argument spec from the 4 values returned by getargvalues.
-
- The first four arguments are (args, varargs, varkw, locals). The
- next four arguments are the corresponding optional formatting functions
- that are called to turn names and values into strings. The ninth
- argument is an optional function to format the sequence of arguments."""
- def convert(name, locals=locals,
- formatarg=formatarg, formatvalue=formatvalue):
- return formatarg(name) + formatvalue(locals[name])
- specs = []
- for i in range(len(args)):
- specs.append(strseq(args[i], convert, join))
- if varargs:
- specs.append(formatvarargs(varargs) + formatvalue(locals[varargs]))
- if varkw:
- specs.append(formatvarkw(varkw) + formatvalue(locals[varkw]))
- return '(' + string.join(specs, ', ') + ')'
-
-# -------------------------------------------------- stack frame extraction
-def getframeinfo(frame, context=1):
- """Get information about a frame or traceback object.
-
- A tuple of five things is returned: the filename, the line number of
- the current line, the function name, a list of lines of context from
- the source code, and the index of the current line within that list.
- The optional second argument specifies the number of lines of context
- to return, which are centered around the current line."""
- raise NotImplementedError
-# if istraceback(frame):
-# frame = frame.tb_frame
-# if not isframe(frame):
-# raise TypeError, 'arg is not a frame or traceback object'
-#
-# filename = getsourcefile(frame)
-# lineno = getlineno(frame)
-# if context > 0:
-# start = lineno - 1 - context//2
-# try:
-# lines, lnum = findsource(frame)
-# except IOError:
-# lines = index = None
-# else:
-# start = max(start, 1)
-# start = min(start, len(lines) - context)
-# lines = lines[start:start+context]
-# index = lineno - 1 - start
-# else:
-# lines = index = None
-#
-# return (filename, lineno, frame.f_code.co_name, lines, index)
-
-def getlineno(frame):
- """Get the line number from a frame object, allowing for optimization."""
- # Written by Marc-Andr Lemburg; revised by Jim Hugunin and Fredrik Lundh.
- lineno = frame.f_lineno
- code = frame.f_code
- if hasattr(code, 'co_lnotab'):
- table = code.co_lnotab
- lineno = code.co_firstlineno
- addr = 0
- for i in range(0, len(table), 2):
- addr = addr + ord(table[i])
- if addr > frame.f_lasti: break
- lineno = lineno + ord(table[i + 1])
- return lineno
-
-def getouterframes(frame, context=1):
- """Get a list of records for a frame and all higher (calling) frames.
-
- Each record contains a frame object, filename, line number, function
- name, a list of lines of context, and index within the context."""
- framelist = []
- while frame:
- framelist.append((frame,) + getframeinfo(frame, context))
- frame = frame.f_back
- return framelist
-
-def getinnerframes(tb, context=1):
- """Get a list of records for a traceback's frame and all lower frames.
-
- Each record contains a frame object, filename, line number, function
- name, a list of lines of context, and index within the context."""
- framelist = []
- while tb:
- framelist.append((tb.tb_frame,) + getframeinfo(tb, context))
- tb = tb.tb_next
- return framelist
-
-def currentframe():
- """Return the frame object for the caller's stack frame."""
- try:
- raise 'catch me'
- except:
- return sys.exc_traceback.tb_frame.f_back #@UndefinedVariable
-
-if hasattr(sys, '_getframe'): currentframe = sys._getframe
-
-def stack(context=1):
- """Return a list of records for the stack above the caller's frame."""
- return getouterframes(currentframe().f_back, context)
-
-def trace(context=1):
- """Return a list of records for the stack below the current exception."""
- return getinnerframes(sys.exc_traceback, context) #@UndefinedVariable
diff --git a/python/helpers/pydev/_pydev_jy_imports_tipper.py b/python/helpers/pydev/_pydev_jy_imports_tipper.py
index 1691e3e1f1dc..db1d7f895106 100644
--- a/python/helpers/pydev/_pydev_jy_imports_tipper.py
+++ b/python/helpers/pydev/_pydev_jy_imports_tipper.py
@@ -1,5 +1,7 @@
import StringIO
import traceback
+from java.lang import StringBuffer #@UnresolvedImport
+from java.lang import String #@UnresolvedImport
import java.lang #@UnresolvedImport
import sys
from _pydev_tipper_common import DoFind
@@ -17,6 +19,7 @@ except NameError: # version < 2.3 -- didn't have the True/False builtins
from org.python.core import PyReflectedFunction #@UnresolvedImport
from org.python import core #@UnresolvedImport
+from org.python.core import PyClass #@UnresolvedImport
try:
xrange
diff --git a/python/helpers/pydev/_pydev_select.py b/python/helpers/pydev/_pydev_select.py
deleted file mode 100644
index b8dad03cc984..000000000000
--- a/python/helpers/pydev/_pydev_select.py
+++ /dev/null
@@ -1 +0,0 @@
-from select import * \ No newline at end of file
diff --git a/python/helpers/pydev/_pydev_socket.py b/python/helpers/pydev/_pydev_socket.py
deleted file mode 100644
index 9e96e800876c..000000000000
--- a/python/helpers/pydev/_pydev_socket.py
+++ /dev/null
@@ -1 +0,0 @@
-from socket import * \ No newline at end of file
diff --git a/python/helpers/pydev/_pydev_threading.py b/python/helpers/pydev/_pydev_threading.py
index d7bfadf04308..62b300b86cd0 100644
--- a/python/helpers/pydev/_pydev_threading.py
+++ b/python/helpers/pydev/_pydev_threading.py
@@ -1,978 +1,14 @@
-"""Thread module emulating a subset of Java's threading model."""
-
-import sys as _sys
-
-from _pydev_imps import _pydev_thread as thread
-import warnings
-
-from _pydev_imps._pydev_time import time as _time, sleep as _sleep
-from traceback import format_exc as _format_exc
-
-# Note regarding PEP 8 compliant aliases
-# This threading model was originally inspired by Java, and inherited
-# the convention of camelCase function and method names from that
-# language. While those names are not in any imminent danger of being
-# deprecated, starting with Python 2.6, the module now provides a
-# PEP 8 compliant alias for any such method name.
-# Using the new PEP 8 compliant names also facilitates substitution
-# with the multiprocessing module, which doesn't provide the old
-# Java inspired names.
-
-
-# Rename some stuff so "from threading import *" is safe
-__all__ = ['activeCount', 'active_count', 'Condition', 'currentThread',
- 'current_thread', 'enumerate', 'Event',
- 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Thread',
- 'Timer', 'setprofile', 'settrace', 'local', 'stack_size']
-
-_start_new_thread = thread.start_new_thread
-_allocate_lock = thread.allocate_lock
-_get_ident = thread.get_ident
-ThreadError = thread.error
-del thread
-
-
-# sys.exc_clear is used to work around the fact that except blocks
-# don't fully clear the exception until 3.0.
-warnings.filterwarnings('ignore', category=DeprecationWarning,
- module='threading', message='sys.exc_clear')
-
-# Debug support (adapted from ihooks.py).
-# All the major classes here derive from _Verbose. We force that to
-# be a new-style class so that all the major classes here are new-style.
-# This helps debugging (type(instance) is more revealing for instances
-# of new-style classes).
-
-_VERBOSE = False
-
-if __debug__:
-
- class _Verbose(object):
-
- def __init__(self, verbose=None):
- if verbose is None:
- verbose = _VERBOSE
- self.__verbose = verbose
-
- def _note(self, format, *args):
- if self.__verbose:
- format = format % args
- # Issue #4188: calling current_thread() can incur an infinite
- # recursion if it has to create a DummyThread on the fly.
- ident = _get_ident()
- try:
- name = _active[ident].name
- except KeyError:
- name = "<OS thread %d>" % ident
- format = "%s: %s\n" % (name, format)
- _sys.stderr.write(format)
-
-else:
- # Disable this when using "python -O"
- class _Verbose(object):
- def __init__(self, verbose=None):
- pass
- def _note(self, *args):
- pass
-
-# Support for profile and trace hooks
-
-_profile_hook = None
-_trace_hook = None
-
-def setprofile(func):
- global _profile_hook
- _profile_hook = func
-
-def settrace(func):
- global _trace_hook
- _trace_hook = func
-
-# Synchronization classes
-
-Lock = _allocate_lock
-
-def RLock(*args, **kwargs):
- return _RLock(*args, **kwargs)
-
-class _RLock(_Verbose):
-
- def __init__(self, verbose=None):
- _Verbose.__init__(self, verbose)
- self.__block = _allocate_lock()
- self.__owner = None
- self.__count = 0
-
- def __repr__(self):
- owner = self.__owner
- try:
- owner = _active[owner].name
- except KeyError:
- pass
- return "<%s owner=%r count=%d>" % (
- self.__class__.__name__, owner, self.__count)
-
- def acquire(self, blocking=1):
- me = _get_ident()
- if self.__owner == me:
- self.__count = self.__count + 1
- if __debug__:
- self._note("%s.acquire(%s): recursive success", self, blocking)
- return 1
- rc = self.__block.acquire(blocking)
- if rc:
- self.__owner = me
- self.__count = 1
- if __debug__:
- self._note("%s.acquire(%s): initial success", self, blocking)
- else:
- if __debug__:
- self._note("%s.acquire(%s): failure", self, blocking)
- return rc
-
- __enter__ = acquire
-
- def release(self):
- if self.__owner != _get_ident():
- raise RuntimeError("cannot release un-acquired lock")
- self.__count = count = self.__count - 1
- if not count:
- self.__owner = None
- self.__block.release()
- if __debug__:
- self._note("%s.release(): final release", self)
- else:
- if __debug__:
- self._note("%s.release(): non-final release", self)
-
- def __exit__(self, t, v, tb):
- self.release()
-
- # Internal methods used by condition variables
-
- def _acquire_restore(self, count_owner):
- count, owner = count_owner
- self.__block.acquire()
- self.__count = count
- self.__owner = owner
- if __debug__:
- self._note("%s._acquire_restore()", self)
-
- def _release_save(self):
- if __debug__:
- self._note("%s._release_save()", self)
- count = self.__count
- self.__count = 0
- owner = self.__owner
- self.__owner = None
- self.__block.release()
- return (count, owner)
-
- def _is_owned(self):
- return self.__owner == _get_ident()
-
-
-def Condition(*args, **kwargs):
- return _Condition(*args, **kwargs)
-
-class _Condition(_Verbose):
-
- def __init__(self, lock=None, verbose=None):
- _Verbose.__init__(self, verbose)
- if lock is None:
- lock = RLock()
- self.__lock = lock
- # Export the lock's acquire() and release() methods
- self.acquire = lock.acquire
- self.release = lock.release
- # If the lock defines _release_save() and/or _acquire_restore(),
- # these override the default implementations (which just call
- # release() and acquire() on the lock). Ditto for _is_owned().
- try:
- self._release_save = lock._release_save
- except AttributeError:
- pass
- try:
- self._acquire_restore = lock._acquire_restore
- except AttributeError:
- pass
- try:
- self._is_owned = lock._is_owned
- except AttributeError:
- pass
- self.__waiters = []
-
- def __enter__(self):
- return self.__lock.__enter__()
-
- def __exit__(self, *args):
- return self.__lock.__exit__(*args)
-
- def __repr__(self):
- return "<Condition(%s, %d)>" % (self.__lock, len(self.__waiters))
-
- def _release_save(self):
- self.__lock.release() # No state to save
-
- def _acquire_restore(self, x):
- self.__lock.acquire() # Ignore saved state
-
- def _is_owned(self):
- # Return True if lock is owned by current_thread.
- # This method is called only if __lock doesn't have _is_owned().
- if self.__lock.acquire(0):
- self.__lock.release()
- return False
- else:
- return True
-
- def wait(self, timeout=None):
- if not self._is_owned():
- raise RuntimeError("cannot wait on un-acquired lock")
- waiter = _allocate_lock()
- waiter.acquire()
- self.__waiters.append(waiter)
- saved_state = self._release_save()
- try: # restore state no matter what (e.g., KeyboardInterrupt)
- if timeout is None:
- waiter.acquire()
- if __debug__:
- self._note("%s.wait(): got it", self)
- else:
- # Balancing act: We can't afford a pure busy loop, so we
- # have to sleep; but if we sleep the whole timeout time,
- # we'll be unresponsive. The scheme here sleeps very
- # little at first, longer as time goes on, but never longer
- # than 20 times per second (or the timeout time remaining).
- endtime = _time() + timeout
- delay = 0.0005 # 500 us -> initial delay of 1 ms
- while True:
- gotit = waiter.acquire(0)
- if gotit:
- break
- remaining = endtime - _time()
- if remaining <= 0:
- break
- delay = min(delay * 2, remaining, .05)
- _sleep(delay)
- if not gotit:
- if __debug__:
- self._note("%s.wait(%s): timed out", self, timeout)
- try:
- self.__waiters.remove(waiter)
- except ValueError:
- pass
- else:
- if __debug__:
- self._note("%s.wait(%s): got it", self, timeout)
- finally:
- self._acquire_restore(saved_state)
-
- def notify(self, n=1):
- if not self._is_owned():
- raise RuntimeError("cannot notify on un-acquired lock")
- __waiters = self.__waiters
- waiters = __waiters[:n]
- if not waiters:
- if __debug__:
- self._note("%s.notify(): no waiters", self)
- return
- self._note("%s.notify(): notifying %d waiter%s", self, n,
- n!=1 and "s" or "")
- for waiter in waiters:
- waiter.release()
- try:
- __waiters.remove(waiter)
- except ValueError:
- pass
-
- def notifyAll(self):
- self.notify(len(self.__waiters))
-
- notify_all = notifyAll
-
-
-def Semaphore(*args, **kwargs):
- return _Semaphore(*args, **kwargs)
-
-class _Semaphore(_Verbose):
-
- # After Tim Peters' semaphore class, but not quite the same (no maximum)
-
- def __init__(self, value=1, verbose=None):
- if value < 0:
- raise ValueError("semaphore initial value must be >= 0")
- _Verbose.__init__(self, verbose)
- self.__cond = Condition(Lock())
- self.__value = value
-
- def acquire(self, blocking=1):
- rc = False
- self.__cond.acquire()
- while self.__value == 0:
- if not blocking:
- break
- if __debug__:
- self._note("%s.acquire(%s): blocked waiting, value=%s",
- self, blocking, self.__value)
- self.__cond.wait()
- else:
- self.__value = self.__value - 1
- if __debug__:
- self._note("%s.acquire: success, value=%s",
- self, self.__value)
- rc = True
- self.__cond.release()
- return rc
-
- __enter__ = acquire
-
- def release(self):
- self.__cond.acquire()
- self.__value = self.__value + 1
- if __debug__:
- self._note("%s.release: success, value=%s",
- self, self.__value)
- self.__cond.notify()
- self.__cond.release()
-
- def __exit__(self, t, v, tb):
- self.release()
-
-
-def BoundedSemaphore(*args, **kwargs):
- return _BoundedSemaphore(*args, **kwargs)
-
-class _BoundedSemaphore(_Semaphore):
- """Semaphore that checks that # releases is <= # acquires"""
- def __init__(self, value=1, verbose=None):
- _Semaphore.__init__(self, value, verbose)
- self._initial_value = value
-
- def release(self):
- if self._Semaphore__value >= self._initial_value:
- raise ValueError, "Semaphore released too many times"
- return _Semaphore.release(self)
-
-
-def Event(*args, **kwargs):
- return _Event(*args, **kwargs)
-
-class _Event(_Verbose):
-
- # After Tim Peters' event class (without is_posted())
-
- def __init__(self, verbose=None):
- _Verbose.__init__(self, verbose)
- self.__cond = Condition(Lock())
- self.__flag = False
-
- def _reset_internal_locks(self):
- # private! called by Thread._reset_internal_locks by _after_fork()
- self.__cond.__init__()
-
- def isSet(self):
- return self.__flag
-
- is_set = isSet
-
- def set(self):
- self.__cond.acquire()
- try:
- self.__flag = True
- self.__cond.notify_all()
- finally:
- self.__cond.release()
-
- def clear(self):
- self.__cond.acquire()
- try:
- self.__flag = False
- finally:
- self.__cond.release()
-
- def wait(self, timeout=None):
- self.__cond.acquire()
- try:
- if not self.__flag:
- self.__cond.wait(timeout)
- return self.__flag
- finally:
- self.__cond.release()
-
-# Helper to generate new thread names
-_counter = 0
-def _newname(template="Thread-%d"):
- global _counter
- _counter = _counter + 1
- return template % _counter
-
-# Active thread administration
-_active_limbo_lock = _allocate_lock()
-_active = {} # maps thread id to Thread object
-_limbo = {}
-
-
-# Main class for threads
-
-class Thread(_Verbose):
-
- __initialized = False
- # Need to store a reference to sys.exc_info for printing
- # out exceptions when a thread tries to use a global var. during interp.
- # shutdown and thus raises an exception about trying to perform some
- # operation on/with a NoneType
- __exc_info = _sys.exc_info
- # Keep sys.exc_clear too to clear the exception just before
- # allowing .join() to return.
- __exc_clear = _sys.exc_clear
-
- def __init__(self, group=None, target=None, name=None,
- args=(), kwargs=None, verbose=None):
- assert group is None, "group argument must be None for now"
- _Verbose.__init__(self, verbose)
- if kwargs is None:
- kwargs = {}
- self.__target = target
- self.__name = str(name or _newname())
- self.__args = args
- self.__kwargs = kwargs
- self.__daemonic = self._set_daemon()
- self.__ident = None
- self.__started = Event()
- self.__stopped = False
- self.__block = Condition(Lock())
- self.__initialized = True
- # sys.stderr is not stored in the class like
- # sys.exc_info since it can be changed between instances
- self.__stderr = _sys.stderr
-
- def _reset_internal_locks(self):
- # private! Called by _after_fork() to reset our internal locks as
- # they may be in an invalid state leading to a deadlock or crash.
- if hasattr(self, '_Thread__block'): # DummyThread deletes self.__block
- self.__block.__init__()
- self.__started._reset_internal_locks()
-
- @property
- def _block(self):
- # used by a unittest
- return self.__block
-
- def _set_daemon(self):
- # Overridden in _MainThread and _DummyThread
- return current_thread().daemon
-
- def __repr__(self):
- assert self.__initialized, "Thread.__init__() was not called"
- status = "initial"
- if self.__started.is_set():
- status = "started"
- if self.__stopped:
- status = "stopped"
- if self.__daemonic:
- status += " daemon"
- if self.__ident is not None:
- status += " %s" % self.__ident
- return "<%s(%s, %s)>" % (self.__class__.__name__, self.__name, status)
-
- def start(self):
- if not self.__initialized:
- raise RuntimeError("thread.__init__() not called")
- if self.__started.is_set():
- raise RuntimeError("threads can only be started once")
- if __debug__:
- self._note("%s.start(): starting thread", self)
- with _active_limbo_lock:
- _limbo[self] = self
- try:
- _start_new_thread(self.__bootstrap, ())
- except Exception:
- with _active_limbo_lock:
- del _limbo[self]
- raise
- self.__started.wait()
-
- def run(self):
- try:
- if self.__target:
- self.__target(*self.__args, **self.__kwargs)
- finally:
- # Avoid a refcycle if the thread is running a function with
- # an argument that has a member that points to the thread.
- del self.__target, self.__args, self.__kwargs
-
- def __bootstrap(self):
- # Wrapper around the real bootstrap code that ignores
- # exceptions during interpreter cleanup. Those typically
- # happen when a daemon thread wakes up at an unfortunate
- # moment, finds the world around it destroyed, and raises some
- # random exception *** while trying to report the exception in
- # __bootstrap_inner() below ***. Those random exceptions
- # don't help anybody, and they confuse users, so we suppress
- # them. We suppress them only when it appears that the world
- # indeed has already been destroyed, so that exceptions in
- # __bootstrap_inner() during normal business hours are properly
- # reported. Also, we only suppress them for daemonic threads;
- # if a non-daemonic encounters this, something else is wrong.
- try:
- self.__bootstrap_inner()
- except:
- if self.__daemonic and _sys is None:
- return
- raise
-
- def _set_ident(self):
- self.__ident = _get_ident()
-
- def __bootstrap_inner(self):
- try:
- self._set_ident()
- self.__started.set()
- with _active_limbo_lock:
- _active[self.__ident] = self
- del _limbo[self]
- if __debug__:
- self._note("%s.__bootstrap(): thread started", self)
-
- if _trace_hook:
- self._note("%s.__bootstrap(): registering trace hook", self)
- _sys.settrace(_trace_hook)
- if _profile_hook:
- self._note("%s.__bootstrap(): registering profile hook", self)
- _sys.setprofile(_profile_hook)
-
- try:
- self.run()
- except SystemExit:
- if __debug__:
- self._note("%s.__bootstrap(): raised SystemExit", self)
- except:
- if __debug__:
- self._note("%s.__bootstrap(): unhandled exception", self)
- # If sys.stderr is no more (most likely from interpreter
- # shutdown) use self.__stderr. Otherwise still use sys (as in
- # _sys) in case sys.stderr was redefined since the creation of
- # self.
- if _sys:
- _sys.stderr.write("Exception in thread %s:\n%s\n" %
- (self.name, _format_exc()))
- else:
- # Do the best job possible w/o a huge amt. of code to
- # approximate a traceback (code ideas from
- # Lib/traceback.py)
- exc_type, exc_value, exc_tb = self.__exc_info()
- try:
- print>>self.__stderr, (
- "Exception in thread " + self.name +
- " (most likely raised during interpreter shutdown):")
- print>>self.__stderr, (
- "Traceback (most recent call last):")
- while exc_tb:
- print>>self.__stderr, (
- ' File "%s", line %s, in %s' %
- (exc_tb.tb_frame.f_code.co_filename,
- exc_tb.tb_lineno,
- exc_tb.tb_frame.f_code.co_name))
- exc_tb = exc_tb.tb_next
- print>>self.__stderr, ("%s: %s" % (exc_type, exc_value))
- # Make sure that exc_tb gets deleted since it is a memory
- # hog; deleting everything else is just for thoroughness
- finally:
- del exc_type, exc_value, exc_tb
- else:
- if __debug__:
- self._note("%s.__bootstrap(): normal return", self)
- finally:
- # Prevent a race in
- # test_threading.test_no_refcycle_through_target when
- # the exception keeps the target alive past when we
- # assert that it's dead.
- self.__exc_clear()
- finally:
- with _active_limbo_lock:
- self.__stop()
- try:
- # We don't call self.__delete() because it also
- # grabs _active_limbo_lock.
- del _active[_get_ident()]
- except:
- pass
-
- def __stop(self):
- self.__block.acquire()
- self.__stopped = True
- self.__block.notify_all()
- self.__block.release()
-
- def __delete(self):
- "Remove current thread from the dict of currently running threads."
-
- # Notes about running with dummy_thread:
- #
- # Must take care to not raise an exception if dummy_thread is being
- # used (and thus this module is being used as an instance of
- # dummy_threading). dummy_thread.get_ident() always returns -1 since
- # there is only one thread if dummy_thread is being used. Thus
- # len(_active) is always <= 1 here, and any Thread instance created
- # overwrites the (if any) thread currently registered in _active.
- #
- # An instance of _MainThread is always created by 'threading'. This
- # gets overwritten the instant an instance of Thread is created; both
- # threads return -1 from dummy_thread.get_ident() and thus have the
- # same key in the dict. So when the _MainThread instance created by
- # 'threading' tries to clean itself up when atexit calls this method
- # it gets a KeyError if another Thread instance was created.
- #
- # This all means that KeyError from trying to delete something from
- # _active if dummy_threading is being used is a red herring. But
- # since it isn't if dummy_threading is *not* being used then don't
- # hide the exception.
-
- try:
- with _active_limbo_lock:
- del _active[_get_ident()]
- # There must not be any python code between the previous line
- # and after the lock is released. Otherwise a tracing function
- # could try to acquire the lock again in the same thread, (in
- # current_thread()), and would block.
- except KeyError:
- if 'dummy_threading' not in _sys.modules:
- raise
-
- def join(self, timeout=None):
- if not self.__initialized:
- raise RuntimeError("Thread.__init__() not called")
- if not self.__started.is_set():
- raise RuntimeError("cannot join thread before it is started")
- if self is current_thread():
- raise RuntimeError("cannot join current thread")
-
- if __debug__:
- if not self.__stopped:
- self._note("%s.join(): waiting until thread stops", self)
- self.__block.acquire()
- try:
- if timeout is None:
- while not self.__stopped:
- self.__block.wait()
- if __debug__:
- self._note("%s.join(): thread stopped", self)
- else:
- deadline = _time() + timeout
- while not self.__stopped:
- delay = deadline - _time()
- if delay <= 0:
- if __debug__:
- self._note("%s.join(): timed out", self)
- break
- self.__block.wait(delay)
- else:
- if __debug__:
- self._note("%s.join(): thread stopped", self)
- finally:
- self.__block.release()
-
- @property
- def name(self):
- assert self.__initialized, "Thread.__init__() not called"
- return self.__name
-
- @name.setter
- def name(self, name):
- assert self.__initialized, "Thread.__init__() not called"
- self.__name = str(name)
-
- @property
- def ident(self):
- assert self.__initialized, "Thread.__init__() not called"
- return self.__ident
-
- def isAlive(self):
- assert self.__initialized, "Thread.__init__() not called"
- return self.__started.is_set() and not self.__stopped
-
- is_alive = isAlive
-
- @property
- def daemon(self):
- assert self.__initialized, "Thread.__init__() not called"
- return self.__daemonic
-
- @daemon.setter
- def daemon(self, daemonic):
- if not self.__initialized:
- raise RuntimeError("Thread.__init__() not called")
- if self.__started.is_set():
- raise RuntimeError("cannot set daemon status of active thread");
- self.__daemonic = daemonic
-
- def isDaemon(self):
- return self.daemon
-
- def setDaemon(self, daemonic):
- self.daemon = daemonic
-
- def getName(self):
- return self.name
-
- def setName(self, name):
- self.name = name
-
-# The timer class was contributed by Itamar Shtull-Trauring
-
-def Timer(*args, **kwargs):
- return _Timer(*args, **kwargs)
-
-class _Timer(Thread):
- """Call a function after a specified number of seconds:
-
- t = Timer(30.0, f, args=[], kwargs={})
- t.start()
- t.cancel() # stop the timer's action if it's still waiting
- """
-
- def __init__(self, interval, function, args=[], kwargs={}):
- Thread.__init__(self)
- self.interval = interval
- self.function = function
- self.args = args
- self.kwargs = kwargs
- self.finished = Event()
-
- def cancel(self):
- """Stop the timer if it hasn't finished yet"""
- self.finished.set()
-
- def run(self):
- self.finished.wait(self.interval)
- if not self.finished.is_set():
- self.function(*self.args, **self.kwargs)
- self.finished.set()
-
-# Special thread class to represent the main thread
-# This is garbage collected through an exit handler
-
-class _MainThread(Thread):
-
- def __init__(self):
- Thread.__init__(self, name="MainThread")
- self._Thread__started.set()
- self._set_ident()
- with _active_limbo_lock:
- _active[_get_ident()] = self
-
- def _set_daemon(self):
- return False
-
- def _exitfunc(self):
- self._Thread__stop()
- t = _pickSomeNonDaemonThread()
- if t:
- if __debug__:
- self._note("%s: waiting for other threads", self)
- while t:
- t.join()
- t = _pickSomeNonDaemonThread()
- if __debug__:
- self._note("%s: exiting", self)
- self._Thread__delete()
-
-def _pickSomeNonDaemonThread():
- for t in enumerate():
- if not t.daemon and t.is_alive():
- return t
- return None
-
-
-# Dummy thread class to represent threads not started here.
-# These aren't garbage collected when they die, nor can they be waited for.
-# If they invoke anything in threading.py that calls current_thread(), they
-# leave an entry in the _active dict forever after.
-# Their purpose is to return *something* from current_thread().
-# They are marked as daemon threads so we won't wait for them
-# when we exit (conform previous semantics).
-
-class _DummyThread(Thread):
-
- def __init__(self):
- Thread.__init__(self, name=_newname("Dummy-%d"))
-
- # Thread.__block consumes an OS-level locking primitive, which
- # can never be used by a _DummyThread. Since a _DummyThread
- # instance is immortal, that's bad, so release this resource.
- del self._Thread__block
-
- self._Thread__started.set()
- self._set_ident()
- with _active_limbo_lock:
- _active[_get_ident()] = self
-
- def _set_daemon(self):
- return True
-
- def join(self, timeout=None):
- assert False, "cannot join a dummy thread"
-
-
-# Global API functions
-
-def currentThread():
- try:
- return _active[_get_ident()]
- except KeyError:
- ##print "current_thread(): no current thread for", _get_ident()
- return _DummyThread()
-
-current_thread = currentThread
-
-def activeCount():
- with _active_limbo_lock:
- return len(_active) + len(_limbo)
-
-active_count = activeCount
-
-def _enumerate():
- # Same as enumerate(), but without the lock. Internal use only.
- return _active.values() + _limbo.values()
-
-def enumerate():
- with _active_limbo_lock:
- return _active.values() + _limbo.values()
-
-# Create the main thread object,
-# and make it available for the interpreter
-# (Py_Main) as threading._shutdown.
-
-_shutdown = _MainThread()._exitfunc
-
-# get thread-local implementation, either from the thread
-# module, or from the python fallback
-
+from threading import enumerate, currentThread, Condition, Event, Timer, Thread
try:
- from _pydev_imps._pydev_thread import _local as local
-except ImportError:
- from _threading_local import local
-
+ from threading import settrace
+except:
+ pass
-def _after_fork():
- # This function is called by Python/ceval.c:PyEval_ReInitThreads which
- # is called from PyOS_AfterFork. Here we cleanup threading module state
- # that should not exist after a fork.
- # Reset _active_limbo_lock, in case we forked while the lock was held
- # by another (non-forked) thread. http://bugs.python.org/issue874900
- global _active_limbo_lock
- _active_limbo_lock = _allocate_lock()
-
- # fork() only copied the current thread; clear references to others.
- new_active = {}
- current = current_thread()
- with _active_limbo_lock:
- for thread in _active.itervalues():
- # Any lock/condition variable may be currently locked or in an
- # invalid state, so we reinitialize them.
- if hasattr(thread, '_reset_internal_locks'):
- thread._reset_internal_locks()
- if thread is current:
- # There is only one active thread. We reset the ident to
- # its new value since it can have changed.
- ident = _get_ident()
- thread._Thread__ident = ident
- new_active[ident] = thread
- else:
- # All the others are already stopped.
- thread._Thread__stop()
-
- _limbo.clear()
- _active.clear()
- _active.update(new_active)
- assert len(_active) == 1
-
-
-# Self-test code
-
-def _test():
-
- class BoundedQueue(_Verbose):
-
- def __init__(self, limit):
- _Verbose.__init__(self)
- self.mon = RLock()
- self.rc = Condition(self.mon)
- self.wc = Condition(self.mon)
- self.limit = limit
- self.queue = deque()
-
- def put(self, item):
- self.mon.acquire()
- while len(self.queue) >= self.limit:
- self._note("put(%s): queue full", item)
- self.wc.wait()
- self.queue.append(item)
- self._note("put(%s): appended, length now %d",
- item, len(self.queue))
- self.rc.notify()
- self.mon.release()
-
- def get(self):
- self.mon.acquire()
- while not self.queue:
- self._note("get(): queue empty")
- self.rc.wait()
- item = self.queue.popleft()
- self._note("get(): got %s, %d left", item, len(self.queue))
- self.wc.notify()
- self.mon.release()
- return item
-
- class ProducerThread(Thread):
-
- def __init__(self, queue, quota):
- Thread.__init__(self, name="Producer")
- self.queue = queue
- self.quota = quota
-
- def run(self):
- from random import random
- counter = 0
- while counter < self.quota:
- counter = counter + 1
- self.queue.put("%s.%d" % (self.name, counter))
- _sleep(random() * 0.00001)
-
-
- class ConsumerThread(Thread):
-
- def __init__(self, queue, count):
- Thread.__init__(self, name="Consumer")
- self.queue = queue
- self.count = count
-
- def run(self):
- while self.count > 0:
- item = self.queue.get()
- print item
- self.count = self.count - 1
-
- NP = 3
- QL = 4
- NI = 5
-
- Q = BoundedQueue(QL)
- P = []
- for i in range(NP):
- t = ProducerThread(Q, NI)
- t.name = ("Producer-%d" % (i+1))
- P.append(t)
- C = ConsumerThread(Q, NI*NP)
- for t in P:
- t.start()
- _sleep(0.000001)
- C.start()
- for t in P:
- t.join()
- C.join()
-
-if __name__ == '__main__':
- _test()
+try:
+ from gevent import monkey
+ saved = monkey.saved['threading']
+ for key, val in saved.items():
+ globals()[key] = val
+except:
+ pass
diff --git a/python/helpers/pydev/_pydev_time.py b/python/helpers/pydev/_pydev_time.py
deleted file mode 100644
index 72705db20bdc..000000000000
--- a/python/helpers/pydev/_pydev_time.py
+++ /dev/null
@@ -1 +0,0 @@
-from time import *
diff --git a/python/helpers/pydev/_pydev_xmlrpclib.py b/python/helpers/pydev/_pydev_xmlrpclib.py
deleted file mode 100644
index 5f6e2b7f138c..000000000000
--- a/python/helpers/pydev/_pydev_xmlrpclib.py
+++ /dev/null
@@ -1,1493 +0,0 @@
-#Just a copy of the version in python 2.5 to be used if it's not available in jython 2.1
-import sys
-
-#
-# XML-RPC CLIENT LIBRARY
-#
-# an XML-RPC client interface for Python.
-#
-# the marshalling and response parser code can also be used to
-# implement XML-RPC servers.
-#
-# Notes:
-# this version is designed to work with Python 2.1 or newer.
-#
-# History:
-# 1999-01-14 fl Created
-# 1999-01-15 fl Changed dateTime to use localtime
-# 1999-01-16 fl Added Binary/base64 element, default to RPC2 service
-# 1999-01-19 fl Fixed array data element (from Skip Montanaro)
-# 1999-01-21 fl Fixed dateTime constructor, etc.
-# 1999-02-02 fl Added fault handling, handle empty sequences, etc.
-# 1999-02-10 fl Fixed problem with empty responses (from Skip Montanaro)
-# 1999-06-20 fl Speed improvements, pluggable parsers/transports (0.9.8)
-# 2000-11-28 fl Changed boolean to check the truth value of its argument
-# 2001-02-24 fl Added encoding/Unicode/SafeTransport patches
-# 2001-02-26 fl Added compare support to wrappers (0.9.9/1.0b1)
-# 2001-03-28 fl Make sure response tuple is a singleton
-# 2001-03-29 fl Don't require empty params element (from Nicholas Riley)
-# 2001-06-10 fl Folded in _xmlrpclib accelerator support (1.0b2)
-# 2001-08-20 fl Base xmlrpclib.Error on built-in Exception (from Paul Prescod)
-# 2001-09-03 fl Allow Transport subclass to override getparser
-# 2001-09-10 fl Lazy import of urllib, cgi, xmllib (20x import speedup)
-# 2001-10-01 fl Remove containers from memo cache when done with them
-# 2001-10-01 fl Use faster escape method (80% dumps speedup)
-# 2001-10-02 fl More dumps microtuning
-# 2001-10-04 fl Make sure import expat gets a parser (from Guido van Rossum)
-# 2001-10-10 sm Allow long ints to be passed as ints if they don't overflow
-# 2001-10-17 sm Test for int and long overflow (allows use on 64-bit systems)
-# 2001-11-12 fl Use repr() to marshal doubles (from Paul Felix)
-# 2002-03-17 fl Avoid buffered read when possible (from James Rucker)
-# 2002-04-07 fl Added pythondoc comments
-# 2002-04-16 fl Added __str__ methods to datetime/binary wrappers
-# 2002-05-15 fl Added error constants (from Andrew Kuchling)
-# 2002-06-27 fl Merged with Python CVS version
-# 2002-10-22 fl Added basic authentication (based on code from Phillip Eby)
-# 2003-01-22 sm Add support for the bool type
-# 2003-02-27 gvr Remove apply calls
-# 2003-04-24 sm Use cStringIO if available
-# 2003-04-25 ak Add support for nil
-# 2003-06-15 gn Add support for time.struct_time
-# 2003-07-12 gp Correct marshalling of Faults
-# 2003-10-31 mvl Add multicall support
-# 2004-08-20 mvl Bump minimum supported Python version to 2.1
-#
-# Copyright (c) 1999-2002 by Secret Labs AB.
-# Copyright (c) 1999-2002 by Fredrik Lundh.
-#
-# info@pythonware.com
-# http://www.pythonware.com
-#
-# --------------------------------------------------------------------
-# The XML-RPC client interface is
-#
-# Copyright (c) 1999-2002 by Secret Labs AB
-# Copyright (c) 1999-2002 by Fredrik Lundh
-#
-# By obtaining, using, and/or copying this software and/or its
-# associated documentation, you agree that you have read, understood,
-# and will comply with the following terms and conditions:
-#
-# Permission to use, copy, modify, and distribute this software and
-# its associated documentation for any purpose and without fee is
-# hereby granted, provided that the above copyright notice appears in
-# all copies, and that both that copyright notice and this permission
-# notice appear in supporting documentation, and that the name of
-# Secret Labs AB or the author not be used in advertising or publicity
-# pertaining to distribution of the software without specific, written
-# prior permission.
-#
-# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
-# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
-# ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR
-# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
-# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
-# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
-# OF THIS SOFTWARE.
-# --------------------------------------------------------------------
-
-#
-# things to look into some day:
-
-# TODO: sort out True/False/boolean issues for Python 2.3
-
-"""
-An XML-RPC client interface for Python.
-
-The marshalling and response parser code can also be used to
-implement XML-RPC servers.
-
-Exported exceptions:
-
- Error Base class for client errors
- ProtocolError Indicates an HTTP protocol error
- ResponseError Indicates a broken response package
- Fault Indicates an XML-RPC fault package
-
-Exported classes:
-
- ServerProxy Represents a logical connection to an XML-RPC server
-
- MultiCall Executor of boxcared xmlrpc requests
- Boolean boolean wrapper to generate a "boolean" XML-RPC value
- DateTime dateTime wrapper for an ISO 8601 string or time tuple or
- localtime integer value to generate a "dateTime.iso8601"
- XML-RPC value
- Binary binary data wrapper
-
- SlowParser Slow but safe standard parser (based on xmllib)
- Marshaller Generate an XML-RPC params chunk from a Python data structure
- Unmarshaller Unmarshal an XML-RPC response from incoming XML event message
- Transport Handles an HTTP transaction to an XML-RPC server
- SafeTransport Handles an HTTPS transaction to an XML-RPC server
-
-Exported constants:
-
- True
- False
-
-Exported functions:
-
- boolean Convert any Python value to an XML-RPC boolean
- getparser Create instance of the fastest available parser & attach
- to an unmarshalling object
- dumps Convert an argument tuple or a Fault instance to an XML-RPC
- request (or response, if the methodresponse option is used).
- loads Convert an XML-RPC packet to unmarshalled data plus a method
- name (None if not present).
-"""
-
-import re, string, time, operator
-
-from types import *
-
-# --------------------------------------------------------------------
-# Internal stuff
-
-try:
- unicode
-except NameError:
- unicode = None # unicode support not available
-
-try:
- import datetime
-except ImportError:
- datetime = None
-
-try:
- _bool_is_builtin = False.__class__.__name__ == "bool"
-except (NameError, AttributeError):
- _bool_is_builtin = 0
-
-def _decode(data, encoding, is8bit=re.compile("[\x80-\xff]").search):
- # decode non-ascii string (if possible)
- if unicode and encoding and is8bit(data):
- data = unicode(data, encoding)
- return data
-
-def escape(s, replace=string.replace):
- s = replace(s, "&", "&amp;")
- s = replace(s, "<", "&lt;")
- return replace(s, ">", "&gt;",)
-
-if unicode:
- def _stringify(string):
- # convert to 7-bit ascii if possible
- try:
- return string.encode("ascii")
- except UnicodeError:
- return string
-else:
- def _stringify(string):
- return string
-
-__version__ = "1.0.1"
-
-# xmlrpc integer limits
-try:
- long
-except NameError:
- long = int
-MAXINT = long(2) ** 31 - 1
-MININT = long(-2) ** 31
-
-# --------------------------------------------------------------------
-# Error constants (from Dan Libby's specification at
-# http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php)
-
-# Ranges of errors
-PARSE_ERROR = -32700
-SERVER_ERROR = -32600
-APPLICATION_ERROR = -32500
-SYSTEM_ERROR = -32400
-TRANSPORT_ERROR = -32300
-
-# Specific errors
-NOT_WELLFORMED_ERROR = -32700
-UNSUPPORTED_ENCODING = -32701
-INVALID_ENCODING_CHAR = -32702
-INVALID_XMLRPC = -32600
-METHOD_NOT_FOUND = -32601
-INVALID_METHOD_PARAMS = -32602
-INTERNAL_ERROR = -32603
-
-# --------------------------------------------------------------------
-# Exceptions
-
-##
-# Base class for all kinds of client-side errors.
-
-class Error(Exception):
- """Base class for client errors."""
- def __str__(self):
- return repr(self)
-
-##
-# Indicates an HTTP-level protocol error. This is raised by the HTTP
-# transport layer, if the server returns an error code other than 200
-# (OK).
-#
-# @param url The target URL.
-# @param errcode The HTTP error code.
-# @param errmsg The HTTP error message.
-# @param headers The HTTP header dictionary.
-
-class ProtocolError(Error):
- """Indicates an HTTP protocol error."""
- def __init__(self, url, errcode, errmsg, headers):
- Error.__init__(self)
- self.url = url
- self.errcode = errcode
- self.errmsg = errmsg
- self.headers = headers
- def __repr__(self):
- return (
- "<ProtocolError for %s: %s %s>" %
- (self.url, self.errcode, self.errmsg)
- )
-
-##
-# Indicates a broken XML-RPC response package. This exception is
-# raised by the unmarshalling layer, if the XML-RPC response is
-# malformed.
-
-class ResponseError(Error):
- """Indicates a broken response package."""
- pass
-
-##
-# Indicates an XML-RPC fault response package. This exception is
-# raised by the unmarshalling layer, if the XML-RPC response contains
-# a fault string. This exception can also used as a class, to
-# generate a fault XML-RPC message.
-#
-# @param faultCode The XML-RPC fault code.
-# @param faultString The XML-RPC fault string.
-
-class Fault(Error):
- """Indicates an XML-RPC fault package."""
- def __init__(self, faultCode, faultString, **extra):
- Error.__init__(self)
- self.faultCode = faultCode
- self.faultString = faultString
- def __repr__(self):
- return (
- "<Fault %s: %s>" %
- (self.faultCode, repr(self.faultString))
- )
-
-# --------------------------------------------------------------------
-# Special values
-
-##
-# Wrapper for XML-RPC boolean values. Use the xmlrpclib.True and
-# xmlrpclib.False constants, or the xmlrpclib.boolean() function, to
-# generate boolean XML-RPC values.
-#
-# @param value A boolean value. Any true value is interpreted as True,
-# all other values are interpreted as False.
-
-if _bool_is_builtin:
- boolean = Boolean = bool #@UndefinedVariable
- # to avoid breaking code which references xmlrpclib.{True,False}
- True, False = True, False
-else:
- class Boolean:
- """Boolean-value wrapper.
-
- Use True or False to generate a "boolean" XML-RPC value.
- """
-
- def __init__(self, value=0):
- self.value = operator.truth(value)
-
- def encode(self, out):
- out.write("<value><boolean>%d</boolean></value>\n" % self.value)
-
- def __cmp__(self, other):
- if isinstance(other, Boolean):
- other = other.value
- return cmp(self.value, other)
-
- def __repr__(self):
- if self.value:
- return "<Boolean True at %x>" % id(self)
- else:
- return "<Boolean False at %x>" % id(self)
-
- def __int__(self):
- return self.value
-
- def __nonzero__(self):
- return self.value
-
- True, False = Boolean(1), Boolean(0)
-
- ##
- # Map true or false value to XML-RPC boolean values.
- #
- # @def boolean(value)
- # @param value A boolean value. Any true value is mapped to True,
- # all other values are mapped to False.
- # @return xmlrpclib.True or xmlrpclib.False.
- # @see Boolean
- # @see True
- # @see False
-
- def boolean(value, _truefalse=(False, True)):
- """Convert any Python value to XML-RPC 'boolean'."""
- return _truefalse[operator.truth(value)]
-
-##
-# Wrapper for XML-RPC DateTime values. This converts a time value to
-# the format used by XML-RPC.
-# <p>
-# The value can be given as a string in the format
-# "yyyymmddThh:mm:ss", as a 9-item time tuple (as returned by
-# time.localtime()), or an integer value (as returned by time.time()).
-# The wrapper uses time.localtime() to convert an integer to a time
-# tuple.
-#
-# @param value The time, given as an ISO 8601 string, a time
-# tuple, or a integer time value.
-
-class DateTime:
- """DateTime wrapper for an ISO 8601 string or time tuple or
- localtime integer value to generate 'dateTime.iso8601' XML-RPC
- value.
- """
-
- def __init__(self, value=0):
- if not isinstance(value, StringType):
- if datetime and isinstance(value, datetime.datetime):
- self.value = value.strftime("%Y%m%dT%H:%M:%S")
- return
- if datetime and isinstance(value, datetime.date):
- self.value = value.strftime("%Y%m%dT%H:%M:%S")
- return
- if datetime and isinstance(value, datetime.time):
- today = datetime.datetime.now().strftime("%Y%m%d")
- self.value = value.strftime(today + "T%H:%M:%S")
- return
- if not isinstance(value, (TupleType, time.struct_time)): #@UndefinedVariable
- if value == 0:
- value = time.time()
- value = time.localtime(value)
- value = time.strftime("%Y%m%dT%H:%M:%S", value)
- self.value = value
-
- def __cmp__(self, other):
- if isinstance(other, DateTime):
- other = other.value
- return cmp(self.value, other)
-
- ##
- # Get date/time value.
- #
- # @return Date/time value, as an ISO 8601 string.
-
- def __str__(self):
- return self.value
-
- def __repr__(self):
- return "<DateTime %s at %x>" % (repr(self.value), id(self))
-
- def decode(self, data):
- data = str(data)
- self.value = string.strip(data)
-
- def encode(self, out):
- out.write("<value><dateTime.iso8601>")
- out.write(self.value)
- out.write("</dateTime.iso8601></value>\n")
-
-def _datetime(data):
- # decode xml element contents into a DateTime structure.
- value = DateTime()
- value.decode(data)
- return value
-
-def _datetime_type(data):
- t = time.strptime(data, "%Y%m%dT%H:%M:%S") #@UndefinedVariable
- return datetime.datetime(*tuple(t)[:6])
-
-##
-# Wrapper for binary data. This can be used to transport any kind
-# of binary data over XML-RPC, using BASE64 encoding.
-#
-# @param data An 8-bit string containing arbitrary data.
-
-import base64
-try:
- import cStringIO as StringIO
-except ImportError:
- import StringIO
-
-class Binary:
- """Wrapper for binary data."""
-
- def __init__(self, data=None):
- self.data = data
-
- ##
- # Get buffer contents.
- #
- # @return Buffer contents, as an 8-bit string.
-
- def __str__(self):
- return self.data or ""
-
- def __cmp__(self, other):
- if isinstance(other, Binary):
- other = other.data
- return cmp(self.data, other)
-
- def decode(self, data):
- self.data = base64.decodestring(data)
-
- def encode(self, out):
- out.write("<value><base64>\n")
- base64.encode(StringIO.StringIO(self.data), out)
- out.write("</base64></value>\n")
-
-def _binary(data):
- # decode xml element contents into a Binary structure
- value = Binary()
- value.decode(data)
- return value
-
-WRAPPERS = (DateTime, Binary)
-if not _bool_is_builtin:
- WRAPPERS = WRAPPERS + (Boolean,)
-
-# --------------------------------------------------------------------
-# XML parsers
-
-try:
- # optional xmlrpclib accelerator
- import _xmlrpclib #@UnresolvedImport
- FastParser = _xmlrpclib.Parser
- FastUnmarshaller = _xmlrpclib.Unmarshaller
-except (AttributeError, ImportError):
- FastParser = FastUnmarshaller = None
-
-try:
- import _xmlrpclib #@UnresolvedImport
- FastMarshaller = _xmlrpclib.Marshaller
-except (AttributeError, ImportError):
- FastMarshaller = None
-
-#
-# the SGMLOP parser is about 15x faster than Python's builtin
-# XML parser. SGMLOP sources can be downloaded from:
-#
-# http://www.pythonware.com/products/xml/sgmlop.htm
-#
-
-try:
- import sgmlop
- if not hasattr(sgmlop, "XMLParser"):
- raise ImportError()
-except ImportError:
- SgmlopParser = None # sgmlop accelerator not available
-else:
- class SgmlopParser:
- def __init__(self, target):
-
- # setup callbacks
- self.finish_starttag = target.start
- self.finish_endtag = target.end
- self.handle_data = target.data
- self.handle_xml = target.xml
-
- # activate parser
- self.parser = sgmlop.XMLParser()
- self.parser.register(self)
- self.feed = self.parser.feed
- self.entity = {
- "amp": "&", "gt": ">", "lt": "<",
- "apos": "'", "quot": '"'
- }
-
- def close(self):
- try:
- self.parser.close()
- finally:
- self.parser = self.feed = None # nuke circular reference
-
- def handle_proc(self, tag, attr):
- m = re.search("encoding\s*=\s*['\"]([^\"']+)[\"']", attr) #@UndefinedVariable
- if m:
- self.handle_xml(m.group(1), 1)
-
- def handle_entityref(self, entity):
- # <string> entity
- try:
- self.handle_data(self.entity[entity])
- except KeyError:
- self.handle_data("&%s;" % entity)
-
-try:
- from xml.parsers import expat
- if not hasattr(expat, "ParserCreate"):
- raise ImportError()
-except ImportError:
- ExpatParser = None # expat not available
-else:
- class ExpatParser:
- # fast expat parser for Python 2.0 and later. this is about
- # 50% slower than sgmlop, on roundtrip testing
- def __init__(self, target):
- self._parser = parser = expat.ParserCreate(None, None)
- self._target = target
- parser.StartElementHandler = target.start
- parser.EndElementHandler = target.end
- parser.CharacterDataHandler = target.data
- encoding = None
- if not parser.returns_unicode:
- encoding = "utf-8"
- target.xml(encoding, None)
-
- def feed(self, data):
- self._parser.Parse(data, 0)
-
- def close(self):
- self._parser.Parse("", 1) # end of data
- del self._target, self._parser # get rid of circular references
-
-class SlowParser:
- """Default XML parser (based on xmllib.XMLParser)."""
- # this is about 10 times slower than sgmlop, on roundtrip
- # testing.
- def __init__(self, target):
- import xmllib # lazy subclassing (!)
- if xmllib.XMLParser not in SlowParser.__bases__:
- SlowParser.__bases__ = (xmllib.XMLParser,)
- self.handle_xml = target.xml
- self.unknown_starttag = target.start
- self.handle_data = target.data
- self.handle_cdata = target.data
- self.unknown_endtag = target.end
- try:
- xmllib.XMLParser.__init__(self, accept_utf8=1)
- except TypeError:
- xmllib.XMLParser.__init__(self) # pre-2.0
-
-# --------------------------------------------------------------------
-# XML-RPC marshalling and unmarshalling code
-
-##
-# XML-RPC marshaller.
-#
-# @param encoding Default encoding for 8-bit strings. The default
-# value is None (interpreted as UTF-8).
-# @see dumps
-
-class Marshaller:
- """Generate an XML-RPC params chunk from a Python data structure.
-
- Create a Marshaller instance for each set of parameters, and use
- the "dumps" method to convert your data (represented as a tuple)
- to an XML-RPC params chunk. To write a fault response, pass a
- Fault instance instead. You may prefer to use the "dumps" module
- function for this purpose.
- """
-
- # by the way, if you don't understand what's going on in here,
- # that's perfectly ok.
-
- def __init__(self, encoding=None, allow_none=0):
- self.memo = {}
- self.data = None
- self.encoding = encoding
- self.allow_none = allow_none
-
- dispatch = {}
-
- def dumps(self, values):
- out = []
- write = out.append
- dump = self.__dump
- if isinstance(values, Fault):
- # fault instance
- write("<fault>\n")
- dump({'faultCode': values.faultCode,
- 'faultString': values.faultString},
- write)
- write("</fault>\n")
- else:
- # parameter block
- # FIXME: the xml-rpc specification allows us to leave out
- # the entire <params> block if there are no parameters.
- # however, changing this may break older code (including
- # old versions of xmlrpclib.py), so this is better left as
- # is for now. See @XMLRPC3 for more information. /F
- write("<params>\n")
- for v in values:
- write("<param>\n")
- dump(v, write)
- write("</param>\n")
- write("</params>\n")
- result = string.join(out, "")
- return result
-
- def __dump(self, value, write):
- try:
- f = self.dispatch[type(value)]
- except KeyError:
- raise TypeError("cannot marshal %s objects" % type(value))
- else:
- f(self, value, write)
-
- def dump_nil (self, value, write):
- if not self.allow_none:
- raise TypeError("cannot marshal None unless allow_none is enabled")
- write("<value><nil/></value>")
- dispatch[NoneType] = dump_nil
-
- def dump_int(self, value, write):
- # in case ints are > 32 bits
- if value > MAXINT or value < MININT:
- raise OverflowError("int exceeds XML-RPC limits")
- write("<value><int>")
- write(str(value))
- write("</int></value>\n")
- dispatch[IntType] = dump_int
-
- if _bool_is_builtin:
- def dump_bool(self, value, write):
- write("<value><boolean>")
- write(value and "1" or "0")
- write("</boolean></value>\n")
- dispatch[bool] = dump_bool #@UndefinedVariable
-
- def dump_long(self, value, write):
- if value > MAXINT or value < MININT:
- raise OverflowError("long int exceeds XML-RPC limits")
- write("<value><int>")
- write(str(int(value)))
- write("</int></value>\n")
- dispatch[LongType] = dump_long
-
- def dump_double(self, value, write):
- write("<value><double>")
- write(repr(value))
- write("</double></value>\n")
- dispatch[FloatType] = dump_double
-
- def dump_string(self, value, write, escape=escape):
- write("<value><string>")
- write(escape(value))
- write("</string></value>\n")
- dispatch[StringType] = dump_string
-
- if unicode:
- def dump_unicode(self, value, write, escape=escape):
- value = value.encode(self.encoding)
- write("<value><string>")
- write(escape(value))
- write("</string></value>\n")
- dispatch[UnicodeType] = dump_unicode
-
- def dump_array(self, value, write):
- i = id(value)
- if self.memo.has_key(i):
- raise TypeError("cannot marshal recursive sequences")
- self.memo[i] = None
- dump = self.__dump
- write("<value><array><data>\n")
- for v in value:
- dump(v, write)
- write("</data></array></value>\n")
- del self.memo[i]
- dispatch[TupleType] = dump_array
- dispatch[ListType] = dump_array
-
- def dump_struct(self, value, write, escape=escape):
- i = id(value)
- if self.memo.has_key(i):
- raise TypeError("cannot marshal recursive dictionaries")
- self.memo[i] = None
- dump = self.__dump
- write("<value><struct>\n")
- for k, v in value.items():
- write("<member>\n")
- if type(k) is not StringType:
- if unicode and type(k) is UnicodeType:
- k = k.encode(self.encoding)
- else:
- raise TypeError("dictionary key must be string")
- write("<name>%s</name>\n" % escape(k))
- dump(v, write)
- write("</member>\n")
- write("</struct></value>\n")
- del self.memo[i]
- dispatch[DictType] = dump_struct
-
- if datetime:
- def dump_datetime(self, value, write):
- write("<value><dateTime.iso8601>")
- write(value.strftime("%Y%m%dT%H:%M:%S"))
- write("</dateTime.iso8601></value>\n")
- dispatch[datetime.datetime] = dump_datetime
-
- def dump_date(self, value, write):
- write("<value><dateTime.iso8601>")
- write(value.strftime("%Y%m%dT00:00:00"))
- write("</dateTime.iso8601></value>\n")
- dispatch[datetime.date] = dump_date
-
- def dump_time(self, value, write):
- write("<value><dateTime.iso8601>")
- write(datetime.datetime.now().date().strftime("%Y%m%dT"))
- write(value.strftime("%H:%M:%S"))
- write("</dateTime.iso8601></value>\n")
- dispatch[datetime.time] = dump_time
-
- def dump_instance(self, value, write):
- # check for special wrappers
- if value.__class__ in WRAPPERS:
- self.write = write
- value.encode(self)
- del self.write
- else:
- # store instance attributes as a struct (really?)
- self.dump_struct(value.__dict__, write)
- dispatch[InstanceType] = dump_instance
-
-##
-# XML-RPC unmarshaller.
-#
-# @see loads
-
-class Unmarshaller:
- """Unmarshal an XML-RPC response, based on incoming XML event
- messages (start, data, end). Call close() to get the resulting
- data structure.
-
- Note that this reader is fairly tolerant, and gladly accepts bogus
- XML-RPC data without complaining (but not bogus XML).
- """
-
- # and again, if you don't understand what's going on in here,
- # that's perfectly ok.
-
- def __init__(self, use_datetime=0):
- self._type = None
- self._stack = []
- self._marks = []
- self._data = []
- self._methodname = None
- self._encoding = "utf-8"
- self.append = self._stack.append
- self._use_datetime = use_datetime
- if use_datetime and not datetime:
- raise ValueError("the datetime module is not available")
-
- def close(self):
- # return response tuple and target method
- if self._type is None or self._marks:
- raise ResponseError()
- if self._type == "fault":
- raise Fault(**self._stack[0])
- return tuple(self._stack)
-
- def getmethodname(self):
- return self._methodname
-
- #
- # event handlers
-
- def xml(self, encoding, standalone):
- self._encoding = encoding
- # FIXME: assert standalone == 1 ???
-
- def start(self, tag, attrs):
- # prepare to handle this element
- if tag == "array" or tag == "struct":
- self._marks.append(len(self._stack))
- self._data = []
- self._value = (tag == "value")
-
- def data(self, text):
- self._data.append(text)
-
- def end(self, tag, join=string.join):
- # call the appropriate end tag handler
- try:
- f = self.dispatch[tag]
- except KeyError:
- pass # unknown tag ?
- else:
- return f(self, join(self._data, ""))
-
- #
- # accelerator support
-
- def end_dispatch(self, tag, data):
- # dispatch data
- try:
- f = self.dispatch[tag]
- except KeyError:
- pass # unknown tag ?
- else:
- return f(self, data)
-
- #
- # element decoders
-
- dispatch = {}
-
- def end_nil (self, data):
- self.append(None)
- self._value = 0
- dispatch["nil"] = end_nil
-
- def end_boolean(self, data):
- if data == "0":
- self.append(False)
- elif data == "1":
- self.append(True)
- else:
- raise TypeError("bad boolean value")
- self._value = 0
- dispatch["boolean"] = end_boolean
-
- def end_int(self, data):
- self.append(int(data))
- self._value = 0
- dispatch["i4"] = end_int
- dispatch["int"] = end_int
-
- def end_double(self, data):
- self.append(float(data))
- self._value = 0
- dispatch["double"] = end_double
-
- def end_string(self, data):
- if self._encoding:
- data = _decode(data, self._encoding)
- self.append(_stringify(data))
- self._value = 0
- dispatch["string"] = end_string
- dispatch["name"] = end_string # struct keys are always strings
-
- def end_array(self, data):
- mark = self._marks.pop()
- # map arrays to Python lists
- self._stack[mark:] = [self._stack[mark:]]
- self._value = 0
- dispatch["array"] = end_array
-
- def end_struct(self, data):
- mark = self._marks.pop()
- # map structs to Python dictionaries
- dict = {}
- items = self._stack[mark:]
- for i in range(0, len(items), 2):
- dict[_stringify(items[i])] = items[i + 1]
- self._stack[mark:] = [dict]
- self._value = 0
- dispatch["struct"] = end_struct
-
- def end_base64(self, data):
- value = Binary()
- value.decode(data)
- self.append(value)
- self._value = 0
- dispatch["base64"] = end_base64
-
- def end_dateTime(self, data):
- value = DateTime()
- value.decode(data)
- if self._use_datetime:
- value = _datetime_type(data)
- self.append(value)
- dispatch["dateTime.iso8601"] = end_dateTime
-
- def end_value(self, data):
- # if we stumble upon a value element with no internal
- # elements, treat it as a string element
- if self._value:
- self.end_string(data)
- dispatch["value"] = end_value
-
- def end_params(self, data):
- self._type = "params"
- dispatch["params"] = end_params
-
- def end_fault(self, data):
- self._type = "fault"
- dispatch["fault"] = end_fault
-
- def end_methodName(self, data):
- if self._encoding:
- data = _decode(data, self._encoding)
- self._methodname = data
- self._type = "methodName" # no params
- dispatch["methodName"] = end_methodName
-
-## Multicall support
-#
-
-class _MultiCallMethod:
- # some lesser magic to store calls made to a MultiCall object
- # for batch execution
- def __init__(self, call_list, name):
- self.__call_list = call_list
- self.__name = name
- def __getattr__(self, name):
- return _MultiCallMethod(self.__call_list, "%s.%s" % (self.__name, name))
- def __call__(self, *args):
- self.__call_list.append((self.__name, args))
-
-class MultiCallIterator:
- """Iterates over the results of a multicall. Exceptions are
- thrown in response to xmlrpc faults."""
-
- def __init__(self, results):
- self.results = results
-
- def __getitem__(self, i):
- item = self.results[i]
- if type(item) == type({}):
- raise Fault(item['faultCode'], item['faultString'])
- elif type(item) == type([]):
- return item[0]
- else:
- raise ValueError("unexpected type in multicall result")
-
-class MultiCall:
- """server -> a object used to boxcar method calls
-
- server should be a ServerProxy object.
-
- Methods can be added to the MultiCall using normal
- method call syntax e.g.:
-
- multicall = MultiCall(server_proxy)
- multicall.add(2,3)
- multicall.get_address("Guido")
-
- To execute the multicall, call the MultiCall object e.g.:
-
- add_result, address = multicall()
- """
-
- def __init__(self, server):
- self.__server = server
- self.__call_list = []
-
- def __repr__(self):
- return "<MultiCall at %x>" % id(self)
-
- __str__ = __repr__
-
- def __getattr__(self, name):
- return _MultiCallMethod(self.__call_list, name)
-
- def __call__(self):
- marshalled_list = []
- for name, args in self.__call_list:
- marshalled_list.append({'methodName' : name, 'params' : args})
-
- return MultiCallIterator(self.__server.system.multicall(marshalled_list))
-
-# --------------------------------------------------------------------
-# convenience functions
-
-##
-# Create a parser object, and connect it to an unmarshalling instance.
-# This function picks the fastest available XML parser.
-#
-# return A (parser, unmarshaller) tuple.
-
-def getparser(use_datetime=0):
- """getparser() -> parser, unmarshaller
-
- Create an instance of the fastest available parser, and attach it
- to an unmarshalling object. Return both objects.
- """
- if use_datetime and not datetime:
- raise ValueError("the datetime module is not available")
- if FastParser and FastUnmarshaller:
- if use_datetime:
- mkdatetime = _datetime_type
- else:
- mkdatetime = _datetime
- target = FastUnmarshaller(True, False, _binary, mkdatetime, Fault)
- parser = FastParser(target)
- else:
- target = Unmarshaller(use_datetime=use_datetime)
- if FastParser:
- parser = FastParser(target)
- elif SgmlopParser:
- parser = SgmlopParser(target)
- elif ExpatParser:
- parser = ExpatParser(target)
- else:
- parser = SlowParser(target)
- return parser, target
-
-##
-# Convert a Python tuple or a Fault instance to an XML-RPC packet.
-#
-# @def dumps(params, **options)
-# @param params A tuple or Fault instance.
-# @keyparam methodname If given, create a methodCall request for
-# this method name.
-# @keyparam methodresponse If given, create a methodResponse packet.
-# If used with a tuple, the tuple must be a singleton (that is,
-# it must contain exactly one element).
-# @keyparam encoding The packet encoding.
-# @return A string containing marshalled data.
-
-def dumps(params, methodname=None, methodresponse=None, encoding=None,
- allow_none=0):
- """data [,options] -> marshalled data
-
- Convert an argument tuple or a Fault instance to an XML-RPC
- request (or response, if the methodresponse option is used).
-
- In addition to the data object, the following options can be given
- as keyword arguments:
-
- methodname: the method name for a methodCall packet
-
- methodresponse: true to create a methodResponse packet.
- If this option is used with a tuple, the tuple must be
- a singleton (i.e. it can contain only one element).
-
- encoding: the packet encoding (default is UTF-8)
-
- All 8-bit strings in the data structure are assumed to use the
- packet encoding. Unicode strings are automatically converted,
- where necessary.
- """
-
- assert isinstance(params, TupleType) or isinstance(params, Fault), \
- "argument must be tuple or Fault instance"
-
- if isinstance(params, Fault):
- methodresponse = 1
- elif methodresponse and isinstance(params, TupleType):
- assert len(params) == 1, "response tuple must be a singleton"
-
- if not encoding:
- encoding = "utf-8"
-
- if FastMarshaller:
- m = FastMarshaller(encoding)
- else:
- m = Marshaller(encoding, allow_none)
-
- data = m.dumps(params)
-
- if encoding != "utf-8":
- xmlheader = "<?xml version='1.0' encoding='%s'?>\n" % str(encoding)
- else:
- xmlheader = "<?xml version='1.0'?>\n" # utf-8 is default
-
- # standard XML-RPC wrappings
- if methodname:
- # a method call
- if not isinstance(methodname, StringType):
- methodname = methodname.encode(encoding)
- data = (
- xmlheader,
- "<methodCall>\n"
- "<methodName>", methodname, "</methodName>\n",
- data,
- "</methodCall>\n"
- )
- elif methodresponse:
- # a method response, or a fault structure
- data = (
- xmlheader,
- "<methodResponse>\n",
- data,
- "</methodResponse>\n"
- )
- else:
- return data # return as is
- return string.join(data, "")
-
-##
-# Convert an XML-RPC packet to a Python object. If the XML-RPC packet
-# represents a fault condition, this function raises a Fault exception.
-#
-# @param data An XML-RPC packet, given as an 8-bit string.
-# @return A tuple containing the unpacked data, and the method name
-# (None if not present).
-# @see Fault
-
-def loads(data, use_datetime=0):
- """data -> unmarshalled data, method name
-
- Convert an XML-RPC packet to unmarshalled data plus a method
- name (None if not present).
-
- If the XML-RPC packet represents a fault condition, this function
- raises a Fault exception.
- """
- p, u = getparser(use_datetime=use_datetime)
- p.feed(data)
- p.close()
- return u.close(), u.getmethodname()
-
-
-# --------------------------------------------------------------------
-# request dispatcher
-
-class _Method:
- # some magic to bind an XML-RPC method to an RPC server.
- # supports "nested" methods (e.g. examples.getStateName)
- def __init__(self, send, name):
- self.__send = send
- self.__name = name
- def __getattr__(self, name):
- return _Method(self.__send, "%s.%s" % (self.__name, name))
- def __call__(self, *args):
- return self.__send(self.__name, args)
-
-##
-# Standard transport class for XML-RPC over HTTP.
-# <p>
-# You can create custom transports by subclassing this method, and
-# overriding selected methods.
-
-class Transport:
- """Handles an HTTP transaction to an XML-RPC server."""
-
- # client identifier (may be overridden)
- user_agent = "xmlrpclib.py/%s (by www.pythonware.com)" % __version__
-
- def __init__(self, use_datetime=0):
- self._use_datetime = use_datetime
-
- ##
- # Send a complete request, and parse the response.
- #
- # @param host Target host.
- # @param handler Target PRC handler.
- # @param request_body XML-RPC request body.
- # @param verbose Debugging flag.
- # @return Parsed response.
-
- def request(self, host, handler, request_body, verbose=0):
- # issue XML-RPC request
-
- h = self.make_connection(host)
- if verbose:
- h.set_debuglevel(1)
-
- self.send_request(h, handler, request_body)
- self.send_host(h, host)
- self.send_user_agent(h)
- self.send_content(h, request_body)
-
- errcode, errmsg, headers = h.getreply()
-
- if errcode != 200:
- raise ProtocolError(
- host + handler,
- errcode, errmsg,
- headers
- )
-
- self.verbose = verbose
-
- try:
- sock = h._conn.sock
- except AttributeError:
- sock = None
-
- return self._parse_response(h.getfile(), sock)
-
- ##
- # Create parser.
- #
- # @return A 2-tuple containing a parser and a unmarshaller.
-
- def getparser(self):
- # get parser and unmarshaller
- return getparser(use_datetime=self._use_datetime)
-
- ##
- # Get authorization info from host parameter
- # Host may be a string, or a (host, x509-dict) tuple; if a string,
- # it is checked for a "user:pw@host" format, and a "Basic
- # Authentication" header is added if appropriate.
- #
- # @param host Host descriptor (URL or (URL, x509 info) tuple).
- # @return A 3-tuple containing (actual host, extra headers,
- # x509 info). The header and x509 fields may be None.
-
- def get_host_info(self, host):
-
- x509 = {}
- if isinstance(host, TupleType):
- host, x509 = host
-
- import urllib
- auth, host = urllib.splituser(host)
-
- if auth:
- import base64
- auth = base64.encodestring(urllib.unquote(auth))
- auth = string.join(string.split(auth), "") # get rid of whitespace
- extra_headers = [
- ("Authorization", "Basic " + auth)
- ]
- else:
- extra_headers = None
-
- return host, extra_headers, x509
-
- ##
- # Connect to server.
- #
- # @param host Target host.
- # @return A connection handle.
-
- def make_connection(self, host):
- # create a HTTP connection object from a host descriptor
- import httplib
- host, extra_headers, x509 = self.get_host_info(host)
- return httplib.HTTP(host)
-
- ##
- # Send request header.
- #
- # @param connection Connection handle.
- # @param handler Target RPC handler.
- # @param request_body XML-RPC body.
-
- def send_request(self, connection, handler, request_body):
- connection.putrequest("POST", handler)
-
- ##
- # Send host name.
- #
- # @param connection Connection handle.
- # @param host Host name.
-
- def send_host(self, connection, host):
- host, extra_headers, x509 = self.get_host_info(host)
- connection.putheader("Host", host)
- if extra_headers:
- if isinstance(extra_headers, DictType):
- extra_headers = extra_headers.items()
- for key, value in extra_headers:
- connection.putheader(key, value)
-
- ##
- # Send user-agent identifier.
- #
- # @param connection Connection handle.
-
- def send_user_agent(self, connection):
- connection.putheader("User-Agent", self.user_agent)
-
- ##
- # Send request body.
- #
- # @param connection Connection handle.
- # @param request_body XML-RPC request body.
-
- def send_content(self, connection, request_body):
- connection.putheader("Content-Type", "text/xml")
- connection.putheader("Content-Length", str(len(request_body)))
- connection.endheaders()
- if request_body:
- connection.send(request_body)
-
- ##
- # Parse response.
- #
- # @param file Stream.
- # @return Response tuple and target method.
-
- def parse_response(self, file):
- # compatibility interface
- return self._parse_response(file, None)
-
- ##
- # Parse response (alternate interface). This is similar to the
- # parse_response method, but also provides direct access to the
- # underlying socket object (where available).
- #
- # @param file Stream.
- # @param sock Socket handle (or None, if the socket object
- # could not be accessed).
- # @return Response tuple and target method.
-
- def _parse_response(self, file, sock):
- # read response from input file/socket, and parse it
-
- p, u = self.getparser()
-
- while 1:
- if sock:
- response = sock.recv(1024)
- else:
- response = file.read(1024)
- if not response:
- break
- if self.verbose:
- sys.stdout.write("body: %s\n" % repr(response))
- p.feed(response)
-
- file.close()
- p.close()
-
- return u.close()
-
-##
-# Standard transport class for XML-RPC over HTTPS.
-
-class SafeTransport(Transport):
- """Handles an HTTPS transaction to an XML-RPC server."""
-
- # FIXME: mostly untested
-
- def make_connection(self, host):
- # create a HTTPS connection object from a host descriptor
- # host may be a string, or a (host, x509-dict) tuple
- import httplib
- host, extra_headers, x509 = self.get_host_info(host)
- try:
- HTTPS = httplib.HTTPS
- except AttributeError:
- raise NotImplementedError(
- "your version of httplib doesn't support HTTPS"
- )
- else:
- return HTTPS(host, None, **(x509 or {}))
-
-##
-# Standard server proxy. This class establishes a virtual connection
-# to an XML-RPC server.
-# <p>
-# This class is available as ServerProxy and Server. New code should
-# use ServerProxy, to avoid confusion.
-#
-# @def ServerProxy(uri, **options)
-# @param uri The connection point on the server.
-# @keyparam transport A transport factory, compatible with the
-# standard transport class.
-# @keyparam encoding The default encoding used for 8-bit strings
-# (default is UTF-8).
-# @keyparam verbose Use a true value to enable debugging output.
-# (printed to standard output).
-# @see Transport
-
-class ServerProxy:
- """uri [,options] -> a logical connection to an XML-RPC server
-
- uri is the connection point on the server, given as
- scheme://host/target.
-
- The standard implementation always supports the "http" scheme. If
- SSL socket support is available (Python 2.0), it also supports
- "https".
-
- If the target part and the slash preceding it are both omitted,
- "/RPC2" is assumed.
-
- The following options can be given as keyword arguments:
-
- transport: a transport factory
- encoding: the request encoding (default is UTF-8)
-
- All 8-bit strings passed to the server proxy are assumed to use
- the given encoding.
- """
-
- def __init__(self, uri, transport=None, encoding=None, verbose=0,
- allow_none=0, use_datetime=0):
- # establish a "logical" server connection
-
- # get the url
- import urllib
- type, uri = urllib.splittype(uri)
- if type not in ("http", "https"):
- raise IOError("unsupported XML-RPC protocol")
- self.__host, self.__handler = urllib.splithost(uri)
- if not self.__handler:
- self.__handler = "/RPC2"
-
- if transport is None:
- if type == "https":
- transport = SafeTransport(use_datetime=use_datetime)
- else:
- transport = Transport(use_datetime=use_datetime)
- self.__transport = transport
-
- self.__encoding = encoding
- self.__verbose = verbose
- self.__allow_none = allow_none
-
- def __request(self, methodname, params):
- # call a method on the remote server
-
- request = dumps(params, methodname, encoding=self.__encoding,
- allow_none=self.__allow_none)
-
- response = self.__transport.request(
- self.__host,
- self.__handler,
- request,
- verbose=self.__verbose
- )
-
- if len(response) == 1:
- response = response[0]
-
- return response
-
- def __repr__(self):
- return (
- "<ServerProxy for %s%s>" %
- (self.__host, self.__handler)
- )
-
- __str__ = __repr__
-
- def __getattr__(self, name):
- # magic method dispatcher
- return _Method(self.__request, name)
-
- # note: to call a remote object with an non-standard name, use
- # result getattr(server, "strange-python-name")(args)
-
-# compatibility
-
-Server = ServerProxy
-
-# --------------------------------------------------------------------
-# test code
-
-if __name__ == "__main__":
-
- # simple test program (from the XML-RPC specification)
-
- # server = ServerProxy("http://localhost:8000") # local server
- server = ServerProxy("http://time.xmlrpc.com/RPC2")
-
- sys.stdout.write('%s\n' % server)
-
- try:
- sys.stdout.write('%s\n' % (server.currentTime.getCurrentTime(),))
- except Error:
- import traceback;traceback.print_exc()
-
- multi = MultiCall(server)
- multi.currentTime.getCurrentTime()
- multi.currentTime.getCurrentTime()
- try:
- for response in multi():
- sys.stdout.write('%s\n' % (response,))
- except Error:
- import traceback;traceback.print_exc()
diff --git a/python/helpers/pydev/django_debug.py b/python/helpers/pydev/django_debug.py
index 417ff0190e84..2b17864db47e 100644
--- a/python/helpers/pydev/django_debug.py
+++ b/python/helpers/pydev/django_debug.py
@@ -2,6 +2,7 @@ import inspect
from django_frame import DjangoTemplateFrame
from pydevd_comm import CMD_SET_BREAK
from pydevd_constants import DJANGO_SUSPEND, GetThreadId, DictContains
+from pydevd_file_utils import NormFileToServer
from pydevd_breakpoints import LineBreakpoint
import pydevd_vars
import traceback
diff --git a/python/helpers/pydev/fix_getpass.py b/python/helpers/pydev/fix_getpass.py
index c81d93523238..160acc8d1be1 100644
--- a/python/helpers/pydev/fix_getpass.py
+++ b/python/helpers/pydev/fix_getpass.py
@@ -1,10 +1,13 @@
def fixGetpass():
- import getpass
- import warnings
- fallback = getattr(getpass, 'fallback_getpass', None) # >= 2.6
- if not fallback:
- fallback = getpass.default_getpass # <= 2.5
- getpass.getpass = fallback
- if hasattr(getpass, 'GetPassWarning'):
- warnings.simplefilter("ignore", category=getpass.GetPassWarning)
+ try:
+ import getpass
+ except ImportError:
+ return #If we can't import it, we can't fix it
+ import warnings
+ fallback = getattr(getpass, 'fallback_getpass', None) # >= 2.6
+ if not fallback:
+ fallback = getpass.default_getpass # <= 2.5
+ getpass.getpass = fallback
+ if hasattr(getpass, 'GetPassWarning'):
+ warnings.simplefilter("ignore", category=getpass.GetPassWarning)
diff --git a/python/helpers/pydev/merge_pydev_pycharm.txt b/python/helpers/pydev/merge_pydev_pycharm.txt
index 1cbd356958ae..e5e10f7421a1 100644
--- a/python/helpers/pydev/merge_pydev_pycharm.txt
+++ b/python/helpers/pydev/merge_pydev_pycharm.txt
@@ -35,13 +35,25 @@ Done in the merge (started from the PyCharm version and bringing in things from
- When the code is interrupted, the buffer in the python side is cleared.
-- GEvent debugging: for remote debugging, one has to import pydevd before doing the gevent patching -- even if
- pydevd.settrace will only be done later.
-
+- GEvent debugging: improved PyDev not to use the threading module (uses the thread
+ primitives directly), so, gevent debugging can work even if pydevd is used for
+ remote debugging.
+
Also, the gevent debugging should probably be closer to the stackless debugging,
where we actually show the live stackless threads -- so, we should show the live
- gevent greenlets -- which the current version doesn't do.
-
+ gevent greenlets -- which the current version doesn't do (future work).
+
+- Supporting Jython 2.2 onwards (note: CPython only tested with 2.7/3.3)
+
+- When there are big sets/tuples/lists/dicts, the items won't be all shown so that the
+ debugger speed doesn't suffer (the user should use the console if he wants to see
+ those items in this case). The limit was set to show up to 300 items (pydevd_resolver.MAX_ITEMS_TO_HANDLE)
+
+- Monkey-patching qt (QThread/QRunnable) to enable the debugger to work.
+ Notes:
+ - It must be imported before the user actually runs its code (as the definitions of QThread/QRunnable
+ are monkey-patched), so, for the remote debugger to work, pydevd must be imported at the start of
+ the program, even if pydevd.settrace will only be used later on.
Things to be fixed in PyCharm:
--------------------------------
diff --git a/python/helpers/pydev/pycompletionserver.py b/python/helpers/pydev/pycompletionserver.py
index 0b11cb6ff4f7..154ad630aca3 100644
--- a/python/helpers/pydev/pycompletionserver.py
+++ b/python/helpers/pydev/pycompletionserver.py
@@ -17,23 +17,17 @@ except NameError:
setattr(__builtin__, 'True', 1) # Python 3.0 does not accept __builtin__.True = 1 in its syntax
setattr(__builtin__, 'False', 0)
-import pydevd_constants
+from pydevd_constants import IS_JYTHON
-try:
- from java.lang import Thread
- IS_JYTHON = True
+if IS_JYTHON:
+ import java.lang
SERVER_NAME = 'jycompletionserver'
import _pydev_jy_imports_tipper # as _pydev_imports_tipper #changed to be backward compatible with 1.5
_pydev_imports_tipper = _pydev_jy_imports_tipper
-except ImportError:
+else:
# it is python
- IS_JYTHON = False
SERVER_NAME = 'pycompletionserver'
- if pydevd_constants.USE_LIB_COPY:
- from _pydev_threading import Thread
- else:
- from threading import Thread
import _pydev_imports_tipper
@@ -185,14 +179,16 @@ class Processor:
return '%s(%s)%s' % (MSG_COMPLETIONS, ''.join(compMsg), MSG_END)
+class Exit(Exception):
+ pass
-class T(Thread):
+class CompletionServer:
def __init__(self, port):
- Thread.__init__(self)
self.ended = False
self.port = port
self.socket = None # socket to send messages.
+ self.exit_process_on_kill = True
self.processor = Processor()
@@ -266,7 +262,7 @@ class T(Thread):
while data.find(MSG_END) == -1:
received = self.socket.recv(BUFFER_SIZE)
if len(received) == 0:
- sys.exit(0) # ok, connection ended
+ raise Exit() # ok, connection ended
if IS_PYTHON3K:
data = data + received.decode('utf-8')
else:
@@ -278,7 +274,7 @@ class T(Thread):
dbg(SERVER_NAME + ' kill message received', INFO1)
# break if we received kill message.
self.ended = True
- sys.exit(0)
+ raise Exit()
dbg(SERVER_NAME + ' starting keep alive thread', INFO2)
@@ -359,7 +355,7 @@ class T(Thread):
else:
self.send(MSG_INVALID_REQUEST)
- except SystemExit:
+ except Exit:
self.send(self.getCompletionsMessage(None, [('Exit:', 'SystemExit', '')]))
raise
@@ -378,11 +374,12 @@ class T(Thread):
self.socket.close()
self.ended = True
- sys.exit(0) # connection broken
+ raise Exit() # connection broken
- except SystemExit:
- raise
+ except Exit:
+ if self.exit_process_on_kill:
+ sys.exit(0)
# No need to log SystemExit error
except:
s = StringIO.StringIO()
@@ -399,8 +396,6 @@ if __name__ == '__main__':
port = int(sys.argv[1]) # this is from where we want to receive messages.
- t = T(port)
+ t = CompletionServer(port)
dbg(SERVER_NAME + ' will start', INFO1)
- t.start()
- time.sleep(5)
- t.join()
+ t.run()
diff --git a/python/helpers/pydev/pydev_console_utils.py b/python/helpers/pydev/pydev_console_utils.py
index bd7b7de073d2..6e532183b0d1 100644
--- a/python/helpers/pydev/pydev_console_utils.py
+++ b/python/helpers/pydev/pydev_console_utils.py
@@ -1,6 +1,5 @@
from pydev_imports import xmlrpclib, _queue, Exec
import sys
-from pydevd_constants import USE_LIB_COPY
from pydevd_constants import IS_JYTHON
from _pydev_imps import _pydev_thread as thread
import pydevd_xml
@@ -418,10 +417,7 @@ class BaseInterpreterInterface:
try:
# Try to import the packages needed to attach the debugger
import pydevd
- if USE_LIB_COPY:
- import _pydev_threading as threading
- else:
- import threading
+ import _pydev_threading as threading
except:
# This happens on Jython embedded in host eclipse
diff --git a/python/helpers/pydev/pydev_imports.py b/python/helpers/pydev/pydev_imports.py
index 69804a871eaf..c5132cffbfe3 100644
--- a/python/helpers/pydev/pydev_imports.py
+++ b/python/helpers/pydev/pydev_imports.py
@@ -53,9 +53,9 @@ except:
from pydevd_exec2 import Exec
try:
- from urllib import quote
+ from urllib import quote, quote_plus, unquote_plus
except:
- from urllib.parse import quote #@UnresolvedImport
+ from urllib.parse import quote, quote_plus, unquote_plus #@UnresolvedImport
import os
diff --git a/python/helpers/pydev/pydev_ipython/inputhookglut.py b/python/helpers/pydev/pydev_ipython/inputhookglut.py
index e1e67e9930ed..477e48d3d22b 100644
--- a/python/helpers/pydev/pydev_ipython/inputhookglut.py
+++ b/python/helpers/pydev/pydev_ipython/inputhookglut.py
@@ -29,6 +29,7 @@ GLUT Inputhook support functions
#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
+import os
import sys
from _pydev_imps import _pydev_time as time
import signal
diff --git a/python/helpers/pydev/pydev_ipython/inputhookpyglet.py b/python/helpers/pydev/pydev_ipython/inputhookpyglet.py
index 64dd2e559545..94a8ac7adaba 100644
--- a/python/helpers/pydev/pydev_ipython/inputhookpyglet.py
+++ b/python/helpers/pydev/pydev_ipython/inputhookpyglet.py
@@ -20,6 +20,7 @@ Authors
# Imports
#-----------------------------------------------------------------------------
+import os
import sys
from _pydev_imps import _pydev_time as time
from timeit import default_timer as clock
diff --git a/python/helpers/pydev/pydev_ipython/inputhookqt4.py b/python/helpers/pydev/pydev_ipython/inputhookqt4.py
index 27598fa742fe..b7e1cf0527a8 100644
--- a/python/helpers/pydev/pydev_ipython/inputhookqt4.py
+++ b/python/helpers/pydev/pydev_ipython/inputhookqt4.py
@@ -19,11 +19,7 @@ Author: Christian Boos
import os
import signal
-from pydevd_constants import USE_LIB_COPY
-if USE_LIB_COPY:
- import _pydev_threading as threading
-else:
- import threading
+import threading
from pydev_ipython.qt_for_kernel import QtCore, QtGui
diff --git a/python/helpers/pydev/pydev_ipython_console.py b/python/helpers/pydev/pydev_ipython_console.py
index 0c51dfe3ed44..68c26747c6e0 100644
--- a/python/helpers/pydev/pydev_ipython_console.py
+++ b/python/helpers/pydev/pydev_ipython_console.py
@@ -9,7 +9,7 @@ os.environ['TERM'] = 'emacs' #to use proper page_more() for paging
# Uncomment to force PyDev standard shell.
# raise ImportError()
-from pydev_ipython_console_011 import PyDevFrontEnd
+from pydev_ipython_console_011 import get_pydev_frontend
#=======================================================================================================================
# InterpreterInterface
@@ -23,7 +23,7 @@ class InterpreterInterface(BaseInterpreterInterface):
BaseInterpreterInterface.__init__(self, mainThread)
self.client_port = client_port
self.host = host
- self.interpreter = PyDevFrontEnd(host, client_port)
+ self.interpreter = get_pydev_frontend(host, client_port)
self._input_error_printed = False
self.notification_succeeded = False
self.notification_tries = 0
diff --git a/python/helpers/pydev/pydev_ipython_console_011.py b/python/helpers/pydev/pydev_ipython_console_011.py
index 54458e7c4af5..717aaccbc26e 100644
--- a/python/helpers/pydev/pydev_ipython_console_011.py
+++ b/python/helpers/pydev/pydev_ipython_console_011.py
@@ -19,7 +19,6 @@ import os
import codeop
from IPython.core.error import UsageError
-from IPython.core.inputsplitter import IPythonInputSplitter
from IPython.core.completer import IPCompleter
from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
from IPython.core.usage import default_banner_parts
@@ -53,7 +52,8 @@ def show_in_pager(self, strng):
print(strng)
def create_editor_hook(pydev_host, pydev_client_port):
- def call_editor(self, filename, line=0, wait=True):
+
+ def call_editor(filename, line=0, wait=True):
""" Open an editor in PyDev """
if line is None:
line = 0
@@ -62,6 +62,9 @@ def create_editor_hook(pydev_host, pydev_client_port):
# we don't launch a process. This is more like what happens in the zmqshell
filename = os.path.abspath(filename)
+ # import sys
+ # sys.__stderr__.write('Calling editor at: %s:%s\n' % (pydev_host, pydev_client_port))
+
# Tell PyDev to open the editor
server = xmlrpclib.Server('http://%s:%s' % (pydev_host, pydev_client_port))
server.IPythonEditor(filename, str(line))
@@ -291,22 +294,17 @@ class PyDevTerminalInteractiveShell(TerminalInteractiveShell):
InteractiveShellABC.register(PyDevTerminalInteractiveShell) # @UndefinedVariable
#=======================================================================================================================
-# PyDevFrontEnd
+# _PyDevFrontEnd
#=======================================================================================================================
-class PyDevFrontEnd:
+class _PyDevFrontEnd:
version = release.__version__
- def __init__(self, pydev_host, pydev_client_port, *args, **kwarg):
+ def __init__(self, *args, **kwarg):
# Create and initialize our IPython instance.
self.ipython = PyDevTerminalInteractiveShell.instance()
- # Back channel to PyDev to open editors (in the future other
- # info may go back this way. This is the same channel that is
- # used to get stdin, see StdIn in pydev_console_utils)
- self.ipython.set_hook('editor', create_editor_hook(pydev_host, pydev_client_port))
-
# Display the IPython banner, this has version info and
# help info
self.ipython.show_banner()
@@ -412,6 +410,9 @@ class PyDevFrontEnd:
def getNamespace(self):
return self.ipython.user_ns
+
+ def clearBuffer(self):
+ del self._curr_exec_lines[:]
def addExec(self, line):
if self._curr_exec_lines:
@@ -463,3 +464,28 @@ IPython.lib.inputhook.enable_gui = pydev_ipython.inputhook.enable_gui
# rely on using the inputhooks directly.
for name in pydev_ipython.inputhook.__all__:
setattr(IPython.lib.inputhook, name, getattr(pydev_ipython.inputhook, name))
+
+
+class _PyDevFrontEndContainer:
+ _instance = None
+ _last_host_port = None
+
+def get_pydev_frontend(pydev_host, pydev_client_port):
+ if _PyDevFrontEndContainer._instance is None:
+ _PyDevFrontEndContainer._instance = _PyDevFrontEnd()
+
+ if _PyDevFrontEndContainer._last_host_port != (pydev_host, pydev_client_port):
+ _PyDevFrontEndContainer._last_host_port = pydev_host, pydev_client_port
+
+ # Back channel to PyDev to open editors (in the future other
+ # info may go back this way. This is the same channel that is
+ # used to get stdin, see StdIn in pydev_console_utils)
+ _PyDevFrontEndContainer._instance.ipython.hooks['editor'] = create_editor_hook(pydev_host, pydev_client_port)
+
+ # Note: setting the callback directly because setting it with set_hook would actually create a chain instead
+ # of ovewriting at each new call).
+ # _PyDevFrontEndContainer._instance.ipython.set_hook('editor', create_editor_hook(pydev_host, pydev_client_port))
+
+ return _PyDevFrontEndContainer._instance
+
+ \ No newline at end of file
diff --git a/python/helpers/pydev/pydev_localhost.py b/python/helpers/pydev/pydev_localhost.py
index 13c4d02bba9e..eacabb5602ba 100644
--- a/python/helpers/pydev/pydev_localhost.py
+++ b/python/helpers/pydev/pydev_localhost.py
@@ -1,4 +1,4 @@
-
+import pydevd_constants
from _pydev_imps import _pydev_socket as socket
_cache = None
diff --git a/python/helpers/pydev/pydev_monkey.py b/python/helpers/pydev/pydev_monkey.py
index 2b12ed27522c..d92378ed0ee1 100644
--- a/python/helpers/pydev/pydev_monkey.py
+++ b/python/helpers/pydev/pydev_monkey.py
@@ -392,40 +392,42 @@ def patch_new_process_functions_with_warning():
class _NewThreadStartupWithTrace:
- def __init__(self, original_func):
+ def __init__(self, original_func, args, kwargs):
self.original_func = original_func
+ self.args = args
+ self.kwargs = kwargs
- def __call__(self, *args, **kwargs):
+ def __call__(self):
from pydevd_comm import GetGlobalDebugger
global_debugger = GetGlobalDebugger()
if global_debugger is not None:
global_debugger.SetTrace(global_debugger.trace_dispatch)
- return self.original_func(*args, **kwargs)
+ return self.original_func(*self.args, **self.kwargs)
class _NewThreadStartupWithoutTrace:
- def __init__(self, original_func):
+ def __init__(self, original_func, args, kwargs):
self.original_func = original_func
+ self.args = args
+ self.kwargs = kwargs
- def __call__(self, *args, **kwargs):
- return self.original_func(*args, **kwargs)
+ def __call__(self):
+ return self.original_func(*self.args, **self.kwargs)
_UseNewThreadStartup = _NewThreadStartupWithTrace
-def _get_threading_modules():
- threading_modules = []
- from _pydev_imps import _pydev_thread
- threading_modules.append(_pydev_thread)
+def _get_threading_modules_to_patch():
+ threading_modules_to_patch = []
try:
import thread as _thread
- threading_modules.append(_thread)
+ threading_modules_to_patch.append(_thread)
except:
import _thread
- threading_modules.append(_thread)
- return threading_modules
+ threading_modules_to_patch.append(_thread)
+ return threading_modules_to_patch
-threading_modules = _get_threading_modules()
+threading_modules_to_patch = _get_threading_modules_to_patch()
@@ -439,12 +441,12 @@ def patch_thread_module(thread):
class ClassWithPydevStartNewThread:
- def pydev_start_new_thread(self, function, args, kwargs={}):
+ def pydev_start_new_thread(self, function, args=(), kwargs={}):
'''
We need to replace the original thread.start_new_thread with this function so that threads started
through it and not through the threading module are properly traced.
'''
- return _original_start_new_thread(_UseNewThreadStartup(function), args, kwargs)
+ return _original_start_new_thread(_UseNewThreadStartup(function, args, kwargs), ())
# This is a hack for the situation where the thread.start_new_thread is declared inside a class, such as the one below
# class F(object):
@@ -465,11 +467,11 @@ def patch_thread_module(thread):
pass
def patch_thread_modules():
- for t in threading_modules:
+ for t in threading_modules_to_patch:
patch_thread_module(t)
def undo_patch_thread_modules():
- for t in threading_modules:
+ for t in threading_modules_to_patch:
try:
t.start_new_thread = t._original_start_new_thread
except:
@@ -494,3 +496,9 @@ def enable_trace_thread_modules():
'''
global _UseNewThreadStartup
_UseNewThreadStartup = _NewThreadStartupWithTrace
+
+def get_original_start_new_thread(threading_module):
+ try:
+ return threading_module._original_start_new_thread
+ except:
+ return threading_module.start_new_thread
diff --git a/python/helpers/pydev/pydev_monkey_qt.py b/python/helpers/pydev/pydev_monkey_qt.py
new file mode 100644
index 000000000000..9c62686173dd
--- /dev/null
+++ b/python/helpers/pydev/pydev_monkey_qt.py
@@ -0,0 +1,89 @@
+from __future__ import nested_scopes
+
+def set_trace_in_qt():
+ import pydevd_tracing
+ from pydevd_comm import GetGlobalDebugger
+ debugger = GetGlobalDebugger()
+ if debugger is not None:
+ pydevd_tracing.SetTrace(debugger.trace_dispatch)
+
+
+_patched_qt = False
+def patch_qt():
+ '''
+ This method patches qt (PySide or PyQt4) so that we have hooks to set the tracing for QThread.
+ '''
+
+ # Avoid patching more than once
+ global _patched_qt
+ if _patched_qt:
+ return
+
+ _patched_qt = True
+
+ try:
+ from PySide import QtCore
+ except:
+ try:
+ from PyQt4 import QtCore
+ except:
+ return
+
+ _original_thread_init = QtCore.QThread.__init__
+ _original_runnable_init = QtCore.QRunnable.__init__
+
+
+ class FuncWrapper:
+
+ def __init__(self, original):
+ self._original = original
+
+ def __call__(self, *args, **kwargs):
+ set_trace_in_qt()
+ return self._original(*args, **kwargs)
+
+ class StartedSignalWrapper: # Wrapper for the QThread.started signal
+
+ def __init__(self, thread, original_started):
+ self.thread = thread
+ self.original_started = original_started
+
+ def connect(self, func, *args, **kwargs):
+ return self.original_started.connect(FuncWrapper(func), *args, **kwargs)
+
+ def disconnect(self, *args, **kwargs):
+ return self.original_started.disconnect(*args, **kwargs)
+
+ def emit(self, *args, **kwargs):
+ return self.original_started.emit(*args, **kwargs)
+
+
+ class ThreadWrapper(QtCore.QThread): # Wrapper for QThread
+
+ def __init__(self, *args, **kwargs):
+ _original_thread_init(self)
+
+ self._original_run = self.run
+ self.run = self._new_run
+ self._original_started = self.started
+ self.started = StartedSignalWrapper(self, self.started)
+
+ def _new_run(self):
+ set_trace_in_qt()
+ return self._original_run()
+
+ class RunnableWrapper(QtCore.QRunnable): # Wrapper for QRunnable
+
+ def __init__(self, *args, **kwargs):
+ _original_runnable_init(self)
+
+ self._original_run = self.run
+ self.run = self._new_run
+
+
+ def _new_run(self):
+ set_trace_in_qt()
+ return self._original_run()
+
+ QtCore.QThread = ThreadWrapper
+ QtCore.QRunnable = RunnableWrapper
diff --git a/python/helpers/pydev/pydev_run_in_console.py b/python/helpers/pydev/pydev_run_in_console.py
new file mode 100644
index 000000000000..1b8e1d230175
--- /dev/null
+++ b/python/helpers/pydev/pydev_run_in_console.py
@@ -0,0 +1,83 @@
+
+from pydevconsole import *
+
+import pydev_imports
+
+
+def run_file(file, globals=None, locals=None):
+ if os.path.isdir(file):
+ new_target = os.path.join(file, '__main__.py')
+ if os.path.isfile(new_target):
+ file = new_target
+
+ if globals is None:
+ # patch provided by: Scott Schlesier - when script is run, it does not
+ # use globals from pydevd:
+ # This will prevent the pydevd script from contaminating the namespace for the script to be debugged
+
+ # pretend pydevd is not the main module, and
+ # convince the file to be debugged that it was loaded as main
+ sys.modules['pydevd'] = sys.modules['__main__']
+ sys.modules['pydevd'].__name__ = 'pydevd'
+
+ from imp import new_module
+ m = new_module('__main__')
+ sys.modules['__main__'] = m
+ if hasattr(sys.modules['pydevd'], '__loader__'):
+ setattr(m, '__loader__', getattr(sys.modules['pydevd'], '__loader__'))
+
+ m.__file__ = file
+ globals = m.__dict__
+ try:
+ globals['__builtins__'] = __builtins__
+ except NameError:
+ pass # Not there on Jython...
+
+ if locals is None:
+ locals = globals
+
+
+ print('Running %s'%file)
+ pydev_imports.execfile(file, globals, locals) # execute the script
+
+ return globals
+
+#=======================================================================================================================
+# main
+#=======================================================================================================================
+if __name__ == '__main__':
+ sys.stdin = BaseStdIn()
+ port, client_port = sys.argv[1:3]
+
+ del sys.argv[1]
+ del sys.argv[1]
+
+ file = sys.argv[1]
+
+ import pydev_localhost
+
+ if int(port) == 0 and int(client_port) == 0:
+ (h, p) = pydev_localhost.get_socket_name()
+
+ client_port = p
+
+ host = pydev_localhost.get_localhost()
+
+
+ #replace exit (see comments on method)
+ #note that this does not work in jython!!! (sys method can't be replaced).
+ sys.exit = DoExit
+
+ interpreter = InterpreterInterface(host, int(client_port), threading.currentThread())
+
+ server_thread = threading.Thread(target=start_server,
+ name='ServerThread',
+ args=(host, int(port), interpreter))
+ server_thread.setDaemon(True)
+ server_thread.start()
+
+ globals = run_file(file, None, None)
+
+ interpreter.getNamespace().update(globals)
+
+ process_exec_queue(interpreter) \ No newline at end of file
diff --git a/python/helpers/pydev/pydev_runfiles_parallel.py b/python/helpers/pydev/pydev_runfiles_parallel.py
index e14f36d79139..91f55283d5c5 100644
--- a/python/helpers/pydev/pydev_runfiles_parallel.py
+++ b/python/helpers/pydev/pydev_runfiles_parallel.py
@@ -1,4 +1,5 @@
import unittest
+from _pydev_imps import _pydev_thread
try:
import Queue
except:
@@ -282,13 +283,9 @@ class ClientThread(threading.Thread):
if False:
proc = subprocess.Popen(args, env=os.environ, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- stdout_thread = threading.Thread(target=self._reader_thread,args=(proc.stdout, sys.stdout))
- stdout_thread.setDaemon(True)
- stdout_thread.start()
+ _pydev_thread.start_new_thread(self._reader_thread,(proc.stdout, sys.stdout))
- stderr_thread = threading.Thread(target=self._reader_thread,args=(proc.stderr, sys.stderr))
- stderr_thread.setDaemon(True)
- stderr_thread.start()
+ _pydev_thread.start_new_thread(target=self._reader_thread,args=(proc.stderr, sys.stderr))
else:
proc = subprocess.Popen(args, env=os.environ, shell=False)
proc.wait()
diff --git a/python/helpers/pydev/pydev_runfiles_pytest2.py b/python/helpers/pydev/pydev_runfiles_pytest2.py
index e40d60f12e24..6a4d94f532b4 100644
--- a/python/helpers/pydev/pydev_runfiles_pytest2.py
+++ b/python/helpers/pydev/pydev_runfiles_pytest2.py
@@ -1,7 +1,4 @@
-import pickle
-import zlib
-import base64
-import os
+import pickle, zlib, base64, os
import py
from py._code import code # @UnresolvedImport
import pydev_runfiles_xml_rpc
@@ -11,7 +8,6 @@ import sys
import time
-
#===================================================================================================
# Load filters with tests we should skip
#===================================================================================================
diff --git a/python/helpers/pydev/pydev_runfiles_xml_rpc.py b/python/helpers/pydev/pydev_runfiles_xml_rpc.py
index bcaa38a53ae2..062f778ac40e 100644
--- a/python/helpers/pydev/pydev_runfiles_xml_rpc.py
+++ b/python/helpers/pydev/pydev_runfiles_xml_rpc.py
@@ -1,3 +1,4 @@
+import threading
import traceback
import warnings
diff --git a/python/helpers/pydev/pydevconsole.py b/python/helpers/pydev/pydevconsole.py
index 2f07a826aa7d..8d4375f5a5aa 100644
--- a/python/helpers/pydev/pydevconsole.py
+++ b/python/helpers/pydev/pydevconsole.py
@@ -1,3 +1,5 @@
+from _pydev_imps._pydev_thread import start_new_thread
+
try:
from code import InteractiveConsole
except ImportError:
@@ -9,12 +11,7 @@ from code import InteractiveInterpreter
import os
import sys
-from pydevd_constants import USE_LIB_COPY
-
-if USE_LIB_COPY:
- import _pydev_threading as threading
-else:
- import threading
+import _pydev_threading as threading
import traceback
import fix_getpass
@@ -61,13 +58,14 @@ class Command:
self.code_fragment = code_fragment
self.more = None
- @staticmethod
+
def symbol_for_fragment(code_fragment):
if code_fragment.is_single_line:
symbol = 'single'
else:
symbol = 'exec' # Jython doesn't support this
return symbol
+ symbol_for_fragment = staticmethod(symbol_for_fragment)
def run(self):
text = self.code_fragment.text
@@ -228,7 +226,7 @@ except:
#=======================================================================================================================
# _DoExit
#=======================================================================================================================
-def _DoExit(*args):
+def DoExit(*args):
'''
We have to override the exit because calling sys.exit will only actually exit the main thread,
and as we're in a Xml-rpc server, that won't work.
@@ -300,15 +298,11 @@ def start_server(host, port, interpreter):
def StartServer(host, port, client_port):
#replace exit (see comments on method)
#note that this does not work in jython!!! (sys method can't be replaced).
- sys.exit = _DoExit
+ sys.exit = DoExit
interpreter = InterpreterInterface(host, client_port, threading.currentThread())
- server_thread = threading.Thread(target=start_server,
- name='ServerThread',
- args=(host, port, interpreter))
- server_thread.setDaemon(True)
- server_thread.start()
+ start_new_thread(start_server,(host, port, interpreter))
process_exec_queue(interpreter)
diff --git a/python/helpers/pydev/pydevd.py b/python/helpers/pydev/pydevd.py
index 1733c26b5e91..9d0da096c07d 100644
--- a/python/helpers/pydev/pydevd.py
+++ b/python/helpers/pydev/pydevd.py
@@ -1,10 +1,13 @@
#IMPORTANT: pydevd_constants must be the 1st thing defined because it'll keep a reference to the original sys._getframe
from __future__ import nested_scopes # Jython 2.1 support
+from pydevd_constants import * # @UnusedWildImport
+
+import pydev_monkey_qt
+pydev_monkey_qt.patch_qt()
import traceback
from django_debug import DjangoLineBreakpoint
-from pydevd_signature import SignatureFactory
from pydevd_frame import add_exception_to_frame
import pydev_imports
from pydevd_breakpoints import * #@UnusedWildImport
@@ -59,7 +62,8 @@ from pydevd_comm import CMD_CHANGE_VARIABLE, \
StartServer, \
InternalSetNextStatementThread, \
ReloadCodeCommand, \
- CMD_SET_PY_EXCEPTION, \
+ ID_TO_MEANING,\
+ CMD_SET_PY_EXCEPTION, \
CMD_IGNORE_THROWN_EXCEPTION_AT,\
InternalGetBreakpointException, \
InternalSendCurrExceptionTrace,\
@@ -81,14 +85,12 @@ from pydevd_custom_frames import CustomFramesContainer, CustomFramesContainerIni
import pydevd_dont_trace
import pydevd_traceproperty
-from _pydev_imps import _pydev_time as time
+from _pydev_imps import _pydev_time as time, _pydev_thread
-if USE_LIB_COPY:
- import _pydev_threading as threading
-else:
- import threading
+import _pydev_threading as threading
import os
+import atexit
threadingEnumerate = threading.enumerate
@@ -112,9 +114,11 @@ DONT_TRACE = {
'_pydev_execfile.py':1,
'_pydev_jython_execfile.py':1,
'_pydev_threading':1,
+ '_pydev_Queue':1,
'django_debug.py':1,
'django_frame.py':1,
'pydev_log.py':1,
+ 'pydev_monkey.py':1 ,
'pydevd.py':1 ,
'pydevd_additional_thread_info.py':1,
'pydevd_comm.py':1,
@@ -219,7 +223,7 @@ class PyDBCommandThread(PyDBDaemonThread):
def killAllPydevThreads():
- threads = threadingEnumerate()
+ threads = DictKeys(PyDBDaemonThread.created_pydb_daemon_threads)
for t in threads:
if hasattr(t, 'doKillPydevThread'):
t.doKillPydevThread()
@@ -233,12 +237,23 @@ class PyDBCheckAliveThread(PyDBDaemonThread):
def __init__(self, pyDb):
PyDBDaemonThread.__init__(self)
self.pyDb = pyDb
- self.setDaemon(False)
self.setName('pydevd.CheckAliveThread')
def OnRun(self):
if self.dontTraceMe:
- self.pyDb.SetTrace(None) # no debugging on this thread
+
+ disable_tracing = True
+
+ if pydevd_vm_type.GetVmType() == pydevd_vm_type.PydevdVmType.JYTHON and sys.hexversion <= 0x020201f0:
+ # don't run untraced threads if we're in jython 2.2.1 or lower
+ # jython bug: if we start a thread and another thread changes the tracing facility
+ # it affects other threads (it's not set only for the thread but globally)
+ # Bug: http://sourceforge.net/tracker/index.php?func=detail&aid=1870039&group_id=12867&atid=112867
+ disable_tracing = False
+
+ if disable_tracing:
+ pydevd_tracing.SetTrace(None) # no debugging on this thread
+
while not self.killReceived:
if not self.pyDb.haveAliveThreads():
try:
@@ -298,8 +313,8 @@ class PyDB:
self.django_exception_break = {}
self.readyToRun = False
- self._main_lock = threading.Lock()
- self._lock_running_thread_ids = threading.Lock()
+ self._main_lock = _pydev_thread.allocate_lock()
+ self._lock_running_thread_ids = _pydev_thread.allocate_lock()
self._py_db_command_thread_event = threading.Event()
CustomFramesContainer._py_db_command_thread_event = self._py_db_command_thread_event
self._finishDebuggingSession = False
@@ -332,7 +347,17 @@ class PyDB:
def haveAliveThreads(self):
for t in threadingEnumerate():
- if not isinstance(t, PyDBDaemonThread) and isThreadAlive(t) and not t.isDaemon():
+ if isinstance(t, PyDBDaemonThread):
+ pydev_log.error_once(
+ 'Error in debugger: Found PyDBDaemonThread through threading.enumerate().\n')
+
+ if getattr(t, 'is_pydev_daemon_thread', False):
+ #Important: Jython 2.5rc4 has a bug where a thread created with thread.start_new_thread won't be
+ #set as a daemon thread, so, we also have to check for the 'is_pydev_daemon_thread' flag.
+ #See: https://github.com/fabioz/PyDev.Debugger/issues/11
+ continue
+
+ if isThreadAlive(t) and not t.isDaemon():
return True
return False
@@ -387,11 +412,9 @@ class PyDB:
if thread_id == "*":
threads = threadingEnumerate()
for t in threads:
- thread_name = t.getName()
- if not thread_name.startswith('pydevd.') or thread_name == 'pydevd.CommandThread':
- thread_id = GetThreadId(t)
- queue = self.getInternalQueue(thread_id)
- queue.put(int_cmd)
+ thread_id = GetThreadId(t)
+ queue = self.getInternalQueue(thread_id)
+ queue.put(int_cmd)
else:
queue = self.getInternalQueue(thread_id)
@@ -442,7 +465,13 @@ class PyDB:
for t in all_threads:
thread_id = GetThreadId(t)
- if not isinstance(t, PyDBDaemonThread) and isThreadAlive(t):
+ if isinstance(t, PyDBDaemonThread):
+ pydev_log.error_once('Found PyDBDaemonThread in threading.enumerate.')
+
+ elif getattr(t, 'is_pydev_daemon_thread', False):
+ pass # I.e.: skip the DummyThreads created from pydev daemon threads
+
+ elif isThreadAlive(t):
program_threads_alive[thread_id] = t
if not DictContains(self._running_thread_ids, thread_id):
@@ -505,19 +534,18 @@ class PyDB:
threads = threadingEnumerate()
try:
for t in threads:
- if not t.getName().startswith('pydevd.'):
- # TODO: optimize so that we only actually add that tracing if it's in
- # the new breakpoint context.
- additionalInfo = None
- try:
- additionalInfo = t.additionalInfo
- except AttributeError:
- pass # that's ok, no info currently set
-
- if additionalInfo is not None:
- for frame in additionalInfo.IterFrames():
- if frame is not ignore_frame:
- self.SetTraceForFrameAndParents(frame, overwrite_prev_trace=overwrite_prev_trace)
+ # TODO: optimize so that we only actually add that tracing if it's in
+ # the new breakpoint context.
+ additionalInfo = None
+ try:
+ additionalInfo = t.additionalInfo
+ except AttributeError:
+ pass # that's ok, no info currently set
+
+ if additionalInfo is not None:
+ for frame in additionalInfo.IterFrames():
+ if frame is not ignore_frame:
+ self.SetTraceForFrameAndParents(frame, overwrite_prev_trace=overwrite_prev_trace)
finally:
frame = None
t = None
@@ -592,7 +620,7 @@ class PyDB:
it may be worth refactoring it (actually, reordering the ifs so that the ones used mostly come before
probably will give better performance).
'''
- #print ID_TO_MEANING[str(cmd_id)], repr(text)
+ #print(ID_TO_MEANING[str(cmd_id)], repr(text))
self._main_lock.acquire()
try:
@@ -834,7 +862,7 @@ class PyDB:
id_to_pybreakpoint[breakpoint_id] = breakpoint
self.consolidate_breakpoints(file, id_to_pybreakpoint, breakpoints)
- self.setTracingForUntracedContexts()
+ self.setTracingForUntracedContexts(overwrite_prev_trace=True)
elif cmd_id == CMD_REMOVE_BREAK:
#command to remove some breakpoint
@@ -862,7 +890,7 @@ class PyDB:
raise NameError(breakpoint_type)
try:
- id_to_pybreakpoint = file_to_id_to_breakpoint[file]
+ id_to_pybreakpoint = file_to_id_to_breakpoint.get(file, {})
if DebugInfoHolder.DEBUG_TRACE_BREAKPOINTS > 0:
existing = id_to_pybreakpoint[breakpoint_id]
sys.stderr.write('Removed breakpoint:%s - line:%s - func_name:%s (id: %s)\n' % (
@@ -1319,7 +1347,7 @@ class PyDB:
if self._finishDebuggingSession and not self._terminationEventSent:
#that was not working very well because jython gave some socket errors
try:
- threads = threadingEnumerate()
+ threads = DictKeys(PyDBDaemonThread.created_pydb_daemon_threads)
for t in threads:
if hasattr(t, 'doKillPydevThread'):
t.doKillPydevThread()
@@ -1332,10 +1360,10 @@ class PyDB:
is_file_to_ignore = DictContains(DONT_TRACE, base) #we don't want to debug threading or anything related to pydevd
+ #print('trace_dispatch', base, frame.f_lineno, event, frame.f_code.co_name, is_file_to_ignore)
if is_file_to_ignore:
return None
- #print('trace_dispatch', base, frame.f_lineno, event, frame.f_code.co_name)
try:
#this shouldn't give an exception, but it could happen... (python bug)
#see http://mail.python.org/pipermail/python-bugs-list/2007-June/038796.html
@@ -1378,9 +1406,14 @@ class PyDB:
except Exception:
# Log it
- if traceback is not None:
- # This can actually happen during the interpreter shutdown in Python 2.7
- traceback.print_exc()
+ try:
+ if traceback is not None:
+ # This can actually happen during the interpreter shutdown in Python 2.7
+ traceback.print_exc()
+ except:
+ # Error logging? We're really in the interpreter shutdown...
+ # (https://github.com/fabioz/PyDev.Debugger/issues/8)
+ pass
return None
if USE_PSYCO_OPTIMIZATION:
@@ -1401,8 +1434,9 @@ class PyDB:
- def SetTraceForFrameAndParents(self, frame, also_add_to_passed_frame=True, overwrite_prev_trace=False):
- dispatch_func = self.trace_dispatch
+ def SetTraceForFrameAndParents(self, frame, also_add_to_passed_frame=True, overwrite_prev_trace=False, dispatch_func=None):
+ if dispatch_func is None:
+ dispatch_func = self.trace_dispatch
if also_add_to_passed_frame:
self.update_trace(frame, dispatch_func, overwrite_prev_trace)
@@ -1432,15 +1466,8 @@ class PyDB:
def prepareToRun(self):
''' Shared code to prepare debugging by installing traces and registering threads '''
-
- # for completeness, we'll register the pydevd.reader & pydevd.writer threads
- net = NetCommand(str(CMD_THREAD_CREATE), 0, '<xml><thread name="pydevd.reader" id="-1"/></xml>')
- self.writer.addCommand(net)
- net = NetCommand(str(CMD_THREAD_CREATE), 0, '<xml><thread name="pydevd.writer" id="-1"/></xml>')
- self.writer.addCommand(net)
-
- pydevd_tracing.SetTrace(self.trace_dispatch)
self.patch_threads()
+ pydevd_tracing.SetTrace(self.trace_dispatch)
PyDBCommandThread(self).start()
@@ -1519,6 +1546,8 @@ class PyDB:
pydev_imports.execfile(file, globals, locals) # execute the script
+ return globals
+
def exiting(self):
sys.stdout.flush()
sys.stderr.flush()
@@ -1526,6 +1555,22 @@ class PyDB:
cmd = self.cmdFactory.makeExitMessage()
self.writer.addCommand(cmd)
+ def wait_for_commands(self, globals):
+ thread = threading.currentThread()
+ import pydevd_frame_utils
+ frame = pydevd_frame_utils.Frame(None, -1, pydevd_frame_utils.FCode("Console",
+ os.path.abspath(os.path.dirname(__file__))), globals, globals)
+ thread_id = GetThreadId(thread)
+ import pydevd_vars
+ pydevd_vars.addAdditionalFrameById(thread_id, {id(frame): frame})
+
+ cmd = self.cmdFactory.makeShowConsoleMessage(thread_id, frame)
+ self.writer.addCommand(cmd)
+
+ while True:
+ self.processInternalCommands()
+ time.sleep(0.01)
+
def set_debug(setup):
setup['DEBUG_RECORD_SOCKET_READS'] = True
setup['DEBUG_TRACE_BREAKPOINTS'] = 1
@@ -1543,43 +1588,51 @@ def processCommandLine(argv):
setup['multiproc'] = False #Used by PyCharm (reuses connection: ssh tunneling)
setup['multiprocess'] = False # Used by PyDev (creates new connection to ide)
setup['save-signatures'] = False
+ setup['print-in-debugger-startup'] = False
+ setup['cmd-line'] = False
i = 0
del argv[0]
while (i < len(argv)):
- if (argv[i] == '--port'):
+ if argv[i] == '--port':
del argv[i]
setup['port'] = int(argv[i])
del argv[i]
- elif (argv[i] == '--vm_type'):
+ elif argv[i] == '--vm_type':
del argv[i]
setup['vm_type'] = argv[i]
del argv[i]
- elif (argv[i] == '--client'):
+ elif argv[i] == '--client':
del argv[i]
setup['client'] = argv[i]
del argv[i]
- elif (argv[i] == '--server'):
+ elif argv[i] == '--server':
del argv[i]
setup['server'] = True
- elif (argv[i] == '--file'):
+ elif argv[i] == '--file':
del argv[i]
setup['file'] = argv[i]
i = len(argv) # pop out, file is our last argument
- elif (argv[i] == '--DEBUG_RECORD_SOCKET_READS'):
+ elif argv[i] == '--DEBUG_RECORD_SOCKET_READS':
del argv[i]
setup['DEBUG_RECORD_SOCKET_READS'] = True
- elif (argv[i] == '--DEBUG'):
+ elif argv[i] == '--DEBUG':
del argv[i]
set_debug(setup)
- elif (argv[i] == '--multiproc'):
+ elif argv[i] == '--multiproc':
del argv[i]
setup['multiproc'] = True
- elif (argv[i] == '--multiprocess'):
+ elif argv[i] == '--multiprocess':
del argv[i]
setup['multiprocess'] = True
- elif (argv[i] == '--save-signatures'):
+ elif argv[i] == '--save-signatures':
del argv[i]
setup['save-signatures'] = True
+ elif argv[i] == '--print-in-debugger-startup':
+ del argv[i]
+ setup['print-in-debugger-startup'] = True
+ elif (argv[i] == '--cmd-line'):
+ del argv[i]
+ setup['cmd-line'] = True
else:
raise ValueError("unexpected option " + argv[i])
return setup
@@ -1590,18 +1643,6 @@ def usage(doExit=0):
if doExit:
sys.exit(0)
-def SetTraceForParents(frame, dispatch_func):
- frame = frame.f_back
- while frame:
- if frame.f_trace is None:
- frame.f_trace = dispatch_func
-
- frame = frame.f_back
- del frame
-
-def exit_hook():
- debugger = GetGlobalDebugger()
- debugger.exiting()
def initStdoutRedirect():
if not getattr(sys, 'stdoutBuf', None):
@@ -1666,7 +1707,7 @@ def settrace(
-_set_trace_lock = threading.Lock()
+_set_trace_lock = _pydev_thread.allocate_lock()
def _locked_settrace(
host,
@@ -1705,11 +1746,6 @@ def _locked_settrace(
bufferStdOutToServer = stdoutToServer
bufferStdErrToServer = stderrToServer
- net = NetCommand(str(CMD_THREAD_CREATE), 0, '<xml><thread name="pydevd.reader" id="-1"/></xml>')
- debugger.writer.addCommand(net)
- net = NetCommand(str(CMD_THREAD_CREATE), 0, '<xml><thread name="pydevd.writer" id="-1"/></xml>')
- debugger.writer.addCommand(net)
-
if bufferStdOutToServer:
initStdoutRedirect()
@@ -1748,7 +1784,9 @@ def _locked_settrace(
# As this is the first connection, also set tracing for any untraced threads
debugger.setTracingForUntracedContexts(ignore_frame=GetFrame(), overwrite_prev_trace=overwrite_prev_trace)
- sys.exitfunc = exit_hook
+ # Stop the tracing as the last thing before the actual shutdown for a clean exit.
+ atexit.register(stoptrace)
+
#Suspend as the last thing after all tracing is in place.
if suspend:
debugger.setSuspend(t, CMD_SET_BREAK)
@@ -1793,16 +1831,15 @@ def stoptrace():
from pydev_monkey import undo_patch_thread_modules
undo_patch_thread_modules()
-
+
debugger = GetGlobalDebugger()
-
+
if debugger:
- debugger.trace_dispatch = None
-
- debugger.SetTraceForFrameAndParents(GetFrame(), False)
-
+
+ debugger.SetTraceForFrameAndParents(
+ GetFrame(), also_add_to_passed_frame=True, overwrite_prev_trace=True, dispatch_func=lambda *args:None)
debugger.exiting()
-
+
killAllPydevThreads()
connected = False
@@ -1830,6 +1867,11 @@ class DispatchReader(ReaderThread):
self.dispatcher = dispatcher
ReaderThread.__init__(self, self.dispatcher.client)
+ def OnRun(self):
+ dummy_thread = threading.currentThread()
+ dummy_thread.is_pydev_daemon_thread = False
+ return ReaderThread.OnRun(self)
+
def handleExcept(self):
ReaderThread.handleExcept(self)
@@ -1893,6 +1935,7 @@ class SetupHolder:
# main
#=======================================================================================================================
if __name__ == '__main__':
+
# parse the command line. --file is our last argument that is required
try:
sys.original_argv = sys.argv[:]
@@ -1902,6 +1945,12 @@ if __name__ == '__main__':
traceback.print_exc()
usage(1)
+ if setup['print-in-debugger-startup']:
+ try:
+ pid = ' (pid: %s)' % os.getpid()
+ except:
+ pid = ''
+ sys.stderr.write("pydev debugger: starting%s\n" % pid)
fix_getpass.fixGetpass()
@@ -2010,6 +2059,12 @@ if __name__ == '__main__':
except:
pass # It's ok not having stackless there...
+ debugger = PyDB()
+
+ if setup['cmd-line']:
+ debugger.cmd_line = True
+
+
if fix_app_engine_debug:
sys.stderr.write("pydev debugger: google app engine integration enabled\n")
curr_dir = os.path.dirname(__file__)
@@ -2022,10 +2077,8 @@ if __name__ == '__main__':
sys.argv.insert(3, '--automatic_restart=no')
sys.argv.insert(4, '--max_module_instances=1')
- debugger = PyDB()
# Run the dev_appserver
debugger.run(setup['file'], None, None, set_trace=False)
-
else:
# as to get here all our imports are already resolved, the psyco module can be
# changed and we'll still get the speedups in the debugger, as those functions
@@ -2041,12 +2094,12 @@ if __name__ == '__main__':
import pydevd_psyco_stub
sys.modules['psyco'] = pydevd_psyco_stub
- debugger = PyDB()
-
if setup['save-signatures']:
if pydevd_vm_type.GetVmType() == pydevd_vm_type.PydevdVmType.JYTHON:
sys.stderr.write("Collecting run-time type information is not supported for Jython\n")
else:
+ # Only import it if we're going to use it!
+ from pydevd_signature import SignatureFactory
debugger.signature_factory = SignatureFactory()
try:
@@ -2058,4 +2111,9 @@ if __name__ == '__main__':
connected = True # Mark that we're connected when started from inside ide.
- debugger.run(setup['file'], None, None)
+ globals = debugger.run(setup['file'], None, None)
+
+ if setup['cmd-line']:
+ debugger.wait_for_commands(globals)
+
+
diff --git a/python/helpers/pydev/pydevd_additional_thread_info.py b/python/helpers/pydev/pydevd_additional_thread_info.py
index fa906adf385e..76fb49ed1986 100644
--- a/python/helpers/pydev/pydevd_additional_thread_info.py
+++ b/python/helpers/pydev/pydevd_additional_thread_info.py
@@ -1,9 +1,6 @@
import sys
from pydevd_constants import * #@UnusedWildImport
-if USE_LIB_COPY:
- import _pydev_threading as threading
-else:
- import threading
+from _pydev_imps import _pydev_thread
from pydevd_frame import PyDBFrame
import weakref
@@ -62,7 +59,7 @@ class PyDBAdditionalThreadInfoWithoutCurrentFramesSupport(AbstractPyDBAdditional
#Or if the user compiled threadframe (from http://www.majid.info/mylos/stories/2004/06/10/threadframe.html)
#NOT RLock!! (could deadlock if it was)
- self.lock = threading.Lock()
+ self.lock = _pydev_thread.allocate_lock()
self._acquire_lock = self.lock.acquire
self._release_lock = self.lock.release
diff --git a/python/helpers/pydev/pydevd_breakpoints.py b/python/helpers/pydev/pydevd_breakpoints.py
index 82a230db2f47..1171157257e9 100644
--- a/python/helpers/pydev/pydevd_breakpoints.py
+++ b/python/helpers/pydev/pydevd_breakpoints.py
@@ -8,10 +8,7 @@ _original_excepthook = None
_handle_exceptions = None
-if USE_LIB_COPY:
- import _pydev_threading as threading
-else:
- import threading
+import _pydev_threading as threading
threadingCurrentThread = threading.currentThread
diff --git a/python/helpers/pydev/pydevd_comm.py b/python/helpers/pydev/pydevd_comm.py
index c7f39a16c483..92a588cbaa93 100644
--- a/python/helpers/pydev/pydevd_comm.py
+++ b/python/helpers/pydev/pydevd_comm.py
@@ -61,12 +61,9 @@ from pydevd_constants import * #@UnusedWildImport
import sys
-from _pydev_imps import _pydev_time as time
-
-if USE_LIB_COPY:
- import _pydev_threading as threading
-else:
- import threading
+from _pydev_imps import _pydev_time as time, _pydev_thread
+from _pydev_imps import _pydev_thread as thread
+import _pydev_threading as threading
from _pydev_imps._pydev_socket import socket, AF_INET, SOCK_STREAM, SHUT_RD, SHUT_WR
from pydev_imports import _queue
@@ -137,6 +134,7 @@ CMD_SEND_CURR_EXCEPTION_TRACE = 138
CMD_SEND_CURR_EXCEPTION_TRACE_PROCEEDED = 139
CMD_IGNORE_THROWN_EXCEPTION_AT = 140
CMD_ENABLE_DONT_TRACE = 141
+CMD_SHOW_CONSOLE = 142
@@ -246,22 +244,42 @@ def SetGlobalDebugger(dbg):
#=======================================================================================================================
# PyDBDaemonThread
#=======================================================================================================================
-class PyDBDaemonThread(threading.Thread):
+class PyDBDaemonThread:
+
+ created_pydb_daemon_threads = {}
def __init__(self):
- threading.Thread.__init__(self)
- self.setDaemon(True)
+ # Note: subclasses are always daemon threads.
self.killReceived = False
self.dontTraceMe = True
- def run(self):
- if sys.platform.startswith("java"):
- import org.python.core as PyCore #@UnresolvedImport
- ss = PyCore.PySystemState()
- # Note: Py.setSystemState() affects only the current thread.
- PyCore.Py.setSystemState(ss)
+ def setName(self, name):
+ self.name = name
- self.OnRun()
+ def start(self):
+ import pydev_monkey
+ start_new_thread = pydev_monkey.get_original_start_new_thread(_pydev_thread)
+ start_new_thread(self.run, ())
+
+ def run(self):
+ created_pydb_daemon = self.created_pydb_daemon_threads
+ created_pydb_daemon[self] = 1
+ dummy_thread = threading.currentThread()
+ dummy_thread.is_pydev_daemon_thread = True
+ try:
+ try:
+ if IS_JYTHON:
+ import org.python.core as PyCore #@UnresolvedImport
+ ss = PyCore.PySystemState()
+ # Note: Py.setSystemState() affects only the current thread.
+ PyCore.Py.setSystemState(ss)
+
+ self.OnRun()
+ except:
+ if sys is not None and traceback is not None:
+ traceback.print_exc()
+ finally:
+ del created_pydb_daemon[self]
def OnRun(self):
raise NotImplementedError('Should be reimplemented by: %s' % self.__class__)
@@ -272,7 +290,18 @@ class PyDBDaemonThread(threading.Thread):
def stopTrace(self):
if self.dontTraceMe:
- pydevd_tracing.SetTrace(None) # no debugging on this thread
+
+ disable_tracing = True
+
+ if pydevd_vm_type.GetVmType() == pydevd_vm_type.PydevdVmType.JYTHON and sys.hexversion <= 0x020201f0:
+ # don't run untraced threads if we're in jython 2.2.1 or lower
+ # jython bug: if we start a thread and another thread changes the tracing facility
+ # it affects other threads (it's not set only for the thread but globally)
+ # Bug: http://sourceforge.net/tracker/index.php?func=detail&aid=1870039&group_id=12867&atid=112867
+ disable_tracing = False
+
+ if disable_tracing:
+ pydevd_tracing.SetTrace(None) # no debugging on this thread
#=======================================================================================================================
@@ -355,7 +384,6 @@ class WriterThread(PyDBDaemonThread):
""" writer thread writes out the commands in an infinite loop """
def __init__(self, sock):
PyDBDaemonThread.__init__(self)
- self.setDaemon(False) #writer isn't daemon to be able to deliver all messages after main thread terminated
self.sock = sock
self.setName("pydevd.Writer")
self.cmdQueue = _queue.Queue()
@@ -373,11 +401,16 @@ class WriterThread(PyDBDaemonThread):
""" just loop and write responses """
self.stopTrace()
+ get_has_timeout = sys.hexversion >= 0x02030000 # 2.3 onwards have it.
try:
while True:
try:
try:
- cmd = self.cmdQueue.get(1, 0.1)
+ if get_has_timeout:
+ cmd = self.cmdQueue.get(1, 0.1)
+ else:
+ time.sleep(.01)
+ cmd = self.cmdQueue.get(0)
except _queue.Empty:
if self.killReceived:
try:
@@ -734,6 +767,12 @@ class NetCommandFactory:
dbg.writer.addCommand(net)
return net
+ def makeShowConsoleMessage(self, thread_id, frame):
+ try:
+ return NetCommand(CMD_SHOW_CONSOLE, 0, self.makeThreadSuspendStr(thread_id, frame, CMD_SHOW_CONSOLE, ''))
+ except:
+ return self.makeErrorMessage(0, GetExceptionTracebackStr())
+
def makeExitMessage(self):
try:
net = NetCommand(CMD_EXIT, 0, '')
@@ -774,7 +813,7 @@ class ReloadCodeCommand(InternalThreadCommand):
self.thread_id = thread_id
self.module_name = module_name
self.executed = False
- self.lock = threading.Lock()
+ self.lock = _pydev_thread.allocate_lock()
def canBeExecutedBy(self, thread_id):
@@ -1155,8 +1194,8 @@ class InternalEvaluateConsoleExpression(InternalThreadCommand):
from pydevd_console import ConsoleMessage
console_message = ConsoleMessage()
console_message.add_console_message(
- pydevd_console.CONSOLE_ERROR,
- "Select the valid frame in the debug view (thread: %s, frame: %s invalid)" % (self.thread_id, self.frame_id),
+ pydevd_console.CONSOLE_ERROR,
+ "Select the valid frame in the debug view (thread: %s, frame: %s invalid)" % (self.thread_id, self.frame_id),
)
cmd = dbg.cmdFactory.makeErrorMessage(self.sequence, console_message.toXML())
except:
diff --git a/python/helpers/pydev/pydevd_constants.py b/python/helpers/pydev/pydevd_constants.py
index 74e897461458..e878d3b48ead 100644
--- a/python/helpers/pydev/pydevd_constants.py
+++ b/python/helpers/pydev/pydevd_constants.py
@@ -72,13 +72,10 @@ except AttributeError:
SUPPORT_GEVENT = os.getenv('GEVENT_SUPPORT', 'False') == 'True'
USE_LIB_COPY = SUPPORT_GEVENT and not IS_PY3K and sys.version_info[1] >= 6
+import _pydev_threading as threading
-if USE_LIB_COPY:
- import _pydev_threading as threading
-else:
- import threading
-
-_nextThreadIdLock = threading.Lock()
+from _pydev_imps import _pydev_thread
+_nextThreadIdLock = _pydev_thread.allocate_lock()
#=======================================================================================================================
# Jython?
diff --git a/python/helpers/pydev/pydevd_custom_frames.py b/python/helpers/pydev/pydevd_custom_frames.py
index e259356b8336..8709e6a17dd6 100644
--- a/python/helpers/pydev/pydevd_custom_frames.py
+++ b/python/helpers/pydev/pydevd_custom_frames.py
@@ -1,5 +1,6 @@
from pydevd_constants import * #@UnusedWildImport
from pydevd_file_utils import GetFilenameAndBase
+from _pydev_imps import _pydev_thread
threadingCurrentThread = threading.currentThread
DEBUG = False
@@ -13,7 +14,7 @@ class CustomFramesContainer:
def CustomFramesContainerInit(): #Note: no staticmethod on jython 2.1 (so, use free-function)
- CustomFramesContainer.custom_frames_lock = threading.Lock()
+ CustomFramesContainer.custom_frames_lock = _pydev_thread.allocate_lock()
# custom_frames can only be accessed if properly locked with custom_frames_lock!
# Key is a string identifying the frame (as well as the thread it belongs to).
diff --git a/python/helpers/pydev/pydevd_file_utils.py b/python/helpers/pydev/pydevd_file_utils.py
index c135c4bd5ad4..147aa66b946d 100644
--- a/python/helpers/pydev/pydevd_file_utils.py
+++ b/python/helpers/pydev/pydevd_file_utils.py
@@ -38,6 +38,10 @@
machine for the paths that'll actually have breakpoints).
'''
+
+
+
+from pydevd_constants import * #@UnusedWildImport
import os.path
import sys
import traceback
diff --git a/python/helpers/pydev/pydevd_frame.py b/python/helpers/pydev/pydevd_frame.py
index 374d2818bf87..5d1e78458391 100644
--- a/python/helpers/pydev/pydevd_frame.py
+++ b/python/helpers/pydev/pydevd_frame.py
@@ -15,7 +15,11 @@ from pydevd_comm import CMD_ADD_DJANGO_EXCEPTION_BREAK, \
CMD_STEP_INTO, CMD_SMART_STEP_INTO, CMD_RUN_TO_LINE, CMD_SET_NEXT_STATEMENT
from pydevd_constants import * # @UnusedWildImport
from pydevd_file_utils import GetFilenameAndBase
-from pydevd_signature import sendSignatureCallTrace
+try:
+ from pydevd_signature import sendSignatureCallTrace
+except ImportError:
+ def sendSignatureCallTrace(*args, **kwargs):
+ pass
import pydevd_vars
import pydevd_dont_trace
diff --git a/python/helpers/pydev/pydevd_frame_utils.py b/python/helpers/pydev/pydevd_frame_utils.py
new file mode 100644
index 000000000000..23becca0570d
--- /dev/null
+++ b/python/helpers/pydev/pydevd_frame_utils.py
@@ -0,0 +1,21 @@
+class Frame:
+ def __init__(
+ self,
+ f_back,
+ f_fileno,
+ f_code,
+ f_locals,
+ f_globals={},
+ f_trace=None):
+ self.f_back = f_back
+ self.f_lineno = f_fileno
+ self.f_code = f_code
+ self.f_locals = f_locals
+ self.f_globals = f_globals
+ self.f_trace = f_trace
+
+
+class FCode:
+ def __init__(self, name, filename):
+ self.co_name = name
+ self.co_filename = filename \ No newline at end of file
diff --git a/python/helpers/pydev/pydevd_resolver.py b/python/helpers/pydev/pydevd_resolver.py
index 3fe895c504a7..ad49bd881ba0 100644
--- a/python/helpers/pydev/pydevd_resolver.py
+++ b/python/helpers/pydev/pydevd_resolver.py
@@ -13,10 +13,13 @@ except:
setattr(__builtin__, 'False', 0)
import pydevd_constants
-from pydevd_constants import DictIterItems, xrange, izip
+from pydevd_constants import DictIterItems, xrange
-MAX_ITEMS_TO_HANDLE = 500
+# Note: 300 is already a lot to see in the outline (after that the user should really use the shell to get things)
+# and this also means we'll pass less information to the client side (which makes debugging faster).
+MAX_ITEMS_TO_HANDLE = 300
+
TOO_LARGE_MSG = 'Too large to show contents. Max items to show: ' + str(MAX_ITEMS_TO_HANDLE)
TOO_LARGE_ATTR = 'Unable to handle:'
@@ -272,19 +275,20 @@ class TupleResolver: #to enumerate tuples and lists
return var[int(attribute)]
def getDictionary(self, var):
- #return dict( [ (i, x) for i, x in enumerate(var) ] )
- # modified 'cause jython does not have enumerate support
l = len(var)
d = {}
- if l < MAX_ITEMS_TO_HANDLE:
- format = '%0' + str(int(len(str(l)))) + 'd'
-
+ format_str = '%0' + str(int(len(str(l)))) + 'd'
- for i, item in izip(xrange(l), var):
- d[ format % i ] = item
- else:
- d[TOO_LARGE_ATTR] = TOO_LARGE_MSG
+ i = 0
+ for item in var:
+ d[format_str % i] = item
+ i += 1
+
+ if i > MAX_ITEMS_TO_HANDLE:
+ d[TOO_LARGE_ATTR] = TOO_LARGE_MSG
+ break
+
d['__len__'] = len(var)
return d
@@ -381,13 +385,24 @@ class NdArrayResolver:
This resolves a numpy ndarray returning some metadata about the NDArray
'''
+ def is_numeric(self, obj):
+ if not hasattr(obj, 'dtype'):
+ return False
+ return obj.dtype.kind in 'biufc'
+
def resolve(self, obj, attribute):
if attribute == '__internals__':
return defaultResolver.getDictionary(obj)
if attribute == 'min':
- return obj.min()
+ if self.is_numeric(obj):
+ return obj.min()
+ else:
+ return None
if attribute == 'max':
- return obj.max()
+ if self.is_numeric(obj):
+ return obj.max()
+ else:
+ return None
if attribute == 'shape':
return obj.shape
if attribute == 'dtype':
@@ -403,8 +418,12 @@ class NdArrayResolver:
ret['min'] = 'ndarray too big, calculating min would slow down debugging'
ret['max'] = 'ndarray too big, calculating max would slow down debugging'
else:
- ret['min'] = obj.min()
- ret['max'] = obj.max()
+ if self.is_numeric(obj):
+ ret['min'] = obj.min()
+ ret['max'] = obj.max()
+ else:
+ ret['min'] = 'not a numeric object'
+ ret['max'] = 'not a numeric object'
ret['shape'] = obj.shape
ret['dtype'] = obj.dtype
ret['size'] = obj.size
diff --git a/python/helpers/pydev/pydevd_signature.py b/python/helpers/pydev/pydevd_signature.py
index 03dc0eb9c98b..d7b37c84cb76 100644
--- a/python/helpers/pydev/pydevd_signature.py
+++ b/python/helpers/pydev/pydevd_signature.py
@@ -1,8 +1,13 @@
import inspect
-import trace
import os
-trace._warn = lambda *args: None # workaround for http://bugs.python.org/issue17143 (PY-8706)
+try:
+ import trace
+except ImportError:
+ pass
+else:
+ trace._warn = lambda *args: None # workaround for http://bugs.python.org/issue17143 (PY-8706)
+
import gc
from pydevd_comm import CMD_SIGNATURE_CALL_TRACE, NetCommand
import pydevd_vars
diff --git a/python/helpers/pydev/pydevd_tracing.py b/python/helpers/pydev/pydevd_tracing.py
index 7bc1ba5c2c23..d362462013a9 100644
--- a/python/helpers/pydev/pydevd_tracing.py
+++ b/python/helpers/pydev/pydevd_tracing.py
@@ -1,4 +1,5 @@
from pydevd_constants import * #@UnusedWildImport
+from _pydev_imps import _pydev_thread
try:
import cStringIO as StringIO #may not always be available @UnusedImport
@@ -8,10 +9,6 @@ except:
except:
import io as StringIO
-if USE_LIB_COPY:
- import _pydev_threading as threading
-else:
- import threading
import sys #@Reimport
import traceback
@@ -21,7 +18,7 @@ class TracingFunctionHolder:
'''
_original_tracing = None
_warn = True
- _lock = threading.Lock()
+ _lock = _pydev_thread.allocate_lock()
_traceback_limit = 1
_warnings_shown = {}
diff --git a/python/helpers/pydev/pydevd_vars.py b/python/helpers/pydev/pydevd_vars.py
index 0cc45f73710f..3baea5b61b99 100644
--- a/python/helpers/pydev/pydevd_vars.py
+++ b/python/helpers/pydev/pydevd_vars.py
@@ -3,10 +3,12 @@
"""
import pickle
from django_frame import DjangoTemplateFrame
+from pydevd_constants import * #@UnusedWildImport
from types import * #@UnusedWildImport
from pydevd_custom_frames import getCustomFrame
from pydevd_xml import *
+from _pydev_imps import _pydev_thread
try:
from StringIO import StringIO
@@ -14,13 +16,10 @@ except ImportError:
from io import StringIO
import sys #@Reimport
-if USE_LIB_COPY:
- import _pydev_threading as threading
-else:
- import threading
+import _pydev_threading as threading
import traceback
import pydevd_save_locals
-from pydev_imports import Exec, execfile
+from pydev_imports import Exec, quote, execfile
try:
import types
@@ -69,7 +68,7 @@ def dumpFrames(thread_id):
# AdditionalFramesContainer
#===============================================================================
class AdditionalFramesContainer:
- lock = threading.Lock()
+ lock = _pydev_thread.allocate_lock()
additional_frames = {} #dict of dicts
diff --git a/python/helpers/pydev/requirements.txt b/python/helpers/pydev/requirements.txt
new file mode 100644
index 000000000000..048a4c65c919
--- /dev/null
+++ b/python/helpers/pydev/requirements.txt
@@ -0,0 +1,4 @@
+Django==1.6.5
+nose==1.3.3
+ipython==2.1.0
+numpy==1.8.2 \ No newline at end of file
diff --git a/python/helpers/pydev/runfiles.py b/python/helpers/pydev/runfiles.py
index 67c88be4fe7c..c2db611055c4 100644
--- a/python/helpers/pydev/runfiles.py
+++ b/python/helpers/pydev/runfiles.py
@@ -75,7 +75,7 @@ def main():
if test_framework == 0:
- pydev_runfiles.main(configuration)
+ return pydev_runfiles.main(configuration) #Note: still doesn't return a proper value.
else:
#We'll convert the parameters to what nose or py.test expects.
@@ -144,7 +144,8 @@ def main():
import pydev_runfiles_nose
PYDEV_NOSE_PLUGIN_SINGLETON = pydev_runfiles_nose.StartPydevNosePluginSingleton(configuration)
argv.append('--with-pydevplugin')
- nose.run(argv=argv, addplugins=[PYDEV_NOSE_PLUGIN_SINGLETON])
+ # Return 'not' because it will return 'success' (so, exit == 0 if success)
+ return not nose.run(argv=argv, addplugins=[PYDEV_NOSE_PLUGIN_SINGLETON])
elif test_framework == PY_TEST_FRAMEWORK:
if DEBUG:
@@ -189,7 +190,7 @@ def main():
argv.append('-p')
argv.append('pydev_runfiles_pytest2')
- pytest.main(argv)
+ return pytest.main(argv)
else:
raise AssertionError('Cannot handle test framework: %s at this point.' % (test_framework,))
diff --git a/python/helpers/pydev/tests/check_pydevconsole.py b/python/helpers/pydev/tests/test_check_pydevconsole.py
index 7d1b7eed4e0b..5d09968cfe19 100644
--- a/python/helpers/pydev/tests/check_pydevconsole.py
+++ b/python/helpers/pydev/tests/test_check_pydevconsole.py
@@ -1,19 +1,11 @@
-import sys
-import os
-
-#Put pydevconsole in the path.
-sys.argv[0] = os.path.dirname(sys.argv[0])
-sys.path.insert(1, os.path.join(os.path.dirname(sys.argv[0])))
-
-print('Running tests with:', sys.executable)
-print('PYTHONPATH:')
-print('\n'.join(sorted(sys.path)))
-
import threading
import unittest
import pydevconsole
from pydev_imports import xmlrpclib, SimpleXMLRPCServer
+import sys
+from pydev_localhost import get_localhost
+from pydev_ipython_console_011 import get_pydev_frontend
try:
raw_input
@@ -36,17 +28,28 @@ class Test(unittest.TestCase):
def run(self):
class HandleRequestInput:
def RequestInput(self):
+ client_thread.requested_input = True
return 'RequestInput: OK'
+
+ def NotifyFinished(self, *args, **kwargs):
+ client_thread.notified_finished += 1
+ return 1
handle_request_input = HandleRequestInput()
import pydev_localhost
- print('Starting client with:', pydev_localhost.get_localhost(), self.client_port)
- client_server = SimpleXMLRPCServer((pydev_localhost.get_localhost(), self.client_port), logRequests=False)
+ self.client_server = client_server = SimpleXMLRPCServer((pydev_localhost.get_localhost(), self.client_port), logRequests=False)
client_server.register_function(handle_request_input.RequestInput)
+ client_server.register_function(handle_request_input.NotifyFinished)
client_server.serve_forever()
-
+
+ def shutdown(self):
+ return
+ self.client_server.shutdown()
+
client_thread = ClientThread(client_port)
+ client_thread.requested_input = False
+ client_thread.notified_finished = 0
client_thread.setDaemon(True)
client_thread.start()
return client_thread
@@ -67,6 +70,9 @@ class Test(unittest.TestCase):
def testServer(self):
+ # Just making sure that the singleton is created in this thread.
+ get_pydev_frontend(get_localhost(), 0)
+
client_port, server_port = self.getFreeAddresses()
class ServerThread(threading.Thread):
def __init__(self, client_port, server_port):
@@ -84,18 +90,27 @@ class Test(unittest.TestCase):
client_thread = self.startClientThread(client_port) #@UnusedVariable
- import time
- time.sleep(.3) #let's give it some time to start the threads
-
- import pydev_localhost
- server = xmlrpclib.Server('http://%s:%s' % (pydev_localhost.get_localhost(), server_port))
- server.addExec("import sys; print('Running with: %s %s' % (sys.executable or sys.platform, sys.version))")
- server.addExec('class Foo:')
- server.addExec(' pass')
- server.addExec('')
- server.addExec('foo = Foo()')
- server.addExec('a = %s()' % raw_input_name)
- server.addExec('print (a)')
+ try:
+ import time
+ time.sleep(.3) #let's give it some time to start the threads
+
+ import pydev_localhost
+ server = xmlrpclib.Server('http://%s:%s' % (pydev_localhost.get_localhost(), server_port))
+ server.execLine("import sys; print('Running with: %s %s' % (sys.executable or sys.platform, sys.version))")
+ server.execLine('class Foo:')
+ server.execLine(' pass')
+ server.execLine('')
+ server.execLine('foo = Foo()')
+ server.execLine('a = %s()' % raw_input_name)
+ initial = time.time()
+ while not client_thread.requested_input:
+ if time.time() - initial > 2:
+ raise AssertionError('Did not get the return asked before the timeout.')
+ time.sleep(.1)
+ frame_xml = server.getFrame()
+ self.assert_('RequestInput' in frame_xml, 'Did not fid RequestInput in:\n%s' % (frame_xml,))
+ finally:
+ client_thread.shutdown()
#=======================================================================================================================
# main
diff --git a/python/helpers/pydev/tests/test_get_referrers.py b/python/helpers/pydev/tests/test_get_referrers.py
index 7fc85142b02e..8284b2779c40 100644
--- a/python/helpers/pydev/tests/test_get_referrers.py
+++ b/python/helpers/pydev/tests/test_get_referrers.py
@@ -1,21 +1,7 @@
-import os.path
import sys
import threading
import time
-IS_JYTHON = sys.platform.find('java') != -1
-
-try:
- this_file_name = __file__
-except NameError:
- # stupid jython. plain old __file__ isnt working for some reason
- import test_runfiles #@UnresolvedImport - importing the module itself
- this_file_name = test_runfiles.__file__
-
-
-desired_runfiles_path = os.path.normpath(os.path.dirname(this_file_name) + "/..")
-sys.path.insert(0, desired_runfiles_path)
-
import unittest
import pydevd_referrers
from pydev_imports import StringIO
diff --git a/python/helpers/pydev/tests/test_jyserver.py b/python/helpers/pydev/tests/test_jyserver.py
index 8765400ae39d..12be8bcf5b1b 100644
--- a/python/helpers/pydev/tests/test_jyserver.py
+++ b/python/helpers/pydev/tests/test_jyserver.py
@@ -36,10 +36,15 @@ class Test(unittest.TestCase):
unittest.TestCase.tearDown(self)
def testIt(self):
+ if not IS_JYTHON:
+ return
dbg('ok')
def testMessage(self):
+ if not IS_JYTHON:
+ return
t = jycompletionserver.T(0)
+ t.exit_process_on_kill = False
l = []
l.append(('Def', 'description' , 'args'))
@@ -65,6 +70,8 @@ class Test(unittest.TestCase):
def testCompletionSocketsAndMessages(self):
+ if not IS_JYTHON:
+ return
dbg('testCompletionSocketsAndMessages')
t, socket = self.createConnections()
self.socket = socket
@@ -121,6 +128,7 @@ class Test(unittest.TestCase):
Creates the connections needed for testing.
'''
t = jycompletionserver.T(p1)
+ t.exit_process_on_kill = False
t.start()
diff --git a/python/helpers/pydev/tests/test_jysimpleTipper.py b/python/helpers/pydev/tests/test_jysimpleTipper.py
index 4a755634bdc7..bf421b2347c2 100644
--- a/python/helpers/pydev/tests/test_jysimpleTipper.py
+++ b/python/helpers/pydev/tests/test_jysimpleTipper.py
@@ -4,17 +4,14 @@
import unittest
import os
import sys
-#make it as if we were executing from the directory above this one (so that we can use pycompletionserver
-#without the need for it being in the pythonpath)
-sys.argv[0] = os.path.dirname(sys.argv[0])
-#twice the dirname to get the previous level from this file.
-sys.path.insert(1, os.path.join(os.path.dirname(sys.argv[0])))
#this does not work (they must be in the system pythonpath)
#sys.path.insert(1, r"D:\bin\eclipse321\plugins\org.junit_3.8.1\junit.jar" ) #some late loading jar tests
#sys.path.insert(1, r"D:\bin\eclipse331_1\plugins\org.apache.ant_1.7.0.v200706080842\lib\ant.jar" ) #some late loading jar tests
+IS_JYTHON = 0
if sys.platform.find('java') != -1:
+ IS_JYTHON = 1
from _pydev_jy_imports_tipper import ismethod
from _pydev_jy_imports_tipper import isclass
from _pydev_jy_imports_tipper import dirObj
@@ -25,6 +22,8 @@ if sys.platform.find('java') != -1:
from java.lang.System import arraycopy #@UnresolvedImport
from java.lang.System import out #@UnresolvedImport
import java.lang.String #@UnresolvedImport
+ import org.python.core.PyDictionary #@UnresolvedImport
+
__DBG = 0
def dbg(s):
@@ -234,22 +233,24 @@ class TestCompl(unittest.TestCase):
assert isMet[1][0].basicAsStr() == "function:met2 args=['arg1', 'arg2'], varargs=vararg, kwargs=kwarg, docs:docmet2"
assert not isclass(met2)
+
+if not IS_JYTHON:
+ # Disable tests if not running under Jython
+ class TestMod(unittest.TestCase):
+ pass
+ class TestCompl(TestMod):
+ pass
+ class TestSearch(TestMod):
+ pass
if __name__ == '__main__':
- if sys.platform.find('java') != -1:
- #Only run if jython
- suite = unittest.makeSuite(TestCompl)
- suite2 = unittest.makeSuite(TestMod)
- suite3 = unittest.makeSuite(TestSearch)
-
- unittest.TextTestRunner(verbosity=1).run(suite)
- unittest.TextTestRunner(verbosity=1).run(suite2)
- unittest.TextTestRunner(verbosity=1).run(suite3)
-
-# suite.addTest(Test('testCase12'))
-# suite = unittest.TestSuite()
-# unittest.TextTestRunner(verbosity=1).run(suite)
-
- else:
- sys.stdout.write('Not running jython tests for non-java platform: %s' % sys.platform)
+ #Only run if jython
+ suite = unittest.makeSuite(TestCompl)
+ suite2 = unittest.makeSuite(TestMod)
+ suite3 = unittest.makeSuite(TestSearch)
+
+ unittest.TextTestRunner(verbosity=1).run(suite)
+ unittest.TextTestRunner(verbosity=1).run(suite2)
+ unittest.TextTestRunner(verbosity=1).run(suite3)
+
diff --git a/python/helpers/pydev/tests/test_pydev_ipython_010.py b/python/helpers/pydev/tests/test_pydev_ipython_010.py
deleted file mode 100644
index 5ce1dc32c34a..000000000000
--- a/python/helpers/pydev/tests/test_pydev_ipython_010.py
+++ /dev/null
@@ -1,80 +0,0 @@
-#TODO: This test no longer works (check if it should be fixed or removed altogether).
-
-#import unittest
-#import sys
-#import os
-##make it as if we were executing from the directory above this one
-#sys.argv[0] = os.path.dirname(sys.argv[0])
-##twice the dirname to get the previous level from this file.
-#sys.path.insert(1, os.path.join(os.path.dirname(sys.argv[0])))
-#
-#from pydev_localhost import get_localhost
-#
-#
-#IS_JYTHON = sys.platform.find('java') != -1
-#
-##=======================================================================================================================
-## TestCase
-##=======================================================================================================================
-#class TestCase(unittest.TestCase):
-#
-# def setUp(self):
-# unittest.TestCase.setUp(self)
-#
-# def tearDown(self):
-# unittest.TestCase.tearDown(self)
-#
-# def testIPython(self):
-# try:
-# from pydev_ipython_console import PyDevFrontEnd
-# except:
-# if IS_JYTHON:
-# return
-# front_end = PyDevFrontEnd(get_localhost(), 0)
-#
-# front_end.input_buffer = 'if True:'
-# self.assert_(not front_end._on_enter())
-#
-# front_end.input_buffer = 'if True:\n' + \
-# front_end.continuation_prompt() + ' a = 10\n'
-# self.assert_(not front_end._on_enter())
-#
-#
-# front_end.input_buffer = 'if True:\n' + \
-# front_end.continuation_prompt() + ' a = 10\n\n'
-# self.assert_(front_end._on_enter())
-#
-#
-## front_end.input_buffer = ' print a'
-## self.assert_(not front_end._on_enter())
-## front_end.input_buffer = ''
-## self.assert_(front_end._on_enter())
-#
-#
-## front_end.input_buffer = 'a.'
-## front_end.complete_current_input()
-## front_end.input_buffer = 'if True:'
-## front_end._on_enter()
-# front_end.input_buffer = 'a = 30'
-# front_end._on_enter()
-# front_end.input_buffer = 'print a'
-# front_end._on_enter()
-# front_end.input_buffer = 'a?'
-# front_end._on_enter()
-# print front_end.complete('%')
-# print front_end.complete('%e')
-# print front_end.complete('cd c:/t')
-# print front_end.complete('cd c:/temp/')
-## front_end.input_buffer = 'print raw_input("press enter\\n")'
-## front_end._on_enter()
-##
-#
-##=======================================================================================================================
-## main
-##=======================================================================================================================
-#if __name__ == '__main__':
-# if sys.platform.find('java') == -1:
-# #IPython not available for Jython
-# unittest.main()
-# else:
-# print('not supported on Jython')
diff --git a/python/helpers/pydev/tests/test_pydev_ipython_011.py b/python/helpers/pydev/tests/test_pydev_ipython_011.py
index 3cfa70fd0112..dc4684f35f3d 100644
--- a/python/helpers/pydev/tests/test_pydev_ipython_011.py
+++ b/python/helpers/pydev/tests/test_pydev_ipython_011.py
@@ -7,81 +7,87 @@ from pydev_imports import StringIO, SimpleXMLRPCServer
from pydev_localhost import get_localhost
from pydev_console_utils import StdIn
import socket
+from pydev_ipython_console_011 import get_pydev_frontend
+import time
-# make it as if we were executing from the directory above this one
-sys.argv[0] = os.path.dirname(sys.argv[0])
-# twice the dirname to get the previous level from this file.
-sys.path.insert(1, os.path.join(os.path.dirname(sys.argv[0])))
+try:
+ xrange
+except:
+ xrange = range
-# PyDevFrontEnd depends on singleton in IPython, so you
-# can't make multiple versions. So we reuse front_end for
-# all the tests
-
-orig_stdout = sys.stdout
-orig_stderr = sys.stderr
-
-stdout = sys.stdout = StringIO()
-stderr = sys.stderr = StringIO()
-
-from pydev_ipython_console_011 import PyDevFrontEnd
-s = socket.socket()
-s.bind(('', 0))
-client_port = s.getsockname()[1]
-s.close()
-front_end = PyDevFrontEnd(get_localhost(), client_port)
-
-
-def addExec(code, expected_more=False):
- more = front_end.addExec(code)
- eq_(expected_more, more)
class TestBase(unittest.TestCase):
+
+
def setUp(self):
- front_end.input_splitter.reset()
- stdout.truncate(0)
- stdout.seek(0)
- stderr.truncate(0)
- stderr.seek(0)
+ # PyDevFrontEnd depends on singleton in IPython, so you
+ # can't make multiple versions. So we reuse self.front_end for
+ # all the tests
+ self.front_end = get_pydev_frontend(get_localhost(), 0)
+
+ from pydev_ipython.inputhook import set_return_control_callback
+ set_return_control_callback(lambda:True)
+ self.front_end.clearBuffer()
+
def tearDown(self):
pass
+
+ def addExec(self, code, expected_more=False):
+ more = self.front_end.addExec(code)
+ eq_(expected_more, more)
+
+ def redirectStdout(self):
+ from IPython.utils import io
+
+ self.original_stdout = sys.stdout
+ sys.stdout = io.stdout = StringIO()
+
+ def restoreStdout(self):
+ from IPython.utils import io
+ io.stdout = sys.stdout = self.original_stdout
class TestPyDevFrontEnd(TestBase):
+
def testAddExec_1(self):
- addExec('if True:', True)
+ self.addExec('if True:', True)
+
def testAddExec_2(self):
- addExec('if True:\n testAddExec_a = 10\n', True)
+ #Change: 'more' must now be controlled in the client side after the initial 'True' returned.
+ self.addExec('if True:\n testAddExec_a = 10\n', False)
+ assert 'testAddExec_a' in self.front_end.getNamespace()
+
def testAddExec_3(self):
- assert 'testAddExec_a' not in front_end.getNamespace()
- addExec('if True:\n testAddExec_a = 10\n\n')
- assert 'testAddExec_a' in front_end.getNamespace()
- eq_(front_end.getNamespace()['testAddExec_a'], 10)
+ assert 'testAddExec_x' not in self.front_end.getNamespace()
+ self.addExec('if True:\n testAddExec_x = 10\n\n')
+ assert 'testAddExec_x' in self.front_end.getNamespace()
+ eq_(self.front_end.getNamespace()['testAddExec_x'], 10)
def testGetNamespace(self):
- assert 'testGetNamespace_a' not in front_end.getNamespace()
- addExec('testGetNamespace_a = 10')
- assert 'testGetNamespace_a' in front_end.getNamespace()
- eq_(front_end.getNamespace()['testGetNamespace_a'], 10)
+ assert 'testGetNamespace_a' not in self.front_end.getNamespace()
+ self.addExec('testGetNamespace_a = 10')
+ assert 'testGetNamespace_a' in self.front_end.getNamespace()
+ eq_(self.front_end.getNamespace()['testGetNamespace_a'], 10)
def testComplete(self):
- unused_text, matches = front_end.complete('%')
+ unused_text, matches = self.front_end.complete('%')
assert len(matches) > 1, 'at least one magic should appear in completions'
def testCompleteDoesNotDoPythonMatches(self):
# Test that IPython's completions do not do the things that
# PyDev's completions will handle
- addExec('testComplete_a = 5')
- addExec('testComplete_b = 10')
- addExec('testComplete_c = 15')
- unused_text, matches = front_end.complete('testComplete_')
+ self.addExec('testComplete_a = 5')
+ self.addExec('testComplete_b = 10')
+ self.addExec('testComplete_c = 15')
+ unused_text, matches = self.front_end.complete('testComplete_')
assert len(matches) == 0
def testGetCompletions_1(self):
# Test the merged completions include the standard completions
- addExec('testComplete_a = 5')
- addExec('testComplete_b = 10')
- addExec('testComplete_c = 15')
- res = front_end.getCompletions('testComplete_', 'testComplete_')
+ self.addExec('testComplete_a = 5')
+ self.addExec('testComplete_b = 10')
+ self.addExec('testComplete_c = 15')
+ res = self.front_end.getCompletions('testComplete_', 'testComplete_')
matches = [f[0] for f in res]
assert len(matches) == 3
eq_(set(['testComplete_a', 'testComplete_b', 'testComplete_c']), set(matches))
@@ -90,60 +96,80 @@ class TestPyDevFrontEnd(TestBase):
# Test that we get IPython completions in results
# we do this by checking kw completion which PyDev does
# not do by default
- addExec('def ccc(ABC=123): pass')
- res = front_end.getCompletions('ccc(', '')
+ self.addExec('def ccc(ABC=123): pass')
+ res = self.front_end.getCompletions('ccc(', '')
matches = [f[0] for f in res]
assert 'ABC=' in matches
def testGetCompletions_3(self):
# Test that magics return IPYTHON magic as type
- res = front_end.getCompletions('%cd', '%cd')
+ res = self.front_end.getCompletions('%cd', '%cd')
assert len(res) == 1
eq_(res[0][3], '12') # '12' == IToken.TYPE_IPYTHON_MAGIC
assert len(res[0][1]) > 100, 'docstring for %cd should be a reasonably long string'
class TestRunningCode(TestBase):
def testPrint(self):
- addExec('print("output")')
- eq_(stdout.getvalue(), 'output\n')
+ self.redirectStdout()
+ try:
+ self.addExec('print("output")')
+ eq_(sys.stdout.getvalue(), 'output\n')
+ finally:
+ self.restoreStdout()
def testQuestionMark_1(self):
- addExec('?')
- assert len(stdout.getvalue()) > 1000, 'IPython help should be pretty big'
+ self.redirectStdout()
+ try:
+ self.addExec('?')
+ assert len(sys.stdout.getvalue()) > 1000, 'IPython help should be pretty big'
+ finally:
+ self.restoreStdout()
def testQuestionMark_2(self):
- addExec('int?')
- assert stdout.getvalue().find('Convert') != -1
+ self.redirectStdout()
+ try:
+ self.addExec('int?')
+ assert sys.stdout.getvalue().find('Convert') != -1
+ finally:
+ self.restoreStdout()
def testGui(self):
- from pydev_ipython.inputhook import get_inputhook, set_stdin_file
- set_stdin_file(sys.stdin)
- assert get_inputhook() is None
- addExec('%gui tk')
- # we can't test the GUI works here because we aren't connected to XML-RPC so
- # nowhere for hook to run
- assert get_inputhook() is not None
- addExec('%gui none')
- assert get_inputhook() is None
+ try:
+ import Tkinter
+ except:
+ return
+ else:
+ from pydev_ipython.inputhook import get_inputhook
+ assert get_inputhook() is None
+ self.addExec('%gui tk')
+ # we can't test the GUI works here because we aren't connected to XML-RPC so
+ # nowhere for hook to run
+ assert get_inputhook() is not None
+ self.addExec('%gui none')
+ assert get_inputhook() is None
def testHistory(self):
''' Make sure commands are added to IPython's history '''
- addExec('a=1')
- addExec('b=2')
- _ih = front_end.getNamespace()['_ih']
- eq_(_ih[-1], 'b=2')
- eq_(_ih[-2], 'a=1')
-
- addExec('history')
- hist = stdout.getvalue().split('\n')
- eq_(hist[-1], '')
- eq_(hist[-2], 'history')
- eq_(hist[-3], 'b=2')
- eq_(hist[-4], 'a=1')
+ self.redirectStdout()
+ try:
+ self.addExec('a=1')
+ self.addExec('b=2')
+ _ih = self.front_end.getNamespace()['_ih']
+ eq_(_ih[-1], 'b=2')
+ eq_(_ih[-2], 'a=1')
+
+ self.addExec('history')
+ hist = sys.stdout.getvalue().split('\n')
+ eq_(hist[-1], '')
+ eq_(hist[-2], 'history')
+ eq_(hist[-3], 'b=2')
+ eq_(hist[-4], 'a=1')
+ finally:
+ self.restoreStdout()
def testEdit(self):
- ''' Make sure we can issue an edit command '''
+ ''' Make sure we can issue an edit command'''
called_RequestInput = [False]
called_IPythonEditor = [False]
def startClientThread(client_port):
@@ -163,26 +189,47 @@ class TestRunningCode(TestBase):
handle_request_input = HandleRequestInput()
import pydev_localhost
- client_server = SimpleXMLRPCServer((pydev_localhost.get_localhost(), self.client_port), logRequests=False)
+ self.client_server = client_server = SimpleXMLRPCServer(
+ (pydev_localhost.get_localhost(), self.client_port), logRequests=False)
client_server.register_function(handle_request_input.RequestInput)
client_server.register_function(handle_request_input.IPythonEditor)
client_server.serve_forever()
+
+ def shutdown(self):
+ return
+ self.client_server.shutdown()
client_thread = ClientThread(client_port)
client_thread.setDaemon(True)
client_thread.start()
return client_thread
- startClientThread(client_port)
+ # PyDevFrontEnd depends on singleton in IPython, so you
+ # can't make multiple versions. So we reuse self.front_end for
+ # all the tests
+ s = socket.socket()
+ s.bind(('', 0))
+ self.client_port = client_port = s.getsockname()[1]
+ s.close()
+ self.front_end = get_pydev_frontend(get_localhost(), client_port)
+
+ client_thread = startClientThread(self.client_port)
orig_stdin = sys.stdin
- sys.stdin = StdIn(self, get_localhost(), client_port)
+ sys.stdin = StdIn(self, get_localhost(), self.client_port)
try:
filename = 'made_up_file.py'
- addExec('%edit ' + filename)
- eq_(called_IPythonEditor[0], (os.path.abspath(filename), 0))
+ self.addExec('%edit ' + filename)
+
+ for i in xrange(10):
+ if called_IPythonEditor[0] == (os.path.abspath(filename), '0'):
+ break
+ time.sleep(.1)
+
+ eq_(called_IPythonEditor[0], (os.path.abspath(filename), '0'))
assert called_RequestInput[0], "Make sure the 'wait' parameter has been respected"
finally:
sys.stdin = orig_stdin
+ client_thread.shutdown()
if __name__ == '__main__':
diff --git a/python/helpers/pydev/tests/test_pydevconsole.py b/python/helpers/pydev/tests/test_pydevconsole.py
index 9a9e3edaf124..18421980ae82 100644
--- a/python/helpers/pydev/tests/test_pydevconsole.py
+++ b/python/helpers/pydev/tests/test_pydevconsole.py
@@ -1,10 +1,6 @@
import threading
import unittest
import sys
-import os
-
-sys.argv[0] = os.path.dirname(sys.argv[0])
-sys.path.insert(1, os.path.join(os.path.dirname(sys.argv[0])))
import pydevconsole
from pydev_imports import xmlrpclib, SimpleXMLRPCServer, StringIO
@@ -19,104 +15,112 @@ except NameError:
#=======================================================================================================================
class Test(unittest.TestCase):
- def setUp(self):
+ def testConsoleHello(self):
self.original_stdout = sys.stdout
sys.stdout = StringIO()
-
-
- def tearDown(self):
- ret = sys.stdout #@UnusedVariable
- sys.stdout = self.original_stdout
- #print_ ret.getvalue() -- use to see test output
-
- def testConsoleHello(self):
- client_port, _server_port = self.getFreeAddresses()
- client_thread = self.startClientThread(client_port) #@UnusedVariable
- import time
- time.sleep(.3) #let's give it some time to start the threads
-
- import pydev_localhost
- interpreter = pydevconsole.InterpreterInterface(pydev_localhost.get_localhost(), client_port, server=None)
-
- (result,) = interpreter.hello("Hello pydevconsole")
- self.assertEqual(result, "Hello eclipse")
+
+ try:
+ client_port, _server_port = self.getFreeAddresses()
+ client_thread = self.startClientThread(client_port) #@UnusedVariable
+ import time
+ time.sleep(.3) #let's give it some time to start the threads
+
+ import pydev_localhost
+ interpreter = pydevconsole.InterpreterInterface(pydev_localhost.get_localhost(), client_port, threading.currentThread())
+
+ (result,) = interpreter.hello("Hello pydevconsole")
+ self.assertEqual(result, "Hello eclipse")
+ finally:
+ sys.stdout = self.original_stdout
def testConsoleRequests(self):
- client_port, _server_port = self.getFreeAddresses()
- client_thread = self.startClientThread(client_port) #@UnusedVariable
- import time
- time.sleep(.3) #let's give it some time to start the threads
-
- import pydev_localhost
- interpreter = pydevconsole.InterpreterInterface(pydev_localhost.get_localhost(), client_port, server=None)
- interpreter.addExec('class Foo:')
- interpreter.addExec(' CONSTANT=1')
- interpreter.addExec('')
- interpreter.addExec('foo=Foo()')
- interpreter.addExec('foo.__doc__=None')
- interpreter.addExec('val = %s()' % (raw_input_name,))
- interpreter.addExec('50')
- interpreter.addExec('print (val)')
- found = sys.stdout.getvalue().split()
+ self.original_stdout = sys.stdout
+ sys.stdout = StringIO()
+
try:
- self.assertEqual(['50', 'input_request'], found)
- except:
- self.assertEqual(['input_request'], found) #IPython
-
- comps = interpreter.getCompletions('foo.', 'foo.')
- self.assert_(
- ('CONSTANT', '', '', '3') in comps or ('CONSTANT', '', '', '4') in comps, \
- 'Found: %s' % comps
- )
-
- comps = interpreter.getCompletions('"".', '"".')
- self.assert_(
- ('__add__', 'x.__add__(y) <==> x+y', '', '3') in comps or
- ('__add__', '', '', '4') in comps or
- ('__add__', 'x.__add__(y) <==> x+y\r\nx.__add__(y) <==> x+y', '()', '2') in comps or
- ('__add__', 'x.\n__add__(y) <==> x+yx.\n__add__(y) <==> x+y', '()', '2'),
- 'Did not find __add__ in : %s' % (comps,)
- )
-
-
- completions = interpreter.getCompletions('', '')
- for c in completions:
- if c[0] == 'AssertionError':
- break
- else:
- self.fail('Could not find AssertionError')
-
- completions = interpreter.getCompletions('Assert', 'Assert')
- for c in completions:
- if c[0] == 'RuntimeError':
- self.fail('Did not expect to find RuntimeError there')
-
- self.assert_(('__doc__', None, '', '3') not in interpreter.getCompletions('foo.CO', 'foo.'))
-
- comps = interpreter.getCompletions('va', 'va')
- self.assert_(('val', '', '', '3') in comps or ('val', '', '', '4') in comps)
-
- interpreter.addExec('s = "mystring"')
-
- desc = interpreter.getDescription('val')
- self.assert_(desc.find('str(object) -> string') >= 0 or
- desc == "'input_request'" or
- desc.find('str(string[, encoding[, errors]]) -> str') >= 0 or
- desc.find('str(Char* value)') >= 0 or
- desc.find('str(value: Char*)') >= 0,
- 'Could not find what was needed in %s' % desc)
-
- desc = interpreter.getDescription('val.join')
- self.assert_(desc.find('S.join(sequence) -> string') >= 0 or
- desc.find('S.join(sequence) -> str') >= 0 or
- desc.find('S.join(iterable) -> string') >= 0 or
- desc == "<builtin method 'join'>" or
- desc == "<built-in method join of str object>" or
- desc.find('str join(str self, list sequence)') >= 0 or
- desc.find('S.join(iterable) -> str') >= 0 or
- desc.find('join(self: str, sequence: list) -> str') >= 0,
- "Could not recognize: %s" % (desc,))
+ client_port, _server_port = self.getFreeAddresses()
+ client_thread = self.startClientThread(client_port) #@UnusedVariable
+ import time
+ time.sleep(.3) #let's give it some time to start the threads
+
+ import pydev_localhost
+ from pydev_console_utils import CodeFragment
+
+ interpreter = pydevconsole.InterpreterInterface(pydev_localhost.get_localhost(), client_port, threading.currentThread())
+ sys.stdout = StringIO()
+ interpreter.addExec(CodeFragment('class Foo:'))
+ interpreter.addExec(CodeFragment(' CONSTANT=1'))
+ interpreter.addExec(CodeFragment(''))
+ interpreter.addExec(CodeFragment('foo=Foo()'))
+ interpreter.addExec(CodeFragment('foo.__doc__=None'))
+ interpreter.addExec(CodeFragment('val = %s()' % (raw_input_name,)))
+ interpreter.addExec(CodeFragment('50'))
+ interpreter.addExec(CodeFragment('print (val)'))
+ found = sys.stdout.getvalue().split()
+ try:
+ self.assertEqual(['50', 'input_request'], found)
+ except:
+ self.assertEqual(['input_request'], found) #IPython
+
+ comps = interpreter.getCompletions('foo.', 'foo.')
+ self.assert_(
+ ('CONSTANT', '', '', '3') in comps or ('CONSTANT', '', '', '4') in comps, \
+ 'Found: %s' % comps
+ )
+
+ comps = interpreter.getCompletions('"".', '"".')
+ self.assert_(
+ ('__add__', 'x.__add__(y) <==> x+y', '', '3') in comps or
+ ('__add__', '', '', '4') in comps or
+ ('__add__', 'x.__add__(y) <==> x+y\r\nx.__add__(y) <==> x+y', '()', '2') in comps or
+ ('__add__', 'x.\n__add__(y) <==> x+yx.\n__add__(y) <==> x+y', '()', '2'),
+ 'Did not find __add__ in : %s' % (comps,)
+ )
+
+
+ completions = interpreter.getCompletions('', '')
+ for c in completions:
+ if c[0] == 'AssertionError':
+ break
+ else:
+ self.fail('Could not find AssertionError')
+
+ completions = interpreter.getCompletions('Assert', 'Assert')
+ for c in completions:
+ if c[0] == 'RuntimeError':
+ self.fail('Did not expect to find RuntimeError there')
+
+ self.assert_(('__doc__', None, '', '3') not in interpreter.getCompletions('foo.CO', 'foo.'))
+
+ comps = interpreter.getCompletions('va', 'va')
+ self.assert_(('val', '', '', '3') in comps or ('val', '', '', '4') in comps)
+
+ interpreter.addExec(CodeFragment('s = "mystring"'))
+
+ desc = interpreter.getDescription('val')
+ self.assert_(desc.find('str(object) -> string') >= 0 or
+ desc == "'input_request'" or
+ desc.find('str(string[, encoding[, errors]]) -> str') >= 0 or
+ desc.find('str(Char* value)') >= 0 or
+ desc.find('str(object=\'\') -> string') >= 0 or
+ desc.find('str(value: Char*)') >= 0 or
+ desc.find('str(object=\'\') -> str') >= 0
+ ,
+ 'Could not find what was needed in %s' % desc)
+
+ desc = interpreter.getDescription('val.join')
+ self.assert_(desc.find('S.join(sequence) -> string') >= 0 or
+ desc.find('S.join(sequence) -> str') >= 0 or
+ desc.find('S.join(iterable) -> string') >= 0 or
+ desc == "<builtin method 'join'>" or
+ desc == "<built-in method join of str object>" or
+ desc.find('str join(str self, list sequence)') >= 0 or
+ desc.find('S.join(iterable) -> str') >= 0 or
+ desc.find('join(self: str, sequence: list) -> str') >= 0,
+ "Could not recognize: %s" % (desc,))
+ finally:
+ sys.stdout = self.original_stdout
def startClientThread(self, client_port):
@@ -124,19 +128,28 @@ class Test(unittest.TestCase):
def __init__(self, client_port):
threading.Thread.__init__(self)
self.client_port = client_port
+
def run(self):
class HandleRequestInput:
def RequestInput(self):
+ client_thread.requested_input = True
return 'input_request'
-
+
+ def NotifyFinished(self, *args, **kwargs):
+ client_thread.notified_finished += 1
+ return 1
+
handle_request_input = HandleRequestInput()
-
+
import pydev_localhost
client_server = SimpleXMLRPCServer((pydev_localhost.get_localhost(), self.client_port), logRequests=False)
client_server.register_function(handle_request_input.RequestInput)
+ client_server.register_function(handle_request_input.NotifyFinished)
client_server.serve_forever()
-
+
client_thread = ClientThread(client_port)
+ client_thread.requested_input = False
+ client_thread.notified_finished = 0
client_thread.setDaemon(True)
client_thread.start()
return client_thread
@@ -194,34 +207,50 @@ class Test(unittest.TestCase):
def testServer(self):
- client_port, server_port = self.getFreeAddresses()
- class ServerThread(threading.Thread):
- def __init__(self, client_port, server_port):
- threading.Thread.__init__(self)
- self.client_port = client_port
- self.server_port = server_port
-
- def run(self):
- import pydev_localhost
- pydevconsole.StartServer(pydev_localhost.get_localhost(), self.server_port, self.client_port)
- server_thread = ServerThread(client_port, server_port)
- server_thread.setDaemon(True)
- server_thread.start()
-
- client_thread = self.startClientThread(client_port) #@UnusedVariable
-
- import time
- time.sleep(.3) #let's give it some time to start the threads
-
- import pydev_localhost
- server = xmlrpclib.Server('http://%s:%s' % (pydev_localhost.get_localhost(), server_port))
- server.addExec('class Foo:')
- server.addExec(' pass')
- server.addExec('')
- server.addExec('foo = Foo()')
- server.addExec('a = %s()' % (raw_input_name,))
- server.addExec('print (a)')
- self.assertEqual(['input_request'], sys.stdout.getvalue().split())
+ self.original_stdout = sys.stdout
+ sys.stdout = StringIO()
+ try:
+ client_port, server_port = self.getFreeAddresses()
+ class ServerThread(threading.Thread):
+ def __init__(self, client_port, server_port):
+ threading.Thread.__init__(self)
+ self.client_port = client_port
+ self.server_port = server_port
+
+ def run(self):
+ import pydev_localhost
+ pydevconsole.StartServer(pydev_localhost.get_localhost(), self.server_port, self.client_port)
+ server_thread = ServerThread(client_port, server_port)
+ server_thread.setDaemon(True)
+ server_thread.start()
+
+ client_thread = self.startClientThread(client_port) #@UnusedVariable
+
+ import time
+ time.sleep(.3) #let's give it some time to start the threads
+ sys.stdout = StringIO()
+
+ import pydev_localhost
+ server = xmlrpclib.Server('http://%s:%s' % (pydev_localhost.get_localhost(), server_port))
+ server.execLine('class Foo:')
+ server.execLine(' pass')
+ server.execLine('')
+ server.execLine('foo = Foo()')
+ server.execLine('a = %s()' % (raw_input_name,))
+ server.execLine('print (a)')
+ initial = time.time()
+ while not client_thread.requested_input:
+ if time.time() - initial > 2:
+ raise AssertionError('Did not get the return asked before the timeout.')
+ time.sleep(.1)
+
+ while ['input_request'] != sys.stdout.getvalue().split():
+ if time.time() - initial > 2:
+ break
+ time.sleep(.1)
+ self.assertEqual(['input_request'], sys.stdout.getvalue().split())
+ finally:
+ sys.stdout = self.original_stdout
#=======================================================================================================================
# main
diff --git a/python/helpers/pydev/tests/test_pyserver.py b/python/helpers/pydev/tests/test_pyserver.py
index a74876b8c8b9..ea9daff14e39 100644
--- a/python/helpers/pydev/tests/test_pyserver.py
+++ b/python/helpers/pydev/tests/test_pyserver.py
@@ -3,6 +3,7 @@
'''
import sys
import os
+from _pydev_imps._pydev_thread import start_new_thread
#make it as if we were executing from the directory above this one (so that we can use pycompletionserver
#without the need for it being in the pythonpath)
@@ -13,6 +14,13 @@ sys.path.insert(1, os.path.join(os.path.dirname(sys.argv[0])))
IS_PYTHON_3K = 0
if sys.platform.find('java') == -1:
+ try:
+ import __builtin__ #@UnusedImport
+ BUILTIN_MOD = '__builtin__'
+ except ImportError:
+ BUILTIN_MOD = 'builtins'
+
+
try:
import inspect
@@ -41,7 +49,7 @@ if sys.platform.find('java') == -1:
unittest.TestCase.tearDown(self)
def testMessage(self):
- t = pycompletionserver.T(0)
+ t = pycompletionserver.CompletionServer(0)
l = []
l.append(('Def', 'description' , 'args'))
@@ -62,14 +70,14 @@ if sys.platform.find('java') == -1:
'''
Creates the connections needed for testing.
'''
- t = pycompletionserver.T(p1)
-
- t.start()
-
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((pycompletionserver.HOST, p1))
server.listen(1) #socket to receive messages.
+ t = pycompletionserver.CompletionServer(p1)
+ t.exit_process_on_kill = False
+ start_new_thread(t.run, ())
+
s, addr = server.accept()
return t, s
@@ -106,6 +114,8 @@ if sys.platform.find('java') == -1:
#math is a builtin and because of that, it starts with None as a file
start = '@@COMPLETIONS(None,(__doc__,'
start_2 = '@@COMPLETIONS(None,(__name__,'
+ if '/math.so,' in completions or '/math.cpython-33m.so,' in completions or '/math.cpython-34m.so,' in completions:
+ return
self.assert_(completions.startswith(start) or completions.startswith(start_2), '%s DOESNT START WITH %s' % (completions, (start, start_2)))
self.assert_('@@COMPLETIONS' in completions)
@@ -113,7 +123,7 @@ if sys.platform.find('java') == -1:
#now, test i
- msg = quote_plus('__builtin__.list')
+ msg = quote_plus('%s.list' % BUILTIN_MOD)
send(socket, "@@IMPORTS:%s\nEND@@" % msg)
found = self.readMsg()
self.assert_('sort' in found, 'Could not find sort in: %s' % (found,))
diff --git a/python/helpers/pydev/tests/test_simpleTipper.py b/python/helpers/pydev/tests/test_simpleTipper.py
index f759ad60f678..255a5218698f 100644
--- a/python/helpers/pydev/tests/test_simpleTipper.py
+++ b/python/helpers/pydev/tests/test_simpleTipper.py
@@ -1,12 +1,7 @@
'''
@author Fabio Zadrozny
'''
-import os
import sys
-#make it as if we were executing from the directory above this one (so that we can use pycompletionserver
-#without the need for it being in the pythonpath)
-#twice the dirname to get the previous level from this file.
-sys.path.insert(1, os.path.split(os.path.split(__file__)[0])[0])
try:
import __builtin__ #@UnusedImport
@@ -50,13 +45,14 @@ if sys.platform.find('java') == -1:
pass
def testImports5(self):
- tip = _pydev_imports_tipper.GenerateTip('__builtin__.list')
+ tip = _pydev_imports_tipper.GenerateTip('%s.list' % BUILTIN_MOD)
s = self.assertIn('sort', tip)
self.CheckArgs(
s,
'(cmp=None, key=None, reverse=False)',
'(self, object cmp, object key, bool reverse)',
- '(self, cmp: object, key: object, reverse: bool)'
+ '(self, cmp: object, key: object, reverse: bool)',
+ '(key=None, reverse=False)',
)
def testImports2a(self):
@@ -64,14 +60,24 @@ if sys.platform.find('java') == -1:
self.assertIn('__doc__', tips)
def testImports2b(self):
- tips = _pydev_imports_tipper.GenerateTip('%s' % BUILTIN_MOD)
- t = self.assertIn('file' , tips)
- self.assert_('->' in t[1].strip() or 'file' in t[1])
+ try:
+ file
+ except:
+ pass
+ else:
+ tips = _pydev_imports_tipper.GenerateTip('%s' % BUILTIN_MOD)
+ t = self.assertIn('file' , tips)
+ self.assert_('->' in t[1].strip() or 'file' in t[1])
def testImports2c(self):
- tips = _pydev_imports_tipper.GenerateTip('%s.file' % BUILTIN_MOD)
- t = self.assertIn('readlines' , tips)
- self.assert_('->' in t[1] or 'sizehint' in t[1])
+ try:
+ file # file is not available on py 3
+ except:
+ pass
+ else:
+ tips = _pydev_imports_tipper.GenerateTip('%s.file' % BUILTIN_MOD)
+ t = self.assertIn('readlines' , tips)
+ self.assert_('->' in t[1] or 'sizehint' in t[1])
def testImports(self):
'''
@@ -110,9 +116,9 @@ if sys.platform.find('java') == -1:
self.assertIn('RuntimeError' , tip)
self.assertIn('RuntimeWarning' , tip)
- t = self.assertIn('cmp' , tip)
-
- self.CheckArgs(t, '(x, y)', '(object x, object y)', '(x: object, y: object)') #args
+ # Remove cmp as it's not available on py 3
+ #t = self.assertIn('cmp' , tip)
+ #self.CheckArgs(t, '(x, y)', '(object x, object y)', '(x: object, y: object)') #args
t = self.assertIn('isinstance' , tip)
self.CheckArgs(t, '(object, class_or_type_or_tuple)', '(object o, type typeinfo)', '(o: object, typeinfo: type)') #args
diff --git a/python/helpers/pydev/tests_mainloop/gui-glut.py b/python/helpers/pydev/tests_mainloop/gui-glut.py
index f05a4bc0beaf..34a16b454171 100644
--- a/python/helpers/pydev/tests_mainloop/gui-glut.py
+++ b/python/helpers/pydev/tests_mainloop/gui-glut.py
@@ -9,42 +9,44 @@ To run this:
4) run: gl.glClearColor(1,1,1,1)
"""
-#!/usr/bin/env python
-import sys
-import OpenGL.GL as gl
-import OpenGL.GLUT as glut
-
-def close():
- glut.glutDestroyWindow(glut.glutGetWindow())
-
-def display():
- gl.glClear (gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
- glut.glutSwapBuffers()
-
-def resize(width,height):
- gl.glViewport(0, 0, width, height+4)
- gl.glMatrixMode(gl.GL_PROJECTION)
- gl.glLoadIdentity()
- gl.glOrtho(0, width, 0, height+4, -1, 1)
- gl.glMatrixMode(gl.GL_MODELVIEW)
-
-if glut.glutGetWindow() > 0:
- interactive = True
- glut.glutInit(sys.argv)
- glut.glutInitDisplayMode(glut.GLUT_DOUBLE |
- glut.GLUT_RGBA |
- glut.GLUT_DEPTH)
-else:
- interactive = False
-
-glut.glutCreateWindow('gui-glut')
-glut.glutDisplayFunc(display)
-glut.glutReshapeFunc(resize)
-# This is necessary on osx to be able to close the window
-# (else the close button is disabled)
-if sys.platform == 'darwin' and not bool(glut.HAVE_FREEGLUT):
- glut.glutWMCloseFunc(close)
-gl.glClearColor(0,0,0,1)
-
-if not interactive:
- glut.glutMainLoop()
+if __name__ == '__main__':
+
+ #!/usr/bin/env python
+ import sys
+ import OpenGL.GL as gl
+ import OpenGL.GLUT as glut
+
+ def close():
+ glut.glutDestroyWindow(glut.glutGetWindow())
+
+ def display():
+ gl.glClear (gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
+ glut.glutSwapBuffers()
+
+ def resize(width,height):
+ gl.glViewport(0, 0, width, height+4)
+ gl.glMatrixMode(gl.GL_PROJECTION)
+ gl.glLoadIdentity()
+ gl.glOrtho(0, width, 0, height+4, -1, 1)
+ gl.glMatrixMode(gl.GL_MODELVIEW)
+
+ if glut.glutGetWindow() > 0:
+ interactive = True
+ glut.glutInit(sys.argv)
+ glut.glutInitDisplayMode(glut.GLUT_DOUBLE |
+ glut.GLUT_RGBA |
+ glut.GLUT_DEPTH)
+ else:
+ interactive = False
+
+ glut.glutCreateWindow('gui-glut')
+ glut.glutDisplayFunc(display)
+ glut.glutReshapeFunc(resize)
+ # This is necessary on osx to be able to close the window
+ # (else the close button is disabled)
+ if sys.platform == 'darwin' and not bool(glut.HAVE_FREEGLUT):
+ glut.glutWMCloseFunc(close)
+ gl.glClearColor(0,0,0,1)
+
+ if not interactive:
+ glut.glutMainLoop()
diff --git a/python/helpers/pydev/tests_mainloop/gui-gtk.py b/python/helpers/pydev/tests_mainloop/gui-gtk.py
index 978f8f9a25f3..6df5c782e96a 100644
--- a/python/helpers/pydev/tests_mainloop/gui-gtk.py
+++ b/python/helpers/pydev/tests_mainloop/gui-gtk.py
@@ -8,27 +8,28 @@ To run this:
interactive console
"""
-import pygtk
-pygtk.require('2.0')
-import gtk
-
-
-def hello_world(wigdet, data=None):
- print("Hello World")
-
-def delete_event(widget, event, data=None):
- return False
-
-def destroy(widget, data=None):
- gtk.main_quit()
-
-window = gtk.Window(gtk.WINDOW_TOPLEVEL)
-window.connect("delete_event", delete_event)
-window.connect("destroy", destroy)
-button = gtk.Button("Hello World")
-button.connect("clicked", hello_world, None)
-
-window.add(button)
-button.show()
-window.show()
-
+if __name__ == '__main__':
+ import pygtk
+ pygtk.require('2.0')
+ import gtk
+
+
+ def hello_world(wigdet, data=None):
+ print("Hello World")
+
+ def delete_event(widget, event, data=None):
+ return False
+
+ def destroy(widget, data=None):
+ gtk.main_quit()
+
+ window = gtk.Window(gtk.WINDOW_TOPLEVEL)
+ window.connect("delete_event", delete_event)
+ window.connect("destroy", destroy)
+ button = gtk.Button("Hello World")
+ button.connect("clicked", hello_world, None)
+
+ window.add(button)
+ button.show()
+ window.show()
+
diff --git a/python/helpers/pydev/tests_mainloop/gui-gtk3.py b/python/helpers/pydev/tests_mainloop/gui-gtk3.py
index a787f7ee9e65..6351d5235ded 100644
--- a/python/helpers/pydev/tests_mainloop/gui-gtk3.py
+++ b/python/helpers/pydev/tests_mainloop/gui-gtk3.py
@@ -8,25 +8,26 @@ To run this:
interactive console
"""
-from gi.repository import Gtk
-
-
-def hello_world(wigdet, data=None):
- print("Hello World")
-
-def delete_event(widget, event, data=None):
- return False
-
-def destroy(widget, data=None):
- Gtk.main_quit()
-
-window = Gtk.Window(Gtk.WindowType.TOPLEVEL)
-window.connect("delete_event", delete_event)
-window.connect("destroy", destroy)
-button = Gtk.Button("Hello World")
-button.connect("clicked", hello_world, None)
-
-window.add(button)
-button.show()
-window.show()
-
+if __name__ == '__main__':
+ from gi.repository import Gtk
+
+
+ def hello_world(wigdet, data=None):
+ print("Hello World")
+
+ def delete_event(widget, event, data=None):
+ return False
+
+ def destroy(widget, data=None):
+ Gtk.main_quit()
+
+ window = Gtk.Window(Gtk.WindowType.TOPLEVEL)
+ window.connect("delete_event", delete_event)
+ window.connect("destroy", destroy)
+ button = Gtk.Button("Hello World")
+ button.connect("clicked", hello_world, None)
+
+ window.add(button)
+ button.show()
+ window.show()
+
diff --git a/python/helpers/pydev/tests_mainloop/gui-pyglet.py b/python/helpers/pydev/tests_mainloop/gui-pyglet.py
index b646093e0967..70f1a7f64724 100644
--- a/python/helpers/pydev/tests_mainloop/gui-pyglet.py
+++ b/python/helpers/pydev/tests_mainloop/gui-pyglet.py
@@ -8,20 +8,21 @@ To run this:
interactive console
"""
-import pyglet
-
-
-window = pyglet.window.Window()
-label = pyglet.text.Label('Hello, world',
- font_name='Times New Roman',
- font_size=36,
- x=window.width//2, y=window.height//2,
- anchor_x='center', anchor_y='center')
-@window.event
-def on_close():
- window.close()
-
-@window.event
-def on_draw():
- window.clear()
- label.draw()
+if __name__ == '__main__':
+ import pyglet
+
+
+ window = pyglet.window.Window()
+ label = pyglet.text.Label('Hello, world',
+ font_name='Times New Roman',
+ font_size=36,
+ x=window.width//2, y=window.height//2,
+ anchor_x='center', anchor_y='center')
+ @window.event
+ def on_close():
+ window.close()
+
+ @window.event
+ def on_draw():
+ window.clear()
+ label.draw()
diff --git a/python/helpers/pydev/tests_mainloop/gui-qt.py b/python/helpers/pydev/tests_mainloop/gui-qt.py
index c27cbd6ff1e6..30fc48d3845a 100644
--- a/python/helpers/pydev/tests_mainloop/gui-qt.py
+++ b/python/helpers/pydev/tests_mainloop/gui-qt.py
@@ -10,26 +10,27 @@ To run this:
Ref: Modified from http://zetcode.com/tutorials/pyqt4/firstprograms/
"""
-import sys
-from PyQt4 import QtGui, QtCore
-
-class SimpleWindow(QtGui.QWidget):
- def __init__(self, parent=None):
- QtGui.QWidget.__init__(self, parent)
-
- self.setGeometry(300, 300, 200, 80)
- self.setWindowTitle('Hello World')
-
- quit = QtGui.QPushButton('Close', self)
- quit.setGeometry(10, 10, 60, 35)
-
- self.connect(quit, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('close()'))
-
if __name__ == '__main__':
- app = QtCore.QCoreApplication.instance()
- if app is None:
- app = QtGui.QApplication([])
-
- sw = SimpleWindow()
- sw.show()
+ import sys
+ from PyQt4 import QtGui, QtCore
+
+ class SimpleWindow(QtGui.QWidget):
+ def __init__(self, parent=None):
+ QtGui.QWidget.__init__(self, parent)
+
+ self.setGeometry(300, 300, 200, 80)
+ self.setWindowTitle('Hello World')
+
+ quit = QtGui.QPushButton('Close', self)
+ quit.setGeometry(10, 10, 60, 35)
+
+ self.connect(quit, QtCore.SIGNAL('clicked()'),
+ self, QtCore.SLOT('close()'))
+
+ if __name__ == '__main__':
+ app = QtCore.QCoreApplication.instance()
+ if app is None:
+ app = QtGui.QApplication([])
+
+ sw = SimpleWindow()
+ sw.show()
diff --git a/python/helpers/pydev/tests_mainloop/gui-tk.py b/python/helpers/pydev/tests_mainloop/gui-tk.py
index 69ceb0b9f053..4cef45f91a4a 100644
--- a/python/helpers/pydev/tests_mainloop/gui-tk.py
+++ b/python/helpers/pydev/tests_mainloop/gui-tk.py
@@ -8,24 +8,26 @@ To run this:
interactive console
"""
-try:
- from Tkinter import *
-except:
- # Python 3
- from tkinter import *
-
-class MyApp:
-
- def __init__(self, root):
- frame = Frame(root)
- frame.pack()
-
- self.button = Button(frame, text="Hello", command=self.hello_world)
- self.button.pack(side=LEFT)
-
- def hello_world(self):
- print("Hello World!")
-
-root = Tk()
-
-app = MyApp(root)
+if __name__ == '__main__':
+
+ try:
+ from Tkinter import *
+ except:
+ # Python 3
+ from tkinter import *
+
+ class MyApp:
+
+ def __init__(self, root):
+ frame = Frame(root)
+ frame.pack()
+
+ self.button = Button(frame, text="Hello", command=self.hello_world)
+ self.button.pack(side=LEFT)
+
+ def hello_world(self):
+ print("Hello World!")
+
+ root = Tk()
+
+ app = MyApp(root)
diff --git a/python/helpers/pydev/tests_mainloop/gui-wx.py b/python/helpers/pydev/tests_mainloop/gui-wx.py
index 2101e7f214d4..b9c28bfc63ab 100644
--- a/python/helpers/pydev/tests_mainloop/gui-wx.py
+++ b/python/helpers/pydev/tests_mainloop/gui-wx.py
@@ -11,91 +11,93 @@ To run this:
Ref: Modified from wxPython source code wxPython/samples/simple/simple.py
"""
-import wx
-
-
-class MyFrame(wx.Frame):
- """
- This is MyFrame. It just shows a few controls on a wxPanel,
- and has a simple menu.
- """
- def __init__(self, parent, title):
- wx.Frame.__init__(self, parent, -1, title,
- pos=(150, 150), size=(350, 200))
-
- # Create the menubar
- menuBar = wx.MenuBar()
-
- # and a menu
- menu = wx.Menu()
-
- # add an item to the menu, using \tKeyName automatically
- # creates an accelerator, the third param is some help text
- # that will show up in the statusbar
- menu.Append(wx.ID_EXIT, "E&xit\tAlt-X", "Exit this simple sample")
-
- # bind the menu event to an event handler
- self.Bind(wx.EVT_MENU, self.OnTimeToClose, id=wx.ID_EXIT)
-
- # and put the menu on the menubar
- menuBar.Append(menu, "&File")
- self.SetMenuBar(menuBar)
-
- self.CreateStatusBar()
-
- # Now create the Panel to put the other controls on.
- panel = wx.Panel(self)
-
- # and a few controls
- text = wx.StaticText(panel, -1, "Hello World!")
- text.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD))
- text.SetSize(text.GetBestSize())
- btn = wx.Button(panel, -1, "Close")
- funbtn = wx.Button(panel, -1, "Just for fun...")
-
- # bind the button events to handlers
- self.Bind(wx.EVT_BUTTON, self.OnTimeToClose, btn)
- self.Bind(wx.EVT_BUTTON, self.OnFunButton, funbtn)
-
- # Use a sizer to layout the controls, stacked vertically and with
- # a 10 pixel border around each
- sizer = wx.BoxSizer(wx.VERTICAL)
- sizer.Add(text, 0, wx.ALL, 10)
- sizer.Add(btn, 0, wx.ALL, 10)
- sizer.Add(funbtn, 0, wx.ALL, 10)
- panel.SetSizer(sizer)
- panel.Layout()
-
-
- def OnTimeToClose(self, evt):
- """Event handler for the button click."""
- print("See ya later!")
- self.Close()
-
- def OnFunButton(self, evt):
- """Event handler for the button click."""
- print("Having fun yet?")
-
-
-class MyApp(wx.App):
- def OnInit(self):
- frame = MyFrame(None, "Simple wxPython App")
- self.SetTopWindow(frame)
-
- print("Print statements go to this stdout window by default.")
-
- frame.Show(True)
- return True
-
-
if __name__ == '__main__':
- app = wx.GetApp()
- if app is None:
- app = MyApp(redirect=False, clearSigInt=False)
- else:
- frame = MyFrame(None, "Simple wxPython App")
- app.SetTopWindow(frame)
- print("Print statements go to this stdout window by default.")
- frame.Show(True)
-
+ import wx
+
+
+ class MyFrame(wx.Frame):
+ """
+ This is MyFrame. It just shows a few controls on a wxPanel,
+ and has a simple menu.
+ """
+ def __init__(self, parent, title):
+ wx.Frame.__init__(self, parent, -1, title,
+ pos=(150, 150), size=(350, 200))
+
+ # Create the menubar
+ menuBar = wx.MenuBar()
+
+ # and a menu
+ menu = wx.Menu()
+
+ # add an item to the menu, using \tKeyName automatically
+ # creates an accelerator, the third param is some help text
+ # that will show up in the statusbar
+ menu.Append(wx.ID_EXIT, "E&xit\tAlt-X", "Exit this simple sample")
+
+ # bind the menu event to an event handler
+ self.Bind(wx.EVT_MENU, self.OnTimeToClose, id=wx.ID_EXIT)
+
+ # and put the menu on the menubar
+ menuBar.Append(menu, "&File")
+ self.SetMenuBar(menuBar)
+
+ self.CreateStatusBar()
+
+ # Now create the Panel to put the other controls on.
+ panel = wx.Panel(self)
+
+ # and a few controls
+ text = wx.StaticText(panel, -1, "Hello World!")
+ text.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD))
+ text.SetSize(text.GetBestSize())
+ btn = wx.Button(panel, -1, "Close")
+ funbtn = wx.Button(panel, -1, "Just for fun...")
+
+ # bind the button events to handlers
+ self.Bind(wx.EVT_BUTTON, self.OnTimeToClose, btn)
+ self.Bind(wx.EVT_BUTTON, self.OnFunButton, funbtn)
+
+ # Use a sizer to layout the controls, stacked vertically and with
+ # a 10 pixel border around each
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ sizer.Add(text, 0, wx.ALL, 10)
+ sizer.Add(btn, 0, wx.ALL, 10)
+ sizer.Add(funbtn, 0, wx.ALL, 10)
+ panel.SetSizer(sizer)
+ panel.Layout()
+
+
+ def OnTimeToClose(self, evt):
+ """Event handler for the button click."""
+ print("See ya later!")
+ self.Close()
+
+ def OnFunButton(self, evt):
+ """Event handler for the button click."""
+ print("Having fun yet?")
+
+
+ class MyApp(wx.App):
+ def OnInit(self):
+ frame = MyFrame(None, "Simple wxPython App")
+ self.SetTopWindow(frame)
+
+ print("Print statements go to this stdout window by default.")
+
+ frame.Show(True)
+ return True
+
+
+ if __name__ == '__main__':
+
+ app = wx.GetApp()
+ if app is None:
+ app = MyApp(redirect=False, clearSigInt=False)
+ else:
+ frame = MyFrame(None, "Simple wxPython App")
+ app.SetTopWindow(frame)
+ print("Print statements go to this stdout window by default.")
+ frame.Show(True)
+
diff --git a/python/helpers/pydev/tests_python/_debugger_case18.py b/python/helpers/pydev/tests_python/_debugger_case18.py
index 69717b2411ee..c221039fd774 100644
--- a/python/helpers/pydev/tests_python/_debugger_case18.py
+++ b/python/helpers/pydev/tests_python/_debugger_case18.py
@@ -1,4 +1,4 @@
-
+import sys
def m2(a):
a = 10
@@ -6,7 +6,7 @@ def m2(a):
c = 30
def function2():
- print a
+ print(a)
return a
diff --git a/python/helpers/pydev/tests_python/_debugger_case19.py b/python/helpers/pydev/tests_python/_debugger_case19.py
index aaf380c8a3f5..07ac951f05e0 100644
--- a/python/helpers/pydev/tests_python/_debugger_case19.py
+++ b/python/helpers/pydev/tests_python/_debugger_case19.py
@@ -5,6 +5,6 @@ class A:
if __name__ == '__main__':
a = A()
- print a._A__var
+ print(a._A__var)
# Evaluate 'a.__var' should give a._A__var_
print('TEST SUCEEDED')
diff --git a/python/helpers/pydev/tests_python/_debugger_case7.py b/python/helpers/pydev/tests_python/_debugger_case7.py
index 263110b1e990..499d8d76e650 100644
--- a/python/helpers/pydev/tests_python/_debugger_case7.py
+++ b/python/helpers/pydev/tests_python/_debugger_case7.py
@@ -5,4 +5,4 @@ def Call():
if __name__ == '__main__':
Call()
- print 'TEST SUCEEDED!'
+ print('TEST SUCEEDED!')
diff --git a/python/helpers/pydev/tests_python/_debugger_case89.py b/python/helpers/pydev/tests_python/_debugger_case89.py
index e6f32dd522bb..e22361d5a38d 100644
--- a/python/helpers/pydev/tests_python/_debugger_case89.py
+++ b/python/helpers/pydev/tests_python/_debugger_case89.py
@@ -1,16 +1,16 @@
def Method1():
- print 'm1'
+ print('m1')
def Method2():
- print 'm2 before'
+ print('m2 before')
Method1()
- print 'm2 after'
+ print('m2 after')
def Method3():
- print 'm3 before'
+ print('m3 before')
Method2()
- print 'm3 after'
+ print('m3 after')
if __name__ == '__main__':
Method3()
- print 'TEST SUCEEDED!'
+ print('TEST SUCEEDED!')
diff --git a/python/helpers/pydev/tests_python/_debugger_case_qthread1.py b/python/helpers/pydev/tests_python/_debugger_case_qthread1.py
new file mode 100644
index 000000000000..eb8729f13577
--- /dev/null
+++ b/python/helpers/pydev/tests_python/_debugger_case_qthread1.py
@@ -0,0 +1,25 @@
+import time
+import sys
+
+try:
+ from PySide import QtCore
+except:
+ from PyQt4 import QtCore
+
+# Subclassing QThread
+# http://doc.qt.nokia.com/latest/qthread.html
+class AThread(QtCore.QThread):
+
+ def run(self):
+ count = 0
+ while count < 5:
+ time.sleep(.5)
+ print("Increasing", count);sys.stdout.flush()
+ count += 1
+
+app = QtCore.QCoreApplication([])
+thread = AThread()
+thread.finished.connect(app.exit)
+thread.start()
+app.exec_()
+print('TEST SUCEEDED!') \ No newline at end of file
diff --git a/python/helpers/pydev/tests_python/_debugger_case_qthread2.py b/python/helpers/pydev/tests_python/_debugger_case_qthread2.py
new file mode 100644
index 000000000000..b2ce3159652c
--- /dev/null
+++ b/python/helpers/pydev/tests_python/_debugger_case_qthread2.py
@@ -0,0 +1,32 @@
+import time
+import sys
+
+try:
+ from PySide import QtCore
+except:
+ from PyQt4 import QtCore
+
+# Subclassing QObject and using moveToThread
+# http://labs.qt.nokia.com/2007/07/05/qthreads-no-longer-abstract/
+class SomeObject(QtCore.QObject):
+
+ finished = QtCore.Signal()
+
+ def longRunning(self):
+ count = 0
+ while count < 5:
+ time.sleep(.5)
+ print "Increasing"
+ count += 1
+ self.finished.emit()
+
+app = QtCore.QCoreApplication([])
+objThread = QtCore.QThread()
+obj = SomeObject()
+obj.moveToThread(objThread)
+obj.finished.connect(objThread.quit)
+objThread.started.connect(obj.longRunning)
+objThread.finished.connect(app.exit)
+objThread.start()
+app.exec_()
+print('TEST SUCEEDED!') \ No newline at end of file
diff --git a/python/helpers/pydev/tests_python/_debugger_case_qthread3.py b/python/helpers/pydev/tests_python/_debugger_case_qthread3.py
new file mode 100644
index 000000000000..22b0c91d7f13
--- /dev/null
+++ b/python/helpers/pydev/tests_python/_debugger_case_qthread3.py
@@ -0,0 +1,29 @@
+import time
+import sys
+
+try:
+ from PySide import QtCore
+except:
+ from PyQt4 import QtCore
+
+# Using a QRunnable
+# http://doc.qt.nokia.com/latest/qthreadpool.html
+# Note that a QRunnable isn't a subclass of QObject and therefore does
+# not provide signals and slots.
+class Runnable(QtCore.QRunnable):
+
+ def run(self):
+ count = 0
+ app = QtCore.QCoreApplication.instance()
+ while count < 5:
+ print "Increasing"
+ time.sleep(.5)
+ count += 1
+ app.quit()
+
+
+app = QtCore.QCoreApplication([])
+runnable = Runnable()
+QtCore.QThreadPool.globalInstance().start(runnable)
+app.exec_()
+print('TEST SUCEEDED!') \ No newline at end of file
diff --git a/python/helpers/pydev/tests_python/test_additional_thread_info.py b/python/helpers/pydev/tests_python/test_additional_thread_info.py
index 6ae260d6a658..71dc35243257 100644
--- a/python/helpers/pydev/tests_python/test_additional_thread_info.py
+++ b/python/helpers/pydev/tests_python/test_additional_thread_info.py
@@ -1,10 +1,21 @@
import sys
import os
+import pydev_monkey
sys.path.insert(0, os.path.split(os.path.split(__file__)[0])[0])
from pydevd_constants import Null
import unittest
+try:
+ import thread
+except:
+ import _thread as thread
+
+try:
+ xrange
+except:
+ xrange = range
+
#=======================================================================================================================
# TestCase
#=======================================================================================================================
@@ -40,10 +51,7 @@ class TestCase(unittest.TestCase):
def testStartNewThread(self):
- import pydevd
- import thread
- original = thread.start_new_thread
- thread.start_new_thread = pydevd.pydev_start_new_thread
+ pydev_monkey.patch_thread_modules()
try:
found = {}
def function(a, b, *args, **kwargs):
@@ -62,15 +70,11 @@ class TestCase(unittest.TestCase):
self.assertEqual({'a': 1, 'b': 2, 'args': (3, 4), 'kwargs': {'e': 2, 'd': 1}}, found)
finally:
- thread.start_new_thread = original
+ pydev_monkey.undo_patch_thread_modules()
def testStartNewThread2(self):
- import pydevd
- import thread
-
- original = thread.start_new_thread
- thread.start_new_thread = pydevd.pydev_start_new_thread
+ pydev_monkey.patch_thread_modules()
try:
found = {}
@@ -101,7 +105,7 @@ class TestCase(unittest.TestCase):
self.assertEqual({'a': 1, 'b': 2, 'args': (3, 4), 'kwargs': {'e': 2, 'd': 1}}, found)
finally:
- thread.start_new_thread = original
+ pydev_monkey.undo_patch_thread_modules()
#=======================================================================================================================
diff --git a/python/helpers/pydev/tests_python/test_debugger.py b/python/helpers/pydev/tests_python/test_debugger.py
index 3a216cb64079..ea569ddce556 100644
--- a/python/helpers/pydev/tests_python/test_debugger.py
+++ b/python/helpers/pydev/tests_python/test_debugger.py
@@ -5,6 +5,17 @@
Note that it's a python script but it'll spawn a process to run as jython, ironpython and as python.
'''
+SHOW_WRITES_AND_READS = False
+SHOW_OTHER_DEBUG_INFO = False
+SHOW_STDOUT = False
+
+
+
+from pydevd_constants import IS_PY3K
+try:
+ from thread import start_new_thread
+except:
+ from _thread import start_new_thread
CMD_SET_PROPERTY_TRACE, CMD_EVALUATE_CONSOLE_EXPRESSION, CMD_RUN_CUSTOM_OPERATION, CMD_ENABLE_DONT_TRACE = 133, 134, 135, 141
PYTHON_EXE = None
IRONPYTHON_EXE = None
@@ -14,9 +25,13 @@ JAVA_LOCATION = None
import unittest
import pydev_localhost
-
port = None
+try:
+ xrange
+except:
+ xrange = range
+
def UpdatePort():
global port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
@@ -25,29 +40,26 @@ def UpdatePort():
s.close()
import os
-def NormFile(filename):
+def _get_debugger_test_file(filename):
try:
rPath = os.path.realpath # @UndefinedVariable
except:
# jython does not support os.path.realpath
# realpath is a no-op on systems without islink support
rPath = os.path.abspath
- return os.path.normcase(rPath(filename))
-
-PYDEVD_FILE = NormFile('../pydevd.py')
-import sys
-sys.path.append(os.path.dirname(PYDEVD_FILE))
+
+ return os.path.normcase(rPath(os.path.join(os.path.dirname(__file__), filename)))
-SHOW_WRITES_AND_READS = False
-SHOW_RESULT_STR = False
-SHOW_OTHER_DEBUG_INFO = False
+import pydevd
+PYDEVD_FILE = pydevd.__file__
+import sys
import subprocess
import socket
import threading
import time
-from urllib import quote_plus, quote, unquote_plus
+from pydev_imports import quote_plus, quote, unquote_plus
#=======================================================================================================================
@@ -59,13 +71,16 @@ class ReaderThread(threading.Thread):
threading.Thread.__init__(self)
self.setDaemon(True)
self.sock = sock
- self.lastReceived = None
+ self.lastReceived = ''
def run(self):
+ last_printed = None
try:
buf = ''
while True:
l = self.sock.recv(1024)
+ if IS_PY3K:
+ l = l.decode('utf-8')
buf += l
if '\n' in buf:
@@ -73,7 +88,9 @@ class ReaderThread(threading.Thread):
buf = ''
if SHOW_WRITES_AND_READS:
- print 'Test Reader Thread Received %s' % self.lastReceived.strip()
+ if last_printed != self.lastReceived.strip():
+ last_printed = self.lastReceived.strip()
+ print('Test Reader Thread Received %s' % last_printed)
except:
pass # ok, finished it
@@ -90,6 +107,8 @@ class AbstractWriterThread(threading.Thread):
self.setDaemon(True)
self.finishedOk = False
self._next_breakpoint_id = 0
+ self.log = []
+
def DoKill(self):
if hasattr(self, 'readerThread'):
@@ -98,10 +117,14 @@ class AbstractWriterThread(threading.Thread):
self.sock.close()
def Write(self, s):
+
last = self.readerThread.lastReceived
if SHOW_WRITES_AND_READS:
- print 'Test Writer Thread Written %s' % (s,)
- self.sock.send(s + '\n')
+ print('Test Writer Thread Written %s' % (s,))
+ msg = s + '\n'
+ if IS_PY3K:
+ msg = msg.encode('utf-8')
+ self.sock.send(msg)
time.sleep(0.2)
i = 0
@@ -112,16 +135,16 @@ class AbstractWriterThread(threading.Thread):
def StartSocket(self):
if SHOW_WRITES_AND_READS:
- print 'StartSocket'
+ print('StartSocket')
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', port))
s.listen(1)
if SHOW_WRITES_AND_READS:
- print 'Waiting in socket.accept()'
+ print('Waiting in socket.accept()')
newSock, addr = s.accept()
if SHOW_WRITES_AND_READS:
- print 'Test Writer Thread Socket:', newSock, addr
+ print('Test Writer Thread Socket:', newSock, addr)
readerThread = self.readerThread = ReaderThread(newSock)
readerThread.start()
@@ -130,6 +153,7 @@ class AbstractWriterThread(threading.Thread):
self._sequence = -1
# initial command is always the version
self.WriteVersion()
+ self.log.append('StartSocket')
def NextBreakpointId(self):
self._next_breakpoint_id += 1
@@ -160,22 +184,27 @@ class AbstractWriterThread(threading.Thread):
109 is return
111 is breakpoint
'''
+ self.log.append('Start: WaitForBreakpointHit')
i = 0
# wait for hit breakpoint
- while not ('stop_reason="%s"' % reason) in self.readerThread.lastReceived:
+ last = self.readerThread.lastReceived
+ while not ('stop_reason="%s"' % reason) in last:
i += 1
time.sleep(1)
+ last = self.readerThread.lastReceived
if i >= 10:
raise AssertionError('After %s seconds, a break with reason: %s was not hit. Found: %s' % \
- (i, reason, self.readerThread.lastReceived))
+ (i, reason, last))
# we have something like <xml><thread id="12152656" stop_reason="111"><frame id="12453120" ...
- splitted = self.readerThread.lastReceived.split('"')
+ splitted = last.split('"')
threadId = splitted[1]
frameId = splitted[7]
if get_line:
+ self.log.append('End(0): WaitForBreakpointHit')
return threadId, frameId, int(splitted[13])
+ self.log.append('End(1): WaitForBreakpointHit')
return threadId, frameId
def WaitForCustomOperation(self, expected):
@@ -264,6 +293,7 @@ class AbstractWriterThread(threading.Thread):
def WriteMakeInitialRun(self):
self.Write("101\t%s\t" % self.NextSeq())
+ self.log.append('WriteMakeInitialRun')
def WriteVersion(self):
self.Write("501\t%s\t1.0\tWINDOWS\tID" % self.NextSeq())
@@ -274,6 +304,7 @@ class AbstractWriterThread(threading.Thread):
'''
breakpoint_id = self.NextBreakpointId()
self.Write("111\t%s\t%s\t%s\t%s\t%s\t%s\tNone\tNone" % (self.NextSeq(), breakpoint_id, 'python-line', self.TEST_FILE, line, func))
+ self.log.append('WriteAddBreakpoint: %s line: %s func: %s' % (breakpoint_id, line, func))
return breakpoint_id
def WriteRemoveBreakpoint(self, breakpoint_id):
@@ -284,6 +315,7 @@ class AbstractWriterThread(threading.Thread):
def WriteGetFrame(self, threadId, frameId):
self.Write("114\t%s\t%s\t%s\tFRAME" % (self.NextSeq(), threadId, frameId))
+ self.log.append('WriteGetFrame')
def WriteGetVariable(self, threadId, frameId, var_attrs):
self.Write("110\t%s\t%s\t%s\tFRAME\t%s" % (self.NextSeq(), threadId, frameId, var_attrs))
@@ -301,6 +333,7 @@ class AbstractWriterThread(threading.Thread):
self.Write("105\t%s\t%s" % (self.NextSeq(), threadId,))
def WriteRunThread(self, threadId):
+ self.log.append('WriteRunThread')
self.Write("106\t%s\t%s" % (self.NextSeq(), threadId,))
def WriteKillThread(self, threadId):
@@ -328,7 +361,7 @@ class AbstractWriterThread(threading.Thread):
#======================================================================================================================
class WriterThreadCase19(AbstractWriterThread):
- TEST_FILE = NormFile('_debugger_case19.py')
+ TEST_FILE = _get_debugger_test_file('_debugger_case19.py')
def run(self):
self.StartSocket()
@@ -352,7 +385,7 @@ class WriterThreadCase19(AbstractWriterThread):
#======================================================================================================================
class WriterThreadCase18(AbstractWriterThread):
- TEST_FILE = NormFile('_debugger_case18.py')
+ TEST_FILE = _get_debugger_test_file('_debugger_case18.py')
def run(self):
self.StartSocket()
@@ -372,7 +405,7 @@ class WriterThreadCase18(AbstractWriterThread):
#======================================================================================================================
class WriterThreadCase17(AbstractWriterThread):
- TEST_FILE = NormFile('_debugger_case17.py')
+ TEST_FILE = _get_debugger_test_file('_debugger_case17.py')
def run(self):
self.StartSocket()
@@ -400,7 +433,7 @@ class WriterThreadCase17(AbstractWriterThread):
#======================================================================================================================
class WriterThreadCase16(AbstractWriterThread):
- TEST_FILE = NormFile('_debugger_case16.py')
+ TEST_FILE = _get_debugger_test_file('_debugger_case16.py')
def run(self):
self.StartSocket()
@@ -430,8 +463,16 @@ class WriterThreadCase16(AbstractWriterThread):
self.WaitForVar('<var name="%27size%27')
self.WriteGetVariable(threadId, frameId, 'bigarray')
- self.WaitForVar(['<var name="min" type="int64" value="int64%253A 0" />', '<var name="size" type="int" value="int%3A 100000" />']) # TODO: When on a 32 bit python we get an int32 (which makes this test fail).
- self.WaitForVar(['<var name="max" type="int64" value="int64%253A 99999" />', '<var name="max" type="int32" value="int32%253A 99999" />'])
+ self.WaitForVar([
+ '<var name="min" type="int64" value="int64%253A 0" />',
+ '<var name="min" type="int64" value="int64%3A 0" />',
+ '<var name="size" type="int" value="int%3A 100000" />',
+ ])
+ self.WaitForVar([
+ '<var name="max" type="int64" value="int64%253A 99999" />',
+ '<var name="max" type="int32" value="int32%253A 99999" />',
+ '<var name="max" type="int64" value="int64%3A 99999"'
+ ])
self.WaitForVar('<var name="shape" type="tuple"')
self.WaitForVar('<var name="dtype" type="dtype"')
self.WaitForVar('<var name="size" type="int"')
@@ -441,8 +482,14 @@ class WriterThreadCase16(AbstractWriterThread):
# this one is different because it crosses the magic threshold where we don't calculate
# the min/max
self.WriteGetVariable(threadId, frameId, 'hugearray')
- self.WaitForVar('<var name="min" type="str" value="str%253A ndarray too big%252C calculating min would slow down debugging" />')
- self.WaitForVar('<var name="max" type="str" value="str%253A ndarray too big%252C calculating max would slow down debugging" />')
+ self.WaitForVar([
+ '<var name="min" type="str" value="str%253A ndarray too big%252C calculating min would slow down debugging" />',
+ '<var name="min" type="str" value="str%3A ndarray too big%252C calculating min would slow down debugging" />',
+ ])
+ self.WaitForVar([
+ '<var name="max" type="str" value="str%253A ndarray too big%252C calculating max would slow down debugging" />',
+ '<var name="max" type="str" value="str%3A ndarray too big%252C calculating max would slow down debugging" />',
+ ])
self.WaitForVar('<var name="shape" type="tuple"')
self.WaitForVar('<var name="dtype" type="dtype"')
self.WaitForVar('<var name="size" type="int"')
@@ -458,7 +505,7 @@ class WriterThreadCase16(AbstractWriterThread):
#======================================================================================================================
class WriterThreadCase15(AbstractWriterThread):
- TEST_FILE = NormFile('_debugger_case15.py')
+ TEST_FILE = _get_debugger_test_file('_debugger_case15.py')
def run(self):
self.StartSocket()
@@ -472,7 +519,7 @@ class WriterThreadCase15(AbstractWriterThread):
self.WaitForCustomOperation('val=Black')
assert 7 == self._sequence, 'Expected 7. Had: %s' % self._sequence
- self.WriteCustomOperation("%s\t%s\tEXPRESSION\tcarObj.color" % (threadId, frameId), "EXECFILE", NormFile('_debugger_case15_execfile.py'), "f")
+ self.WriteCustomOperation("%s\t%s\tEXPRESSION\tcarObj.color" % (threadId, frameId), "EXECFILE", _get_debugger_test_file('_debugger_case15_execfile.py'), "f")
self.WaitForCustomOperation('val=Black')
assert 9 == self._sequence, 'Expected 9. Had: %s' % self._sequence
@@ -486,7 +533,7 @@ class WriterThreadCase15(AbstractWriterThread):
#======================================================================================================================
class WriterThreadCase14(AbstractWriterThread):
- TEST_FILE = NormFile('_debugger_case14.py')
+ TEST_FILE = _get_debugger_test_file('_debugger_case14.py')
def run(self):
self.StartSocket()
@@ -499,21 +546,26 @@ class WriterThreadCase14(AbstractWriterThread):
# Access some variable
self.WriteDebugConsoleExpression("%s\t%s\tEVALUATE\tcarObj.color" % (threadId, frameId))
- self.WaitForMultipleVars(['<more>False</more>', '%27Black%27'])
+ self.WaitForVar(['<more>False</more>', '%27Black%27'])
assert 7 == self._sequence, 'Expected 9. Had: %s' % self._sequence
# Change some variable
self.WriteDebugConsoleExpression("%s\t%s\tEVALUATE\tcarObj.color='Red'" % (threadId, frameId))
self.WriteDebugConsoleExpression("%s\t%s\tEVALUATE\tcarObj.color" % (threadId, frameId))
- self.WaitForMultipleVars(['<more>False</more>', '%27Red%27'])
+ self.WaitForVar(['<more>False</more>', '%27Red%27'])
assert 11 == self._sequence, 'Expected 13. Had: %s' % self._sequence
# Iterate some loop
self.WriteDebugConsoleExpression("%s\t%s\tEVALUATE\tfor i in range(3):" % (threadId, frameId))
- self.WaitForVars('<xml><more>True</more></xml>')
- self.WriteDebugConsoleExpression("%s\t%s\tEVALUATE\t print i" % (threadId, frameId))
+ self.WaitForVar(['<xml><more>True</more></xml>', '<xml><more>1</more></xml>'])
+ self.WriteDebugConsoleExpression("%s\t%s\tEVALUATE\t print(i)" % (threadId, frameId))
self.WriteDebugConsoleExpression("%s\t%s\tEVALUATE\t" % (threadId, frameId))
- self.WaitForVars('<xml><more>False</more><output message="0"></output><output message="1"></output><output message="2"></output></xml>')
+ self.WaitForVar(
+ [
+ '<xml><more>False</more><output message="0"></output><output message="1"></output><output message="2"></output></xml>',
+ '<xml><more>0</more><output message="0"></output><output message="1"></output><output message="2"></output></xml>'
+ ]
+ )
assert 17 == self._sequence, 'Expected 19. Had: %s' % self._sequence
self.WriteRunThread(threadId)
@@ -525,7 +577,7 @@ class WriterThreadCase14(AbstractWriterThread):
#======================================================================================================================
class WriterThreadCase13(AbstractWriterThread):
- TEST_FILE = NormFile('_debugger_case13.py')
+ TEST_FILE = _get_debugger_test_file('_debugger_case13.py')
def run(self):
self.StartSocket()
@@ -575,7 +627,7 @@ class WriterThreadCase13(AbstractWriterThread):
#======================================================================================================================
class WriterThreadCase12(AbstractWriterThread):
- TEST_FILE = NormFile('_debugger_case10.py')
+ TEST_FILE = _get_debugger_test_file('_debugger_case10.py')
def run(self):
self.StartSocket()
@@ -607,7 +659,7 @@ class WriterThreadCase12(AbstractWriterThread):
#======================================================================================================================
class WriterThreadCase11(AbstractWriterThread):
- TEST_FILE = NormFile('_debugger_case10.py')
+ TEST_FILE = _get_debugger_test_file('_debugger_case10.py')
def run(self):
self.StartSocket()
@@ -648,7 +700,7 @@ class WriterThreadCase11(AbstractWriterThread):
#======================================================================================================================
class WriterThreadCase10(AbstractWriterThread):
- TEST_FILE = NormFile('_debugger_case10.py')
+ TEST_FILE = _get_debugger_test_file('_debugger_case10.py')
def run(self):
self.StartSocket()
@@ -682,7 +734,7 @@ class WriterThreadCase10(AbstractWriterThread):
#======================================================================================================================
class WriterThreadCase9(AbstractWriterThread):
- TEST_FILE = NormFile('_debugger_case89.py')
+ TEST_FILE = _get_debugger_test_file('_debugger_case89.py')
def run(self):
self.StartSocket()
@@ -715,7 +767,7 @@ class WriterThreadCase9(AbstractWriterThread):
#======================================================================================================================
class WriterThreadCase8(AbstractWriterThread):
- TEST_FILE = NormFile('_debugger_case89.py')
+ TEST_FILE = _get_debugger_test_file('_debugger_case89.py')
def run(self):
self.StartSocket()
@@ -744,7 +796,7 @@ class WriterThreadCase8(AbstractWriterThread):
#======================================================================================================================
class WriterThreadCase7(AbstractWriterThread):
- TEST_FILE = NormFile('_debugger_case7.py')
+ TEST_FILE = _get_debugger_test_file('_debugger_case7.py')
def run(self):
self.StartSocket()
@@ -782,7 +834,7 @@ class WriterThreadCase7(AbstractWriterThread):
#=======================================================================================================================
class WriterThreadCase6(AbstractWriterThread):
- TEST_FILE = NormFile('_debugger_case56.py')
+ TEST_FILE = _get_debugger_test_file('_debugger_case56.py')
def run(self):
self.StartSocket()
@@ -817,7 +869,7 @@ class WriterThreadCase6(AbstractWriterThread):
#=======================================================================================================================
class WriterThreadCase5(AbstractWriterThread):
- TEST_FILE = NormFile('_debugger_case56.py')
+ TEST_FILE = _get_debugger_test_file('_debugger_case56.py')
def run(self):
self.StartSocket()
@@ -855,7 +907,7 @@ class WriterThreadCase5(AbstractWriterThread):
#=======================================================================================================================
class WriterThreadCase4(AbstractWriterThread):
- TEST_FILE = NormFile('_debugger_case4.py')
+ TEST_FILE = _get_debugger_test_file('_debugger_case4.py')
def run(self):
self.StartSocket()
@@ -877,12 +929,12 @@ class WriterThreadCase4(AbstractWriterThread):
#=======================================================================================================================
class WriterThreadCase3(AbstractWriterThread):
- TEST_FILE = NormFile('_debugger_case3.py')
+ TEST_FILE = _get_debugger_test_file('_debugger_case3.py')
def run(self):
self.StartSocket()
self.WriteMakeInitialRun()
- time.sleep(1)
+ time.sleep(.5)
breakpoint_id = self.WriteAddBreakpoint(4, '')
self.WriteAddBreakpoint(5, 'FuncNotAvailable') # Check that it doesn't get hit in the global when a function is available
@@ -909,7 +961,7 @@ class WriterThreadCase3(AbstractWriterThread):
#=======================================================================================================================
class WriterThreadCase2(AbstractWriterThread):
- TEST_FILE = NormFile('_debugger_case2.py')
+ TEST_FILE = _get_debugger_test_file('_debugger_case2.py')
def run(self):
self.StartSocket()
@@ -930,8 +982,79 @@ class WriterThreadCase2(AbstractWriterThread):
self.WriteRunThread(threadId)
+ self.log.append('Checking sequence. Found: %s' % (self._sequence))
assert 15 == self._sequence, 'Expected 15. Had: %s' % self._sequence
+ self.log.append('Marking finished ok.')
+ self.finishedOk = True
+
+#=======================================================================================================================
+# WriterThreadCaseQThread1
+#=======================================================================================================================
+class WriterThreadCaseQThread1(AbstractWriterThread):
+
+ TEST_FILE = _get_debugger_test_file('_debugger_case_qthread1.py')
+
+ def run(self):
+ self.StartSocket()
+ breakpoint_id = self.WriteAddBreakpoint(16, 'run')
+ self.WriteMakeInitialRun()
+
+ threadId, frameId = self.WaitForBreakpointHit()
+
+ self.WriteRemoveBreakpoint(breakpoint_id)
+ self.WriteRunThread(threadId)
+
+ self.log.append('Checking sequence. Found: %s' % (self._sequence))
+ assert 9 == self._sequence, 'Expected 9. Had: %s' % self._sequence
+
+ self.log.append('Marking finished ok.')
+ self.finishedOk = True
+
+#=======================================================================================================================
+# WriterThreadCaseQThread2
+#=======================================================================================================================
+class WriterThreadCaseQThread2(AbstractWriterThread):
+
+ TEST_FILE = _get_debugger_test_file('_debugger_case_qthread2.py')
+
+ def run(self):
+ self.StartSocket()
+ breakpoint_id = self.WriteAddBreakpoint(18, 'longRunning')
+ self.WriteMakeInitialRun()
+
+ threadId, frameId = self.WaitForBreakpointHit()
+
+ self.WriteRemoveBreakpoint(breakpoint_id)
+ self.WriteRunThread(threadId)
+
+ self.log.append('Checking sequence. Found: %s' % (self._sequence))
+ assert 9 == self._sequence, 'Expected 9. Had: %s' % self._sequence
+
+ self.log.append('Marking finished ok.')
+ self.finishedOk = True
+
+#=======================================================================================================================
+# WriterThreadCaseQThread3
+#=======================================================================================================================
+class WriterThreadCaseQThread3(AbstractWriterThread):
+
+ TEST_FILE = _get_debugger_test_file('_debugger_case_qthread3.py')
+
+ def run(self):
+ self.StartSocket()
+ breakpoint_id = self.WriteAddBreakpoint(19, 'run')
+ self.WriteMakeInitialRun()
+
+ threadId, frameId = self.WaitForBreakpointHit()
+
+ self.WriteRemoveBreakpoint(breakpoint_id)
+ self.WriteRunThread(threadId)
+
+ self.log.append('Checking sequence. Found: %s' % (self._sequence))
+ assert 9 == self._sequence, 'Expected 9. Had: %s' % self._sequence
+
+ self.log.append('Marking finished ok.')
self.finishedOk = True
#=======================================================================================================================
@@ -939,24 +1062,39 @@ class WriterThreadCase2(AbstractWriterThread):
#=======================================================================================================================
class WriterThreadCase1(AbstractWriterThread):
- TEST_FILE = NormFile('_debugger_case1.py')
+ TEST_FILE = _get_debugger_test_file('_debugger_case1.py')
def run(self):
self.StartSocket()
+
+ self.log.append('writing add breakpoint')
self.WriteAddBreakpoint(6, 'SetUp')
+
+ self.log.append('making initial run')
self.WriteMakeInitialRun()
+ self.log.append('waiting for breakpoint hit')
threadId, frameId = self.WaitForBreakpointHit()
+ self.log.append('get frame')
self.WriteGetFrame(threadId, frameId)
+ self.log.append('step over')
self.WriteStepOver(threadId)
+ self.log.append('get frame')
self.WriteGetFrame(threadId, frameId)
+ self.log.append('run thread')
self.WriteRunThread(threadId)
- assert 13 == self._sequence, 'Expected 13. Had: %s' % self._sequence
+ self.log.append('asserting')
+ try:
+ assert 13 == self._sequence, 'Expected 13. Had: %s' % self._sequence
+ except:
+ self.log.append('assert failed!')
+ raise
+ self.log.append('asserted')
self.finishedOk = True
@@ -972,6 +1110,7 @@ class DebuggerBase(object):
UpdatePort()
writerThread = writerThreadClass()
writerThread.start()
+ time.sleep(1)
localhost = pydev_localhost.get_localhost()
args = self.getCommandLine()
@@ -987,60 +1126,74 @@ class DebuggerBase(object):
]
if SHOW_OTHER_DEBUG_INFO:
- print 'executing', ' '.join(args)
-
-# process = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=os.path.dirname(PYDEVD_FILE))
- process = subprocess.Popen(args, stdout=subprocess.PIPE, cwd=os.path.dirname(PYDEVD_FILE))
- class ProcessReadThread(threading.Thread):
- def run(self):
- self.resultStr = None
- self.resultStr = process.stdout.read()
- process.stdout.close()
-
- def DoKill(self):
- process.stdout.close()
-
- processReadThread = ProcessReadThread()
- processReadThread.setDaemon(True)
- processReadThread.start()
+ print('executing', ' '.join(args))
+
+ process = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=os.path.dirname(PYDEVD_FILE))
+
+ stdout = []
+ stderr = []
+
+ def read(stream, buffer):
+ for line in stream.readlines():
+ if IS_PY3K:
+ line = line.decode('utf-8')
+
+ if SHOW_STDOUT:
+ print(line)
+ buffer.append(line)
+
+ start_new_thread(read, (process.stdout, stdout))
+
+
if SHOW_OTHER_DEBUG_INFO:
- print 'Both processes started'
+ print('Both processes started')
# polls can fail (because the process may finish and the thread still not -- so, we give it some more chances to
# finish successfully).
- pools_failed = 0
- while writerThread.isAlive():
+ check = 0
+ while True:
if process.poll() is not None:
- pools_failed += 1
- time.sleep(.2)
- if pools_failed == 10:
break
-
- if process.poll() is None:
- for i in range(10):
- if processReadThread.resultStr is None:
- time.sleep(.5)
- else:
- break
else:
- writerThread.DoKill()
-
- else:
- if process.poll() < 0:
- self.fail("The other process exited with error code: " + str(process.poll()) + " result:" + processReadThread.resultStr)
-
+ if not writerThread.isAlive():
+ check += 1
+ if check == 20:
+ print('Warning: writer thread exited and process still did not.')
+ if check == 100:
+ self.fail_with_message(
+ "The other process should've exited but still didn't (timeout for process to exit).",
+ stdout, stderr, writerThread
+ )
+ time.sleep(.2)
+
+
+ poll = process.poll()
+ if poll < 0:
+ self.fail_with_message(
+ "The other process exited with error code: " + str(poll), stdout, stderr, writerThread)
- if SHOW_RESULT_STR:
- print processReadThread.resultStr
- if processReadThread.resultStr is None:
- self.fail("The other process may still be running -- and didn't give any output")
+ if stdout is None:
+ self.fail_with_message(
+ "The other process may still be running -- and didn't give any output.", stdout, stderr, writerThread)
- if 'TEST SUCEEDED' not in processReadThread.resultStr:
- self.fail(processReadThread.resultStr)
+ if 'TEST SUCEEDED' not in ''.join(stdout):
+ self.fail_with_message("TEST SUCEEDED not found in stdout.", stdout, stderr, writerThread)
+ for i in xrange(100):
+ if not writerThread.finishedOk:
+ time.sleep(.1)
+
if not writerThread.finishedOk:
- self.fail("The thread that was doing the tests didn't finish successfully. Output: %s" % processReadThread.resultStr)
+ self.fail_with_message(
+ "The thread that was doing the tests didn't finish successfully.", stdout, stderr, writerThread)
+
+ def fail_with_message(self, msg, stdout, stderr, writerThread):
+ self.fail(msg+
+ "\nStdout: \n"+'\n'.join(stdout)+
+ "\nStderr:"+'\n'.join(stderr)+
+ "\nLog:\n"+'\n'.join(getattr(writerThread, 'log', [])))
+
def testCase1(self):
self.CheckCase(WriterThreadCase1)
@@ -1098,6 +1251,30 @@ class DebuggerBase(object):
def testCase19(self):
self.CheckCase(WriterThreadCase19)
+
+ def _has_qt(self):
+ try:
+ from PySide import QtCore
+ return True
+ except:
+ try:
+ from PyQt4 import QtCore
+ return True
+ except:
+ pass
+ return False
+
+ def testCaseQthread1(self):
+ if self._has_qt():
+ self.CheckCase(WriterThreadCaseQThread1)
+
+ def testCaseQthread2(self):
+ if self._has_qt():
+ self.CheckCase(WriterThreadCaseQThread2)
+
+ def testCaseQthread3(self):
+ if self._has_qt():
+ self.CheckCase(WriterThreadCaseQThread3)
class TestPython(unittest.TestCase, DebuggerBase):
@@ -1117,9 +1294,6 @@ class TestJython(unittest.TestCase, DebuggerBase):
def testCase13(self):
self.skipTest("Unsupported Decorators")
- def testCase16(self):
- self.skipTest("Unsupported numpy")
-
# This case requires decorators to work (which are not present on Jython 2.1), so, this test is just removed from the jython run.
def testCase17(self):
self.skipTest("Unsupported Decorators")
@@ -1127,6 +1301,9 @@ class TestJython(unittest.TestCase, DebuggerBase):
def testCase18(self):
self.skipTest("Unsupported assign to local")
+ def testCase16(self):
+ self.skipTest("Unsupported numpy")
+
class TestIronPython(unittest.TestCase, DebuggerBase):
def getCommandLine(self):
return [
@@ -1134,8 +1311,22 @@ class TestIronPython(unittest.TestCase, DebuggerBase):
'-X:Frames'
]
+ def testCase3(self):
+ self.skipTest("Timing issues") # This test fails once in a while due to timing issues on IronPython, so, skipping it.
+
+ def testCase7(self):
+ # This test checks that we start without variables and at each step a new var is created, but on ironpython,
+ # the variables exist all at once (with None values), so, we can't test it properly.
+ self.skipTest("Different behavior on IronPython")
+
+ def testCase13(self):
+ self.skipTest("Unsupported Decorators") # Not sure why it doesn't work on IronPython, but it's not so common, so, leave it be.
+
def testCase16(self):
self.skipTest("Unsupported numpy")
+
+ def testCase18(self):
+ self.skipTest("Unsupported assign to local")
def GetLocationFromLine(line):
@@ -1157,49 +1348,90 @@ def SplitLine(line):
+
import platform
sysname = platform.system().lower()
test_dependent = os.path.join('../../../', 'org.python.pydev.core', 'tests', 'org', 'python', 'pydev', 'core', 'TestDependent.' + sysname + '.properties')
-f = open(test_dependent)
-try:
- for line in f.readlines():
- var, loc = SplitLine(line)
- if 'PYTHON_EXE' == var:
- PYTHON_EXE = loc
-
- if 'IRONPYTHON_EXE' == var:
- IRONPYTHON_EXE = loc
-
- if 'JYTHON_JAR_LOCATION' == var:
- JYTHON_JAR_LOCATION = loc
-
- if 'JAVA_LOCATION' == var:
- JAVA_LOCATION = loc
-finally:
- f.close()
-
-assert PYTHON_EXE, 'PYTHON_EXE not found in %s' % (test_dependent,)
-assert IRONPYTHON_EXE, 'IRONPYTHON_EXE not found in %s' % (test_dependent,)
-assert JYTHON_JAR_LOCATION, 'JYTHON_JAR_LOCATION not found in %s' % (test_dependent,)
-assert JAVA_LOCATION, 'JAVA_LOCATION not found in %s' % (test_dependent,)
-assert os.path.exists(PYTHON_EXE), 'The location: %s is not valid' % (PYTHON_EXE,)
-assert os.path.exists(IRONPYTHON_EXE), 'The location: %s is not valid' % (IRONPYTHON_EXE,)
-assert os.path.exists(JYTHON_JAR_LOCATION), 'The location: %s is not valid' % (JYTHON_JAR_LOCATION,)
-assert os.path.exists(JAVA_LOCATION), 'The location: %s is not valid' % (JAVA_LOCATION,)
-
-if False:
- suite = unittest.TestSuite()
- #PYTHON_EXE = r'C:\bin\Anaconda\python.exe'
-# suite.addTest(TestPython('testCase10'))
-# suite.addTest(TestPython('testCase3'))
-# suite.addTest(TestPython('testCase16'))
-# suite.addTest(TestPython('testCase17'))
-# suite.addTest(TestPython('testCase18'))
-# suite.addTest(TestPython('testCase19'))
- suite = unittest.makeSuite(TestPython)
- unittest.TextTestRunner(verbosity=3).run(suite)
+
+if os.path.exists(test_dependent):
+ f = open(test_dependent)
+ try:
+ for line in f.readlines():
+ var, loc = SplitLine(line)
+ if 'PYTHON_EXE' == var:
+ PYTHON_EXE = loc
+
+ if 'IRONPYTHON_EXE' == var:
+ IRONPYTHON_EXE = loc
+
+ if 'JYTHON_JAR_LOCATION' == var:
+ JYTHON_JAR_LOCATION = loc
+
+ if 'JAVA_LOCATION' == var:
+ JAVA_LOCATION = loc
+ finally:
+ f.close()
+else:
+ pass
+
+if IRONPYTHON_EXE is None:
+ sys.stderr.write('Warning: not running IronPython tests.\n')
+ class TestIronPython(unittest.TestCase):
+ pass
+
+if JAVA_LOCATION is None:
+ sys.stderr.write('Warning: not running Jython tests.\n')
+ class TestJython(unittest.TestCase):
+ pass
-# unittest.TextTestRunner(verbosity=3).run(suite)
-#
-# suite = unittest.makeSuite(TestJython)
-# unittest.TextTestRunner(verbosity=3).run(suite)
+# if PYTHON_EXE is None:
+PYTHON_EXE = sys.executable
+
+
+if __name__ == '__main__':
+ if False:
+ assert PYTHON_EXE, 'PYTHON_EXE not found in %s' % (test_dependent,)
+ assert IRONPYTHON_EXE, 'IRONPYTHON_EXE not found in %s' % (test_dependent,)
+ assert JYTHON_JAR_LOCATION, 'JYTHON_JAR_LOCATION not found in %s' % (test_dependent,)
+ assert JAVA_LOCATION, 'JAVA_LOCATION not found in %s' % (test_dependent,)
+ assert os.path.exists(PYTHON_EXE), 'The location: %s is not valid' % (PYTHON_EXE,)
+ assert os.path.exists(IRONPYTHON_EXE), 'The location: %s is not valid' % (IRONPYTHON_EXE,)
+ assert os.path.exists(JYTHON_JAR_LOCATION), 'The location: %s is not valid' % (JYTHON_JAR_LOCATION,)
+ assert os.path.exists(JAVA_LOCATION), 'The location: %s is not valid' % (JAVA_LOCATION,)
+
+ if True:
+ #try:
+ # os.remove(r'X:\pydev\plugins\org.python.pydev\pysrc\pydevd.pyc')
+ #except:
+ # pass
+ suite = unittest.TestSuite()
+
+# suite.addTests(unittest.makeSuite(TestJython)) # Note: Jython should be 2.2.1
+#
+# suite.addTests(unittest.makeSuite(TestIronPython))
+#
+# suite.addTests(unittest.makeSuite(TestPython))
+
+
+
+
+# suite.addTest(TestIronPython('testCase18'))
+# suite.addTest(TestIronPython('testCase17'))
+# suite.addTest(TestIronPython('testCase3'))
+# suite.addTest(TestIronPython('testCase7'))
+#
+ suite.addTest(TestPython('testCaseQthread1'))
+ suite.addTest(TestPython('testCaseQthread2'))
+ suite.addTest(TestPython('testCaseQthread3'))
+
+# suite.addTest(TestPython('testCase4'))
+
+
+# suite.addTest(TestJython('testCase1'))
+# suite.addTest(TestPython('testCase2'))
+# unittest.TextTestRunner(verbosity=3).run(suite)
+ # suite.addTest(TestPython('testCase17'))
+ # suite.addTest(TestPython('testCase18'))
+ # suite.addTest(TestPython('testCase19'))
+
+ unittest.TextTestRunner(verbosity=3).run(suite)
diff --git a/python/helpers/pydev/tests_python/test_pydev_monkey.py b/python/helpers/pydev/tests_python/test_pydev_monkey.py
index 3eb7930b73ae..be1312a066d3 100644
--- a/python/helpers/pydev/tests_python/test_pydev_monkey.py
+++ b/python/helpers/pydev/tests_python/test_pydev_monkey.py
@@ -1,17 +1,32 @@
import unittest
import pydev_monkey
import sys
+from pydevd import SetupHolder
+from pydev_monkey import pydev_src_dir
class TestCase(unittest.TestCase):
def test_monkey(self):
- check='''C:\\bin\\python.exe -u -c "
+ original = SetupHolder.setup
+
+ try:
+ SetupHolder.setup = {'client':'127.0.0.1', 'port': '0'}
+ check='''C:\\bin\\python.exe -u -c "
connect(\\"127.0.0.1\\")
"'''
- sys.original_argv = []
- self.assertEqual('"-u" "-c" "\nconnect(\\"127.0.0.1\\")\n"', pydev_monkey.patch_arg_str_win(check))
+ sys.original_argv = []
+ self.assertEqual(
+ '"C:\\bin\\python.exe" "-u" "-c" "import sys; '
+ 'sys.path.append(r\'%s\'); '
+ 'import pydevd; pydevd.settrace(host=\'127.0.0.1\', port=0, suspend=False, '
+ 'trace_only_current_thread=False, patch_multiprocessing=True); '
+ '\nconnect(\\"127.0.0.1\\")\n"' % pydev_src_dir,
+ pydev_monkey.patch_arg_str_win(check)
+ )
+ finally:
+ SetupHolder.setup = original
def test_str_to_args_windows(self):
diff --git a/python/helpers/pydev/tests_python/test_save_locals.py b/python/helpers/pydev/tests_python/test_save_locals.py
index fe65d4d438d1..a3beb567d305 100644
--- a/python/helpers/pydev/tests_python/test_save_locals.py
+++ b/python/helpers/pydev/tests_python/test_save_locals.py
@@ -16,7 +16,7 @@ def use_save_locals(name, value):
save_locals(frame)
-def test_method(fn):
+def check_method(fn):
"""
A harness for testing methods that attempt to modify the values of locals on the stack.
"""
@@ -36,7 +36,7 @@ class TestSetLocals(unittest.TestCase):
def test_set_locals_using_save_locals(self):
- x = test_method(use_save_locals)
+ x = check_method(use_save_locals)
self.assertEqual(x, 2) # Expected to succeed
@@ -65,7 +65,7 @@ class TestSetLocals(unittest.TestCase):
def check_co_vars(a):
frame = sys._getframe()
def function2():
- print a
+ print(a)
assert 'a' in frame.f_code.co_cellvars
frame = sys._getframe()
diff --git a/python/helpers/pydev/tests_runfiles/samples/__init__.py b/python/helpers/pydev/tests_runfiles/samples/__init__.py
deleted file mode 100644
index e69de29bb2d1..000000000000
--- a/python/helpers/pydev/tests_runfiles/samples/__init__.py
+++ /dev/null
diff --git a/python/helpers/pydev/tests_runfiles/samples/nested_dir/.cvsignore b/python/helpers/pydev/tests_runfiles/samples/nested_dir/.cvsignore
new file mode 100644
index 000000000000..d1c899510a28
--- /dev/null
+++ b/python/helpers/pydev/tests_runfiles/samples/nested_dir/.cvsignore
@@ -0,0 +1,2 @@
+*.class
+*.pyc
diff --git a/python/helpers/pydev/tests_runfiles/samples/nested_dir/nested2/.cvsignore b/python/helpers/pydev/tests_runfiles/samples/nested_dir/nested2/.cvsignore
new file mode 100644
index 000000000000..d1c899510a28
--- /dev/null
+++ b/python/helpers/pydev/tests_runfiles/samples/nested_dir/nested2/.cvsignore
@@ -0,0 +1,2 @@
+*.class
+*.pyc
diff --git a/python/helpers/pydev/tests_runfiles/samples/nested_dir/nested3/.cvsignore b/python/helpers/pydev/tests_runfiles/samples/nested_dir/nested3/.cvsignore
new file mode 100644
index 000000000000..d1c899510a28
--- /dev/null
+++ b/python/helpers/pydev/tests_runfiles/samples/nested_dir/nested3/.cvsignore
@@ -0,0 +1,2 @@
+*.class
+*.pyc
diff --git a/python/helpers/pydev/tests_runfiles/samples/not_in_default_pythonpath.txt b/python/helpers/pydev/tests_runfiles/samples/not_in_default_pythonpath.txt
new file mode 100644
index 000000000000..29cdc5bc1078
--- /dev/null
+++ b/python/helpers/pydev/tests_runfiles/samples/not_in_default_pythonpath.txt
@@ -0,0 +1 @@
+(no __init__.py file) \ No newline at end of file
diff --git a/python/helpers/pydev/tests_runfiles/test_runfiles.py b/python/helpers/pydev/tests_runfiles/test_runfiles.py
index 0c04764e99fc..fb34c40c80a7 100644
--- a/python/helpers/pydev/tests_runfiles/test_runfiles.py
+++ b/python/helpers/pydev/tests_runfiles/test_runfiles.py
@@ -26,6 +26,7 @@ if 'pydev_runfiles' in sys.modules:
import pydev_runfiles
import unittest
import tempfile
+import re
try:
set
@@ -191,7 +192,7 @@ class RunfilesTest(unittest.TestCase):
files_with_tests = [1 for t in self.all_tests if len(t._tests) > 0]
self.assertNotEquals(len(self.files), len(files_with_tests))
- def count_tests(self, tests):
+ def count_suite(self, tests=None):
total = 0
for t in tests:
total += t.countTestCases()
@@ -207,60 +208,60 @@ class RunfilesTest(unittest.TestCase):
def test_finding_tests_from_modules_with_bad_filter_returns_0_tests(self):
self._setup_scenario(self.file_dir, ["NO_TESTS_ARE_SURE_TO_HAVE_THIS_NAME"])
- self.assertEquals(0, self.count_tests(self.all_tests))
+ self.assertEquals(0, self.count_suite(self.all_tests))
def test_finding_test_with_unique_name_returns_1_test(self):
self._setup_scenario(self.file_dir, include_tests=["test_i_am_a_unique_test_name"])
filtered_tests = self.MyTestRunner.filter_tests(self.all_tests)
- self.assertEquals(1, self.count_tests(filtered_tests))
+ self.assertEquals(1, self.count_suite(filtered_tests))
def test_finding_test_with_non_unique_name(self):
self._setup_scenario(self.file_dir, include_tests=["test_non_unique_name"])
filtered_tests = self.MyTestRunner.filter_tests(self.all_tests)
- self.assertEquals(1, self.count_tests(filtered_tests) > 2)
+ self.assertEquals(1, self.count_suite(filtered_tests) > 2)
def test_finding_tests_with_regex_filters(self):
self._setup_scenario(self.file_dir, include_tests=["test_non*"])
filtered_tests = self.MyTestRunner.filter_tests(self.all_tests)
- self.assertEquals(1, self.count_tests(filtered_tests) > 2)
+ self.assertEquals(1, self.count_suite(filtered_tests) > 2)
self._setup_scenario(self.file_dir, ["^$"])
filtered_tests = self.MyTestRunner.filter_tests(self.all_tests)
- self.assertEquals(0, self.count_tests(filtered_tests))
+ self.assertEquals(0, self.count_suite(filtered_tests))
self._setup_scenario(self.file_dir, None, exclude_tests=["*"])
filtered_tests = self.MyTestRunner.filter_tests(self.all_tests)
- self.assertEquals(0, self.count_tests(filtered_tests))
+ self.assertEquals(0, self.count_suite(filtered_tests))
def test_matching_tests(self):
self._setup_scenario(self.file_dir, None, ['StillYetAnotherSampleTest'])
filtered_tests = self.MyTestRunner.filter_tests(self.all_tests)
- self.assertEqual(1, self.count_tests(filtered_tests))
+ self.assertEqual(1, self.count_suite(filtered_tests))
self._setup_scenario(self.file_dir, None, ['SampleTest.test_xxxxxx1'])
filtered_tests = self.MyTestRunner.filter_tests(self.all_tests)
- self.assertEqual(1, self.count_tests(filtered_tests))
+ self.assertEqual(1, self.count_suite(filtered_tests))
self._setup_scenario(self.file_dir, None, ['SampleTest'])
filtered_tests = self.MyTestRunner.filter_tests(self.all_tests)
- self.assertEqual(8, self.count_tests(filtered_tests))
+ self.assertEqual(8, self.count_suite(filtered_tests))
self._setup_scenario(self.file_dir, None, ['AnotherSampleTest.todo_not_tested'])
filtered_tests = self.MyTestRunner.filter_tests(self.all_tests)
- self.assertEqual(1, self.count_tests(filtered_tests))
+ self.assertEqual(1, self.count_suite(filtered_tests))
self._setup_scenario(self.file_dir, None, ['StillYetAnotherSampleTest', 'SampleTest.test_xxxxxx1'])
filtered_tests = self.MyTestRunner.filter_tests(self.all_tests)
- self.assertEqual(2, self.count_tests(filtered_tests))
+ self.assertEqual(2, self.count_suite(filtered_tests))
self._setup_scenario(self.file_dir, None, exclude_tests=['*'])
filtered_tests = self.MyTestRunner.filter_tests(self.all_tests)
- self.assertEqual(self.count_tests(filtered_tests), 0)
+ self.assertEqual(self.count_suite(filtered_tests), 0)
self._setup_scenario(self.file_dir, None, exclude_tests=['*a*'])
filtered_tests = self.MyTestRunner.filter_tests(self.all_tests)
- self.assertEqual(self.count_tests(filtered_tests), 6)
+ self.assertEqual(self.count_suite(filtered_tests), 6)
self.assertEqual(
set(self.MyTestRunner.list_test_names(filtered_tests)),
@@ -269,7 +270,7 @@ class RunfilesTest(unittest.TestCase):
self._setup_scenario(self.file_dir, None, exclude_tests=['*a*', '*x*'])
filtered_tests = self.MyTestRunner.filter_tests(self.all_tests)
- self.assertEqual(self.count_tests(filtered_tests), 2)
+ self.assertEqual(self.count_suite(filtered_tests), 2)
self.assertEqual(
set(self.MyTestRunner.list_test_names(filtered_tests)),
@@ -362,17 +363,43 @@ class RunfilesTest(unittest.TestCase):
('notifyTest', 'ok', '', '', simple_test, 'SampleTest.test_xxxxxx2'),
('notifyTest', 'ok', '', '', simple_test2, 'YetAnotherSampleTest.test_abc'),
]
+
if not IS_JYTHON:
- expected.append(('notifyTest', 'error', '', 'ValueError: This is an INTENTIONAL value error in setUpClass.',
- simpleClass_test.replace('/', os.path.sep), 'samples.simpleClass_test.SetUpClassTest <setUpClass>'))
- expected.append(('notifyTest', 'error', '', 'ValueError: This is an INTENTIONAL value error in setUpModule.',
- simpleModule_test.replace('/', os.path.sep), 'samples.simpleModule_test <setUpModule>'))
+ if 'samples.simpleClass_test' in str(notifications):
+ expected.append(('notifyTest', 'error', '', 'ValueError: This is an INTENTIONAL value error in setUpClass.',
+ simpleClass_test.replace('/', os.path.sep), 'samples.simpleClass_test.SetUpClassTest <setUpClass>'))
+ expected.append(('notifyTest', 'error', '', 'ValueError: This is an INTENTIONAL value error in setUpModule.',
+ simpleModule_test.replace('/', os.path.sep), 'samples.simpleModule_test <setUpModule>'))
+ else:
+ expected.append(('notifyTest', 'error', '', 'ValueError: This is an INTENTIONAL value error in setUpClass.',
+ simpleClass_test.replace('/', os.path.sep), 'simpleClass_test.SetUpClassTest <setUpClass>'))
+ expected.append(('notifyTest', 'error', '', 'ValueError: This is an INTENTIONAL value error in setUpModule.',
+ simpleModule_test.replace('/', os.path.sep), 'simpleModule_test <setUpModule>'))
else:
expected.append(('notifyTest', 'ok', '', '', simpleClass_test, 'SetUpClassTest.test_blank'))
expected.append(('notifyTest', 'ok', '', '', simpleModule_test, 'SetUpModuleTest.test_blank'))
expected.append(('notifyTestRunFinished',))
expected.sort()
+ new_notifications = []
+ for notification in expected:
+ try:
+ if len(notification) == 6:
+ # Some are binary on Py3.
+ new_notifications.append((
+ notification[0],
+ notification[1],
+ notification[2].encode('latin1'),
+ notification[3].encode('latin1'),
+ notification[4],
+ notification[5],
+ ))
+ else:
+ new_notifications.append(notification)
+ except:
+ raise
+ expected = new_notifications
+
notifications.sort()
self.assertEqual(
expected,
diff --git a/python/helpers/pydev/third_party/__init__.py b/python/helpers/pydev/third_party/__init__.py
new file mode 100644
index 000000000000..8b137891791f
--- /dev/null
+++ b/python/helpers/pydev/third_party/__init__.py
@@ -0,0 +1 @@
+
diff --git a/python/helpers/pydev/third_party/pep8/autopep8.py b/python/helpers/pydev/third_party/pep8/autopep8.py
new file mode 100644
index 000000000000..224b5c645949
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/autopep8.py
@@ -0,0 +1,3687 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2010-2011 Hideo Hattori
+# Copyright (C) 2011-2013 Hideo Hattori, Steven Myint
+# Copyright (C) 2013-2014 Hideo Hattori, Steven Myint, Bill Wendling
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+"""Automatically formats Python code to conform to the PEP 8 style guide.
+
+Fixes that only need be done once can be added by adding a function of the form
+"fix_<code>(source)" to this module. They should return the fixed source code.
+These fixes are picked up by apply_global_fixes().
+
+Fixes that depend on pep8 should be added as methods to FixPEP8. See the class
+documentation for more information.
+
+"""
+
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
+from __future__ import unicode_literals
+
+import bisect
+import codecs
+import collections
+import copy
+import difflib
+import fnmatch
+import inspect
+import io
+import itertools
+import keyword
+import locale
+import os
+import re
+import signal
+import sys
+import token
+import tokenize
+
+import pep8
+
+
+try:
+ unicode
+except NameError:
+ unicode = str
+
+
+__version__ = '1.0.3'
+
+
+CR = '\r'
+LF = '\n'
+CRLF = '\r\n'
+
+
+PYTHON_SHEBANG_REGEX = re.compile(r'^#!.*\bpython[23]?\b\s*$')
+
+
+# For generating line shortening candidates.
+SHORTEN_OPERATOR_GROUPS = frozenset([
+ frozenset([',']),
+ frozenset(['%']),
+ frozenset([',', '(', '[', '{']),
+ frozenset(['%', '(', '[', '{']),
+ frozenset([',', '(', '[', '{', '%', '+', '-', '*', '/', '//']),
+ frozenset(['%', '+', '-', '*', '/', '//']),
+])
+
+
+DEFAULT_IGNORE = 'E24'
+DEFAULT_INDENT_SIZE = 4
+
+
+# W602 is handled separately due to the need to avoid "with_traceback".
+CODE_TO_2TO3 = {
+ 'E721': ['idioms'],
+ 'W601': ['has_key'],
+ 'W603': ['ne'],
+ 'W604': ['repr'],
+ 'W690': ['apply',
+ 'except',
+ 'exitfunc',
+ 'import',
+ 'numliterals',
+ 'operator',
+ 'paren',
+ 'reduce',
+ 'renames',
+ 'standarderror',
+ 'sys_exc',
+ 'throw',
+ 'tuple_params',
+ 'xreadlines']}
+
+
+def check_lib2to3():
+ try:
+ import lib2to3
+ except ImportError:
+ sys.path.append(os.path.join(os.path.dirname(__file__), 'lib2to3'))
+ import lib2to3
+
+
+def open_with_encoding(filename, encoding=None, mode='r'):
+ """Return opened file with a specific encoding."""
+ if not encoding:
+ encoding = detect_encoding(filename)
+
+ return io.open(filename, mode=mode, encoding=encoding,
+ newline='') # Preserve line endings
+
+
+def detect_encoding(filename):
+ """Return file encoding."""
+ try:
+ with open(filename, 'rb') as input_file:
+ check_lib2to3()
+ from lib2to3.pgen2 import tokenize as lib2to3_tokenize
+ encoding = lib2to3_tokenize.detect_encoding(input_file.readline)[0]
+
+ # Check for correctness of encoding
+ with open_with_encoding(filename, encoding) as test_file:
+ test_file.read()
+
+ return encoding
+ except (LookupError, SyntaxError, UnicodeDecodeError):
+ return 'latin-1'
+
+
+def readlines_from_file(filename):
+ """Return contents of file."""
+ with open_with_encoding(filename) as input_file:
+ return input_file.readlines()
+
+
+def extended_blank_lines(logical_line,
+ blank_lines,
+ indent_level,
+ previous_logical):
+ """Check for missing blank lines after class declaration."""
+ if previous_logical.startswith('class '):
+ if (
+ logical_line.startswith(('def ', 'class ', '@')) or
+ pep8.DOCSTRING_REGEX.match(logical_line)
+ ):
+ if indent_level and not blank_lines:
+ yield (0, 'E309 expected 1 blank line after class declaration')
+ elif previous_logical.startswith('def '):
+ if blank_lines and pep8.DOCSTRING_REGEX.match(logical_line):
+ yield (0, 'E303 too many blank lines ({0})'.format(blank_lines))
+ elif pep8.DOCSTRING_REGEX.match(previous_logical):
+ # Missing blank line between class docstring and method declaration.
+ if (
+ indent_level and
+ not blank_lines and
+ logical_line.startswith(('def ')) and
+ '(self' in logical_line
+ ):
+ yield (0, 'E301 expected 1 blank line, found 0')
+pep8.register_check(extended_blank_lines)
+
+
+def continued_indentation(logical_line, tokens, indent_level, indent_char,
+ noqa):
+ """Override pep8's function to provide indentation information."""
+ first_row = tokens[0][2][0]
+ nrows = 1 + tokens[-1][2][0] - first_row
+ if noqa or nrows == 1:
+ return
+
+ # indent_next tells us whether the next block is indented. Assuming
+ # that it is indented by 4 spaces, then we should not allow 4-space
+ # indents on the final continuation line. In turn, some other
+ # indents are allowed to have an extra 4 spaces.
+ indent_next = logical_line.endswith(':')
+
+ row = depth = 0
+ valid_hangs = (
+ (DEFAULT_INDENT_SIZE,)
+ if indent_char != '\t' else (DEFAULT_INDENT_SIZE,
+ 2 * DEFAULT_INDENT_SIZE)
+ )
+
+ # Remember how many brackets were opened on each line.
+ parens = [0] * nrows
+
+ # Relative indents of physical lines.
+ rel_indent = [0] * nrows
+
+ # For each depth, collect a list of opening rows.
+ open_rows = [[0]]
+ # For each depth, memorize the hanging indentation.
+ hangs = [None]
+
+ # Visual indents.
+ indent_chances = {}
+ last_indent = tokens[0][2]
+ indent = [last_indent[1]]
+
+ last_token_multiline = None
+ line = None
+ last_line = ''
+ last_line_begins_with_multiline = False
+ for token_type, text, start, end, line in tokens:
+
+ newline = row < start[0] - first_row
+ if newline:
+ row = start[0] - first_row
+ newline = (not last_token_multiline and
+ token_type not in (tokenize.NL, tokenize.NEWLINE))
+ last_line_begins_with_multiline = last_token_multiline
+
+ if newline:
+ # This is the beginning of a continuation line.
+ last_indent = start
+
+ # Record the initial indent.
+ rel_indent[row] = pep8.expand_indent(line) - indent_level
+
+ # Identify closing bracket.
+ close_bracket = (token_type == tokenize.OP and text in ']})')
+
+ # Is the indent relative to an opening bracket line?
+ for open_row in reversed(open_rows[depth]):
+ hang = rel_indent[row] - rel_indent[open_row]
+ hanging_indent = hang in valid_hangs
+ if hanging_indent:
+ break
+ if hangs[depth]:
+ hanging_indent = (hang == hangs[depth])
+
+ visual_indent = (not close_bracket and hang > 0 and
+ indent_chances.get(start[1]))
+
+ if close_bracket and indent[depth]:
+ # Closing bracket for visual indent.
+ if start[1] != indent[depth]:
+ yield (start, 'E124 {0}'.format(indent[depth]))
+ elif close_bracket and not hang:
+ pass
+ elif indent[depth] and start[1] < indent[depth]:
+ # Visual indent is broken.
+ yield (start, 'E128 {0}'.format(indent[depth]))
+ elif (hanging_indent or
+ (indent_next and
+ rel_indent[row] == 2 * DEFAULT_INDENT_SIZE)):
+ # Hanging indent is verified.
+ if close_bracket:
+ yield (start, 'E123 {0}'.format(indent_level +
+ rel_indent[open_row]))
+ hangs[depth] = hang
+ elif visual_indent is True:
+ # Visual indent is verified.
+ indent[depth] = start[1]
+ elif visual_indent in (text, unicode):
+ # Ignore token lined up with matching one from a previous line.
+ pass
+ else:
+ one_indented = (indent_level + rel_indent[open_row] +
+ DEFAULT_INDENT_SIZE)
+ # Indent is broken.
+ if hang <= 0:
+ error = ('E122', one_indented)
+ elif indent[depth]:
+ error = ('E127', indent[depth])
+ elif hang > DEFAULT_INDENT_SIZE:
+ error = ('E126', one_indented)
+ else:
+ hangs[depth] = hang
+ error = ('E121', one_indented)
+
+ yield (start, '{0} {1}'.format(*error))
+
+ # Look for visual indenting.
+ if (parens[row] and token_type not in (tokenize.NL, tokenize.COMMENT)
+ and not indent[depth]):
+ indent[depth] = start[1]
+ indent_chances[start[1]] = True
+ # Deal with implicit string concatenation.
+ elif (token_type in (tokenize.STRING, tokenize.COMMENT) or
+ text in ('u', 'ur', 'b', 'br')):
+ indent_chances[start[1]] = unicode
+ # Special case for the "if" statement because len("if (") is equal to
+ # 4.
+ elif not indent_chances and not row and not depth and text == 'if':
+ indent_chances[end[1] + 1] = True
+ elif text == ':' and line[end[1]:].isspace():
+ open_rows[depth].append(row)
+
+ # Keep track of bracket depth.
+ if token_type == tokenize.OP:
+ if text in '([{':
+ depth += 1
+ indent.append(0)
+ hangs.append(None)
+ if len(open_rows) == depth:
+ open_rows.append([])
+ open_rows[depth].append(row)
+ parens[row] += 1
+ elif text in ')]}' and depth > 0:
+ # Parent indents should not be more than this one.
+ prev_indent = indent.pop() or last_indent[1]
+ hangs.pop()
+ for d in range(depth):
+ if indent[d] > prev_indent:
+ indent[d] = 0
+ for ind in list(indent_chances):
+ if ind >= prev_indent:
+ del indent_chances[ind]
+ del open_rows[depth + 1:]
+ depth -= 1
+ if depth:
+ indent_chances[indent[depth]] = True
+ for idx in range(row, -1, -1):
+ if parens[idx]:
+ parens[idx] -= 1
+ break
+ assert len(indent) == depth + 1
+ if (
+ start[1] not in indent_chances and
+ # This is for purposes of speeding up E121 (GitHub #90).
+ not last_line.rstrip().endswith(',')
+ ):
+ # Allow to line up tokens.
+ indent_chances[start[1]] = text
+
+ last_token_multiline = (start[0] != end[0])
+ if last_token_multiline:
+ rel_indent[end[0] - first_row] = rel_indent[row]
+
+ last_line = line
+
+ if (
+ indent_next and
+ not last_line_begins_with_multiline and
+ pep8.expand_indent(line) == indent_level + DEFAULT_INDENT_SIZE
+ ):
+ pos = (start[0], indent[0] + 4)
+ yield (pos, 'E125 {0}'.format(indent_level +
+ 2 * DEFAULT_INDENT_SIZE))
+del pep8._checks['logical_line'][pep8.continued_indentation]
+pep8.register_check(continued_indentation)
+
+
+class FixPEP8(object):
+
+ """Fix invalid code.
+
+ Fixer methods are prefixed "fix_". The _fix_source() method looks for these
+ automatically.
+
+ The fixer method can take either one or two arguments (in addition to
+ self). The first argument is "result", which is the error information from
+ pep8. The second argument, "logical", is required only for logical-line
+ fixes.
+
+ The fixer method can return the list of modified lines or None. An empty
+ list would mean that no changes were made. None would mean that only the
+ line reported in the pep8 error was modified. Note that the modified line
+ numbers that are returned are indexed at 1. This typically would correspond
+ with the line number reported in the pep8 error information.
+
+ [fixed method list]
+ - e121,e122,e123,e124,e125,e126,e127,e128,e129
+ - e201,e202,e203
+ - e211
+ - e221,e222,e223,e224,e225
+ - e231
+ - e251
+ - e261,e262
+ - e271,e272,e273,e274
+ - e301,e302,e303
+ - e401
+ - e502
+ - e701,e702
+ - e711
+ - w291
+
+ """
+
+ def __init__(self, filename,
+ options,
+ contents=None,
+ long_line_ignore_cache=None):
+ self.filename = filename
+ if contents is None:
+ self.source = readlines_from_file(filename)
+ else:
+ sio = io.StringIO(contents)
+ self.source = sio.readlines()
+ self.options = options
+ self.indent_word = _get_indentword(''.join(self.source))
+
+ self.long_line_ignore_cache = (
+ set() if long_line_ignore_cache is None
+ else long_line_ignore_cache)
+
+ # Many fixers are the same even though pep8 categorizes them
+ # differently.
+ self.fix_e115 = self.fix_e112
+ self.fix_e116 = self.fix_e113
+ self.fix_e121 = self._fix_reindent
+ self.fix_e122 = self._fix_reindent
+ self.fix_e123 = self._fix_reindent
+ self.fix_e124 = self._fix_reindent
+ self.fix_e126 = self._fix_reindent
+ self.fix_e127 = self._fix_reindent
+ self.fix_e128 = self._fix_reindent
+ self.fix_e129 = self._fix_reindent
+ self.fix_e202 = self.fix_e201
+ self.fix_e203 = self.fix_e201
+ self.fix_e211 = self.fix_e201
+ self.fix_e221 = self.fix_e271
+ self.fix_e222 = self.fix_e271
+ self.fix_e223 = self.fix_e271
+ self.fix_e226 = self.fix_e225
+ self.fix_e227 = self.fix_e225
+ self.fix_e228 = self.fix_e225
+ self.fix_e241 = self.fix_e271
+ self.fix_e242 = self.fix_e224
+ self.fix_e261 = self.fix_e262
+ self.fix_e272 = self.fix_e271
+ self.fix_e273 = self.fix_e271
+ self.fix_e274 = self.fix_e271
+ self.fix_e309 = self.fix_e301
+ self.fix_e501 = (
+ self.fix_long_line_logically if
+ options and (options.aggressive >= 2 or options.experimental) else
+ self.fix_long_line_physically)
+ self.fix_e703 = self.fix_e702
+
+ self._ws_comma_done = False
+
+ def _fix_source(self, results):
+ try:
+ (logical_start, logical_end) = _find_logical(self.source)
+ logical_support = True
+ except (SyntaxError, tokenize.TokenError): # pragma: no cover
+ logical_support = False
+
+ completed_lines = set()
+ for result in sorted(results, key=_priority_key):
+ if result['line'] in completed_lines:
+ continue
+
+ fixed_methodname = 'fix_' + result['id'].lower()
+ if hasattr(self, fixed_methodname):
+ fix = getattr(self, fixed_methodname)
+
+ line_index = result['line'] - 1
+ original_line = self.source[line_index]
+
+ is_logical_fix = len(inspect.getargspec(fix).args) > 2
+ if is_logical_fix:
+ logical = None
+ if logical_support:
+ logical = _get_logical(self.source,
+ result,
+ logical_start,
+ logical_end)
+ if logical and set(range(
+ logical[0][0] + 1,
+ logical[1][0] + 1)).intersection(
+ completed_lines):
+ continue
+
+ modified_lines = fix(result, logical)
+ else:
+ modified_lines = fix(result)
+
+ if modified_lines is None:
+ # Force logical fixes to report what they modified.
+ assert not is_logical_fix
+
+ if self.source[line_index] == original_line:
+ modified_lines = []
+
+ if modified_lines:
+ completed_lines.update(modified_lines)
+ elif modified_lines == []: # Empty list means no fix
+ if self.options.verbose >= 2:
+ print(
+ '---> Not fixing {f} on line {l}'.format(
+ f=result['id'], l=result['line']),
+ file=sys.stderr)
+ else: # We assume one-line fix when None.
+ completed_lines.add(result['line'])
+ else:
+ if self.options.verbose >= 3:
+ print(
+ "---> '{0}' is not defined.".format(fixed_methodname),
+ file=sys.stderr)
+
+ info = result['info'].strip()
+ print('---> {0}:{1}:{2}:{3}'.format(self.filename,
+ result['line'],
+ result['column'],
+ info),
+ file=sys.stderr)
+
+ def fix(self):
+ """Return a version of the source code with PEP 8 violations fixed."""
+ pep8_options = {
+ 'ignore': self.options.ignore,
+ 'select': self.options.select,
+ 'max_line_length': self.options.max_line_length,
+ }
+ results = _execute_pep8(pep8_options, self.source)
+
+ if self.options.verbose:
+ progress = {}
+ for r in results:
+ if r['id'] not in progress:
+ progress[r['id']] = set()
+ progress[r['id']].add(r['line'])
+ print('---> {n} issue(s) to fix {progress}'.format(
+ n=len(results), progress=progress), file=sys.stderr)
+
+ if self.options.line_range:
+ start, end = self.options.line_range
+ results = [r for r in results
+ if start <= r['line'] <= end]
+
+ self._fix_source(filter_results(source=''.join(self.source),
+ results=results,
+ aggressive=self.options.aggressive))
+
+ if self.options.line_range:
+ # If number of lines has changed then change line_range.
+ count = sum(sline.count('\n')
+ for sline in self.source[start - 1:end])
+ self.options.line_range[1] = start + count - 1
+
+ return ''.join(self.source)
+
+ def _fix_reindent(self, result):
+ """Fix a badly indented line.
+
+ This is done by adding or removing from its initial indent only.
+
+ """
+ num_indent_spaces = int(result['info'].split()[1])
+ line_index = result['line'] - 1
+ target = self.source[line_index]
+
+ self.source[line_index] = ' ' * num_indent_spaces + target.lstrip()
+
+ def fix_e112(self, result):
+ """Fix under-indented comments."""
+ line_index = result['line'] - 1
+ target = self.source[line_index]
+
+ if not target.lstrip().startswith('#'):
+ # Don't screw with invalid syntax.
+ return []
+
+ self.source[line_index] = self.indent_word + target
+
+ def fix_e113(self, result):
+ """Fix over-indented comments."""
+ line_index = result['line'] - 1
+ target = self.source[line_index]
+
+ indent = _get_indentation(target)
+ stripped = target.lstrip()
+
+ if not stripped.startswith('#'):
+ # Don't screw with invalid syntax.
+ return []
+
+ self.source[line_index] = indent[1:] + stripped
+
+ def fix_e125(self, result):
+ """Fix indentation undistinguish from the next logical line."""
+ num_indent_spaces = int(result['info'].split()[1])
+ line_index = result['line'] - 1
+ target = self.source[line_index]
+
+ spaces_to_add = num_indent_spaces - len(_get_indentation(target))
+ indent = len(_get_indentation(target))
+ modified_lines = []
+
+ while len(_get_indentation(self.source[line_index])) >= indent:
+ self.source[line_index] = (' ' * spaces_to_add +
+ self.source[line_index])
+ modified_lines.append(1 + line_index) # Line indexed at 1.
+ line_index -= 1
+
+ return modified_lines
+
+ def fix_e201(self, result):
+ """Remove extraneous whitespace."""
+ line_index = result['line'] - 1
+ target = self.source[line_index]
+ offset = result['column'] - 1
+
+ if is_probably_part_of_multiline(target):
+ return []
+
+ fixed = fix_whitespace(target,
+ offset=offset,
+ replacement='')
+
+ self.source[line_index] = fixed
+
+ def fix_e224(self, result):
+ """Remove extraneous whitespace around operator."""
+ target = self.source[result['line'] - 1]
+ offset = result['column'] - 1
+ fixed = target[:offset] + target[offset:].replace('\t', ' ')
+ self.source[result['line'] - 1] = fixed
+
+ def fix_e225(self, result):
+ """Fix missing whitespace around operator."""
+ target = self.source[result['line'] - 1]
+ offset = result['column'] - 1
+ fixed = target[:offset] + ' ' + target[offset:]
+
+ # Only proceed if non-whitespace characters match.
+ # And make sure we don't break the indentation.
+ if (
+ fixed.replace(' ', '') == target.replace(' ', '') and
+ _get_indentation(fixed) == _get_indentation(target)
+ ):
+ self.source[result['line'] - 1] = fixed
+ else:
+ return []
+
+ def fix_e231(self, result):
+ """Add missing whitespace."""
+ # Optimize for comma case. This will fix all commas in the full source
+ # code in one pass. Don't do this more than once. If it fails the first
+ # time, there is no point in trying again.
+ if ',' in result['info'] and not self._ws_comma_done:
+ self._ws_comma_done = True
+ original = ''.join(self.source)
+ new = refactor(original, ['ws_comma'])
+ if original.strip() != new.strip():
+ self.source = [new]
+ return range(1, 1 + len(original))
+
+ line_index = result['line'] - 1
+ target = self.source[line_index]
+ offset = result['column']
+ fixed = target[:offset] + ' ' + target[offset:]
+ self.source[line_index] = fixed
+
+ def fix_e251(self, result):
+ """Remove whitespace around parameter '=' sign."""
+ line_index = result['line'] - 1
+ target = self.source[line_index]
+
+ # This is necessary since pep8 sometimes reports columns that goes
+ # past the end of the physical line. This happens in cases like,
+ # foo(bar\n=None)
+ c = min(result['column'] - 1,
+ len(target) - 1)
+
+ if target[c].strip():
+ fixed = target
+ else:
+ fixed = target[:c].rstrip() + target[c:].lstrip()
+
+ # There could be an escaped newline
+ #
+ # def foo(a=\
+ # 1)
+ if fixed.endswith(('=\\\n', '=\\\r\n', '=\\\r')):
+ self.source[line_index] = fixed.rstrip('\n\r \t\\')
+ self.source[line_index + 1] = self.source[line_index + 1].lstrip()
+ return [line_index + 1, line_index + 2] # Line indexed at 1
+
+ self.source[result['line'] - 1] = fixed
+
+ def fix_e262(self, result):
+ """Fix spacing after comment hash."""
+ target = self.source[result['line'] - 1]
+ offset = result['column']
+
+ code = target[:offset].rstrip(' \t#')
+ comment = target[offset:].lstrip(' \t#')
+
+ fixed = code + (' # ' + comment if comment.strip() else '\n')
+
+ self.source[result['line'] - 1] = fixed
+
+ def fix_e271(self, result):
+ """Fix extraneous whitespace around keywords."""
+ line_index = result['line'] - 1
+ target = self.source[line_index]
+ offset = result['column'] - 1
+
+ if is_probably_part_of_multiline(target):
+ return []
+
+ fixed = fix_whitespace(target,
+ offset=offset,
+ replacement=' ')
+
+ if fixed == target:
+ return []
+ else:
+ self.source[line_index] = fixed
+
+ def fix_e301(self, result):
+ """Add missing blank line."""
+ cr = '\n'
+ self.source[result['line'] - 1] = cr + self.source[result['line'] - 1]
+
+ def fix_e302(self, result):
+ """Add missing 2 blank lines."""
+ add_linenum = 2 - int(result['info'].split()[-1])
+ cr = '\n' * add_linenum
+ self.source[result['line'] - 1] = cr + self.source[result['line'] - 1]
+
+ def fix_e303(self, result):
+ """Remove extra blank lines."""
+ delete_linenum = int(result['info'].split('(')[1].split(')')[0]) - 2
+ delete_linenum = max(1, delete_linenum)
+
+ # We need to count because pep8 reports an offset line number if there
+ # are comments.
+ cnt = 0
+ line = result['line'] - 2
+ modified_lines = []
+ while cnt < delete_linenum and line >= 0:
+ if not self.source[line].strip():
+ self.source[line] = ''
+ modified_lines.append(1 + line) # Line indexed at 1
+ cnt += 1
+ line -= 1
+
+ return modified_lines
+
+ def fix_e304(self, result):
+ """Remove blank line following function decorator."""
+ line = result['line'] - 2
+ if not self.source[line].strip():
+ self.source[line] = ''
+
+ def fix_e401(self, result):
+ """Put imports on separate lines."""
+ line_index = result['line'] - 1
+ target = self.source[line_index]
+ offset = result['column'] - 1
+
+ if not target.lstrip().startswith('import'):
+ return []
+
+ indentation = re.split(pattern=r'\bimport\b',
+ string=target, maxsplit=1)[0]
+ fixed = (target[:offset].rstrip('\t ,') + '\n' +
+ indentation + 'import ' + target[offset:].lstrip('\t ,'))
+ self.source[line_index] = fixed
+
+ def fix_long_line_logically(self, result, logical):
+ """Try to make lines fit within --max-line-length characters."""
+ if (
+ not logical or
+ len(logical[2]) == 1 or
+ self.source[result['line'] - 1].lstrip().startswith('#')
+ ):
+ return self.fix_long_line_physically(result)
+
+ start_line_index = logical[0][0]
+ end_line_index = logical[1][0]
+ logical_lines = logical[2]
+
+ previous_line = get_item(self.source, start_line_index - 1, default='')
+ next_line = get_item(self.source, end_line_index + 1, default='')
+
+ single_line = join_logical_line(''.join(logical_lines))
+
+ try:
+ fixed = self.fix_long_line(
+ target=single_line,
+ previous_line=previous_line,
+ next_line=next_line,
+ original=''.join(logical_lines))
+ except (SyntaxError, tokenize.TokenError):
+ return self.fix_long_line_physically(result)
+
+ if fixed:
+ for line_index in range(start_line_index, end_line_index + 1):
+ self.source[line_index] = ''
+ self.source[start_line_index] = fixed
+ return range(start_line_index + 1, end_line_index + 1)
+ else:
+ return []
+
+ def fix_long_line_physically(self, result):
+ """Try to make lines fit within --max-line-length characters."""
+ line_index = result['line'] - 1
+ target = self.source[line_index]
+
+ previous_line = get_item(self.source, line_index - 1, default='')
+ next_line = get_item(self.source, line_index + 1, default='')
+
+ try:
+ fixed = self.fix_long_line(
+ target=target,
+ previous_line=previous_line,
+ next_line=next_line,
+ original=target)
+ except (SyntaxError, tokenize.TokenError):
+ return []
+
+ if fixed:
+ self.source[line_index] = fixed
+ return [line_index + 1]
+ else:
+ return []
+
+ def fix_long_line(self, target, previous_line,
+ next_line, original):
+ cache_entry = (target, previous_line, next_line)
+ if cache_entry in self.long_line_ignore_cache:
+ return []
+
+ if target.lstrip().startswith('#'):
+ # Wrap commented lines.
+ return shorten_comment(
+ line=target,
+ max_line_length=self.options.max_line_length,
+ last_comment=not next_line.lstrip().startswith('#'))
+
+ fixed = get_fixed_long_line(
+ target=target,
+ previous_line=previous_line,
+ original=original,
+ indent_word=self.indent_word,
+ max_line_length=self.options.max_line_length,
+ aggressive=self.options.aggressive,
+ experimental=self.options.experimental,
+ verbose=self.options.verbose)
+ if fixed and not code_almost_equal(original, fixed):
+ return fixed
+ else:
+ self.long_line_ignore_cache.add(cache_entry)
+ return None
+
+ def fix_e502(self, result):
+ """Remove extraneous escape of newline."""
+ line_index = result['line'] - 1
+ target = self.source[line_index]
+ self.source[line_index] = target.rstrip('\n\r \t\\') + '\n'
+
+ def fix_e701(self, result):
+ """Put colon-separated compound statement on separate lines."""
+ line_index = result['line'] - 1
+ target = self.source[line_index]
+ c = result['column']
+
+ fixed_source = (target[:c] + '\n' +
+ _get_indentation(target) + self.indent_word +
+ target[c:].lstrip('\n\r \t\\'))
+ self.source[result['line'] - 1] = fixed_source
+ return [result['line'], result['line'] + 1]
+
+ def fix_e702(self, result, logical):
+ """Put semicolon-separated compound statement on separate lines."""
+ if not logical:
+ return [] # pragma: no cover
+ logical_lines = logical[2]
+
+ line_index = result['line'] - 1
+ target = self.source[line_index]
+
+ if target.rstrip().endswith('\\'):
+ # Normalize '1; \\\n2' into '1; 2'.
+ self.source[line_index] = target.rstrip('\n \r\t\\')
+ self.source[line_index + 1] = self.source[line_index + 1].lstrip()
+ return [line_index + 1, line_index + 2]
+
+ if target.rstrip().endswith(';'):
+ self.source[line_index] = target.rstrip('\n \r\t;') + '\n'
+ return [line_index + 1]
+
+ offset = result['column'] - 1
+ first = target[:offset].rstrip(';').rstrip()
+ second = (_get_indentation(logical_lines[0]) +
+ target[offset:].lstrip(';').lstrip())
+
+ self.source[line_index] = first + '\n' + second
+ return [line_index + 1]
+
+ def fix_e711(self, result):
+ """Fix comparison with None."""
+ line_index = result['line'] - 1
+ target = self.source[line_index]
+ offset = result['column'] - 1
+
+ right_offset = offset + 2
+ if right_offset >= len(target):
+ return []
+
+ left = target[:offset].rstrip()
+ center = target[offset:right_offset]
+ right = target[right_offset:].lstrip()
+
+ if not right.startswith('None'):
+ return []
+
+ if center.strip() == '==':
+ new_center = 'is'
+ elif center.strip() == '!=':
+ new_center = 'is not'
+ else:
+ return []
+
+ self.source[line_index] = ' '.join([left, new_center, right])
+
+ def fix_e712(self, result):
+ """Fix comparison with boolean."""
+ line_index = result['line'] - 1
+ target = self.source[line_index]
+ offset = result['column'] - 1
+
+ # Handle very easy "not" special cases.
+ if re.match(r'^\s*if \w+ == False:$', target):
+ self.source[line_index] = re.sub(r'if (\w+) == False:',
+ r'if not \1:', target, count=1)
+ elif re.match(r'^\s*if \w+ != True:$', target):
+ self.source[line_index] = re.sub(r'if (\w+) != True:',
+ r'if not \1:', target, count=1)
+ else:
+ right_offset = offset + 2
+ if right_offset >= len(target):
+ return []
+
+ left = target[:offset].rstrip()
+ center = target[offset:right_offset]
+ right = target[right_offset:].lstrip()
+
+ # Handle simple cases only.
+ new_right = None
+ if center.strip() == '==':
+ if re.match(r'\bTrue\b', right):
+ new_right = re.sub(r'\bTrue\b *', '', right, count=1)
+ elif center.strip() == '!=':
+ if re.match(r'\bFalse\b', right):
+ new_right = re.sub(r'\bFalse\b *', '', right, count=1)
+
+ if new_right is None:
+ return []
+
+ if new_right[0].isalnum():
+ new_right = ' ' + new_right
+
+ self.source[line_index] = left + new_right
+
+ def fix_e713(self, result):
+ """Fix non-membership check."""
+ line_index = result['line'] - 1
+ target = self.source[line_index]
+
+ # Handle very easy case only.
+ if re.match(r'^\s*if not \w+ in \w+:$', target):
+ self.source[line_index] = re.sub(r'if not (\w+) in (\w+):',
+ r'if \1 not in \2:',
+ target,
+ count=1)
+
+ def fix_w291(self, result):
+ """Remove trailing whitespace."""
+ fixed_line = self.source[result['line'] - 1].rstrip()
+ self.source[result['line'] - 1] = fixed_line + '\n'
+
+
+def get_fixed_long_line(target, previous_line, original,
+ indent_word=' ', max_line_length=79,
+ aggressive=False, experimental=False, verbose=False):
+ """Break up long line and return result.
+
+ Do this by generating multiple reformatted candidates and then
+ ranking the candidates to heuristically select the best option.
+
+ """
+ indent = _get_indentation(target)
+ source = target[len(indent):]
+ assert source.lstrip() == source
+
+ # Check for partial multiline.
+ tokens = list(generate_tokens(source))
+
+ candidates = shorten_line(
+ tokens, source, indent,
+ indent_word,
+ max_line_length,
+ aggressive=aggressive,
+ experimental=experimental,
+ previous_line=previous_line)
+
+ # Also sort alphabetically as a tie breaker (for determinism).
+ candidates = sorted(
+ sorted(set(candidates).union([target, original])),
+ key=lambda x: line_shortening_rank(x,
+ indent_word,
+ max_line_length,
+ experimental))
+
+ if verbose >= 4:
+ print(('-' * 79 + '\n').join([''] + candidates + ['']),
+ file=codecs.getwriter('utf-8')(sys.stderr.buffer
+ if hasattr(sys.stderr,
+ 'buffer')
+ else sys.stderr))
+
+ if candidates:
+ return candidates[0]
+
+
+def join_logical_line(logical_line):
+ """Return single line based on logical line input."""
+ indentation = _get_indentation(logical_line)
+
+ return indentation + untokenize_without_newlines(
+ generate_tokens(logical_line.lstrip())) + '\n'
+
+
+def untokenize_without_newlines(tokens):
+ """Return source code based on tokens."""
+ text = ''
+ last_row = 0
+ last_column = -1
+
+ for t in tokens:
+ token_string = t[1]
+ (start_row, start_column) = t[2]
+ (end_row, end_column) = t[3]
+
+ if start_row > last_row:
+ last_column = 0
+ if (
+ (start_column > last_column or token_string == '\n') and
+ not text.endswith(' ')
+ ):
+ text += ' '
+
+ if token_string != '\n':
+ text += token_string
+
+ last_row = end_row
+ last_column = end_column
+
+ return text
+
+
+def _find_logical(source_lines):
+ # Make a variable which is the index of all the starts of lines.
+ logical_start = []
+ logical_end = []
+ last_newline = True
+ parens = 0
+ for t in generate_tokens(''.join(source_lines)):
+ if t[0] in [tokenize.COMMENT, tokenize.DEDENT,
+ tokenize.INDENT, tokenize.NL,
+ tokenize.ENDMARKER]:
+ continue
+ if not parens and t[0] in [tokenize.NEWLINE, tokenize.SEMI]:
+ last_newline = True
+ logical_end.append((t[3][0] - 1, t[2][1]))
+ continue
+ if last_newline and not parens:
+ logical_start.append((t[2][0] - 1, t[2][1]))
+ last_newline = False
+ if t[0] == tokenize.OP:
+ if t[1] in '([{':
+ parens += 1
+ elif t[1] in '}])':
+ parens -= 1
+ return (logical_start, logical_end)
+
+
+def _get_logical(source_lines, result, logical_start, logical_end):
+ """Return the logical line corresponding to the result.
+
+ Assumes input is already E702-clean.
+
+ """
+ row = result['line'] - 1
+ col = result['column'] - 1
+ ls = None
+ le = None
+ for i in range(0, len(logical_start), 1):
+ assert logical_end
+ x = logical_end[i]
+ if x[0] > row or (x[0] == row and x[1] > col):
+ le = x
+ ls = logical_start[i]
+ break
+ if ls is None:
+ return None
+ original = source_lines[ls[0]:le[0] + 1]
+ return ls, le, original
+
+
+def get_item(items, index, default=None):
+ if 0 <= index < len(items):
+ return items[index]
+ else:
+ return default
+
+
+def reindent(source, indent_size):
+ """Reindent all lines."""
+ reindenter = Reindenter(source)
+ return reindenter.run(indent_size)
+
+
+def code_almost_equal(a, b):
+ """Return True if code is similar.
+
+ Ignore whitespace when comparing specific line.
+
+ """
+ split_a = split_and_strip_non_empty_lines(a)
+ split_b = split_and_strip_non_empty_lines(b)
+
+ if len(split_a) != len(split_b):
+ return False
+
+ for index in range(len(split_a)):
+ if ''.join(split_a[index].split()) != ''.join(split_b[index].split()):
+ return False
+
+ return True
+
+
+def split_and_strip_non_empty_lines(text):
+ """Return lines split by newline.
+
+ Ignore empty lines.
+
+ """
+ return [line.strip() for line in text.splitlines() if line.strip()]
+
+
+def fix_e265(source, aggressive=False): # pylint: disable=unused-argument
+ """Format block comments."""
+ if '#' not in source:
+ # Optimization.
+ return source
+
+ ignored_line_numbers = multiline_string_lines(
+ source,
+ include_docstrings=True) | set(commented_out_code_lines(source))
+
+ fixed_lines = []
+ sio = io.StringIO(source)
+ line_number = 0
+ for line in sio.readlines():
+ line_number += 1
+ if (
+ line.lstrip().startswith('#') and
+ line_number not in ignored_line_numbers
+ ):
+ indentation = _get_indentation(line)
+ line = line.lstrip()
+
+ # Normalize beginning if not a shebang.
+ if len(line) > 1:
+ if (
+ # Leave multiple spaces like '# ' alone.
+ (line.count('#') > 1 or line[1].isalnum())
+ # Leave stylistic outlined blocks alone.
+ and not line.rstrip().endswith('#')
+ ):
+ line = '# ' + line.lstrip('# \t')
+
+ fixed_lines.append(indentation + line)
+ else:
+ fixed_lines.append(line)
+
+ return ''.join(fixed_lines)
+
+
+def refactor(source, fixer_names, ignore=None):
+ """Return refactored code using lib2to3.
+
+ Skip if ignore string is produced in the refactored code.
+
+ """
+ check_lib2to3()
+ from lib2to3 import pgen2
+ try:
+ new_text = refactor_with_2to3(source,
+ fixer_names=fixer_names)
+ except (pgen2.parse.ParseError,
+ SyntaxError,
+ UnicodeDecodeError,
+ UnicodeEncodeError):
+ return source
+
+ if ignore:
+ if ignore in new_text and ignore not in source:
+ return source
+
+ return new_text
+
+
+def code_to_2to3(select, ignore):
+ fixes = set()
+ for code, fix in CODE_TO_2TO3.items():
+ if code_match(code, select=select, ignore=ignore):
+ fixes |= set(fix)
+ return fixes
+
+
+def fix_2to3(source, aggressive=True, select=None, ignore=None):
+ """Fix various deprecated code (via lib2to3)."""
+ if not aggressive:
+ return source
+
+ select = select or []
+ ignore = ignore or []
+
+ return refactor(source,
+ code_to_2to3(select=select,
+ ignore=ignore))
+
+
+def fix_w602(source, aggressive=True):
+ """Fix deprecated form of raising exception."""
+ if not aggressive:
+ return source
+
+ return refactor(source, ['raise'],
+ ignore='with_traceback')
+
+
+def find_newline(source):
+ """Return type of newline used in source.
+
+ Input is a list of lines.
+
+ """
+ assert not isinstance(source, unicode)
+
+ counter = collections.defaultdict(int)
+ for line in source:
+ if line.endswith(CRLF):
+ counter[CRLF] += 1
+ elif line.endswith(CR):
+ counter[CR] += 1
+ elif line.endswith(LF):
+ counter[LF] += 1
+
+ return (sorted(counter, key=counter.get, reverse=True) or [LF])[0]
+
+
+def _get_indentword(source):
+ """Return indentation type."""
+ indent_word = ' ' # Default in case source has no indentation
+ try:
+ for t in generate_tokens(source):
+ if t[0] == token.INDENT:
+ indent_word = t[1]
+ break
+ except (SyntaxError, tokenize.TokenError):
+ pass
+ return indent_word
+
+
+def _get_indentation(line):
+ """Return leading whitespace."""
+ if line.strip():
+ non_whitespace_index = len(line) - len(line.lstrip())
+ return line[:non_whitespace_index]
+ else:
+ return ''
+
+
+def get_diff_text(old, new, filename):
+ """Return text of unified diff between old and new."""
+ newline = '\n'
+ diff = difflib.unified_diff(
+ old, new,
+ 'original/' + filename,
+ 'fixed/' + filename,
+ lineterm=newline)
+
+ text = ''
+ for line in diff:
+ text += line
+
+ # Work around missing newline (http://bugs.python.org/issue2142).
+ if text and not line.endswith(newline):
+ text += newline + r'\ No newline at end of file' + newline
+
+ return text
+
+
+def _priority_key(pep8_result):
+ """Key for sorting PEP8 results.
+
+ Global fixes should be done first. This is important for things like
+ indentation.
+
+ """
+ priority = [
+ # Fix multiline colon-based before semicolon based.
+ 'e701',
+ # Break multiline statements early.
+ 'e702',
+ # Things that make lines longer.
+ 'e225', 'e231',
+ # Remove extraneous whitespace before breaking lines.
+ 'e201',
+ # Shorten whitespace in comment before resorting to wrapping.
+ 'e262'
+ ]
+ middle_index = 10000
+ lowest_priority = [
+ # We need to shorten lines last since the logical fixer can get in a
+ # loop, which causes us to exit early.
+ 'e501'
+ ]
+ key = pep8_result['id'].lower()
+ try:
+ return priority.index(key)
+ except ValueError:
+ try:
+ return middle_index + lowest_priority.index(key) + 1
+ except ValueError:
+ return middle_index
+
+
+def shorten_line(tokens, source, indentation, indent_word, max_line_length,
+ aggressive=False, experimental=False, previous_line=''):
+ """Separate line at OPERATOR.
+
+ Multiple candidates will be yielded.
+
+ """
+ for candidate in _shorten_line(tokens=tokens,
+ source=source,
+ indentation=indentation,
+ indent_word=indent_word,
+ aggressive=aggressive,
+ previous_line=previous_line):
+ yield candidate
+
+ if aggressive:
+ for key_token_strings in SHORTEN_OPERATOR_GROUPS:
+ shortened = _shorten_line_at_tokens(
+ tokens=tokens,
+ source=source,
+ indentation=indentation,
+ indent_word=indent_word,
+ key_token_strings=key_token_strings,
+ aggressive=aggressive)
+
+ if shortened is not None and shortened != source:
+ yield shortened
+
+ if experimental:
+ for shortened in _shorten_line_at_tokens_new(
+ tokens=tokens,
+ source=source,
+ indentation=indentation,
+ max_line_length=max_line_length):
+
+ yield shortened
+
+
+def _shorten_line(tokens, source, indentation, indent_word,
+ aggressive=False, previous_line=''):
+ """Separate line at OPERATOR.
+
+ The input is expected to be free of newlines except for inside multiline
+ strings and at the end.
+
+ Multiple candidates will be yielded.
+
+ """
+ for (token_type,
+ token_string,
+ start_offset,
+ end_offset) in token_offsets(tokens):
+
+ if (
+ token_type == tokenize.COMMENT and
+ not is_probably_part_of_multiline(previous_line) and
+ not is_probably_part_of_multiline(source) and
+ not source[start_offset + 1:].strip().lower().startswith(
+ ('noqa', 'pragma:', 'pylint:'))
+ ):
+ # Move inline comments to previous line.
+ first = source[:start_offset]
+ second = source[start_offset:]
+ yield (indentation + second.strip() + '\n' +
+ indentation + first.strip() + '\n')
+ elif token_type == token.OP and token_string != '=':
+ # Don't break on '=' after keyword as this violates PEP 8.
+
+ assert token_type != token.INDENT
+
+ first = source[:end_offset]
+
+ second_indent = indentation
+ if first.rstrip().endswith('('):
+ second_indent += indent_word
+ elif '(' in first:
+ second_indent += ' ' * (1 + first.find('('))
+ else:
+ second_indent += indent_word
+
+ second = (second_indent + source[end_offset:].lstrip())
+ if (
+ not second.strip() or
+ second.lstrip().startswith('#')
+ ):
+ continue
+
+ # Do not begin a line with a comma
+ if second.lstrip().startswith(','):
+ continue
+ # Do end a line with a dot
+ if first.rstrip().endswith('.'):
+ continue
+ if token_string in '+-*/':
+ fixed = first + ' \\' + '\n' + second
+ else:
+ fixed = first + '\n' + second
+
+ # Only fix if syntax is okay.
+ if check_syntax(normalize_multiline(fixed)
+ if aggressive else fixed):
+ yield indentation + fixed
+
+
+# A convenient way to handle tokens.
+Token = collections.namedtuple('Token', ['token_type', 'token_string',
+ 'spos', 'epos', 'line'])
+
+
+class ReformattedLines(object):
+
+ """The reflowed lines of atoms.
+
+ Each part of the line is represented as an "atom." They can be moved
+ around when need be to get the optimal formatting.
+
+ """
+
+ ###########################################################################
+ # Private Classes
+
+ class _Indent(object):
+
+ """Represent an indentation in the atom stream."""
+
+ def __init__(self, indent_amt):
+ self._indent_amt = indent_amt
+
+ def emit(self):
+ return ' ' * self._indent_amt
+
+ @property
+ def size(self):
+ return self._indent_amt
+
+ class _Space(object):
+
+ """Represent a space in the atom stream."""
+
+ def emit(self):
+ return ' '
+
+ @property
+ def size(self):
+ return 1
+
+ class _LineBreak(object):
+
+ """Represent a line break in the atom stream."""
+
+ def emit(self):
+ return '\n'
+
+ @property
+ def size(self):
+ return 0
+
+ def __init__(self, max_line_length):
+ self._max_line_length = max_line_length
+ self._lines = []
+ self._bracket_depth = 0
+ self._prev_item = None
+ self._prev_prev_item = None
+
+ def __repr__(self):
+ return self.emit()
+
+ ###########################################################################
+ # Public Methods
+
+ def add(self, obj, indent_amt, break_after_open_bracket):
+ if isinstance(obj, Atom):
+ self._add_item(obj, indent_amt)
+ return
+
+ self._add_container(obj, indent_amt, break_after_open_bracket)
+
+ def add_comment(self, item):
+ num_spaces = 2
+ if len(self._lines) > 1:
+ if isinstance(self._lines[-1], self._Space):
+ num_spaces -= 1
+ if len(self._lines) > 2:
+ if isinstance(self._lines[-2], self._Space):
+ num_spaces -= 1
+
+ while num_spaces > 0:
+ self._lines.append(self._Space())
+ num_spaces -= 1
+ self._lines.append(item)
+
+ def add_indent(self, indent_amt):
+ self._lines.append(self._Indent(indent_amt))
+
+ def add_line_break(self, indent):
+ self._lines.append(self._LineBreak())
+ self.add_indent(len(indent))
+
+ def add_line_break_at(self, index, indent_amt):
+ self._lines.insert(index, self._LineBreak())
+ self._lines.insert(index + 1, self._Indent(indent_amt))
+
+ def add_space_if_needed(self, curr_text, equal=False):
+ if (
+ not self._lines or isinstance(
+ self._lines[-1], (self._LineBreak, self._Indent, self._Space))
+ ):
+ return
+
+ prev_text = unicode(self._prev_item)
+ prev_prev_text = (
+ unicode(self._prev_prev_item) if self._prev_prev_item else '')
+
+ if (
+ # The previous item was a keyword or identifier and the current
+ # item isn't an operator that doesn't require a space.
+ ((self._prev_item.is_keyword or self._prev_item.is_string or
+ self._prev_item.is_name or self._prev_item.is_number) and
+ (curr_text[0] not in '([{.,:}])' or
+ (curr_text[0] == '=' and equal))) or
+
+ # Don't place spaces around a '.', unless it's in an 'import'
+ # statement.
+ ((prev_prev_text != 'from' and prev_text[-1] != '.' and
+ curr_text != 'import') and
+
+ # Don't place a space before a colon.
+ curr_text[0] != ':' and
+
+ # Don't split up ending brackets by spaces.
+ ((prev_text[-1] in '}])' and curr_text[0] not in '.,}])') or
+
+ # Put a space after a colon or comma.
+ prev_text[-1] in ':,' or
+
+ # Put space around '=' if asked to.
+ (equal and prev_text == '=') or
+
+ # Put spaces around non-unary arithmetic operators.
+ ((self._prev_prev_item and
+ (prev_text not in '+-' and
+ (self._prev_prev_item.is_name or
+ self._prev_prev_item.is_number or
+ self._prev_prev_item.is_string)) and
+ prev_text in ('+', '-', '%', '*', '/', '//', '**')))))
+ ):
+ self._lines.append(self._Space())
+
+ def previous_item(self):
+ """Return the previous non-whitespace item."""
+ return self._prev_item
+
+ def fits_on_current_line(self, item_extent):
+ return self.current_size() + item_extent <= self._max_line_length
+
+ def current_size(self):
+ """The size of the current line minus the indentation."""
+ size = 0
+ for item in reversed(self._lines):
+ size += item.size
+ if isinstance(item, self._LineBreak):
+ break
+
+ return size
+
+ def line_empty(self):
+ return (self._lines and
+ isinstance(self._lines[-1],
+ (self._LineBreak, self._Indent)))
+
+ def emit(self):
+ string = ''
+ for item in self._lines:
+ if isinstance(item, self._LineBreak):
+ string = string.rstrip()
+ string += item.emit()
+
+ return string.rstrip() + '\n'
+
+ ###########################################################################
+ # Private Methods
+
+ def _add_item(self, item, indent_amt):
+ """Add an item to the line.
+
+ Reflow the line to get the best formatting after the item is
+ inserted. The bracket depth indicates if the item is being
+ inserted inside of a container or not.
+
+ """
+ if self._prev_item and self._prev_item.is_string and item.is_string:
+ # Place consecutive string literals on separate lines.
+ self._lines.append(self._LineBreak())
+ self._lines.append(self._Indent(indent_amt))
+
+ item_text = unicode(item)
+ if self._lines and self._bracket_depth:
+ # Adding the item into a container.
+ self._prevent_default_initializer_splitting(item, indent_amt)
+
+ if item_text in '.,)]}':
+ self._split_after_delimiter(item, indent_amt)
+
+ elif self._lines and not self.line_empty():
+ # Adding the item outside of a container.
+ if self.fits_on_current_line(len(item_text)):
+ self._enforce_space(item)
+
+ else:
+ # Line break for the new item.
+ self._lines.append(self._LineBreak())
+ self._lines.append(self._Indent(indent_amt))
+
+ self._lines.append(item)
+ self._prev_item, self._prev_prev_item = item, self._prev_item
+
+ if item_text in '([{':
+ self._bracket_depth += 1
+
+ elif item_text in '}])':
+ self._bracket_depth -= 1
+ assert self._bracket_depth >= 0
+
+ def _add_container(self, container, indent_amt, break_after_open_bracket):
+ actual_indent = indent_amt + 1
+
+ if (
+ unicode(self._prev_item) != '=' and
+ not self.line_empty() and
+ not self.fits_on_current_line(
+ container.size + self._bracket_depth + 2)
+ ):
+
+ if unicode(container)[0] == '(' and self._prev_item.is_name:
+ # Don't split before the opening bracket of a call.
+ break_after_open_bracket = True
+ actual_indent = indent_amt + 4
+ elif (
+ break_after_open_bracket or
+ unicode(self._prev_item) not in '([{'
+ ):
+ # If the container doesn't fit on the current line and the
+ # current line isn't empty, place the container on the next
+ # line.
+ self._lines.append(self._LineBreak())
+ self._lines.append(self._Indent(indent_amt))
+ break_after_open_bracket = False
+ else:
+ actual_indent = self.current_size() + 1
+ break_after_open_bracket = False
+
+ if isinstance(container, (ListComprehension, IfExpression)):
+ actual_indent = indent_amt
+
+ # Increase the continued indentation only if recursing on a
+ # container.
+ container.reflow(self, ' ' * actual_indent,
+ break_after_open_bracket=break_after_open_bracket)
+
+ def _prevent_default_initializer_splitting(self, item, indent_amt):
+ """Prevent splitting between a default initializer.
+
+ When there is a default initializer, it's best to keep it all on
+ the same line. It's nicer and more readable, even if it goes
+ over the maximum allowable line length. This goes back along the
+ current line to determine if we have a default initializer, and,
+ if so, to remove extraneous whitespaces and add a line
+ break/indent before it if needed.
+
+ """
+ if unicode(item) == '=':
+ # This is the assignment in the initializer. Just remove spaces for
+ # now.
+ self._delete_whitespace()
+ return
+
+ if (not self._prev_item or not self._prev_prev_item or
+ unicode(self._prev_item) != '='):
+ return
+
+ self._delete_whitespace()
+ prev_prev_index = self._lines.index(self._prev_prev_item)
+
+ if (
+ isinstance(self._lines[prev_prev_index - 1], self._Indent) or
+ self.fits_on_current_line(item.size + 1)
+ ):
+ # The default initializer is already the only item on this line.
+ # Don't insert a newline here.
+ return
+
+ # Replace the space with a newline/indent combo.
+ if isinstance(self._lines[prev_prev_index - 1], self._Space):
+ del self._lines[prev_prev_index - 1]
+
+ self.add_line_break_at(self._lines.index(self._prev_prev_item),
+ indent_amt)
+
+ def _split_after_delimiter(self, item, indent_amt):
+ """Split the line only after a delimiter."""
+ self._delete_whitespace()
+
+ if self.fits_on_current_line(item.size):
+ return
+
+ last_space = None
+ for item in reversed(self._lines):
+ if (
+ last_space and
+ (not isinstance(item, Atom) or not item.is_colon)
+ ):
+ break
+ else:
+ last_space = None
+ if isinstance(item, self._Space):
+ last_space = item
+ if isinstance(item, (self._LineBreak, self._Indent)):
+ return
+
+ if not last_space:
+ return
+
+ self.add_line_break_at(self._lines.index(last_space), indent_amt)
+
+ def _enforce_space(self, item):
+ """Enforce a space in certain situations.
+
+ There are cases where we will want a space where normally we
+ wouldn't put one. This just enforces the addition of a space.
+
+ """
+ if isinstance(self._lines[-1],
+ (self._Space, self._LineBreak, self._Indent)):
+ return
+
+ if not self._prev_item:
+ return
+
+ item_text = unicode(item)
+ prev_text = unicode(self._prev_item)
+
+ # Prefer a space around a '.' in an import statement, and between the
+ # 'import' and '('.
+ if (
+ (item_text == '.' and prev_text == 'from') or
+ (item_text == 'import' and prev_text == '.') or
+ (item_text == '(' and prev_text == 'import')
+ ):
+ self._lines.append(self._Space())
+
+ def _delete_whitespace(self):
+ """Delete all whitespace from the end of the line."""
+ while isinstance(self._lines[-1], (self._Space, self._LineBreak,
+ self._Indent)):
+ del self._lines[-1]
+
+
+class Atom(object):
+
+ """The smallest unbreakable unit that can be reflowed."""
+
+ def __init__(self, atom):
+ self._atom = atom
+
+ def __repr__(self):
+ return self._atom.token_string
+
+ def __len__(self):
+ return self.size
+
+ def reflow(
+ self, reflowed_lines, continued_indent, extent,
+ break_after_open_bracket=False,
+ is_list_comp_or_if_expr=False,
+ next_is_dot=False
+ ):
+ if self._atom.token_type == tokenize.COMMENT:
+ reflowed_lines.add_comment(self)
+ return
+
+ total_size = extent if extent else self.size
+
+ if self._atom.token_string not in ',:([{}])':
+ # Some atoms will need an extra 1-sized space token after them.
+ total_size += 1
+
+ prev_item = reflowed_lines.previous_item()
+ if (
+ not is_list_comp_or_if_expr and
+ not reflowed_lines.fits_on_current_line(total_size) and
+ not (next_is_dot and
+ reflowed_lines.fits_on_current_line(self.size + 1)) and
+ not reflowed_lines.line_empty() and
+ not self.is_colon and
+ not (prev_item and prev_item.is_name and
+ unicode(self) == '(')
+ ):
+ # Start a new line if there is already something on the line and
+ # adding this atom would make it go over the max line length.
+ reflowed_lines.add_line_break(continued_indent)
+ else:
+ reflowed_lines.add_space_if_needed(unicode(self))
+
+ reflowed_lines.add(self, len(continued_indent),
+ break_after_open_bracket)
+
+ def emit(self):
+ return self.__repr__()
+
+ @property
+ def is_keyword(self):
+ return keyword.iskeyword(self._atom.token_string)
+
+ @property
+ def is_string(self):
+ return self._atom.token_type == tokenize.STRING
+
+ @property
+ def is_name(self):
+ return self._atom.token_type == tokenize.NAME
+
+ @property
+ def is_number(self):
+ return self._atom.token_type == tokenize.NUMBER
+
+ @property
+ def is_comma(self):
+ return self._atom.token_string == ','
+
+ @property
+ def is_colon(self):
+ return self._atom.token_string == ':'
+
+ @property
+ def size(self):
+ return len(self._atom.token_string)
+
+
+class Container(object):
+
+ """Base class for all container types."""
+
+ def __init__(self, items):
+ self._items = items
+
+ def __repr__(self):
+ string = ''
+ last_was_keyword = False
+
+ for item in self._items:
+ if item.is_comma:
+ string += ', '
+ elif item.is_colon:
+ string += ': '
+ else:
+ item_string = unicode(item)
+ if (
+ string and
+ (last_was_keyword or
+ (not string.endswith(tuple('([{,.:}]) ')) and
+ not item_string.startswith(tuple('([{,.:}])'))))
+ ):
+ string += ' '
+ string += item_string
+
+ last_was_keyword = item.is_keyword
+ return string
+
+ def __iter__(self):
+ for element in self._items:
+ yield element
+
+ def __getitem__(self, idx):
+ return self._items[idx]
+
+ def reflow(self, reflowed_lines, continued_indent,
+ break_after_open_bracket=False):
+ last_was_container = False
+ for (index, item) in enumerate(self._items):
+ next_item = get_item(self._items, index + 1)
+
+ if isinstance(item, Atom):
+ is_list_comp_or_if_expr = (
+ isinstance(self, (ListComprehension, IfExpression)))
+ item.reflow(reflowed_lines, continued_indent,
+ self._get_extent(index),
+ is_list_comp_or_if_expr=is_list_comp_or_if_expr,
+ next_is_dot=(next_item and
+ unicode(next_item) == '.'))
+ if last_was_container and item.is_comma:
+ reflowed_lines.add_line_break(continued_indent)
+ last_was_container = False
+ else: # isinstance(item, Container)
+ reflowed_lines.add(item, len(continued_indent),
+ break_after_open_bracket)
+ last_was_container = not isinstance(item, (ListComprehension,
+ IfExpression))
+
+ if (
+ break_after_open_bracket and index == 0 and
+ # Prefer to keep empty containers together instead of
+ # separating them.
+ unicode(item) == self.open_bracket and
+ (not next_item or unicode(next_item) != self.close_bracket) and
+ (len(self._items) != 3 or not isinstance(next_item, Atom))
+ ):
+ reflowed_lines.add_line_break(continued_indent)
+ break_after_open_bracket = False
+ else:
+ next_next_item = get_item(self._items, index + 2)
+ if (
+ unicode(item) not in ['.', '%', 'in'] and
+ next_item and not isinstance(next_item, Container) and
+ unicode(next_item) != ':' and
+ next_next_item and (not isinstance(next_next_item, Atom) or
+ unicode(next_item) == 'not') and
+ not reflowed_lines.line_empty() and
+ not reflowed_lines.fits_on_current_line(
+ self._get_extent(index + 1) + 2)
+ ):
+ reflowed_lines.add_line_break(continued_indent)
+
+ def _get_extent(self, index):
+ """The extent of the full element.
+
+ E.g., the length of a function call or keyword.
+
+ """
+ extent = 0
+ prev_item = get_item(self._items, index - 1)
+ seen_dot = prev_item and unicode(prev_item) == '.'
+ while index < len(self._items):
+ item = get_item(self._items, index)
+ index += 1
+
+ if isinstance(item, (ListComprehension, IfExpression)):
+ break
+
+ if isinstance(item, Container):
+ if prev_item and prev_item.is_name:
+ if seen_dot:
+ extent += 1
+ else:
+ extent += item.size
+
+ prev_item = item
+ continue
+ elif (unicode(item) not in ['.', '=', ':', 'not'] and
+ not item.is_name and not item.is_string):
+ break
+
+ if unicode(item) == '.':
+ seen_dot = True
+
+ extent += item.size
+ prev_item = item
+
+ return extent
+
+ @property
+ def is_string(self):
+ return False
+
+ @property
+ def size(self):
+ return len(self.__repr__())
+
+ @property
+ def is_keyword(self):
+ return False
+
+ @property
+ def is_name(self):
+ return False
+
+ @property
+ def is_comma(self):
+ return False
+
+ @property
+ def is_colon(self):
+ return False
+
+ @property
+ def open_bracket(self):
+ return None
+
+ @property
+ def close_bracket(self):
+ return None
+
+
+class Tuple(Container):
+
+ """A high-level representation of a tuple."""
+
+ @property
+ def open_bracket(self):
+ return '('
+
+ @property
+ def close_bracket(self):
+ return ')'
+
+
+class List(Container):
+
+ """A high-level representation of a list."""
+
+ @property
+ def open_bracket(self):
+ return '['
+
+ @property
+ def close_bracket(self):
+ return ']'
+
+
+class DictOrSet(Container):
+
+ """A high-level representation of a dictionary or set."""
+
+ @property
+ def open_bracket(self):
+ return '{'
+
+ @property
+ def close_bracket(self):
+ return '}'
+
+
+class ListComprehension(Container):
+
+ """A high-level representation of a list comprehension."""
+
+ @property
+ def size(self):
+ length = 0
+ for item in self._items:
+ if isinstance(item, IfExpression):
+ break
+ length += item.size
+ return length
+
+
+class IfExpression(Container):
+
+ """A high-level representation of an if-expression."""
+
+
+def _parse_container(tokens, index, for_or_if=None):
+ """Parse a high-level container, such as a list, tuple, etc."""
+
+ # Store the opening bracket.
+ items = [Atom(Token(*tokens[index]))]
+ index += 1
+
+ num_tokens = len(tokens)
+ while index < num_tokens:
+ tok = Token(*tokens[index])
+
+ if tok.token_string in ',)]}':
+ # First check if we're at the end of a list comprehension or
+ # if-expression. Don't add the ending token as part of the list
+ # comprehension or if-expression, because they aren't part of those
+ # constructs.
+ if for_or_if == 'for':
+ return (ListComprehension(items), index - 1)
+
+ elif for_or_if == 'if':
+ return (IfExpression(items), index - 1)
+
+ # We've reached the end of a container.
+ items.append(Atom(tok))
+
+ # If not, then we are at the end of a container.
+ if tok.token_string == ')':
+ # The end of a tuple.
+ return (Tuple(items), index)
+
+ elif tok.token_string == ']':
+ # The end of a list.
+ return (List(items), index)
+
+ elif tok.token_string == '}':
+ # The end of a dictionary or set.
+ return (DictOrSet(items), index)
+
+ elif tok.token_string in '([{':
+ # A sub-container is being defined.
+ (container, index) = _parse_container(tokens, index)
+ items.append(container)
+
+ elif tok.token_string == 'for':
+ (container, index) = _parse_container(tokens, index, 'for')
+ items.append(container)
+
+ elif tok.token_string == 'if':
+ (container, index) = _parse_container(tokens, index, 'if')
+ items.append(container)
+
+ else:
+ items.append(Atom(tok))
+
+ index += 1
+
+ return (None, None)
+
+
+def _parse_tokens(tokens):
+ """Parse the tokens.
+
+ This converts the tokens into a form where we can manipulate them
+ more easily.
+
+ """
+
+ index = 0
+ parsed_tokens = []
+
+ num_tokens = len(tokens)
+ while index < num_tokens:
+ tok = Token(*tokens[index])
+
+ assert tok.token_type != token.INDENT
+ if tok.token_type == tokenize.NEWLINE:
+ # There's only one newline and it's at the end.
+ break
+
+ if tok.token_string in '([{':
+ (container, index) = _parse_container(tokens, index)
+ if not container:
+ return None
+ parsed_tokens.append(container)
+ else:
+ parsed_tokens.append(Atom(tok))
+
+ index += 1
+
+ return parsed_tokens
+
+
+def _reflow_lines(parsed_tokens, indentation, max_line_length,
+ start_on_prefix_line):
+ """Reflow the lines so that it looks nice."""
+
+ if unicode(parsed_tokens[0]) == 'def':
+ # A function definition gets indented a bit more.
+ continued_indent = indentation + ' ' * 2 * DEFAULT_INDENT_SIZE
+ else:
+ continued_indent = indentation + ' ' * DEFAULT_INDENT_SIZE
+
+ break_after_open_bracket = not start_on_prefix_line
+
+ lines = ReformattedLines(max_line_length)
+ lines.add_indent(len(indentation.lstrip('\r\n')))
+
+ if not start_on_prefix_line:
+ # If splitting after the opening bracket will cause the first element
+ # to be aligned weirdly, don't try it.
+ first_token = get_item(parsed_tokens, 0)
+ second_token = get_item(parsed_tokens, 1)
+
+ if (
+ first_token and second_token and
+ unicode(second_token)[0] == '(' and
+ len(indentation) + len(first_token) + 1 == len(continued_indent)
+ ):
+ return None
+
+ for item in parsed_tokens:
+ lines.add_space_if_needed(unicode(item), equal=True)
+
+ save_continued_indent = continued_indent
+ if start_on_prefix_line and isinstance(item, Container):
+ start_on_prefix_line = False
+ continued_indent = ' ' * (lines.current_size() + 1)
+
+ item.reflow(lines, continued_indent, break_after_open_bracket)
+ continued_indent = save_continued_indent
+
+ return lines.emit()
+
+
+def _shorten_line_at_tokens_new(tokens, source, indentation,
+ max_line_length):
+ """Shorten the line taking its length into account.
+
+ The input is expected to be free of newlines except for inside
+ multiline strings and at the end.
+
+ """
+ # Yield the original source so to see if it's a better choice than the
+ # shortened candidate lines we generate here.
+ yield indentation + source
+
+ parsed_tokens = _parse_tokens(tokens)
+
+ if parsed_tokens:
+ # Perform two reflows. The first one starts on the same line as the
+ # prefix. The second starts on the line after the prefix.
+ fixed = _reflow_lines(parsed_tokens, indentation, max_line_length,
+ start_on_prefix_line=True)
+ if fixed and check_syntax(normalize_multiline(fixed.lstrip())):
+ yield fixed
+
+ fixed = _reflow_lines(parsed_tokens, indentation, max_line_length,
+ start_on_prefix_line=False)
+ if fixed and check_syntax(normalize_multiline(fixed.lstrip())):
+ yield fixed
+
+
+def _shorten_line_at_tokens(tokens, source, indentation, indent_word,
+ key_token_strings, aggressive):
+ """Separate line by breaking at tokens in key_token_strings.
+
+ The input is expected to be free of newlines except for inside
+ multiline strings and at the end.
+
+ """
+ offsets = []
+ for (index, _t) in enumerate(token_offsets(tokens)):
+ (token_type,
+ token_string,
+ start_offset,
+ end_offset) = _t
+
+ assert token_type != token.INDENT
+
+ if token_string in key_token_strings:
+ # Do not break in containers with zero or one items.
+ unwanted_next_token = {
+ '(': ')',
+ '[': ']',
+ '{': '}'}.get(token_string)
+ if unwanted_next_token:
+ if (
+ get_item(tokens,
+ index + 1,
+ default=[None, None])[1] == unwanted_next_token or
+ get_item(tokens,
+ index + 2,
+ default=[None, None])[1] == unwanted_next_token
+ ):
+ continue
+
+ if (
+ index > 2 and token_string == '(' and
+ tokens[index - 1][1] in ',(%['
+ ):
+ # Don't split after a tuple start, or before a tuple start if
+ # the tuple is in a list.
+ continue
+
+ if end_offset < len(source) - 1:
+ # Don't split right before newline.
+ offsets.append(end_offset)
+ else:
+ # Break at adjacent strings. These were probably meant to be on
+ # separate lines in the first place.
+ previous_token = get_item(tokens, index - 1)
+ if (
+ token_type == tokenize.STRING and
+ previous_token and previous_token[0] == tokenize.STRING
+ ):
+ offsets.append(start_offset)
+
+ current_indent = None
+ fixed = None
+ for line in split_at_offsets(source, offsets):
+ if fixed:
+ fixed += '\n' + current_indent + line
+
+ for symbol in '([{':
+ if line.endswith(symbol):
+ current_indent += indent_word
+ else:
+ # First line.
+ fixed = line
+ assert not current_indent
+ current_indent = indent_word
+
+ assert fixed is not None
+
+ if check_syntax(normalize_multiline(fixed)
+ if aggressive > 1 else fixed):
+ return indentation + fixed
+ else:
+ return None
+
+
+def token_offsets(tokens):
+ """Yield tokens and offsets."""
+ end_offset = 0
+ previous_end_row = 0
+ previous_end_column = 0
+ for t in tokens:
+ token_type = t[0]
+ token_string = t[1]
+ (start_row, start_column) = t[2]
+ (end_row, end_column) = t[3]
+
+ # Account for the whitespace between tokens.
+ end_offset += start_column
+ if previous_end_row == start_row:
+ end_offset -= previous_end_column
+
+ # Record the start offset of the token.
+ start_offset = end_offset
+
+ # Account for the length of the token itself.
+ end_offset += len(token_string)
+
+ yield (token_type,
+ token_string,
+ start_offset,
+ end_offset)
+
+ previous_end_row = end_row
+ previous_end_column = end_column
+
+
+def normalize_multiline(line):
+ """Normalize multiline-related code that will cause syntax error.
+
+ This is for purposes of checking syntax.
+
+ """
+ if line.startswith('def ') and line.rstrip().endswith(':'):
+ return line + ' pass'
+ elif line.startswith('return '):
+ return 'def _(): ' + line
+ elif line.startswith('@'):
+ return line + 'def _(): pass'
+ elif line.startswith('class '):
+ return line + ' pass'
+ elif line.startswith('if '):
+ return line + ' pass'
+ else:
+ return line
+
+
+def fix_whitespace(line, offset, replacement):
+ """Replace whitespace at offset and return fixed line."""
+ # Replace escaped newlines too
+ left = line[:offset].rstrip('\n\r \t\\')
+ right = line[offset:].lstrip('\n\r \t\\')
+ if right.startswith('#'):
+ return line
+ else:
+ return left + replacement + right
+
+
+def _execute_pep8(pep8_options, source):
+ """Execute pep8 via python method calls."""
+ class QuietReport(pep8.BaseReport):
+
+ """Version of checker that does not print."""
+
+ def __init__(self, options):
+ super(QuietReport, self).__init__(options)
+ self.__full_error_results = []
+
+ def error(self, line_number, offset, text, _):
+ """Collect errors."""
+ code = super(QuietReport, self).error(line_number, offset, text, _)
+ if code:
+ self.__full_error_results.append(
+ {'id': code,
+ 'line': line_number,
+ 'column': offset + 1,
+ 'info': text})
+
+ def full_error_results(self):
+ """Return error results in detail.
+
+ Results are in the form of a list of dictionaries. Each
+ dictionary contains 'id', 'line', 'column', and 'info'.
+
+ """
+ return self.__full_error_results
+
+ checker = pep8.Checker('', lines=source,
+ reporter=QuietReport, **pep8_options)
+ checker.check_all()
+ return checker.report.full_error_results()
+
+
+def _remove_leading_and_normalize(line):
+ return line.lstrip().rstrip(CR + LF) + '\n'
+
+
+class Reindenter(object):
+
+ """Reindents badly-indented code to uniformly use four-space indentation.
+
+ Released to the public domain, by Tim Peters, 03 October 2000.
+
+ """
+
+ def __init__(self, input_text):
+ sio = io.StringIO(input_text)
+ source_lines = sio.readlines()
+
+ self.string_content_line_numbers = multiline_string_lines(input_text)
+
+ # File lines, rstripped & tab-expanded. Dummy at start is so
+ # that we can use tokenize's 1-based line numbering easily.
+ # Note that a line is all-blank iff it is a newline.
+ self.lines = []
+ line_number = 0
+ for line in source_lines:
+ line_number += 1
+ # Do not modify if inside a multiline string.
+ if line_number in self.string_content_line_numbers:
+ self.lines.append(line)
+ else:
+ # Only expand leading tabs.
+ self.lines.append(_get_indentation(line).expandtabs() +
+ _remove_leading_and_normalize(line))
+
+ self.lines.insert(0, None)
+ self.index = 1 # index into self.lines of next line
+ self.input_text = input_text
+
+ def run(self, indent_size=DEFAULT_INDENT_SIZE):
+ """Fix indentation and return modified line numbers.
+
+ Line numbers are indexed at 1.
+
+ """
+ if indent_size < 1:
+ return self.input_text
+
+ try:
+ stats = _reindent_stats(tokenize.generate_tokens(self.getline))
+ except (SyntaxError, tokenize.TokenError):
+ return self.input_text
+ # Remove trailing empty lines.
+ lines = self.lines
+ while lines and lines[-1] == '\n':
+ lines.pop()
+ # Sentinel.
+ stats.append((len(lines), 0))
+ # Map count of leading spaces to # we want.
+ have2want = {}
+ # Program after transformation.
+ after = []
+ # Copy over initial empty lines -- there's nothing to do until
+ # we see a line with *something* on it.
+ i = stats[0][0]
+ after.extend(lines[1:i])
+ for i in range(len(stats) - 1):
+ thisstmt, thislevel = stats[i]
+ nextstmt = stats[i + 1][0]
+ have = _leading_space_count(lines[thisstmt])
+ want = thislevel * indent_size
+ if want < 0:
+ # A comment line.
+ if have:
+ # An indented comment line. If we saw the same
+ # indentation before, reuse what it most recently
+ # mapped to.
+ want = have2want.get(have, -1)
+ if want < 0:
+ # Then it probably belongs to the next real stmt.
+ for j in range(i + 1, len(stats) - 1):
+ jline, jlevel = stats[j]
+ if jlevel >= 0:
+ if have == _leading_space_count(lines[jline]):
+ want = jlevel * indent_size
+ break
+ if want < 0: # Maybe it's a hanging
+ # comment like this one,
+ # in which case we should shift it like its base
+ # line got shifted.
+ for j in range(i - 1, -1, -1):
+ jline, jlevel = stats[j]
+ if jlevel >= 0:
+ want = (have + _leading_space_count(
+ after[jline - 1]) -
+ _leading_space_count(lines[jline]))
+ break
+ if want < 0:
+ # Still no luck -- leave it alone.
+ want = have
+ else:
+ want = 0
+ assert want >= 0
+ have2want[have] = want
+ diff = want - have
+ if diff == 0 or have == 0:
+ after.extend(lines[thisstmt:nextstmt])
+ else:
+ line_number = thisstmt - 1
+ for line in lines[thisstmt:nextstmt]:
+ line_number += 1
+ if line_number in self.string_content_line_numbers:
+ after.append(line)
+ elif diff > 0:
+ if line == '\n':
+ after.append(line)
+ else:
+ after.append(' ' * diff + line)
+ else:
+ remove = min(_leading_space_count(line), -diff)
+ after.append(line[remove:])
+
+ return ''.join(after)
+
+ def getline(self):
+ """Line-getter for tokenize."""
+ if self.index >= len(self.lines):
+ line = ''
+ else:
+ line = self.lines[self.index]
+ self.index += 1
+ return line
+
+
+def _reindent_stats(tokens):
+ """Return list of (lineno, indentlevel) pairs.
+
+ One for each stmt and comment line. indentlevel is -1 for comment lines, as
+ a signal that tokenize doesn't know what to do about them; indeed, they're
+ our headache!
+
+ """
+ find_stmt = 1 # Next token begins a fresh stmt?
+ level = 0 # Current indent level.
+ stats = []
+
+ for t in tokens:
+ token_type = t[0]
+ sline = t[2][0]
+ line = t[4]
+
+ if token_type == tokenize.NEWLINE:
+ # A program statement, or ENDMARKER, will eventually follow,
+ # after some (possibly empty) run of tokens of the form
+ # (NL | COMMENT)* (INDENT | DEDENT+)?
+ find_stmt = 1
+
+ elif token_type == tokenize.INDENT:
+ find_stmt = 1
+ level += 1
+
+ elif token_type == tokenize.DEDENT:
+ find_stmt = 1
+ level -= 1
+
+ elif token_type == tokenize.COMMENT:
+ if find_stmt:
+ stats.append((sline, -1))
+ # But we're still looking for a new stmt, so leave
+ # find_stmt alone.
+
+ elif token_type == tokenize.NL:
+ pass
+
+ elif find_stmt:
+ # This is the first "real token" following a NEWLINE, so it
+ # must be the first token of the next program statement, or an
+ # ENDMARKER.
+ find_stmt = 0
+ if line: # Not endmarker.
+ stats.append((sline, level))
+
+ return stats
+
+
+def _leading_space_count(line):
+ """Return number of leading spaces in line."""
+ i = 0
+ while i < len(line) and line[i] == ' ':
+ i += 1
+ return i
+
+
+def refactor_with_2to3(source_text, fixer_names):
+ """Use lib2to3 to refactor the source.
+
+ Return the refactored source code.
+
+ """
+ check_lib2to3()
+ from lib2to3.refactor import RefactoringTool
+ fixers = ['lib2to3.fixes.fix_' + name for name in fixer_names]
+ tool = RefactoringTool(fixer_names=fixers, explicit=fixers)
+
+ from lib2to3.pgen2 import tokenize as lib2to3_tokenize
+ try:
+ return unicode(tool.refactor_string(source_text, name=''))
+ except lib2to3_tokenize.TokenError:
+ return source_text
+
+
+def check_syntax(code):
+ """Return True if syntax is okay."""
+ try:
+ return compile(code, '<string>', 'exec')
+ except (SyntaxError, TypeError, UnicodeDecodeError):
+ return False
+
+
+def filter_results(source, results, aggressive):
+ """Filter out spurious reports from pep8.
+
+ If aggressive is True, we allow possibly unsafe fixes (E711, E712).
+
+ """
+ non_docstring_string_line_numbers = multiline_string_lines(
+ source, include_docstrings=False)
+ all_string_line_numbers = multiline_string_lines(
+ source, include_docstrings=True)
+
+ commented_out_code_line_numbers = commented_out_code_lines(source)
+
+ for r in results:
+ issue_id = r['id'].lower()
+
+ if r['line'] in non_docstring_string_line_numbers:
+ if issue_id.startswith(('e1', 'e501', 'w191')):
+ continue
+
+ if r['line'] in all_string_line_numbers:
+ if issue_id in ['e501']:
+ continue
+
+ # We must offset by 1 for lines that contain the trailing contents of
+ # multiline strings.
+ if not aggressive and (r['line'] + 1) in all_string_line_numbers:
+ # Do not modify multiline strings in non-aggressive mode. Remove
+ # trailing whitespace could break doctests.
+ if issue_id.startswith(('w29', 'w39')):
+ continue
+
+ if aggressive <= 0:
+ if issue_id.startswith(('e711', 'w6')):
+ continue
+
+ if aggressive <= 1:
+ if issue_id.startswith(('e712', 'e713')):
+ continue
+
+ if r['line'] in commented_out_code_line_numbers:
+ if issue_id.startswith(('e26', 'e501')):
+ continue
+
+ yield r
+
+
+def multiline_string_lines(source, include_docstrings=False):
+ """Return line numbers that are within multiline strings.
+
+ The line numbers are indexed at 1.
+
+ Docstrings are ignored.
+
+ """
+ line_numbers = set()
+ previous_token_type = ''
+ try:
+ for t in generate_tokens(source):
+ token_type = t[0]
+ start_row = t[2][0]
+ end_row = t[3][0]
+
+ if token_type == tokenize.STRING and start_row != end_row:
+ if (
+ include_docstrings or
+ previous_token_type != tokenize.INDENT
+ ):
+ # We increment by one since we want the contents of the
+ # string.
+ line_numbers |= set(range(1 + start_row, 1 + end_row))
+
+ previous_token_type = token_type
+ except (SyntaxError, tokenize.TokenError):
+ pass
+
+ return line_numbers
+
+
+def commented_out_code_lines(source):
+ """Return line numbers of comments that are likely code.
+
+ Commented-out code is bad practice, but modifying it just adds even more
+ clutter.
+
+ """
+ line_numbers = []
+ try:
+ for t in generate_tokens(source):
+ token_type = t[0]
+ token_string = t[1]
+ start_row = t[2][0]
+ line = t[4]
+
+ # Ignore inline comments.
+ if not line.lstrip().startswith('#'):
+ continue
+
+ if token_type == tokenize.COMMENT:
+ stripped_line = token_string.lstrip('#').strip()
+ if (
+ ' ' in stripped_line and
+ '#' not in stripped_line and
+ check_syntax(stripped_line)
+ ):
+ line_numbers.append(start_row)
+ except (SyntaxError, tokenize.TokenError):
+ pass
+
+ return line_numbers
+
+
+def shorten_comment(line, max_line_length, last_comment=False):
+ """Return trimmed or split long comment line.
+
+ If there are no comments immediately following it, do a text wrap.
+ Doing this wrapping on all comments in general would lead to jagged
+ comment text.
+
+ """
+ assert len(line) > max_line_length
+ line = line.rstrip()
+
+ # PEP 8 recommends 72 characters for comment text.
+ indentation = _get_indentation(line) + '# '
+ max_line_length = min(max_line_length,
+ len(indentation) + 72)
+
+ MIN_CHARACTER_REPEAT = 5
+ if (
+ len(line) - len(line.rstrip(line[-1])) >= MIN_CHARACTER_REPEAT and
+ not line[-1].isalnum()
+ ):
+ # Trim comments that end with things like ---------
+ return line[:max_line_length] + '\n'
+ elif last_comment and re.match(r'\s*#+\s*\w+', line):
+ import textwrap
+ split_lines = textwrap.wrap(line.lstrip(' \t#'),
+ initial_indent=indentation,
+ subsequent_indent=indentation,
+ width=max_line_length,
+ break_long_words=False,
+ break_on_hyphens=False)
+ return '\n'.join(split_lines) + '\n'
+ else:
+ return line + '\n'
+
+
+def normalize_line_endings(lines, newline):
+ """Return fixed line endings.
+
+ All lines will be modified to use the most common line ending.
+
+ """
+ return [line.rstrip('\n\r') + newline for line in lines]
+
+
+def mutual_startswith(a, b):
+ return b.startswith(a) or a.startswith(b)
+
+
+def code_match(code, select, ignore):
+ if ignore:
+ assert not isinstance(ignore, unicode)
+ for ignored_code in [c.strip() for c in ignore]:
+ if mutual_startswith(code.lower(), ignored_code.lower()):
+ return False
+
+ if select:
+ assert not isinstance(select, unicode)
+ for selected_code in [c.strip() for c in select]:
+ if mutual_startswith(code.lower(), selected_code.lower()):
+ return True
+ return False
+
+ return True
+
+
+def fix_code(source, options=None, encoding=None):
+ """Return fixed source code."""
+ if not options:
+ options = parse_args([''])
+
+ if not isinstance(source, unicode):
+ source = source.decode(encoding or locale.getpreferredencoding())
+
+ sio = io.StringIO(source)
+ return fix_lines(sio.readlines(), options=options)
+
+
+def fix_lines(source_lines, options, filename=''):
+ """Return fixed source code."""
+ # Transform everything to line feed. Then change them back to original
+ # before returning fixed source code.
+ original_newline = find_newline(source_lines)
+ tmp_source = ''.join(normalize_line_endings(source_lines, '\n'))
+
+ # Keep a history to break out of cycles.
+ previous_hashes = set()
+
+ if options.line_range:
+ fixed_source = apply_local_fixes(tmp_source, options)
+ else:
+ # Apply global fixes only once (for efficiency).
+ fixed_source = apply_global_fixes(tmp_source, options)
+
+ passes = 0
+ long_line_ignore_cache = set()
+ while hash(fixed_source) not in previous_hashes:
+ if options.pep8_passes >= 0 and passes > options.pep8_passes:
+ break
+ passes += 1
+
+ previous_hashes.add(hash(fixed_source))
+
+ tmp_source = copy.copy(fixed_source)
+
+ fix = FixPEP8(
+ filename,
+ options,
+ contents=tmp_source,
+ long_line_ignore_cache=long_line_ignore_cache)
+
+ fixed_source = fix.fix()
+
+ sio = io.StringIO(fixed_source)
+ return ''.join(normalize_line_endings(sio.readlines(), original_newline))
+
+
+def fix_file(filename, options=None, output=None):
+ if not options:
+ options = parse_args([filename])
+
+ original_source = readlines_from_file(filename)
+
+ fixed_source = original_source
+
+ if options.in_place or output:
+ encoding = detect_encoding(filename)
+
+ if output:
+ output = codecs.getwriter(encoding)(output.buffer
+ if hasattr(output, 'buffer')
+ else output)
+
+ output = LineEndingWrapper(output)
+
+ fixed_source = fix_lines(fixed_source, options, filename=filename)
+
+ if options.diff:
+ new = io.StringIO(fixed_source)
+ new = new.readlines()
+ diff = get_diff_text(original_source, new, filename)
+ if output:
+ output.write(diff)
+ output.flush()
+ else:
+ return diff
+ elif options.in_place:
+ fp = open_with_encoding(filename, encoding=encoding,
+ mode='w')
+ fp.write(fixed_source)
+ fp.close()
+ else:
+ if output:
+ output.write(fixed_source)
+ output.flush()
+ else:
+ return fixed_source
+
+
+def global_fixes():
+ """Yield multiple (code, function) tuples."""
+ for function in globals().values():
+ if inspect.isfunction(function):
+ arguments = inspect.getargspec(function)[0]
+ if arguments[:1] != ['source']:
+ continue
+
+ code = extract_code_from_function(function)
+ if code:
+ yield (code, function)
+
+
+def apply_global_fixes(source, options, where='global'):
+ """Run global fixes on source code.
+
+ These are fixes that only need be done once (unlike those in
+ FixPEP8, which are dependent on pep8).
+
+ """
+ if code_match('E101', select=options.select, ignore=options.ignore):
+ source = reindent(source,
+ indent_size=options.indent_size)
+
+ for (code, function) in global_fixes():
+ if code_match(code, select=options.select, ignore=options.ignore):
+ if options.verbose:
+ print('---> Applying {0} fix for {1}'.format(where,
+ code.upper()),
+ file=sys.stderr)
+ source = function(source,
+ aggressive=options.aggressive)
+
+ source = fix_2to3(source,
+ aggressive=options.aggressive,
+ select=options.select,
+ ignore=options.ignore)
+
+ return source
+
+
+def apply_local_fixes(source, options):
+ """Ananologus to apply_global_fixes, but runs only those which makes sense
+ for the given line_range.
+
+ Do as much as we can without breaking code.
+
+ """
+ def find_ge(a, x):
+ """Find leftmost item greater than or equal to x."""
+ i = bisect.bisect_left(a, x)
+ if i != len(a):
+ return i, a[i]
+ return len(a) - 1, a[-1]
+
+ def find_le(a, x):
+ """Find rightmost value less than or equal to x."""
+ i = bisect.bisect_right(a, x)
+ if i:
+ return i - 1, a[i - 1]
+ return 0, a[0]
+
+ def local_fix(source, start_log, end_log,
+ start_lines, end_lines, indents, last_line):
+ """apply_global_fixes to the source between start_log and end_log.
+
+ The subsource must be the correct syntax of a complete python program
+ (but all lines may share an indentation). The subsource's shared indent
+ is removed, fixes are applied and the indent prepended back. Taking
+ care to not reindent strings.
+
+ last_line is the strict cut off (options.line_range[1]), so that
+ lines after last_line are not modified.
+
+ """
+ if end_log < start_log:
+ return source
+
+ ind = indents[start_log]
+ indent = _get_indentation(source[start_lines[start_log]])
+
+ sl = slice(start_lines[start_log], end_lines[end_log] + 1)
+
+ subsource = source[sl]
+ # Remove indent from subsource.
+ if ind:
+ for line_no in start_lines[start_log:end_log + 1]:
+ pos = line_no - start_lines[start_log]
+ subsource[pos] = subsource[pos][ind:]
+
+ # Fix indentation of subsource.
+ fixed_subsource = apply_global_fixes(''.join(subsource),
+ options,
+ where='local')
+ fixed_subsource = fixed_subsource.splitlines(True)
+
+ # Add back indent for non multi-line strings lines.
+ msl = multiline_string_lines(''.join(fixed_subsource),
+ include_docstrings=False)
+ for i, line in enumerate(fixed_subsource):
+ if not i + 1 in msl:
+ fixed_subsource[i] = indent + line if line != '\n' else line
+
+ # We make a special case to look at the final line, if it's a multiline
+ # *and* the cut off is somewhere inside it, we take the fixed
+ # subset up until last_line, this assumes that the number of lines
+ # does not change in this multiline line.
+ changed_lines = len(fixed_subsource)
+ if (start_lines[end_log] != end_lines[end_log]
+ and end_lines[end_log] > last_line):
+ after_end = end_lines[end_log] - last_line
+ fixed_subsource = (fixed_subsource[:-after_end] +
+ source[sl][-after_end:])
+ changed_lines -= after_end
+
+ options.line_range[1] = (options.line_range[0] +
+ changed_lines - 1)
+
+ return (source[:start_lines[start_log]] +
+ fixed_subsource +
+ source[end_lines[end_log] + 1:])
+
+ def is_continued_stmt(line,
+ continued_stmts=frozenset(['else', 'elif',
+ 'finally', 'except'])):
+ return re.split('[ :]', line.strip(), 1)[0] in continued_stmts
+
+ assert options.line_range
+ start, end = options.line_range
+ start -= 1
+ end -= 1
+ last_line = end # We shouldn't modify lines after this cut-off.
+
+ try:
+ logical = _find_logical(source)
+ except (SyntaxError, tokenize.TokenError):
+ return ''.join(source)
+
+ if not logical[0]:
+ # Just blank lines, this should imply that it will become '\n' ?
+ return apply_global_fixes(source, options)
+
+ start_lines, indents = zip(*logical[0])
+ end_lines, _ = zip(*logical[1])
+
+ source = source.splitlines(True)
+
+ start_log, start = find_ge(start_lines, start)
+ end_log, end = find_le(start_lines, end)
+
+ # Look behind one line, if it's indented less than current indent
+ # then we can move to this previous line knowing that its
+ # indentation level will not be changed.
+ if (start_log > 0
+ and indents[start_log - 1] < indents[start_log]
+ and not is_continued_stmt(source[start_log - 1])):
+ start_log -= 1
+ start = start_lines[start_log]
+
+ while start < end:
+
+ if is_continued_stmt(source[start]):
+ start_log += 1
+ start = start_lines[start_log]
+ continue
+
+ ind = indents[start_log]
+ for t in itertools.takewhile(lambda t: t[1][1] >= ind,
+ enumerate(logical[0][start_log:])):
+ n_log, n = start_log + t[0], t[1][0]
+ # start shares indent up to n.
+
+ if n <= end:
+ source = local_fix(source, start_log, n_log,
+ start_lines, end_lines,
+ indents, last_line)
+ start_log = n_log if n == end else n_log + 1
+ start = start_lines[start_log]
+ continue
+
+ else:
+ # Look at the line after end and see if allows us to reindent.
+ after_end_log, after_end = find_ge(start_lines, end + 1)
+
+ if indents[after_end_log] > indents[start_log]:
+ start_log, start = find_ge(start_lines, start + 1)
+ continue
+
+ if (indents[after_end_log] == indents[start_log]
+ and is_continued_stmt(source[after_end])):
+ # find n, the beginning of the last continued statement
+ # Apply fix to previous block if there is one.
+ only_block = True
+ for n, n_ind in logical[0][start_log:end_log + 1][::-1]:
+ if n_ind == ind and not is_continued_stmt(source[n]):
+ n_log = start_lines.index(n)
+ source = local_fix(source, start_log, n_log - 1,
+ start_lines, end_lines,
+ indents, last_line)
+ start_log = n_log + 1
+ start = start_lines[start_log]
+ only_block = False
+ break
+ if only_block:
+ end_log, end = find_le(start_lines, end - 1)
+ continue
+
+ source = local_fix(source, start_log, end_log,
+ start_lines, end_lines,
+ indents, last_line)
+ break
+
+ return ''.join(source)
+
+
+def extract_code_from_function(function):
+ """Return code handled by function."""
+ if not function.__name__.startswith('fix_'):
+ return None
+
+ code = re.sub('^fix_', '', function.__name__)
+ if not code:
+ return None
+
+ try:
+ int(code[1:])
+ except ValueError:
+ return None
+
+ return code
+
+
+def create_parser():
+ """Return command-line parser."""
+ # Do import locally to be friendly to those who use autopep8 as a library
+ # and are supporting Python 2.6.
+ import argparse
+
+ parser = argparse.ArgumentParser(description=docstring_summary(__doc__),
+ prog='autopep8')
+ parser.add_argument('--version', action='version',
+ version='%(prog)s ' + __version__)
+ parser.add_argument('-v', '--verbose', action='count', dest='verbose',
+ default=0,
+ help='print verbose messages; '
+ 'multiple -v result in more verbose messages')
+ parser.add_argument('-d', '--diff', action='store_true', dest='diff',
+ help='print the diff for the fixed source')
+ parser.add_argument('-i', '--in-place', action='store_true',
+ help='make changes to files in place')
+ parser.add_argument('-r', '--recursive', action='store_true',
+ help='run recursively over directories; '
+ 'must be used with --in-place or --diff')
+ parser.add_argument('-j', '--jobs', type=int, metavar='n', default=1,
+ help='number of parallel jobs; '
+ 'match CPU count if value is less than 1')
+ parser.add_argument('-p', '--pep8-passes', metavar='n',
+ default=-1, type=int,
+ help='maximum number of additional pep8 passes '
+ '(default: infinite)')
+ parser.add_argument('-a', '--aggressive', action='count', default=0,
+ help='enable non-whitespace changes; '
+ 'multiple -a result in more aggressive changes')
+ parser.add_argument('--experimental', action='store_true',
+ help='enable experimental fixes')
+ parser.add_argument('--exclude', metavar='globs',
+ help='exclude file/directory names that match these '
+ 'comma-separated globs')
+ parser.add_argument('--list-fixes', action='store_true',
+ help='list codes for fixes; '
+ 'used by --ignore and --select')
+ parser.add_argument('--ignore', metavar='errors', default='',
+ help='do not fix these errors/warnings '
+ '(default: {0})'.format(DEFAULT_IGNORE))
+ parser.add_argument('--select', metavar='errors', default='',
+ help='fix only these errors/warnings (e.g. E4,W)')
+ parser.add_argument('--max-line-length', metavar='n', default=79, type=int,
+ help='set maximum allowed line length '
+ '(default: %(default)s)')
+ parser.add_argument('--range', metavar='line', dest='line_range',
+ default=None, type=int, nargs=2,
+ help='only fix errors found within this inclusive '
+ 'range of line numbers (e.g. 1 99); '
+ 'line numbers are indexed at 1')
+ parser.add_argument('--indent-size', default=DEFAULT_INDENT_SIZE,
+ type=int, metavar='n',
+ help='number of spaces per indent level '
+ '(default %(default)s)')
+ parser.add_argument('files', nargs='*',
+ help="files to format or '-' for standard in")
+
+ return parser
+
+
+def parse_args(arguments):
+ """Parse command-line options."""
+ parser = create_parser()
+ args = parser.parse_args(arguments)
+
+ if not args.files and not args.list_fixes:
+ parser.error('incorrect number of arguments')
+
+ args.files = [decode_filename(name) for name in args.files]
+
+ if '-' in args.files:
+ if len(args.files) > 1:
+ parser.error('cannot mix stdin and regular files')
+
+ if args.diff:
+ parser.error('--diff cannot be used with standard input')
+
+ if args.in_place:
+ parser.error('--in-place cannot be used with standard input')
+
+ if args.recursive:
+ parser.error('--recursive cannot be used with standard input')
+
+ if len(args.files) > 1 and not (args.in_place or args.diff):
+ parser.error('autopep8 only takes one filename as argument '
+ 'unless the "--in-place" or "--diff" args are '
+ 'used')
+
+ if args.recursive and not (args.in_place or args.diff):
+ parser.error('--recursive must be used with --in-place or --diff')
+
+ if args.exclude and not args.recursive:
+ parser.error('--exclude is only relevant when used with --recursive')
+
+ if args.in_place and args.diff:
+ parser.error('--in-place and --diff are mutually exclusive')
+
+ if args.max_line_length <= 0:
+ parser.error('--max-line-length must be greater than 0')
+
+ if args.select:
+ args.select = args.select.split(',')
+
+ if args.ignore:
+ args.ignore = args.ignore.split(',')
+ elif not args.select:
+ if args.aggressive:
+ # Enable everything by default if aggressive.
+ args.select = ['E', 'W']
+ else:
+ args.ignore = DEFAULT_IGNORE.split(',')
+
+ if args.exclude:
+ args.exclude = args.exclude.split(',')
+ else:
+ args.exclude = []
+
+ if args.jobs < 1:
+ # Do not import multiprocessing globally in case it is not supported
+ # on the platform.
+ import multiprocessing
+ args.jobs = multiprocessing.cpu_count()
+
+ if args.jobs > 1 and not args.in_place:
+ parser.error('parallel jobs requires --in-place')
+
+ if args.line_range:
+ if args.line_range[0] <= 0:
+ parser.error('--range must be positive numbers')
+ if args.line_range[0] > args.line_range[1]:
+ parser.error('First value of --range should be less than or equal '
+ 'to the second')
+
+ return args
+
+
+def decode_filename(filename):
+ """Return Unicode filename."""
+ if isinstance(filename, unicode):
+ return filename
+ else:
+ return filename.decode(sys.getfilesystemencoding())
+
+
+def supported_fixes():
+ """Yield pep8 error codes that autopep8 fixes.
+
+ Each item we yield is a tuple of the code followed by its
+ description.
+
+ """
+ yield ('E101', docstring_summary(reindent.__doc__))
+
+ instance = FixPEP8(filename=None, options=None, contents='')
+ for attribute in dir(instance):
+ code = re.match('fix_([ew][0-9][0-9][0-9])', attribute)
+ if code:
+ yield (
+ code.group(1).upper(),
+ re.sub(r'\s+', ' ',
+ docstring_summary(getattr(instance, attribute).__doc__))
+ )
+
+ for (code, function) in sorted(global_fixes()):
+ yield (code.upper() + (4 - len(code)) * ' ',
+ re.sub(r'\s+', ' ', docstring_summary(function.__doc__)))
+
+ for code in sorted(CODE_TO_2TO3):
+ yield (code.upper() + (4 - len(code)) * ' ',
+ re.sub(r'\s+', ' ', docstring_summary(fix_2to3.__doc__)))
+
+
+def docstring_summary(docstring):
+ """Return summary of docstring."""
+ return docstring.split('\n')[0]
+
+
+def line_shortening_rank(candidate, indent_word, max_line_length,
+ experimental=False):
+ """Return rank of candidate.
+
+ This is for sorting candidates.
+
+ """
+ if not candidate.strip():
+ return 0
+
+ rank = 0
+ lines = candidate.split('\n')
+
+ offset = 0
+ if (
+ not lines[0].lstrip().startswith('#') and
+ lines[0].rstrip()[-1] not in '([{'
+ ):
+ for (opening, closing) in ('()', '[]', '{}'):
+ # Don't penalize empty containers that aren't split up. Things like
+ # this "foo(\n )" aren't particularly good.
+ opening_loc = lines[0].find(opening)
+ closing_loc = lines[0].find(closing)
+ if opening_loc >= 0:
+ if closing_loc < 0 or closing_loc != opening_loc + 1:
+ offset = max(offset, 1 + opening_loc)
+
+ current_longest = max(offset + len(x.strip()) for x in lines)
+
+ rank += 4 * max(0, current_longest - max_line_length)
+
+ rank += len(lines)
+
+ # Too much variation in line length is ugly.
+ rank += 2 * standard_deviation(len(line) for line in lines)
+
+ bad_staring_symbol = {
+ '(': ')',
+ '[': ']',
+ '{': '}'}.get(lines[0][-1])
+
+ if len(lines) > 1:
+ if (
+ bad_staring_symbol and
+ lines[1].lstrip().startswith(bad_staring_symbol)
+ ):
+ rank += 20
+
+ for lineno, current_line in enumerate(lines):
+ current_line = current_line.strip()
+
+ if current_line.startswith('#'):
+ continue
+
+ for bad_start in ['.', '%', '+', '-', '/']:
+ if current_line.startswith(bad_start):
+ rank += 100
+
+ # Do not tolerate operators on their own line.
+ if current_line == bad_start:
+ rank += 1000
+
+ if current_line.endswith(('(', '[', '{', '.')):
+ # Avoid lonely opening. They result in longer lines.
+ if len(current_line) <= len(indent_word):
+ rank += 100
+
+ # Avoid the ugliness of ", (\n".
+ if (
+ current_line.endswith('(') and
+ current_line[:-1].rstrip().endswith(',')
+ ):
+ rank += 100
+
+ # Also avoid the ugliness of "foo.\nbar"
+ if current_line.endswith('.'):
+ rank += 100
+
+ if has_arithmetic_operator(current_line):
+ rank += 100
+
+ if current_line.endswith(('%', '(', '[', '{')):
+ rank -= 20
+
+ # Try to break list comprehensions at the "for".
+ if current_line.startswith('for '):
+ rank -= 50
+
+ if current_line.endswith('\\'):
+ # If a line ends in \-newline, it may be part of a
+ # multiline string. In that case, we would like to know
+ # how long that line is without the \-newline. If it's
+ # longer than the maximum, or has comments, then we assume
+ # that the \-newline is an okay candidate and only
+ # penalize it a bit.
+ total_len = len(current_line)
+ lineno += 1
+ while lineno < len(lines):
+ total_len += len(lines[lineno])
+
+ if lines[lineno].lstrip().startswith('#'):
+ total_len = max_line_length
+ break
+
+ if not lines[lineno].endswith('\\'):
+ break
+
+ lineno += 1
+
+ if total_len < max_line_length:
+ rank += 10
+ else:
+ rank += 100 if experimental else 1
+
+ # Prefer breaking at commas rather than colon.
+ if ',' in current_line and current_line.endswith(':'):
+ rank += 10
+
+ rank += 10 * count_unbalanced_brackets(current_line)
+
+ return max(0, rank)
+
+
+def standard_deviation(numbers):
+ """Return standard devation."""
+ numbers = list(numbers)
+ if not numbers:
+ return 0
+ mean = sum(numbers) / len(numbers)
+ return (sum((n - mean) ** 2 for n in numbers) /
+ len(numbers)) ** .5
+
+
+def has_arithmetic_operator(line):
+ """Return True if line contains any arithmetic operators."""
+ for operator in pep8.ARITHMETIC_OP:
+ if operator in line:
+ return True
+
+ return False
+
+
+def count_unbalanced_brackets(line):
+ """Return number of unmatched open/close brackets."""
+ count = 0
+ for opening, closing in ['()', '[]', '{}']:
+ count += abs(line.count(opening) - line.count(closing))
+
+ return count
+
+
+def split_at_offsets(line, offsets):
+ """Split line at offsets.
+
+ Return list of strings.
+
+ """
+ result = []
+
+ previous_offset = 0
+ current_offset = 0
+ for current_offset in sorted(offsets):
+ if current_offset < len(line) and previous_offset != current_offset:
+ result.append(line[previous_offset:current_offset].strip())
+ previous_offset = current_offset
+
+ result.append(line[current_offset:])
+
+ return result
+
+
+class LineEndingWrapper(object):
+
+ r"""Replace line endings to work with sys.stdout.
+
+ It seems that sys.stdout expects only '\n' as the line ending, no matter
+ the platform. Otherwise, we get repeated line endings.
+
+ """
+
+ def __init__(self, output):
+ self.__output = output
+
+ def write(self, s):
+ self.__output.write(s.replace('\r\n', '\n').replace('\r', '\n'))
+
+ def flush(self):
+ self.__output.flush()
+
+
+def match_file(filename, exclude):
+ """Return True if file is okay for modifying/recursing."""
+ base_name = os.path.basename(filename)
+
+ if base_name.startswith('.'):
+ return False
+
+ for pattern in exclude:
+ if fnmatch.fnmatch(base_name, pattern):
+ return False
+
+ if not os.path.isdir(filename) and not is_python_file(filename):
+ return False
+
+ return True
+
+
+def find_files(filenames, recursive, exclude):
+ """Yield filenames."""
+ while filenames:
+ name = filenames.pop(0)
+ if recursive and os.path.isdir(name):
+ for root, directories, children in os.walk(name):
+ filenames += [os.path.join(root, f) for f in children
+ if match_file(os.path.join(root, f),
+ exclude)]
+ directories[:] = [d for d in directories
+ if match_file(os.path.join(root, d),
+ exclude)]
+ else:
+ yield name
+
+
+def _fix_file(parameters):
+ """Helper function for optionally running fix_file() in parallel."""
+ if parameters[1].verbose:
+ print('[file:{0}]'.format(parameters[0]), file=sys.stderr)
+ try:
+ fix_file(*parameters)
+ except IOError as error:
+ print(unicode(error), file=sys.stderr)
+
+
+def fix_multiple_files(filenames, options, output=None):
+ """Fix list of files.
+
+ Optionally fix files recursively.
+
+ """
+ filenames = find_files(filenames, options.recursive, options.exclude)
+ if options.jobs > 1:
+ import multiprocessing
+ pool = multiprocessing.Pool(options.jobs)
+ pool.map(_fix_file,
+ [(name, options) for name in filenames])
+ else:
+ for name in filenames:
+ _fix_file((name, options, output))
+
+
+def is_python_file(filename):
+ """Return True if filename is Python file."""
+ if filename.endswith('.py'):
+ return True
+
+ try:
+ with open_with_encoding(filename) as f:
+ first_line = f.readlines(1)[0]
+ except (IOError, IndexError):
+ return False
+
+ if not PYTHON_SHEBANG_REGEX.match(first_line):
+ return False
+
+ return True
+
+
+def is_probably_part_of_multiline(line):
+ """Return True if line is likely part of a multiline string.
+
+ When multiline strings are involved, pep8 reports the error as being
+ at the start of the multiline string, which doesn't work for us.
+
+ """
+ return (
+ '"""' in line or
+ "'''" in line or
+ line.rstrip().endswith('\\')
+ )
+
+
+def main():
+ """Tool main."""
+ try:
+ # Exit on broken pipe.
+ signal.signal(signal.SIGPIPE, signal.SIG_DFL)
+ except AttributeError: # pragma: no cover
+ # SIGPIPE is not available on Windows.
+ pass
+
+ try:
+ args = parse_args(sys.argv[1:])
+
+ if args.list_fixes:
+ for code, description in sorted(supported_fixes()):
+ print('{code} - {description}'.format(
+ code=code, description=description))
+ return 0
+
+ if args.files == ['-']:
+ assert not args.in_place
+
+ # LineEndingWrapper is unnecessary here due to the symmetry between
+ # standard in and standard out.
+
+ sys.stdout.write(
+ fix_code(
+ sys.stdin.read(),
+ args,
+ encoding=sys.stdin.encoding))
+ else:
+ if args.in_place or args.diff:
+ args.files = list(set(args.files))
+ else:
+ assert len(args.files) == 1
+ assert not args.recursive
+
+ fix_multiple_files(args.files, args, sys.stdout)
+ except KeyboardInterrupt:
+ return 1 # pragma: no cover
+
+
+class CachedTokenizer(object):
+
+ """A one-element cache around tokenize.generate_tokens().
+
+ Original code written by Ned Batchelder, in coverage.py.
+
+ """
+
+ def __init__(self):
+ self.last_text = None
+ self.last_tokens = None
+
+ def generate_tokens(self, text):
+ """A stand-in for tokenize.generate_tokens()."""
+ if text != self.last_text:
+ string_io = io.StringIO(text)
+ self.last_tokens = list(
+ tokenize.generate_tokens(string_io.readline)
+ )
+ self.last_text = text
+ return self.last_tokens
+
+_cached_tokenizer = CachedTokenizer()
+generate_tokens = _cached_tokenizer.generate_tokens
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/.gitignore b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/.gitignore
new file mode 100644
index 000000000000..1c45ce5be3e2
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/.gitignore
@@ -0,0 +1 @@
+*.pickle
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/Grammar.txt b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/Grammar.txt
new file mode 100644
index 000000000000..1e1f24cfbc76
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/Grammar.txt
@@ -0,0 +1,158 @@
+# Grammar for 2to3. This grammar supports Python 2.x and 3.x.
+
+# Note: Changing the grammar specified in this file will most likely
+# require corresponding changes in the parser module
+# (../Modules/parsermodule.c). If you can't make the changes to
+# that module yourself, please co-ordinate the required changes
+# with someone who can; ask around on python-dev for help. Fred
+# Drake <fdrake@acm.org> will probably be listening there.
+
+# NOTE WELL: You should also follow all the steps listed in PEP 306,
+# "How to Change Python's Grammar"
+
+# Commands for Kees Blom's railroad program
+#diagram:token NAME
+#diagram:token NUMBER
+#diagram:token STRING
+#diagram:token NEWLINE
+#diagram:token ENDMARKER
+#diagram:token INDENT
+#diagram:output\input python.bla
+#diagram:token DEDENT
+#diagram:output\textwidth 20.04cm\oddsidemargin 0.0cm\evensidemargin 0.0cm
+#diagram:rules
+
+# Start symbols for the grammar:
+# file_input is a module or sequence of commands read from an input file;
+# single_input is a single interactive statement;
+# eval_input is the input for the eval() and input() functions.
+# NB: compound_stmt in single_input is followed by extra NEWLINE!
+file_input: (NEWLINE | stmt)* ENDMARKER
+single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE
+eval_input: testlist NEWLINE* ENDMARKER
+
+decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
+decorators: decorator+
+decorated: decorators (classdef | funcdef)
+funcdef: 'def' NAME parameters ['->' test] ':' suite
+parameters: '(' [typedargslist] ')'
+typedargslist: ((tfpdef ['=' test] ',')*
+ ('*' [tname] (',' tname ['=' test])* [',' '**' tname] | '**' tname)
+ | tfpdef ['=' test] (',' tfpdef ['=' test])* [','])
+tname: NAME [':' test]
+tfpdef: tname | '(' tfplist ')'
+tfplist: tfpdef (',' tfpdef)* [',']
+varargslist: ((vfpdef ['=' test] ',')*
+ ('*' [vname] (',' vname ['=' test])* [',' '**' vname] | '**' vname)
+ | vfpdef ['=' test] (',' vfpdef ['=' test])* [','])
+vname: NAME
+vfpdef: vname | '(' vfplist ')'
+vfplist: vfpdef (',' vfpdef)* [',']
+
+stmt: simple_stmt | compound_stmt
+simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
+small_stmt: (expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt |
+ import_stmt | global_stmt | exec_stmt | assert_stmt)
+expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
+ ('=' (yield_expr|testlist_star_expr))*)
+testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
+augassign: ('+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' |
+ '<<=' | '>>=' | '**=' | '//=')
+# For normal assignments, additional restrictions enforced by the interpreter
+print_stmt: 'print' ( [ test (',' test)* [','] ] |
+ '>>' test [ (',' test)+ [','] ] )
+del_stmt: 'del' exprlist
+pass_stmt: 'pass'
+flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt
+break_stmt: 'break'
+continue_stmt: 'continue'
+return_stmt: 'return' [testlist]
+yield_stmt: yield_expr
+raise_stmt: 'raise' [test ['from' test | ',' test [',' test]]]
+import_stmt: import_name | import_from
+import_name: 'import' dotted_as_names
+import_from: ('from' ('.'* dotted_name | '.'+)
+ 'import' ('*' | '(' import_as_names ')' | import_as_names))
+import_as_name: NAME ['as' NAME]
+dotted_as_name: dotted_name ['as' NAME]
+import_as_names: import_as_name (',' import_as_name)* [',']
+dotted_as_names: dotted_as_name (',' dotted_as_name)*
+dotted_name: NAME ('.' NAME)*
+global_stmt: ('global' | 'nonlocal') NAME (',' NAME)*
+exec_stmt: 'exec' expr ['in' test [',' test]]
+assert_stmt: 'assert' test [',' test]
+
+compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated
+if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
+while_stmt: 'while' test ':' suite ['else' ':' suite]
+for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite]
+try_stmt: ('try' ':' suite
+ ((except_clause ':' suite)+
+ ['else' ':' suite]
+ ['finally' ':' suite] |
+ 'finally' ':' suite))
+with_stmt: 'with' with_item (',' with_item)* ':' suite
+with_item: test ['as' expr]
+with_var: 'as' expr
+# NB compile.c makes sure that the default except clause is last
+except_clause: 'except' [test [(',' | 'as') test]]
+suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT
+
+# Backward compatibility cruft to support:
+# [ x for x in lambda: True, lambda: False if x() ]
+# even while also allowing:
+# lambda x: 5 if x else 2
+# (But not a mix of the two)
+testlist_safe: old_test [(',' old_test)+ [',']]
+old_test: or_test | old_lambdef
+old_lambdef: 'lambda' [varargslist] ':' old_test
+
+test: or_test ['if' or_test 'else' test] | lambdef
+or_test: and_test ('or' and_test)*
+and_test: not_test ('and' not_test)*
+not_test: 'not' not_test | comparison
+comparison: expr (comp_op expr)*
+comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
+star_expr: '*' expr
+expr: xor_expr ('|' xor_expr)*
+xor_expr: and_expr ('^' and_expr)*
+and_expr: shift_expr ('&' shift_expr)*
+shift_expr: arith_expr (('<<'|'>>') arith_expr)*
+arith_expr: term (('+'|'-') term)*
+term: factor (('*'|'/'|'%'|'//') factor)*
+factor: ('+'|'-'|'~') factor | power
+power: atom trailer* ['**' factor]
+atom: ('(' [yield_expr|testlist_gexp] ')' |
+ '[' [listmaker] ']' |
+ '{' [dictsetmaker] '}' |
+ '`' testlist1 '`' |
+ NAME | NUMBER | STRING+ | '.' '.' '.')
+listmaker: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] )
+testlist_gexp: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] )
+lambdef: 'lambda' [varargslist] ':' test
+trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
+subscriptlist: subscript (',' subscript)* [',']
+subscript: test | [test] ':' [test] [sliceop]
+sliceop: ':' [test]
+exprlist: (expr|star_expr) (',' (expr|star_expr))* [',']
+testlist: test (',' test)* [',']
+dictsetmaker: ( (test ':' test (comp_for | (',' test ':' test)* [','])) |
+ (test (comp_for | (',' test)* [','])) )
+
+classdef: 'class' NAME ['(' [arglist] ')'] ':' suite
+
+arglist: (argument ',')* (argument [',']
+ |'*' test (',' argument)* [',' '**' test]
+ |'**' test)
+argument: test [comp_for] | test '=' test # Really [keyword '='] test
+
+comp_iter: comp_for | comp_if
+comp_for: 'for' exprlist 'in' testlist_safe [comp_iter]
+comp_if: 'if' old_test [comp_iter]
+
+testlist1: test (',' test)*
+
+# not used in grammar, but may appear in "node" passed from Parser to Compiler
+encoding_decl: NAME
+
+yield_expr: 'yield' [testlist]
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/PatternGrammar.txt b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/PatternGrammar.txt
new file mode 100644
index 000000000000..36bf8148273b
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/PatternGrammar.txt
@@ -0,0 +1,28 @@
+# Copyright 2006 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+# A grammar to describe tree matching patterns.
+# Not shown here:
+# - 'TOKEN' stands for any token (leaf node)
+# - 'any' stands for any node (leaf or interior)
+# With 'any' we can still specify the sub-structure.
+
+# The start symbol is 'Matcher'.
+
+Matcher: Alternatives ENDMARKER
+
+Alternatives: Alternative ('|' Alternative)*
+
+Alternative: (Unit | NegatedUnit)+
+
+Unit: [NAME '='] ( STRING [Repeater]
+ | NAME [Details] [Repeater]
+ | '(' Alternatives ')' [Repeater]
+ | '[' Alternatives ']'
+ )
+
+NegatedUnit: 'not' (STRING | NAME [Details] | '(' Alternatives ')')
+
+Repeater: '*' | '+' | '{' NUMBER [',' NUMBER] '}'
+
+Details: '<' Alternatives '>'
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/__init__.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/__init__.py
new file mode 100644
index 000000000000..ea30561d8397
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/__init__.py
@@ -0,0 +1 @@
+#empty
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/__main__.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/__main__.py
new file mode 100644
index 000000000000..80688baf27ab
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/__main__.py
@@ -0,0 +1,4 @@
+import sys
+from .main import main
+
+sys.exit(main("lib2to3.fixes"))
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/btm_matcher.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/btm_matcher.py
new file mode 100644
index 000000000000..736ba2b9d83a
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/btm_matcher.py
@@ -0,0 +1,168 @@
+"""A bottom-up tree matching algorithm implementation meant to speed
+up 2to3's matching process. After the tree patterns are reduced to
+their rarest linear path, a linear Aho-Corasick automaton is
+created. The linear automaton traverses the linear paths from the
+leaves to the root of the AST and returns a set of nodes for further
+matching. This reduces significantly the number of candidate nodes."""
+
+__author__ = "George Boutsioukis <gboutsioukis@gmail.com>"
+
+import logging
+import itertools
+from collections import defaultdict
+
+from . import pytree
+from .btm_utils import reduce_tree
+
+class BMNode(object):
+ """Class for a node of the Aho-Corasick automaton used in matching"""
+ count = itertools.count()
+ def __init__(self):
+ self.transition_table = {}
+ self.fixers = []
+ self.id = next(BMNode.count)
+ self.content = ''
+
+class BottomMatcher(object):
+ """The main matcher class. After instantiating the patterns should
+ be added using the add_fixer method"""
+
+ def __init__(self):
+ self.match = set()
+ self.root = BMNode()
+ self.nodes = [self.root]
+ self.fixers = []
+ self.logger = logging.getLogger("RefactoringTool")
+
+ def add_fixer(self, fixer):
+ """Reduces a fixer's pattern tree to a linear path and adds it
+ to the matcher(a common Aho-Corasick automaton). The fixer is
+ appended on the matching states and called when they are
+ reached"""
+ self.fixers.append(fixer)
+ tree = reduce_tree(fixer.pattern_tree)
+ linear = tree.get_linear_subpattern()
+ match_nodes = self.add(linear, start=self.root)
+ for match_node in match_nodes:
+ match_node.fixers.append(fixer)
+
+ def add(self, pattern, start):
+ "Recursively adds a linear pattern to the AC automaton"
+ #print("adding pattern", pattern, "to", start)
+ if not pattern:
+ #print("empty pattern")
+ return [start]
+ if isinstance(pattern[0], tuple):
+ #alternatives
+ #print("alternatives")
+ match_nodes = []
+ for alternative in pattern[0]:
+ #add all alternatives, and add the rest of the pattern
+ #to each end node
+ end_nodes = self.add(alternative, start=start)
+ for end in end_nodes:
+ match_nodes.extend(self.add(pattern[1:], end))
+ return match_nodes
+ else:
+ #single token
+ #not last
+ if pattern[0] not in start.transition_table:
+ #transition did not exist, create new
+ next_node = BMNode()
+ start.transition_table[pattern[0]] = next_node
+ else:
+ #transition exists already, follow
+ next_node = start.transition_table[pattern[0]]
+
+ if pattern[1:]:
+ end_nodes = self.add(pattern[1:], start=next_node)
+ else:
+ end_nodes = [next_node]
+ return end_nodes
+
+ def run(self, leaves):
+ """The main interface with the bottom matcher. The tree is
+ traversed from the bottom using the constructed
+ automaton. Nodes are only checked once as the tree is
+ retraversed. When the automaton fails, we give it one more
+ shot(in case the above tree matches as a whole with the
+ rejected leaf), then we break for the next leaf. There is the
+ special case of multiple arguments(see code comments) where we
+ recheck the nodes
+
+ Args:
+ The leaves of the AST tree to be matched
+
+ Returns:
+ A dictionary of node matches with fixers as the keys
+ """
+ current_ac_node = self.root
+ results = defaultdict(list)
+ for leaf in leaves:
+ current_ast_node = leaf
+ while current_ast_node:
+ current_ast_node.was_checked = True
+ for child in current_ast_node.children:
+ # multiple statements, recheck
+ if isinstance(child, pytree.Leaf) and child.value == u";":
+ current_ast_node.was_checked = False
+ break
+ if current_ast_node.type == 1:
+ #name
+ node_token = current_ast_node.value
+ else:
+ node_token = current_ast_node.type
+
+ if node_token in current_ac_node.transition_table:
+ #token matches
+ current_ac_node = current_ac_node.transition_table[node_token]
+ for fixer in current_ac_node.fixers:
+ if not fixer in results:
+ results[fixer] = []
+ results[fixer].append(current_ast_node)
+
+ else:
+ #matching failed, reset automaton
+ current_ac_node = self.root
+ if (current_ast_node.parent is not None
+ and current_ast_node.parent.was_checked):
+ #the rest of the tree upwards has been checked, next leaf
+ break
+
+ #recheck the rejected node once from the root
+ if node_token in current_ac_node.transition_table:
+ #token matches
+ current_ac_node = current_ac_node.transition_table[node_token]
+ for fixer in current_ac_node.fixers:
+ if not fixer in results.keys():
+ results[fixer] = []
+ results[fixer].append(current_ast_node)
+
+ current_ast_node = current_ast_node.parent
+ return results
+
+ def print_ac(self):
+ "Prints a graphviz diagram of the BM automaton(for debugging)"
+ print("digraph g{")
+ def print_node(node):
+ for subnode_key in node.transition_table.keys():
+ subnode = node.transition_table[subnode_key]
+ print("%d -> %d [label=%s] //%s" %
+ (node.id, subnode.id, type_repr(subnode_key), str(subnode.fixers)))
+ if subnode_key == 1:
+ print(subnode.content)
+ print_node(subnode)
+ print_node(self.root)
+ print("}")
+
+# taken from pytree.py for debugging; only used by print_ac
+_type_reprs = {}
+def type_repr(type_num):
+ global _type_reprs
+ if not _type_reprs:
+ from .pygram import python_symbols
+ # printing tokens is possible but not as useful
+ # from .pgen2 import token // token.__dict__.items():
+ for name, val in python_symbols.__dict__.items():
+ if type(val) == int: _type_reprs[val] = name
+ return _type_reprs.setdefault(type_num, type_num)
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/btm_utils.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/btm_utils.py
new file mode 100644
index 000000000000..2276dc9e966d
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/btm_utils.py
@@ -0,0 +1,283 @@
+"Utility functions used by the btm_matcher module"
+
+from . import pytree
+from .pgen2 import grammar, token
+from .pygram import pattern_symbols, python_symbols
+
+syms = pattern_symbols
+pysyms = python_symbols
+tokens = grammar.opmap
+token_labels = token
+
+TYPE_ANY = -1
+TYPE_ALTERNATIVES = -2
+TYPE_GROUP = -3
+
+class MinNode(object):
+ """This class serves as an intermediate representation of the
+ pattern tree during the conversion to sets of leaf-to-root
+ subpatterns"""
+
+ def __init__(self, type=None, name=None):
+ self.type = type
+ self.name = name
+ self.children = []
+ self.leaf = False
+ self.parent = None
+ self.alternatives = []
+ self.group = []
+
+ def __repr__(self):
+ return str(self.type) + ' ' + str(self.name)
+
+ def leaf_to_root(self):
+ """Internal method. Returns a characteristic path of the
+ pattern tree. This method must be run for all leaves until the
+ linear subpatterns are merged into a single"""
+ node = self
+ subp = []
+ while node:
+ if node.type == TYPE_ALTERNATIVES:
+ node.alternatives.append(subp)
+ if len(node.alternatives) == len(node.children):
+ #last alternative
+ subp = [tuple(node.alternatives)]
+ node.alternatives = []
+ node = node.parent
+ continue
+ else:
+ node = node.parent
+ subp = None
+ break
+
+ if node.type == TYPE_GROUP:
+ node.group.append(subp)
+ #probably should check the number of leaves
+ if len(node.group) == len(node.children):
+ subp = get_characteristic_subpattern(node.group)
+ node.group = []
+ node = node.parent
+ continue
+ else:
+ node = node.parent
+ subp = None
+ break
+
+ if node.type == token_labels.NAME and node.name:
+ #in case of type=name, use the name instead
+ subp.append(node.name)
+ else:
+ subp.append(node.type)
+
+ node = node.parent
+ return subp
+
+ def get_linear_subpattern(self):
+ """Drives the leaf_to_root method. The reason that
+ leaf_to_root must be run multiple times is because we need to
+ reject 'group' matches; for example the alternative form
+ (a | b c) creates a group [b c] that needs to be matched. Since
+ matching multiple linear patterns overcomes the automaton's
+ capabilities, leaf_to_root merges each group into a single
+ choice based on 'characteristic'ity,
+
+ i.e. (a|b c) -> (a|b) if b more characteristic than c
+
+ Returns: The most 'characteristic'(as defined by
+ get_characteristic_subpattern) path for the compiled pattern
+ tree.
+ """
+
+ for l in self.leaves():
+ subp = l.leaf_to_root()
+ if subp:
+ return subp
+
+ def leaves(self):
+ "Generator that returns the leaves of the tree"
+ for child in self.children:
+ for x in child.leaves():
+ yield x
+ if not self.children:
+ yield self
+
+def reduce_tree(node, parent=None):
+ """
+ Internal function. Reduces a compiled pattern tree to an
+ intermediate representation suitable for feeding the
+ automaton. This also trims off any optional pattern elements(like
+ [a], a*).
+ """
+
+ new_node = None
+ #switch on the node type
+ if node.type == syms.Matcher:
+ #skip
+ node = node.children[0]
+
+ if node.type == syms.Alternatives :
+ #2 cases
+ if len(node.children) <= 2:
+ #just a single 'Alternative', skip this node
+ new_node = reduce_tree(node.children[0], parent)
+ else:
+ #real alternatives
+ new_node = MinNode(type=TYPE_ALTERNATIVES)
+ #skip odd children('|' tokens)
+ for child in node.children:
+ if node.children.index(child)%2:
+ continue
+ reduced = reduce_tree(child, new_node)
+ if reduced is not None:
+ new_node.children.append(reduced)
+ elif node.type == syms.Alternative:
+ if len(node.children) > 1:
+
+ new_node = MinNode(type=TYPE_GROUP)
+ for child in node.children:
+ reduced = reduce_tree(child, new_node)
+ if reduced:
+ new_node.children.append(reduced)
+ if not new_node.children:
+ # delete the group if all of the children were reduced to None
+ new_node = None
+
+ else:
+ new_node = reduce_tree(node.children[0], parent)
+
+ elif node.type == syms.Unit:
+ if (isinstance(node.children[0], pytree.Leaf) and
+ node.children[0].value == '('):
+ #skip parentheses
+ return reduce_tree(node.children[1], parent)
+ if ((isinstance(node.children[0], pytree.Leaf) and
+ node.children[0].value == '[')
+ or
+ (len(node.children)>1 and
+ hasattr(node.children[1], "value") and
+ node.children[1].value == '[')):
+ #skip whole unit if its optional
+ return None
+
+ leaf = True
+ details_node = None
+ alternatives_node = None
+ has_repeater = False
+ repeater_node = None
+ has_variable_name = False
+
+ for child in node.children:
+ if child.type == syms.Details:
+ leaf = False
+ details_node = child
+ elif child.type == syms.Repeater:
+ has_repeater = True
+ repeater_node = child
+ elif child.type == syms.Alternatives:
+ alternatives_node = child
+ if hasattr(child, 'value') and child.value == '=': # variable name
+ has_variable_name = True
+
+ #skip variable name
+ if has_variable_name:
+ #skip variable name, '='
+ name_leaf = node.children[2]
+ if hasattr(name_leaf, 'value') and name_leaf.value == '(':
+ # skip parenthesis
+ name_leaf = node.children[3]
+ else:
+ name_leaf = node.children[0]
+
+ #set node type
+ if name_leaf.type == token_labels.NAME:
+ #(python) non-name or wildcard
+ if name_leaf.value == 'any':
+ new_node = MinNode(type=TYPE_ANY)
+ else:
+ if hasattr(token_labels, name_leaf.value):
+ new_node = MinNode(type=getattr(token_labels, name_leaf.value))
+ else:
+ new_node = MinNode(type=getattr(pysyms, name_leaf.value))
+
+ elif name_leaf.type == token_labels.STRING:
+ #(python) name or character; remove the apostrophes from
+ #the string value
+ name = name_leaf.value.strip("'")
+ if name in tokens:
+ new_node = MinNode(type=tokens[name])
+ else:
+ new_node = MinNode(type=token_labels.NAME, name=name)
+ elif name_leaf.type == syms.Alternatives:
+ new_node = reduce_tree(alternatives_node, parent)
+
+ #handle repeaters
+ if has_repeater:
+ if repeater_node.children[0].value == '*':
+ #reduce to None
+ new_node = None
+ elif repeater_node.children[0].value == '+':
+ #reduce to a single occurence i.e. do nothing
+ pass
+ else:
+ #TODO: handle {min, max} repeaters
+ raise NotImplementedError
+ pass
+
+ #add children
+ if details_node and new_node is not None:
+ for child in details_node.children[1:-1]:
+ #skip '<', '>' markers
+ reduced = reduce_tree(child, new_node)
+ if reduced is not None:
+ new_node.children.append(reduced)
+ if new_node:
+ new_node.parent = parent
+ return new_node
+
+
+def get_characteristic_subpattern(subpatterns):
+ """Picks the most characteristic from a list of linear patterns
+ Current order used is:
+ names > common_names > common_chars
+ """
+ if not isinstance(subpatterns, list):
+ return subpatterns
+ if len(subpatterns)==1:
+ return subpatterns[0]
+
+ # first pick out the ones containing variable names
+ subpatterns_with_names = []
+ subpatterns_with_common_names = []
+ common_names = ['in', 'for', 'if' , 'not', 'None']
+ subpatterns_with_common_chars = []
+ common_chars = "[]().,:"
+ for subpattern in subpatterns:
+ if any(rec_test(subpattern, lambda x: type(x) is str)):
+ if any(rec_test(subpattern,
+ lambda x: isinstance(x, str) and x in common_chars)):
+ subpatterns_with_common_chars.append(subpattern)
+ elif any(rec_test(subpattern,
+ lambda x: isinstance(x, str) and x in common_names)):
+ subpatterns_with_common_names.append(subpattern)
+
+ else:
+ subpatterns_with_names.append(subpattern)
+
+ if subpatterns_with_names:
+ subpatterns = subpatterns_with_names
+ elif subpatterns_with_common_names:
+ subpatterns = subpatterns_with_common_names
+ elif subpatterns_with_common_chars:
+ subpatterns = subpatterns_with_common_chars
+ # of the remaining subpatterns pick out the longest one
+ return max(subpatterns, key=len)
+
+def rec_test(sequence, test_func):
+ """Tests test_func on all items of sequence and items of included
+ sub-iterables"""
+ for x in sequence:
+ if isinstance(x, (list, tuple)):
+ for y in rec_test(x, test_func):
+ yield y
+ else:
+ yield test_func(x)
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixer_base.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixer_base.py
new file mode 100644
index 000000000000..f6421ba3f74f
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixer_base.py
@@ -0,0 +1,189 @@
+# Copyright 2006 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Base class for fixers (optional, but recommended)."""
+
+# Python imports
+import logging
+import itertools
+
+# Local imports
+from .patcomp import PatternCompiler
+from . import pygram
+from .fixer_util import does_tree_import
+
+class BaseFix(object):
+
+ """Optional base class for fixers.
+
+ The subclass name must be FixFooBar where FooBar is the result of
+ removing underscores and capitalizing the words of the fix name.
+ For example, the class name for a fixer named 'has_key' should be
+ FixHasKey.
+ """
+
+ PATTERN = None # Most subclasses should override with a string literal
+ pattern = None # Compiled pattern, set by compile_pattern()
+ pattern_tree = None # Tree representation of the pattern
+ options = None # Options object passed to initializer
+ filename = None # The filename (set by set_filename)
+ logger = None # A logger (set by set_filename)
+ numbers = itertools.count(1) # For new_name()
+ used_names = set() # A set of all used NAMEs
+ order = "post" # Does the fixer prefer pre- or post-order traversal
+ explicit = False # Is this ignored by refactor.py -f all?
+ run_order = 5 # Fixers will be sorted by run order before execution
+ # Lower numbers will be run first.
+ _accept_type = None # [Advanced and not public] This tells RefactoringTool
+ # which node type to accept when there's not a pattern.
+
+ keep_line_order = False # For the bottom matcher: match with the
+ # original line order
+ BM_compatible = False # Compatibility with the bottom matching
+ # module; every fixer should set this
+ # manually
+
+ # Shortcut for access to Python grammar symbols
+ syms = pygram.python_symbols
+
+ def __init__(self, options, log):
+ """Initializer. Subclass may override.
+
+ Args:
+ options: an dict containing the options passed to RefactoringTool
+ that could be used to customize the fixer through the command line.
+ log: a list to append warnings and other messages to.
+ """
+ self.options = options
+ self.log = log
+ self.compile_pattern()
+
+ def compile_pattern(self):
+ """Compiles self.PATTERN into self.pattern.
+
+ Subclass may override if it doesn't want to use
+ self.{pattern,PATTERN} in .match().
+ """
+ if self.PATTERN is not None:
+ PC = PatternCompiler()
+ self.pattern, self.pattern_tree = PC.compile_pattern(self.PATTERN,
+ with_tree=True)
+
+ def set_filename(self, filename):
+ """Set the filename, and a logger derived from it.
+
+ The main refactoring tool should call this.
+ """
+ self.filename = filename
+ self.logger = logging.getLogger(filename)
+
+ def match(self, node):
+ """Returns match for a given parse tree node.
+
+ Should return a true or false object (not necessarily a bool).
+ It may return a non-empty dict of matching sub-nodes as
+ returned by a matching pattern.
+
+ Subclass may override.
+ """
+ results = {"node": node}
+ return self.pattern.match(node, results) and results
+
+ def transform(self, node, results):
+ """Returns the transformation for a given parse tree node.
+
+ Args:
+ node: the root of the parse tree that matched the fixer.
+ results: a dict mapping symbolic names to part of the match.
+
+ Returns:
+ None, or a node that is a modified copy of the
+ argument node. The node argument may also be modified in-place to
+ effect the same change.
+
+ Subclass *must* override.
+ """
+ raise NotImplementedError()
+
+ def new_name(self, template=u"xxx_todo_changeme"):
+ """Return a string suitable for use as an identifier
+
+ The new name is guaranteed not to conflict with other identifiers.
+ """
+ name = template
+ while name in self.used_names:
+ name = template + unicode(self.numbers.next())
+ self.used_names.add(name)
+ return name
+
+ def log_message(self, message):
+ if self.first_log:
+ self.first_log = False
+ self.log.append("### In file %s ###" % self.filename)
+ self.log.append(message)
+
+ def cannot_convert(self, node, reason=None):
+ """Warn the user that a given chunk of code is not valid Python 3,
+ but that it cannot be converted automatically.
+
+ First argument is the top-level node for the code in question.
+ Optional second argument is why it can't be converted.
+ """
+ lineno = node.get_lineno()
+ for_output = node.clone()
+ for_output.prefix = u""
+ msg = "Line %d: could not convert: %s"
+ self.log_message(msg % (lineno, for_output))
+ if reason:
+ self.log_message(reason)
+
+ def warning(self, node, reason):
+ """Used for warning the user about possible uncertainty in the
+ translation.
+
+ First argument is the top-level node for the code in question.
+ Optional second argument is why it can't be converted.
+ """
+ lineno = node.get_lineno()
+ self.log_message("Line %d: %s" % (lineno, reason))
+
+ def start_tree(self, tree, filename):
+ """Some fixers need to maintain tree-wide state.
+ This method is called once, at the start of tree fix-up.
+
+ tree - the root node of the tree to be processed.
+ filename - the name of the file the tree came from.
+ """
+ self.used_names = tree.used_names
+ self.set_filename(filename)
+ self.numbers = itertools.count(1)
+ self.first_log = True
+
+ def finish_tree(self, tree, filename):
+ """Some fixers need to maintain tree-wide state.
+ This method is called once, at the conclusion of tree fix-up.
+
+ tree - the root node of the tree to be processed.
+ filename - the name of the file the tree came from.
+ """
+ pass
+
+
+class ConditionalFix(BaseFix):
+ """ Base class for fixers which not execute if an import is found. """
+
+ # This is the name of the import which, if found, will cause the test to be skipped
+ skip_on = None
+
+ def start_tree(self, *args):
+ super(ConditionalFix, self).start_tree(*args)
+ self._should_skip = None
+
+ def should_skip(self, node):
+ if self._should_skip is not None:
+ return self._should_skip
+ pkg = self.skip_on.split(".")
+ name = pkg[-1]
+ pkg = ".".join(pkg[:-1])
+ self._should_skip = does_tree_import(pkg, name, node)
+ return self._should_skip
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixer_util.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixer_util.py
new file mode 100644
index 000000000000..78fdf26dce4c
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixer_util.py
@@ -0,0 +1,432 @@
+"""Utility functions, node construction macros, etc."""
+# Author: Collin Winter
+
+from itertools import islice
+
+# Local imports
+from .pgen2 import token
+from .pytree import Leaf, Node
+from .pygram import python_symbols as syms
+from . import patcomp
+
+
+###########################################################
+### Common node-construction "macros"
+###########################################################
+
+def KeywordArg(keyword, value):
+ return Node(syms.argument,
+ [keyword, Leaf(token.EQUAL, u"="), value])
+
+def LParen():
+ return Leaf(token.LPAR, u"(")
+
+def RParen():
+ return Leaf(token.RPAR, u")")
+
+def Assign(target, source):
+ """Build an assignment statement"""
+ if not isinstance(target, list):
+ target = [target]
+ if not isinstance(source, list):
+ source.prefix = u" "
+ source = [source]
+
+ return Node(syms.atom,
+ target + [Leaf(token.EQUAL, u"=", prefix=u" ")] + source)
+
+def Name(name, prefix=None):
+ """Return a NAME leaf"""
+ return Leaf(token.NAME, name, prefix=prefix)
+
+def Attr(obj, attr):
+ """A node tuple for obj.attr"""
+ return [obj, Node(syms.trailer, [Dot(), attr])]
+
+def Comma():
+ """A comma leaf"""
+ return Leaf(token.COMMA, u",")
+
+def Dot():
+ """A period (.) leaf"""
+ return Leaf(token.DOT, u".")
+
+def ArgList(args, lparen=LParen(), rparen=RParen()):
+ """A parenthesised argument list, used by Call()"""
+ node = Node(syms.trailer, [lparen.clone(), rparen.clone()])
+ if args:
+ node.insert_child(1, Node(syms.arglist, args))
+ return node
+
+def Call(func_name, args=None, prefix=None):
+ """A function call"""
+ node = Node(syms.power, [func_name, ArgList(args)])
+ if prefix is not None:
+ node.prefix = prefix
+ return node
+
+def Newline():
+ """A newline literal"""
+ return Leaf(token.NEWLINE, u"\n")
+
+def BlankLine():
+ """A blank line"""
+ return Leaf(token.NEWLINE, u"")
+
+def Number(n, prefix=None):
+ return Leaf(token.NUMBER, n, prefix=prefix)
+
+def Subscript(index_node):
+ """A numeric or string subscript"""
+ return Node(syms.trailer, [Leaf(token.LBRACE, u"["),
+ index_node,
+ Leaf(token.RBRACE, u"]")])
+
+def String(string, prefix=None):
+ """A string leaf"""
+ return Leaf(token.STRING, string, prefix=prefix)
+
+def ListComp(xp, fp, it, test=None):
+ """A list comprehension of the form [xp for fp in it if test].
+
+ If test is None, the "if test" part is omitted.
+ """
+ xp.prefix = u""
+ fp.prefix = u" "
+ it.prefix = u" "
+ for_leaf = Leaf(token.NAME, u"for")
+ for_leaf.prefix = u" "
+ in_leaf = Leaf(token.NAME, u"in")
+ in_leaf.prefix = u" "
+ inner_args = [for_leaf, fp, in_leaf, it]
+ if test:
+ test.prefix = u" "
+ if_leaf = Leaf(token.NAME, u"if")
+ if_leaf.prefix = u" "
+ inner_args.append(Node(syms.comp_if, [if_leaf, test]))
+ inner = Node(syms.listmaker, [xp, Node(syms.comp_for, inner_args)])
+ return Node(syms.atom,
+ [Leaf(token.LBRACE, u"["),
+ inner,
+ Leaf(token.RBRACE, u"]")])
+
+def FromImport(package_name, name_leafs):
+ """ Return an import statement in the form:
+ from package import name_leafs"""
+ # XXX: May not handle dotted imports properly (eg, package_name='foo.bar')
+ #assert package_name == '.' or '.' not in package_name, "FromImport has "\
+ # "not been tested with dotted package names -- use at your own "\
+ # "peril!"
+
+ for leaf in name_leafs:
+ # Pull the leaves out of their old tree
+ leaf.remove()
+
+ children = [Leaf(token.NAME, u"from"),
+ Leaf(token.NAME, package_name, prefix=u" "),
+ Leaf(token.NAME, u"import", prefix=u" "),
+ Node(syms.import_as_names, name_leafs)]
+ imp = Node(syms.import_from, children)
+ return imp
+
+
+###########################################################
+### Determine whether a node represents a given literal
+###########################################################
+
+def is_tuple(node):
+ """Does the node represent a tuple literal?"""
+ if isinstance(node, Node) and node.children == [LParen(), RParen()]:
+ return True
+ return (isinstance(node, Node)
+ and len(node.children) == 3
+ and isinstance(node.children[0], Leaf)
+ and isinstance(node.children[1], Node)
+ and isinstance(node.children[2], Leaf)
+ and node.children[0].value == u"("
+ and node.children[2].value == u")")
+
+def is_list(node):
+ """Does the node represent a list literal?"""
+ return (isinstance(node, Node)
+ and len(node.children) > 1
+ and isinstance(node.children[0], Leaf)
+ and isinstance(node.children[-1], Leaf)
+ and node.children[0].value == u"["
+ and node.children[-1].value == u"]")
+
+
+###########################################################
+### Misc
+###########################################################
+
+def parenthesize(node):
+ return Node(syms.atom, [LParen(), node, RParen()])
+
+
+consuming_calls = set(["sorted", "list", "set", "any", "all", "tuple", "sum",
+ "min", "max", "enumerate"])
+
+def attr_chain(obj, attr):
+ """Follow an attribute chain.
+
+ If you have a chain of objects where a.foo -> b, b.foo-> c, etc,
+ use this to iterate over all objects in the chain. Iteration is
+ terminated by getattr(x, attr) is None.
+
+ Args:
+ obj: the starting object
+ attr: the name of the chaining attribute
+
+ Yields:
+ Each successive object in the chain.
+ """
+ next = getattr(obj, attr)
+ while next:
+ yield next
+ next = getattr(next, attr)
+
+p0 = """for_stmt< 'for' any 'in' node=any ':' any* >
+ | comp_for< 'for' any 'in' node=any any* >
+ """
+p1 = """
+power<
+ ( 'iter' | 'list' | 'tuple' | 'sorted' | 'set' | 'sum' |
+ 'any' | 'all' | 'enumerate' | (any* trailer< '.' 'join' >) )
+ trailer< '(' node=any ')' >
+ any*
+>
+"""
+p2 = """
+power<
+ ( 'sorted' | 'enumerate' )
+ trailer< '(' arglist<node=any any*> ')' >
+ any*
+>
+"""
+pats_built = False
+def in_special_context(node):
+ """ Returns true if node is in an environment where all that is required
+ of it is being iterable (ie, it doesn't matter if it returns a list
+ or an iterator).
+ See test_map_nochange in test_fixers.py for some examples and tests.
+ """
+ global p0, p1, p2, pats_built
+ if not pats_built:
+ p0 = patcomp.compile_pattern(p0)
+ p1 = patcomp.compile_pattern(p1)
+ p2 = patcomp.compile_pattern(p2)
+ pats_built = True
+ patterns = [p0, p1, p2]
+ for pattern, parent in zip(patterns, attr_chain(node, "parent")):
+ results = {}
+ if pattern.match(parent, results) and results["node"] is node:
+ return True
+ return False
+
+def is_probably_builtin(node):
+ """
+ Check that something isn't an attribute or function name etc.
+ """
+ prev = node.prev_sibling
+ if prev is not None and prev.type == token.DOT:
+ # Attribute lookup.
+ return False
+ parent = node.parent
+ if parent.type in (syms.funcdef, syms.classdef):
+ return False
+ if parent.type == syms.expr_stmt and parent.children[0] is node:
+ # Assignment.
+ return False
+ if parent.type == syms.parameters or \
+ (parent.type == syms.typedargslist and (
+ (prev is not None and prev.type == token.COMMA) or
+ parent.children[0] is node
+ )):
+ # The name of an argument.
+ return False
+ return True
+
+def find_indentation(node):
+ """Find the indentation of *node*."""
+ while node is not None:
+ if node.type == syms.suite and len(node.children) > 2:
+ indent = node.children[1]
+ if indent.type == token.INDENT:
+ return indent.value
+ node = node.parent
+ return u""
+
+###########################################################
+### The following functions are to find bindings in a suite
+###########################################################
+
+def make_suite(node):
+ if node.type == syms.suite:
+ return node
+ node = node.clone()
+ parent, node.parent = node.parent, None
+ suite = Node(syms.suite, [node])
+ suite.parent = parent
+ return suite
+
+def find_root(node):
+ """Find the top level namespace."""
+ # Scamper up to the top level namespace
+ while node.type != syms.file_input:
+ node = node.parent
+ if not node:
+ raise ValueError("root found before file_input node was found.")
+ return node
+
+def does_tree_import(package, name, node):
+ """ Returns true if name is imported from package at the
+ top level of the tree which node belongs to.
+ To cover the case of an import like 'import foo', use
+ None for the package and 'foo' for the name. """
+ binding = find_binding(name, find_root(node), package)
+ return bool(binding)
+
+def is_import(node):
+ """Returns true if the node is an import statement."""
+ return node.type in (syms.import_name, syms.import_from)
+
+def touch_import(package, name, node):
+ """ Works like `does_tree_import` but adds an import statement
+ if it was not imported. """
+ def is_import_stmt(node):
+ return (node.type == syms.simple_stmt and node.children and
+ is_import(node.children[0]))
+
+ root = find_root(node)
+
+ if does_tree_import(package, name, root):
+ return
+
+ # figure out where to insert the new import. First try to find
+ # the first import and then skip to the last one.
+ insert_pos = offset = 0
+ for idx, node in enumerate(root.children):
+ if not is_import_stmt(node):
+ continue
+ for offset, node2 in enumerate(root.children[idx:]):
+ if not is_import_stmt(node2):
+ break
+ insert_pos = idx + offset
+ break
+
+ # if there are no imports where we can insert, find the docstring.
+ # if that also fails, we stick to the beginning of the file
+ if insert_pos == 0:
+ for idx, node in enumerate(root.children):
+ if (node.type == syms.simple_stmt and node.children and
+ node.children[0].type == token.STRING):
+ insert_pos = idx + 1
+ break
+
+ if package is None:
+ import_ = Node(syms.import_name, [
+ Leaf(token.NAME, u"import"),
+ Leaf(token.NAME, name, prefix=u" ")
+ ])
+ else:
+ import_ = FromImport(package, [Leaf(token.NAME, name, prefix=u" ")])
+
+ children = [import_, Newline()]
+ root.insert_child(insert_pos, Node(syms.simple_stmt, children))
+
+
+_def_syms = set([syms.classdef, syms.funcdef])
+def find_binding(name, node, package=None):
+ """ Returns the node which binds variable name, otherwise None.
+ If optional argument package is supplied, only imports will
+ be returned.
+ See test cases for examples."""
+ for child in node.children:
+ ret = None
+ if child.type == syms.for_stmt:
+ if _find(name, child.children[1]):
+ return child
+ n = find_binding(name, make_suite(child.children[-1]), package)
+ if n: ret = n
+ elif child.type in (syms.if_stmt, syms.while_stmt):
+ n = find_binding(name, make_suite(child.children[-1]), package)
+ if n: ret = n
+ elif child.type == syms.try_stmt:
+ n = find_binding(name, make_suite(child.children[2]), package)
+ if n:
+ ret = n
+ else:
+ for i, kid in enumerate(child.children[3:]):
+ if kid.type == token.COLON and kid.value == ":":
+ # i+3 is the colon, i+4 is the suite
+ n = find_binding(name, make_suite(child.children[i+4]), package)
+ if n: ret = n
+ elif child.type in _def_syms and child.children[1].value == name:
+ ret = child
+ elif _is_import_binding(child, name, package):
+ ret = child
+ elif child.type == syms.simple_stmt:
+ ret = find_binding(name, child, package)
+ elif child.type == syms.expr_stmt:
+ if _find(name, child.children[0]):
+ ret = child
+
+ if ret:
+ if not package:
+ return ret
+ if is_import(ret):
+ return ret
+ return None
+
+_block_syms = set([syms.funcdef, syms.classdef, syms.trailer])
+def _find(name, node):
+ nodes = [node]
+ while nodes:
+ node = nodes.pop()
+ if node.type > 256 and node.type not in _block_syms:
+ nodes.extend(node.children)
+ elif node.type == token.NAME and node.value == name:
+ return node
+ return None
+
+def _is_import_binding(node, name, package=None):
+ """ Will reuturn node if node will import name, or node
+ will import * from package. None is returned otherwise.
+ See test cases for examples. """
+
+ if node.type == syms.import_name and not package:
+ imp = node.children[1]
+ if imp.type == syms.dotted_as_names:
+ for child in imp.children:
+ if child.type == syms.dotted_as_name:
+ if child.children[2].value == name:
+ return node
+ elif child.type == token.NAME and child.value == name:
+ return node
+ elif imp.type == syms.dotted_as_name:
+ last = imp.children[-1]
+ if last.type == token.NAME and last.value == name:
+ return node
+ elif imp.type == token.NAME and imp.value == name:
+ return node
+ elif node.type == syms.import_from:
+ # unicode(...) is used to make life easier here, because
+ # from a.b import parses to ['import', ['a', '.', 'b'], ...]
+ if package and unicode(node.children[1]).strip() != package:
+ return None
+ n = node.children[3]
+ if package and _find(u"as", n):
+ # See test_from_import_as for explanation
+ return None
+ elif n.type == syms.import_as_names and _find(name, n):
+ return node
+ elif n.type == syms.import_as_name:
+ child = n.children[2]
+ if child.type == token.NAME and child.value == name:
+ return node
+ elif n.type == token.NAME and n.value == name:
+ return node
+ elif package and n.type == token.STAR:
+ return node
+ return None
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/__init__.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/__init__.py
new file mode 100644
index 000000000000..b93054b3ecf3
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/__init__.py
@@ -0,0 +1 @@
+# Dummy file to make this directory a package.
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_apply.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_apply.py
new file mode 100644
index 000000000000..a7dc3a046d8f
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_apply.py
@@ -0,0 +1,59 @@
+# Copyright 2006 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer for apply().
+
+This converts apply(func, v, k) into (func)(*v, **k)."""
+
+# Local imports
+from .. import pytree
+from ..pgen2 import token
+from .. import fixer_base
+from ..fixer_util import Call, Comma, parenthesize
+
+class FixApply(fixer_base.BaseFix):
+ BM_compatible = True
+
+ PATTERN = """
+ power< 'apply'
+ trailer<
+ '('
+ arglist<
+ (not argument<NAME '=' any>) func=any ','
+ (not argument<NAME '=' any>) args=any [','
+ (not argument<NAME '=' any>) kwds=any] [',']
+ >
+ ')'
+ >
+ >
+ """
+
+ def transform(self, node, results):
+ syms = self.syms
+ assert results
+ func = results["func"]
+ args = results["args"]
+ kwds = results.get("kwds")
+ prefix = node.prefix
+ func = func.clone()
+ if (func.type not in (token.NAME, syms.atom) and
+ (func.type != syms.power or
+ func.children[-2].type == token.DOUBLESTAR)):
+ # Need to parenthesize
+ func = parenthesize(func)
+ func.prefix = ""
+ args = args.clone()
+ args.prefix = ""
+ if kwds is not None:
+ kwds = kwds.clone()
+ kwds.prefix = ""
+ l_newargs = [pytree.Leaf(token.STAR, u"*"), args]
+ if kwds is not None:
+ l_newargs.extend([Comma(),
+ pytree.Leaf(token.DOUBLESTAR, u"**"),
+ kwds])
+ l_newargs[-2].prefix = u" " # that's the ** token
+ # XXX Sometimes we could be cleverer, e.g. apply(f, (x, y) + t)
+ # can be translated into f(x, y, *t) instead of f(*(x, y) + t)
+ #new = pytree.Node(syms.power, (func, ArgList(l_newargs)))
+ return Call(func, l_newargs, prefix=prefix)
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_basestring.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_basestring.py
new file mode 100644
index 000000000000..a3c9a436492e
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_basestring.py
@@ -0,0 +1,14 @@
+"""Fixer for basestring -> str."""
+# Author: Christian Heimes
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Name
+
+class FixBasestring(fixer_base.BaseFix):
+ BM_compatible = True
+
+ PATTERN = "'basestring'"
+
+ def transform(self, node, results):
+ return Name(u"str", prefix=node.prefix)
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_buffer.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_buffer.py
new file mode 100644
index 000000000000..c6b092802480
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_buffer.py
@@ -0,0 +1,22 @@
+# Copyright 2007 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer that changes buffer(...) into memoryview(...)."""
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Name
+
+
+class FixBuffer(fixer_base.BaseFix):
+ BM_compatible = True
+
+ explicit = True # The user must ask for this fixer
+
+ PATTERN = """
+ power< name='buffer' trailer< '(' [any] ')' > any* >
+ """
+
+ def transform(self, node, results):
+ name = results["name"]
+ name.replace(Name(u"memoryview", prefix=name.prefix))
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_callable.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_callable.py
new file mode 100644
index 000000000000..df33d614ba1b
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_callable.py
@@ -0,0 +1,37 @@
+# Copyright 2007 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer for callable().
+
+This converts callable(obj) into isinstance(obj, collections.Callable), adding a
+collections import if needed."""
+
+# Local imports
+from lib2to3 import fixer_base
+from lib2to3.fixer_util import Call, Name, String, Attr, touch_import
+
+class FixCallable(fixer_base.BaseFix):
+ BM_compatible = True
+
+ order = "pre"
+
+ # Ignore callable(*args) or use of keywords.
+ # Either could be a hint that the builtin callable() is not being used.
+ PATTERN = """
+ power< 'callable'
+ trailer< lpar='('
+ ( not(arglist | argument<any '=' any>) func=any
+ | func=arglist<(not argument<any '=' any>) any ','> )
+ rpar=')' >
+ after=any*
+ >
+ """
+
+ def transform(self, node, results):
+ func = results['func']
+
+ touch_import(None, u'collections', node=node)
+
+ args = [func.clone(), String(u', ')]
+ args.extend(Attr(Name(u'collections'), Name(u'Callable')))
+ return Call(Name(u'isinstance'), args, prefix=node.prefix)
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_dict.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_dict.py
new file mode 100644
index 000000000000..f681e4d71324
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_dict.py
@@ -0,0 +1,107 @@
+# Copyright 2007 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer for dict methods.
+
+d.keys() -> list(d.keys())
+d.items() -> list(d.items())
+d.values() -> list(d.values())
+
+d.iterkeys() -> iter(d.keys())
+d.iteritems() -> iter(d.items())
+d.itervalues() -> iter(d.values())
+
+d.viewkeys() -> d.keys()
+d.viewitems() -> d.items()
+d.viewvalues() -> d.values()
+
+Except in certain very specific contexts: the iter() can be dropped
+when the context is list(), sorted(), iter() or for...in; the list()
+can be dropped when the context is list() or sorted() (but not iter()
+or for...in!). Special contexts that apply to both: list(), sorted(), tuple()
+set(), any(), all(), sum().
+
+Note: iter(d.keys()) could be written as iter(d) but since the
+original d.iterkeys() was also redundant we don't fix this. And there
+are (rare) contexts where it makes a difference (e.g. when passing it
+as an argument to a function that introspects the argument).
+"""
+
+# Local imports
+from .. import pytree
+from .. import patcomp
+from ..pgen2 import token
+from .. import fixer_base
+from ..fixer_util import Name, Call, LParen, RParen, ArgList, Dot
+from .. import fixer_util
+
+
+iter_exempt = fixer_util.consuming_calls | set(["iter"])
+
+
+class FixDict(fixer_base.BaseFix):
+ BM_compatible = True
+
+ PATTERN = """
+ power< head=any+
+ trailer< '.' method=('keys'|'items'|'values'|
+ 'iterkeys'|'iteritems'|'itervalues'|
+ 'viewkeys'|'viewitems'|'viewvalues') >
+ parens=trailer< '(' ')' >
+ tail=any*
+ >
+ """
+
+ def transform(self, node, results):
+ head = results["head"]
+ method = results["method"][0] # Extract node for method name
+ tail = results["tail"]
+ syms = self.syms
+ method_name = method.value
+ isiter = method_name.startswith(u"iter")
+ isview = method_name.startswith(u"view")
+ if isiter or isview:
+ method_name = method_name[4:]
+ assert method_name in (u"keys", u"items", u"values"), repr(method)
+ head = [n.clone() for n in head]
+ tail = [n.clone() for n in tail]
+ special = not tail and self.in_special_context(node, isiter)
+ args = head + [pytree.Node(syms.trailer,
+ [Dot(),
+ Name(method_name,
+ prefix=method.prefix)]),
+ results["parens"].clone()]
+ new = pytree.Node(syms.power, args)
+ if not (special or isview):
+ new.prefix = u""
+ new = Call(Name(u"iter" if isiter else u"list"), [new])
+ if tail:
+ new = pytree.Node(syms.power, [new] + tail)
+ new.prefix = node.prefix
+ return new
+
+ P1 = "power< func=NAME trailer< '(' node=any ')' > any* >"
+ p1 = patcomp.compile_pattern(P1)
+
+ P2 = """for_stmt< 'for' any 'in' node=any ':' any* >
+ | comp_for< 'for' any 'in' node=any any* >
+ """
+ p2 = patcomp.compile_pattern(P2)
+
+ def in_special_context(self, node, isiter):
+ if node.parent is None:
+ return False
+ results = {}
+ if (node.parent.parent is not None and
+ self.p1.match(node.parent.parent, results) and
+ results["node"] is node):
+ if isiter:
+ # iter(d.iterkeys()) -> iter(d.keys()), etc.
+ return results["func"].value in iter_exempt
+ else:
+ # list(d.keys()) -> list(d.keys()), etc.
+ return results["func"].value in fixer_util.consuming_calls
+ if not isiter:
+ return False
+ # for ... in d.iterkeys() -> for ... in d.keys(), etc.
+ return self.p2.match(node.parent, results) and results["node"] is node
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_except.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_except.py
new file mode 100644
index 000000000000..e324718f6490
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_except.py
@@ -0,0 +1,93 @@
+"""Fixer for except statements with named exceptions.
+
+The following cases will be converted:
+
+- "except E, T:" where T is a name:
+
+ except E as T:
+
+- "except E, T:" where T is not a name, tuple or list:
+
+ except E as t:
+ T = t
+
+ This is done because the target of an "except" clause must be a
+ name.
+
+- "except E, T:" where T is a tuple or list literal:
+
+ except E as t:
+ T = t.args
+"""
+# Author: Collin Winter
+
+# Local imports
+from .. import pytree
+from ..pgen2 import token
+from .. import fixer_base
+from ..fixer_util import Assign, Attr, Name, is_tuple, is_list, syms
+
+def find_excepts(nodes):
+ for i, n in enumerate(nodes):
+ if n.type == syms.except_clause:
+ if n.children[0].value == u'except':
+ yield (n, nodes[i+2])
+
+class FixExcept(fixer_base.BaseFix):
+ BM_compatible = True
+
+ PATTERN = """
+ try_stmt< 'try' ':' (simple_stmt | suite)
+ cleanup=(except_clause ':' (simple_stmt | suite))+
+ tail=(['except' ':' (simple_stmt | suite)]
+ ['else' ':' (simple_stmt | suite)]
+ ['finally' ':' (simple_stmt | suite)]) >
+ """
+
+ def transform(self, node, results):
+ syms = self.syms
+
+ tail = [n.clone() for n in results["tail"]]
+
+ try_cleanup = [ch.clone() for ch in results["cleanup"]]
+ for except_clause, e_suite in find_excepts(try_cleanup):
+ if len(except_clause.children) == 4:
+ (E, comma, N) = except_clause.children[1:4]
+ comma.replace(Name(u"as", prefix=u" "))
+
+ if N.type != token.NAME:
+ # Generate a new N for the except clause
+ new_N = Name(self.new_name(), prefix=u" ")
+ target = N.clone()
+ target.prefix = u""
+ N.replace(new_N)
+ new_N = new_N.clone()
+
+ # Insert "old_N = new_N" as the first statement in
+ # the except body. This loop skips leading whitespace
+ # and indents
+ #TODO(cwinter) suite-cleanup
+ suite_stmts = e_suite.children
+ for i, stmt in enumerate(suite_stmts):
+ if isinstance(stmt, pytree.Node):
+ break
+
+ # The assignment is different if old_N is a tuple or list
+ # In that case, the assignment is old_N = new_N.args
+ if is_tuple(N) or is_list(N):
+ assign = Assign(target, Attr(new_N, Name(u'args')))
+ else:
+ assign = Assign(target, new_N)
+
+ #TODO(cwinter) stopgap until children becomes a smart list
+ for child in reversed(suite_stmts[:i]):
+ e_suite.insert_child(0, child)
+ e_suite.insert_child(i, assign)
+ elif N.prefix == u"":
+ # No space after a comma is legal; no space after "as",
+ # not so much.
+ N.prefix = u" "
+
+ #TODO(cwinter) fix this when children becomes a smart list
+ children = [c.clone() for c in node.children[:3]] + try_cleanup + tail
+ return pytree.Node(node.type, children)
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_exec.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_exec.py
new file mode 100644
index 000000000000..50e185445453
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_exec.py
@@ -0,0 +1,40 @@
+# Copyright 2006 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer for exec.
+
+This converts usages of the exec statement into calls to a built-in
+exec() function.
+
+exec code in ns1, ns2 -> exec(code, ns1, ns2)
+"""
+
+# Local imports
+from .. import pytree
+from .. import fixer_base
+from ..fixer_util import Comma, Name, Call
+
+
+class FixExec(fixer_base.BaseFix):
+ BM_compatible = True
+
+ PATTERN = """
+ exec_stmt< 'exec' a=any 'in' b=any [',' c=any] >
+ |
+ exec_stmt< 'exec' (not atom<'(' [any] ')'>) a=any >
+ """
+
+ def transform(self, node, results):
+ assert results
+ syms = self.syms
+ a = results["a"]
+ b = results.get("b")
+ c = results.get("c")
+ args = [a.clone()]
+ args[0].prefix = ""
+ if b is not None:
+ args.extend([Comma(), b.clone()])
+ if c is not None:
+ args.extend([Comma(), c.clone()])
+
+ return Call(Name(u"exec"), args, prefix=node.prefix)
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_execfile.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_execfile.py
new file mode 100644
index 000000000000..2f29d3b281a9
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_execfile.py
@@ -0,0 +1,52 @@
+# Copyright 2006 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer for execfile.
+
+This converts usages of the execfile function into calls to the built-in
+exec() function.
+"""
+
+from .. import fixer_base
+from ..fixer_util import (Comma, Name, Call, LParen, RParen, Dot, Node,
+ ArgList, String, syms)
+
+
+class FixExecfile(fixer_base.BaseFix):
+ BM_compatible = True
+
+ PATTERN = """
+ power< 'execfile' trailer< '(' arglist< filename=any [',' globals=any [',' locals=any ] ] > ')' > >
+ |
+ power< 'execfile' trailer< '(' filename=any ')' > >
+ """
+
+ def transform(self, node, results):
+ assert results
+ filename = results["filename"]
+ globals = results.get("globals")
+ locals = results.get("locals")
+
+ # Copy over the prefix from the right parentheses end of the execfile
+ # call.
+ execfile_paren = node.children[-1].children[-1].clone()
+ # Construct open().read().
+ open_args = ArgList([filename.clone()], rparen=execfile_paren)
+ open_call = Node(syms.power, [Name(u"open"), open_args])
+ read = [Node(syms.trailer, [Dot(), Name(u'read')]),
+ Node(syms.trailer, [LParen(), RParen()])]
+ open_expr = [open_call] + read
+ # Wrap the open call in a compile call. This is so the filename will be
+ # preserved in the execed code.
+ filename_arg = filename.clone()
+ filename_arg.prefix = u" "
+ exec_str = String(u"'exec'", u" ")
+ compile_args = open_expr + [Comma(), filename_arg, Comma(), exec_str]
+ compile_call = Call(Name(u"compile"), compile_args, u"")
+ # Finally, replace the execfile call with an exec call.
+ args = [compile_call]
+ if globals is not None:
+ args.extend([Comma(), globals.clone()])
+ if locals is not None:
+ args.extend([Comma(), locals.clone()])
+ return Call(Name(u"exec"), args, prefix=node.prefix)
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_exitfunc.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_exitfunc.py
new file mode 100644
index 000000000000..89fb3db53367
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_exitfunc.py
@@ -0,0 +1,72 @@
+"""
+Convert use of sys.exitfunc to use the atexit module.
+"""
+
+# Author: Benjamin Peterson
+
+from lib2to3 import pytree, fixer_base
+from lib2to3.fixer_util import Name, Attr, Call, Comma, Newline, syms
+
+
+class FixExitfunc(fixer_base.BaseFix):
+ keep_line_order = True
+ BM_compatible = True
+
+ PATTERN = """
+ (
+ sys_import=import_name<'import'
+ ('sys'
+ |
+ dotted_as_names< (any ',')* 'sys' (',' any)* >
+ )
+ >
+ |
+ expr_stmt<
+ power< 'sys' trailer< '.' 'exitfunc' > >
+ '=' func=any >
+ )
+ """
+
+ def __init__(self, *args):
+ super(FixExitfunc, self).__init__(*args)
+
+ def start_tree(self, tree, filename):
+ super(FixExitfunc, self).start_tree(tree, filename)
+ self.sys_import = None
+
+ def transform(self, node, results):
+ # First, find a the sys import. We'll just hope it's global scope.
+ if "sys_import" in results:
+ if self.sys_import is None:
+ self.sys_import = results["sys_import"]
+ return
+
+ func = results["func"].clone()
+ func.prefix = u""
+ register = pytree.Node(syms.power,
+ Attr(Name(u"atexit"), Name(u"register"))
+ )
+ call = Call(register, [func], node.prefix)
+ node.replace(call)
+
+ if self.sys_import is None:
+ # That's interesting.
+ self.warning(node, "Can't find sys import; Please add an atexit "
+ "import at the top of your file.")
+ return
+
+ # Now add an atexit import after the sys import.
+ names = self.sys_import.children[1]
+ if names.type == syms.dotted_as_names:
+ names.append_child(Comma())
+ names.append_child(Name(u"atexit", u" "))
+ else:
+ containing_stmt = self.sys_import.parent
+ position = containing_stmt.children.index(self.sys_import)
+ stmt_container = containing_stmt.parent
+ new_import = pytree.Node(syms.import_name,
+ [Name(u"import"), Name(u"atexit", u" ")]
+ )
+ new = pytree.Node(syms.simple_stmt, [new_import])
+ containing_stmt.insert_child(position + 1, Newline())
+ containing_stmt.insert_child(position + 2, new)
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_filter.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_filter.py
new file mode 100644
index 000000000000..18ee2ffc0627
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_filter.py
@@ -0,0 +1,76 @@
+# Copyright 2007 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer that changes filter(F, X) into list(filter(F, X)).
+
+We avoid the transformation if the filter() call is directly contained
+in iter(<>), list(<>), tuple(<>), sorted(<>), ...join(<>), or
+for V in <>:.
+
+NOTE: This is still not correct if the original code was depending on
+filter(F, X) to return a string if X is a string and a tuple if X is a
+tuple. That would require type inference, which we don't do. Let
+Python 2.6 figure it out.
+"""
+
+# Local imports
+from ..pgen2 import token
+from .. import fixer_base
+from ..fixer_util import Name, Call, ListComp, in_special_context
+
+class FixFilter(fixer_base.ConditionalFix):
+ BM_compatible = True
+
+ PATTERN = """
+ filter_lambda=power<
+ 'filter'
+ trailer<
+ '('
+ arglist<
+ lambdef< 'lambda'
+ (fp=NAME | vfpdef< '(' fp=NAME ')'> ) ':' xp=any
+ >
+ ','
+ it=any
+ >
+ ')'
+ >
+ >
+ |
+ power<
+ 'filter'
+ trailer< '(' arglist< none='None' ',' seq=any > ')' >
+ >
+ |
+ power<
+ 'filter'
+ args=trailer< '(' [any] ')' >
+ >
+ """
+
+ skip_on = "future_builtins.filter"
+
+ def transform(self, node, results):
+ if self.should_skip(node):
+ return
+
+ if "filter_lambda" in results:
+ new = ListComp(results.get("fp").clone(),
+ results.get("fp").clone(),
+ results.get("it").clone(),
+ results.get("xp").clone())
+
+ elif "none" in results:
+ new = ListComp(Name(u"_f"),
+ Name(u"_f"),
+ results["seq"].clone(),
+ Name(u"_f"))
+
+ else:
+ if in_special_context(node):
+ return None
+ new = node.clone()
+ new.prefix = u""
+ new = Call(Name(u"list"), [new])
+ new.prefix = node.prefix
+ return new
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_funcattrs.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_funcattrs.py
new file mode 100644
index 000000000000..9e45c028574f
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_funcattrs.py
@@ -0,0 +1,21 @@
+"""Fix function attribute names (f.func_x -> f.__x__)."""
+# Author: Collin Winter
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Name
+
+
+class FixFuncattrs(fixer_base.BaseFix):
+ BM_compatible = True
+
+ PATTERN = """
+ power< any+ trailer< '.' attr=('func_closure' | 'func_doc' | 'func_globals'
+ | 'func_name' | 'func_defaults' | 'func_code'
+ | 'func_dict') > any* >
+ """
+
+ def transform(self, node, results):
+ attr = results["attr"][0]
+ attr.replace(Name((u"__%s__" % attr.value[5:]),
+ prefix=attr.prefix))
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_future.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_future.py
new file mode 100644
index 000000000000..fbcb86af0791
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_future.py
@@ -0,0 +1,22 @@
+"""Remove __future__ imports
+
+from __future__ import foo is replaced with an empty line.
+"""
+# Author: Christian Heimes
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import BlankLine
+
+class FixFuture(fixer_base.BaseFix):
+ BM_compatible = True
+
+ PATTERN = """import_from< 'from' module_name="__future__" 'import' any >"""
+
+ # This should be run last -- some things check for the import
+ run_order = 10
+
+ def transform(self, node, results):
+ new = BlankLine()
+ new.prefix = node.prefix
+ return new
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_getcwdu.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_getcwdu.py
new file mode 100644
index 000000000000..82233c8993b3
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_getcwdu.py
@@ -0,0 +1,19 @@
+"""
+Fixer that changes os.getcwdu() to os.getcwd().
+"""
+# Author: Victor Stinner
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Name
+
+class FixGetcwdu(fixer_base.BaseFix):
+ BM_compatible = True
+
+ PATTERN = """
+ power< 'os' trailer< dot='.' name='getcwdu' > any* >
+ """
+
+ def transform(self, node, results):
+ name = results["name"]
+ name.replace(Name(u"getcwd", prefix=name.prefix))
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_has_key.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_has_key.py
new file mode 100644
index 000000000000..bead4cb51cde
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_has_key.py
@@ -0,0 +1,110 @@
+# Copyright 2006 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer for has_key().
+
+Calls to .has_key() methods are expressed in terms of the 'in'
+operator:
+
+ d.has_key(k) -> k in d
+
+CAVEATS:
+1) While the primary target of this fixer is dict.has_key(), the
+ fixer will change any has_key() method call, regardless of its
+ class.
+
+2) Cases like this will not be converted:
+
+ m = d.has_key
+ if m(k):
+ ...
+
+ Only *calls* to has_key() are converted. While it is possible to
+ convert the above to something like
+
+ m = d.__contains__
+ if m(k):
+ ...
+
+ this is currently not done.
+"""
+
+# Local imports
+from .. import pytree
+from ..pgen2 import token
+from .. import fixer_base
+from ..fixer_util import Name, parenthesize
+
+
+class FixHasKey(fixer_base.BaseFix):
+ BM_compatible = True
+
+ PATTERN = """
+ anchor=power<
+ before=any+
+ trailer< '.' 'has_key' >
+ trailer<
+ '('
+ ( not(arglist | argument<any '=' any>) arg=any
+ | arglist<(not argument<any '=' any>) arg=any ','>
+ )
+ ')'
+ >
+ after=any*
+ >
+ |
+ negation=not_test<
+ 'not'
+ anchor=power<
+ before=any+
+ trailer< '.' 'has_key' >
+ trailer<
+ '('
+ ( not(arglist | argument<any '=' any>) arg=any
+ | arglist<(not argument<any '=' any>) arg=any ','>
+ )
+ ')'
+ >
+ >
+ >
+ """
+
+ def transform(self, node, results):
+ assert results
+ syms = self.syms
+ if (node.parent.type == syms.not_test and
+ self.pattern.match(node.parent)):
+ # Don't transform a node matching the first alternative of the
+ # pattern when its parent matches the second alternative
+ return None
+ negation = results.get("negation")
+ anchor = results["anchor"]
+ prefix = node.prefix
+ before = [n.clone() for n in results["before"]]
+ arg = results["arg"].clone()
+ after = results.get("after")
+ if after:
+ after = [n.clone() for n in after]
+ if arg.type in (syms.comparison, syms.not_test, syms.and_test,
+ syms.or_test, syms.test, syms.lambdef, syms.argument):
+ arg = parenthesize(arg)
+ if len(before) == 1:
+ before = before[0]
+ else:
+ before = pytree.Node(syms.power, before)
+ before.prefix = u" "
+ n_op = Name(u"in", prefix=u" ")
+ if negation:
+ n_not = Name(u"not", prefix=u" ")
+ n_op = pytree.Node(syms.comp_op, (n_not, n_op))
+ new = pytree.Node(syms.comparison, (arg, n_op, before))
+ if after:
+ new = parenthesize(new)
+ new = pytree.Node(syms.power, (new,) + tuple(after))
+ if node.parent.type in (syms.comparison, syms.expr, syms.xor_expr,
+ syms.and_expr, syms.shift_expr,
+ syms.arith_expr, syms.term,
+ syms.factor, syms.power):
+ new = parenthesize(new)
+ new.prefix = prefix
+ return new
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_idioms.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_idioms.py
new file mode 100644
index 000000000000..37b6eefa5134
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_idioms.py
@@ -0,0 +1,152 @@
+"""Adjust some old Python 2 idioms to their modern counterparts.
+
+* Change some type comparisons to isinstance() calls:
+ type(x) == T -> isinstance(x, T)
+ type(x) is T -> isinstance(x, T)
+ type(x) != T -> not isinstance(x, T)
+ type(x) is not T -> not isinstance(x, T)
+
+* Change "while 1:" into "while True:".
+
+* Change both
+
+ v = list(EXPR)
+ v.sort()
+ foo(v)
+
+and the more general
+
+ v = EXPR
+ v.sort()
+ foo(v)
+
+into
+
+ v = sorted(EXPR)
+ foo(v)
+"""
+# Author: Jacques Frechet, Collin Winter
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Call, Comma, Name, Node, BlankLine, syms
+
+CMP = "(n='!=' | '==' | 'is' | n=comp_op< 'is' 'not' >)"
+TYPE = "power< 'type' trailer< '(' x=any ')' > >"
+
+class FixIdioms(fixer_base.BaseFix):
+ explicit = True # The user must ask for this fixer
+
+ PATTERN = r"""
+ isinstance=comparison< %s %s T=any >
+ |
+ isinstance=comparison< T=any %s %s >
+ |
+ while_stmt< 'while' while='1' ':' any+ >
+ |
+ sorted=any<
+ any*
+ simple_stmt<
+ expr_stmt< id1=any '='
+ power< list='list' trailer< '(' (not arglist<any+>) any ')' > >
+ >
+ '\n'
+ >
+ sort=
+ simple_stmt<
+ power< id2=any
+ trailer< '.' 'sort' > trailer< '(' ')' >
+ >
+ '\n'
+ >
+ next=any*
+ >
+ |
+ sorted=any<
+ any*
+ simple_stmt< expr_stmt< id1=any '=' expr=any > '\n' >
+ sort=
+ simple_stmt<
+ power< id2=any
+ trailer< '.' 'sort' > trailer< '(' ')' >
+ >
+ '\n'
+ >
+ next=any*
+ >
+ """ % (TYPE, CMP, CMP, TYPE)
+
+ def match(self, node):
+ r = super(FixIdioms, self).match(node)
+ # If we've matched one of the sort/sorted subpatterns above, we
+ # want to reject matches where the initial assignment and the
+ # subsequent .sort() call involve different identifiers.
+ if r and "sorted" in r:
+ if r["id1"] == r["id2"]:
+ return r
+ return None
+ return r
+
+ def transform(self, node, results):
+ if "isinstance" in results:
+ return self.transform_isinstance(node, results)
+ elif "while" in results:
+ return self.transform_while(node, results)
+ elif "sorted" in results:
+ return self.transform_sort(node, results)
+ else:
+ raise RuntimeError("Invalid match")
+
+ def transform_isinstance(self, node, results):
+ x = results["x"].clone() # The thing inside of type()
+ T = results["T"].clone() # The type being compared against
+ x.prefix = u""
+ T.prefix = u" "
+ test = Call(Name(u"isinstance"), [x, Comma(), T])
+ if "n" in results:
+ test.prefix = u" "
+ test = Node(syms.not_test, [Name(u"not"), test])
+ test.prefix = node.prefix
+ return test
+
+ def transform_while(self, node, results):
+ one = results["while"]
+ one.replace(Name(u"True", prefix=one.prefix))
+
+ def transform_sort(self, node, results):
+ sort_stmt = results["sort"]
+ next_stmt = results["next"]
+ list_call = results.get("list")
+ simple_expr = results.get("expr")
+
+ if list_call:
+ list_call.replace(Name(u"sorted", prefix=list_call.prefix))
+ elif simple_expr:
+ new = simple_expr.clone()
+ new.prefix = u""
+ simple_expr.replace(Call(Name(u"sorted"), [new],
+ prefix=simple_expr.prefix))
+ else:
+ raise RuntimeError("should not have reached here")
+ sort_stmt.remove()
+
+ btwn = sort_stmt.prefix
+ # Keep any prefix lines between the sort_stmt and the list_call and
+ # shove them right after the sorted() call.
+ if u"\n" in btwn:
+ if next_stmt:
+ # The new prefix should be everything from the sort_stmt's
+ # prefix up to the last newline, then the old prefix after a new
+ # line.
+ prefix_lines = (btwn.rpartition(u"\n")[0], next_stmt[0].prefix)
+ next_stmt[0].prefix = u"\n".join(prefix_lines)
+ else:
+ assert list_call.parent
+ assert list_call.next_sibling is None
+ # Put a blank line after list_call and set its prefix.
+ end_line = BlankLine()
+ list_call.parent.append_child(end_line)
+ assert list_call.next_sibling is end_line
+ # The new prefix should be everything up to the first new line
+ # of sort_stmt's prefix.
+ end_line.prefix = btwn.rpartition(u"\n")[0]
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_import.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_import.py
new file mode 100644
index 000000000000..201e811e619a
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_import.py
@@ -0,0 +1,99 @@
+"""Fixer for import statements.
+If spam is being imported from the local directory, this import:
+ from spam import eggs
+Becomes:
+ from .spam import eggs
+
+And this import:
+ import spam
+Becomes:
+ from . import spam
+"""
+
+# Local imports
+from .. import fixer_base
+from os.path import dirname, join, exists, sep
+from ..fixer_util import FromImport, syms, token
+
+
+def traverse_imports(names):
+ """
+ Walks over all the names imported in a dotted_as_names node.
+ """
+ pending = [names]
+ while pending:
+ node = pending.pop()
+ if node.type == token.NAME:
+ yield node.value
+ elif node.type == syms.dotted_name:
+ yield "".join([ch.value for ch in node.children])
+ elif node.type == syms.dotted_as_name:
+ pending.append(node.children[0])
+ elif node.type == syms.dotted_as_names:
+ pending.extend(node.children[::-2])
+ else:
+ raise AssertionError("unkown node type")
+
+
+class FixImport(fixer_base.BaseFix):
+ BM_compatible = True
+
+ PATTERN = """
+ import_from< 'from' imp=any 'import' ['('] any [')'] >
+ |
+ import_name< 'import' imp=any >
+ """
+
+ def start_tree(self, tree, name):
+ super(FixImport, self).start_tree(tree, name)
+ self.skip = "absolute_import" in tree.future_features
+
+ def transform(self, node, results):
+ if self.skip:
+ return
+ imp = results['imp']
+
+ if node.type == syms.import_from:
+ # Some imps are top-level (eg: 'import ham')
+ # some are first level (eg: 'import ham.eggs')
+ # some are third level (eg: 'import ham.eggs as spam')
+ # Hence, the loop
+ while not hasattr(imp, 'value'):
+ imp = imp.children[0]
+ if self.probably_a_local_import(imp.value):
+ imp.value = u"." + imp.value
+ imp.changed()
+ else:
+ have_local = False
+ have_absolute = False
+ for mod_name in traverse_imports(imp):
+ if self.probably_a_local_import(mod_name):
+ have_local = True
+ else:
+ have_absolute = True
+ if have_absolute:
+ if have_local:
+ # We won't handle both sibling and absolute imports in the
+ # same statement at the moment.
+ self.warning(node, "absolute and local imports together")
+ return
+
+ new = FromImport(u".", [imp])
+ new.prefix = node.prefix
+ return new
+
+ def probably_a_local_import(self, imp_name):
+ if imp_name.startswith(u"."):
+ # Relative imports are certainly not local imports.
+ return False
+ imp_name = imp_name.split(u".", 1)[0]
+ base_path = dirname(self.filename)
+ base_path = join(base_path, imp_name)
+ # If there is no __init__.py next to the file its not in a package
+ # so can't be a relative import.
+ if not exists(join(dirname(base_path), "__init__.py")):
+ return False
+ for ext in [".py", sep, ".pyc", ".so", ".sl", ".pyd"]:
+ if exists(base_path + ext):
+ return True
+ return False
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_imports.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_imports.py
new file mode 100644
index 000000000000..93c9e6787b16
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_imports.py
@@ -0,0 +1,145 @@
+"""Fix incompatible imports and module references."""
+# Authors: Collin Winter, Nick Edds
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Name, attr_chain
+
+MAPPING = {'StringIO': 'io',
+ 'cStringIO': 'io',
+ 'cPickle': 'pickle',
+ '__builtin__' : 'builtins',
+ 'copy_reg': 'copyreg',
+ 'Queue': 'queue',
+ 'SocketServer': 'socketserver',
+ 'ConfigParser': 'configparser',
+ 'repr': 'reprlib',
+ 'FileDialog': 'tkinter.filedialog',
+ 'tkFileDialog': 'tkinter.filedialog',
+ 'SimpleDialog': 'tkinter.simpledialog',
+ 'tkSimpleDialog': 'tkinter.simpledialog',
+ 'tkColorChooser': 'tkinter.colorchooser',
+ 'tkCommonDialog': 'tkinter.commondialog',
+ 'Dialog': 'tkinter.dialog',
+ 'Tkdnd': 'tkinter.dnd',
+ 'tkFont': 'tkinter.font',
+ 'tkMessageBox': 'tkinter.messagebox',
+ 'ScrolledText': 'tkinter.scrolledtext',
+ 'Tkconstants': 'tkinter.constants',
+ 'Tix': 'tkinter.tix',
+ 'ttk': 'tkinter.ttk',
+ 'Tkinter': 'tkinter',
+ 'markupbase': '_markupbase',
+ '_winreg': 'winreg',
+ 'thread': '_thread',
+ 'dummy_thread': '_dummy_thread',
+ # anydbm and whichdb are handled by fix_imports2
+ 'dbhash': 'dbm.bsd',
+ 'dumbdbm': 'dbm.dumb',
+ 'dbm': 'dbm.ndbm',
+ 'gdbm': 'dbm.gnu',
+ 'xmlrpclib': 'xmlrpc.client',
+ 'DocXMLRPCServer': 'xmlrpc.server',
+ 'SimpleXMLRPCServer': 'xmlrpc.server',
+ 'httplib': 'http.client',
+ 'htmlentitydefs' : 'html.entities',
+ 'HTMLParser' : 'html.parser',
+ 'Cookie': 'http.cookies',
+ 'cookielib': 'http.cookiejar',
+ 'BaseHTTPServer': 'http.server',
+ 'SimpleHTTPServer': 'http.server',
+ 'CGIHTTPServer': 'http.server',
+ #'test.test_support': 'test.support',
+ 'commands': 'subprocess',
+ 'UserString' : 'collections',
+ 'UserList' : 'collections',
+ 'urlparse' : 'urllib.parse',
+ 'robotparser' : 'urllib.robotparser',
+}
+
+
+def alternates(members):
+ return "(" + "|".join(map(repr, members)) + ")"
+
+
+def build_pattern(mapping=MAPPING):
+ mod_list = ' | '.join(["module_name='%s'" % key for key in mapping])
+ bare_names = alternates(mapping.keys())
+
+ yield """name_import=import_name< 'import' ((%s) |
+ multiple_imports=dotted_as_names< any* (%s) any* >) >
+ """ % (mod_list, mod_list)
+ yield """import_from< 'from' (%s) 'import' ['(']
+ ( any | import_as_name< any 'as' any > |
+ import_as_names< any* >) [')'] >
+ """ % mod_list
+ yield """import_name< 'import' (dotted_as_name< (%s) 'as' any > |
+ multiple_imports=dotted_as_names<
+ any* dotted_as_name< (%s) 'as' any > any* >) >
+ """ % (mod_list, mod_list)
+
+ # Find usages of module members in code e.g. thread.foo(bar)
+ yield "power< bare_with_attr=(%s) trailer<'.' any > any* >" % bare_names
+
+
+class FixImports(fixer_base.BaseFix):
+
+ BM_compatible = True
+ keep_line_order = True
+ # This is overridden in fix_imports2.
+ mapping = MAPPING
+
+ # We want to run this fixer late, so fix_import doesn't try to make stdlib
+ # renames into relative imports.
+ run_order = 6
+
+ def build_pattern(self):
+ return "|".join(build_pattern(self.mapping))
+
+ def compile_pattern(self):
+ # We override this, so MAPPING can be pragmatically altered and the
+ # changes will be reflected in PATTERN.
+ self.PATTERN = self.build_pattern()
+ super(FixImports, self).compile_pattern()
+
+ # Don't match the node if it's within another match.
+ def match(self, node):
+ match = super(FixImports, self).match
+ results = match(node)
+ if results:
+ # Module usage could be in the trailer of an attribute lookup, so we
+ # might have nested matches when "bare_with_attr" is present.
+ if "bare_with_attr" not in results and \
+ any(match(obj) for obj in attr_chain(node, "parent")):
+ return False
+ return results
+ return False
+
+ def start_tree(self, tree, filename):
+ super(FixImports, self).start_tree(tree, filename)
+ self.replace = {}
+
+ def transform(self, node, results):
+ import_mod = results.get("module_name")
+ if import_mod:
+ mod_name = import_mod.value
+ new_name = unicode(self.mapping[mod_name])
+ import_mod.replace(Name(new_name, prefix=import_mod.prefix))
+ if "name_import" in results:
+ # If it's not a "from x import x, y" or "import x as y" import,
+ # marked its usage to be replaced.
+ self.replace[mod_name] = new_name
+ if "multiple_imports" in results:
+ # This is a nasty hack to fix multiple imports on a line (e.g.,
+ # "import StringIO, urlparse"). The problem is that I can't
+ # figure out an easy way to make a pattern recognize the keys of
+ # MAPPING randomly sprinkled in an import statement.
+ results = self.match(node)
+ if results:
+ self.transform(node, results)
+ else:
+ # Replace usage of the module.
+ bare_name = results["bare_with_attr"][0]
+ new_name = self.replace.get(bare_name.value)
+ if new_name:
+ bare_name.replace(Name(new_name, prefix=bare_name.prefix))
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_imports2.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_imports2.py
new file mode 100644
index 000000000000..9a33c67b1dc1
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_imports2.py
@@ -0,0 +1,16 @@
+"""Fix incompatible imports and module references that must be fixed after
+fix_imports."""
+from . import fix_imports
+
+
+MAPPING = {
+ 'whichdb': 'dbm',
+ 'anydbm': 'dbm',
+ }
+
+
+class FixImports2(fix_imports.FixImports):
+
+ run_order = 7
+
+ mapping = MAPPING
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_input.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_input.py
new file mode 100644
index 000000000000..fbf4c72f5c9d
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_input.py
@@ -0,0 +1,26 @@
+"""Fixer that changes input(...) into eval(input(...))."""
+# Author: Andre Roberge
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Call, Name
+from .. import patcomp
+
+
+context = patcomp.compile_pattern("power< 'eval' trailer< '(' any ')' > >")
+
+
+class FixInput(fixer_base.BaseFix):
+ BM_compatible = True
+ PATTERN = """
+ power< 'input' args=trailer< '(' [any] ')' > >
+ """
+
+ def transform(self, node, results):
+ # If we're already wrapped in a eval() call, we're done.
+ if context.match(node.parent.parent):
+ return
+
+ new = node.clone()
+ new.prefix = u""
+ return Call(Name(u"eval"), [new], prefix=node.prefix)
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_intern.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_intern.py
new file mode 100644
index 000000000000..e7bb5052b4b5
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_intern.py
@@ -0,0 +1,46 @@
+# Copyright 2006 Georg Brandl.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer for intern().
+
+intern(s) -> sys.intern(s)"""
+
+# Local imports
+from .. import pytree
+from .. import fixer_base
+from ..fixer_util import Name, Attr, touch_import
+
+
+class FixIntern(fixer_base.BaseFix):
+ BM_compatible = True
+ order = "pre"
+
+ PATTERN = """
+ power< 'intern'
+ trailer< lpar='('
+ ( not(arglist | argument<any '=' any>) obj=any
+ | obj=arglist<(not argument<any '=' any>) any ','> )
+ rpar=')' >
+ after=any*
+ >
+ """
+
+ def transform(self, node, results):
+ syms = self.syms
+ obj = results["obj"].clone()
+ if obj.type == syms.arglist:
+ newarglist = obj.clone()
+ else:
+ newarglist = pytree.Node(syms.arglist, [obj.clone()])
+ after = results["after"]
+ if after:
+ after = [n.clone() for n in after]
+ new = pytree.Node(syms.power,
+ Attr(Name(u"sys"), Name(u"intern")) +
+ [pytree.Node(syms.trailer,
+ [results["lpar"].clone(),
+ newarglist,
+ results["rpar"].clone()])] + after)
+ new.prefix = node.prefix
+ touch_import(None, u'sys', node)
+ return new
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_isinstance.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_isinstance.py
new file mode 100644
index 000000000000..4b04c8fd0c66
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_isinstance.py
@@ -0,0 +1,52 @@
+# Copyright 2008 Armin Ronacher.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer that cleans up a tuple argument to isinstance after the tokens
+in it were fixed. This is mainly used to remove double occurrences of
+tokens as a leftover of the long -> int / unicode -> str conversion.
+
+eg. isinstance(x, (int, long)) -> isinstance(x, (int, int))
+ -> isinstance(x, int)
+"""
+
+from .. import fixer_base
+from ..fixer_util import token
+
+
+class FixIsinstance(fixer_base.BaseFix):
+ BM_compatible = True
+ PATTERN = """
+ power<
+ 'isinstance'
+ trailer< '(' arglist< any ',' atom< '('
+ args=testlist_gexp< any+ >
+ ')' > > ')' >
+ >
+ """
+
+ run_order = 6
+
+ def transform(self, node, results):
+ names_inserted = set()
+ testlist = results["args"]
+ args = testlist.children
+ new_args = []
+ iterator = enumerate(args)
+ for idx, arg in iterator:
+ if arg.type == token.NAME and arg.value in names_inserted:
+ if idx < len(args) - 1 and args[idx + 1].type == token.COMMA:
+ iterator.next()
+ continue
+ else:
+ new_args.append(arg)
+ if arg.type == token.NAME:
+ names_inserted.add(arg.value)
+ if new_args and new_args[-1].type == token.COMMA:
+ del new_args[-1]
+ if len(new_args) == 1:
+ atom = testlist.parent
+ new_args[0].prefix = atom.prefix
+ atom.replace(new_args[0])
+ else:
+ args[:] = new_args
+ node.changed()
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_itertools.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_itertools.py
new file mode 100644
index 000000000000..067641b8f86f
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_itertools.py
@@ -0,0 +1,43 @@
+""" Fixer for itertools.(imap|ifilter|izip) --> (map|filter|zip) and
+ itertools.ifilterfalse --> itertools.filterfalse (bugs 2360-2363)
+
+ imports from itertools are fixed in fix_itertools_import.py
+
+ If itertools is imported as something else (ie: import itertools as it;
+ it.izip(spam, eggs)) method calls will not get fixed.
+ """
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Name
+
+class FixItertools(fixer_base.BaseFix):
+ BM_compatible = True
+ it_funcs = "('imap'|'ifilter'|'izip'|'izip_longest'|'ifilterfalse')"
+ PATTERN = """
+ power< it='itertools'
+ trailer<
+ dot='.' func=%(it_funcs)s > trailer< '(' [any] ')' > >
+ |
+ power< func=%(it_funcs)s trailer< '(' [any] ')' > >
+ """ %(locals())
+
+ # Needs to be run after fix_(map|zip|filter)
+ run_order = 6
+
+ def transform(self, node, results):
+ prefix = None
+ func = results['func'][0]
+ if ('it' in results and
+ func.value not in (u'ifilterfalse', u'izip_longest')):
+ dot, it = (results['dot'], results['it'])
+ # Remove the 'itertools'
+ prefix = it.prefix
+ it.remove()
+ # Replace the node which contains ('.', 'function') with the
+ # function (to be consistent with the second part of the pattern)
+ dot.remove()
+ func.parent.replace(func)
+
+ prefix = prefix or func.prefix
+ func.replace(Name(func.value[1:], prefix=prefix))
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_itertools_imports.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_itertools_imports.py
new file mode 100644
index 000000000000..28610cfcb95c
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_itertools_imports.py
@@ -0,0 +1,57 @@
+""" Fixer for imports of itertools.(imap|ifilter|izip|ifilterfalse) """
+
+# Local imports
+from lib2to3 import fixer_base
+from lib2to3.fixer_util import BlankLine, syms, token
+
+
+class FixItertoolsImports(fixer_base.BaseFix):
+ BM_compatible = True
+ PATTERN = """
+ import_from< 'from' 'itertools' 'import' imports=any >
+ """ %(locals())
+
+ def transform(self, node, results):
+ imports = results['imports']
+ if imports.type == syms.import_as_name or not imports.children:
+ children = [imports]
+ else:
+ children = imports.children
+ for child in children[::2]:
+ if child.type == token.NAME:
+ member = child.value
+ name_node = child
+ elif child.type == token.STAR:
+ # Just leave the import as is.
+ return
+ else:
+ assert child.type == syms.import_as_name
+ name_node = child.children[0]
+ member_name = name_node.value
+ if member_name in (u'imap', u'izip', u'ifilter'):
+ child.value = None
+ child.remove()
+ elif member_name in (u'ifilterfalse', u'izip_longest'):
+ node.changed()
+ name_node.value = (u'filterfalse' if member_name[1] == u'f'
+ else u'zip_longest')
+
+ # Make sure the import statement is still sane
+ children = imports.children[:] or [imports]
+ remove_comma = True
+ for child in children:
+ if remove_comma and child.type == token.COMMA:
+ child.remove()
+ else:
+ remove_comma ^= True
+
+ while children and children[-1].type == token.COMMA:
+ children.pop().remove()
+
+ # If there are no imports left, just get rid of the entire statement
+ if (not (imports.children or getattr(imports, 'value', None)) or
+ imports.parent is None):
+ p = node.prefix
+ node = BlankLine()
+ node.prefix = p
+ return node
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_long.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_long.py
new file mode 100644
index 000000000000..5dddde0d08d7
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_long.py
@@ -0,0 +1,19 @@
+# Copyright 2006 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer that turns 'long' into 'int' everywhere.
+"""
+
+# Local imports
+from lib2to3 import fixer_base
+from lib2to3.fixer_util import is_probably_builtin
+
+
+class FixLong(fixer_base.BaseFix):
+ BM_compatible = True
+ PATTERN = "'long'"
+
+ def transform(self, node, results):
+ if is_probably_builtin(node):
+ node.value = u"int"
+ node.changed()
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_map.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_map.py
new file mode 100644
index 000000000000..7a7d0dbc66c0
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_map.py
@@ -0,0 +1,91 @@
+# Copyright 2007 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer that changes map(F, ...) into list(map(F, ...)) unless there
+exists a 'from future_builtins import map' statement in the top-level
+namespace.
+
+As a special case, map(None, X) is changed into list(X). (This is
+necessary because the semantics are changed in this case -- the new
+map(None, X) is equivalent to [(x,) for x in X].)
+
+We avoid the transformation (except for the special case mentioned
+above) if the map() call is directly contained in iter(<>), list(<>),
+tuple(<>), sorted(<>), ...join(<>), or for V in <>:.
+
+NOTE: This is still not correct if the original code was depending on
+map(F, X, Y, ...) to go on until the longest argument is exhausted,
+substituting None for missing values -- like zip(), it now stops as
+soon as the shortest argument is exhausted.
+"""
+
+# Local imports
+from ..pgen2 import token
+from .. import fixer_base
+from ..fixer_util import Name, Call, ListComp, in_special_context
+from ..pygram import python_symbols as syms
+
+class FixMap(fixer_base.ConditionalFix):
+ BM_compatible = True
+
+ PATTERN = """
+ map_none=power<
+ 'map'
+ trailer< '(' arglist< 'None' ',' arg=any [','] > ')' >
+ >
+ |
+ map_lambda=power<
+ 'map'
+ trailer<
+ '('
+ arglist<
+ lambdef< 'lambda'
+ (fp=NAME | vfpdef< '(' fp=NAME ')'> ) ':' xp=any
+ >
+ ','
+ it=any
+ >
+ ')'
+ >
+ >
+ |
+ power<
+ 'map' trailer< '(' [arglist=any] ')' >
+ >
+ """
+
+ skip_on = 'future_builtins.map'
+
+ def transform(self, node, results):
+ if self.should_skip(node):
+ return
+
+ if node.parent.type == syms.simple_stmt:
+ self.warning(node, "You should use a for loop here")
+ new = node.clone()
+ new.prefix = u""
+ new = Call(Name(u"list"), [new])
+ elif "map_lambda" in results:
+ new = ListComp(results["xp"].clone(),
+ results["fp"].clone(),
+ results["it"].clone())
+ else:
+ if "map_none" in results:
+ new = results["arg"].clone()
+ else:
+ if "arglist" in results:
+ args = results["arglist"]
+ if args.type == syms.arglist and \
+ args.children[0].type == token.NAME and \
+ args.children[0].value == "None":
+ self.warning(node, "cannot convert map(None, ...) "
+ "with multiple arguments because map() "
+ "now truncates to the shortest sequence")
+ return
+ if in_special_context(node):
+ return None
+ new = node.clone()
+ new.prefix = u""
+ new = Call(Name(u"list"), [new])
+ new.prefix = node.prefix
+ return new
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_metaclass.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_metaclass.py
new file mode 100644
index 000000000000..4f5593c5feb0
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_metaclass.py
@@ -0,0 +1,228 @@
+"""Fixer for __metaclass__ = X -> (metaclass=X) methods.
+
+ The various forms of classef (inherits nothing, inherits once, inherints
+ many) don't parse the same in the CST so we look at ALL classes for
+ a __metaclass__ and if we find one normalize the inherits to all be
+ an arglist.
+
+ For one-liner classes ('class X: pass') there is no indent/dedent so
+ we normalize those into having a suite.
+
+ Moving the __metaclass__ into the classdef can also cause the class
+ body to be empty so there is some special casing for that as well.
+
+ This fixer also tries very hard to keep original indenting and spacing
+ in all those corner cases.
+
+"""
+# Author: Jack Diederich
+
+# Local imports
+from .. import fixer_base
+from ..pygram import token
+from ..fixer_util import Name, syms, Node, Leaf
+
+
+def has_metaclass(parent):
+ """ we have to check the cls_node without changing it.
+ There are two possiblities:
+ 1) clsdef => suite => simple_stmt => expr_stmt => Leaf('__meta')
+ 2) clsdef => simple_stmt => expr_stmt => Leaf('__meta')
+ """
+ for node in parent.children:
+ if node.type == syms.suite:
+ return has_metaclass(node)
+ elif node.type == syms.simple_stmt and node.children:
+ expr_node = node.children[0]
+ if expr_node.type == syms.expr_stmt and expr_node.children:
+ left_side = expr_node.children[0]
+ if isinstance(left_side, Leaf) and \
+ left_side.value == '__metaclass__':
+ return True
+ return False
+
+
+def fixup_parse_tree(cls_node):
+ """ one-line classes don't get a suite in the parse tree so we add
+ one to normalize the tree
+ """
+ for node in cls_node.children:
+ if node.type == syms.suite:
+ # already in the preferred format, do nothing
+ return
+
+ # !%@#! oneliners have no suite node, we have to fake one up
+ for i, node in enumerate(cls_node.children):
+ if node.type == token.COLON:
+ break
+ else:
+ raise ValueError("No class suite and no ':'!")
+
+ # move everything into a suite node
+ suite = Node(syms.suite, [])
+ while cls_node.children[i+1:]:
+ move_node = cls_node.children[i+1]
+ suite.append_child(move_node.clone())
+ move_node.remove()
+ cls_node.append_child(suite)
+ node = suite
+
+
+def fixup_simple_stmt(parent, i, stmt_node):
+ """ if there is a semi-colon all the parts count as part of the same
+ simple_stmt. We just want the __metaclass__ part so we move
+ everything after the semi-colon into its own simple_stmt node
+ """
+ for semi_ind, node in enumerate(stmt_node.children):
+ if node.type == token.SEMI: # *sigh*
+ break
+ else:
+ return
+
+ node.remove() # kill the semicolon
+ new_expr = Node(syms.expr_stmt, [])
+ new_stmt = Node(syms.simple_stmt, [new_expr])
+ while stmt_node.children[semi_ind:]:
+ move_node = stmt_node.children[semi_ind]
+ new_expr.append_child(move_node.clone())
+ move_node.remove()
+ parent.insert_child(i, new_stmt)
+ new_leaf1 = new_stmt.children[0].children[0]
+ old_leaf1 = stmt_node.children[0].children[0]
+ new_leaf1.prefix = old_leaf1.prefix
+
+
+def remove_trailing_newline(node):
+ if node.children and node.children[-1].type == token.NEWLINE:
+ node.children[-1].remove()
+
+
+def find_metas(cls_node):
+ # find the suite node (Mmm, sweet nodes)
+ for node in cls_node.children:
+ if node.type == syms.suite:
+ break
+ else:
+ raise ValueError("No class suite!")
+
+ # look for simple_stmt[ expr_stmt[ Leaf('__metaclass__') ] ]
+ for i, simple_node in list(enumerate(node.children)):
+ if simple_node.type == syms.simple_stmt and simple_node.children:
+ expr_node = simple_node.children[0]
+ if expr_node.type == syms.expr_stmt and expr_node.children:
+ # Check if the expr_node is a simple assignment.
+ left_node = expr_node.children[0]
+ if isinstance(left_node, Leaf) and \
+ left_node.value == u'__metaclass__':
+ # We found a assignment to __metaclass__.
+ fixup_simple_stmt(node, i, simple_node)
+ remove_trailing_newline(simple_node)
+ yield (node, i, simple_node)
+
+
+def fixup_indent(suite):
+ """ If an INDENT is followed by a thing with a prefix then nuke the prefix
+ Otherwise we get in trouble when removing __metaclass__ at suite start
+ """
+ kids = suite.children[::-1]
+ # find the first indent
+ while kids:
+ node = kids.pop()
+ if node.type == token.INDENT:
+ break
+
+ # find the first Leaf
+ while kids:
+ node = kids.pop()
+ if isinstance(node, Leaf) and node.type != token.DEDENT:
+ if node.prefix:
+ node.prefix = u''
+ return
+ else:
+ kids.extend(node.children[::-1])
+
+
+class FixMetaclass(fixer_base.BaseFix):
+ BM_compatible = True
+
+ PATTERN = """
+ classdef<any*>
+ """
+
+ def transform(self, node, results):
+ if not has_metaclass(node):
+ return
+
+ fixup_parse_tree(node)
+
+ # find metaclasses, keep the last one
+ last_metaclass = None
+ for suite, i, stmt in find_metas(node):
+ last_metaclass = stmt
+ stmt.remove()
+
+ text_type = node.children[0].type # always Leaf(nnn, 'class')
+
+ # figure out what kind of classdef we have
+ if len(node.children) == 7:
+ # Node(classdef, ['class', 'name', '(', arglist, ')', ':', suite])
+ # 0 1 2 3 4 5 6
+ if node.children[3].type == syms.arglist:
+ arglist = node.children[3]
+ # Node(classdef, ['class', 'name', '(', 'Parent', ')', ':', suite])
+ else:
+ parent = node.children[3].clone()
+ arglist = Node(syms.arglist, [parent])
+ node.set_child(3, arglist)
+ elif len(node.children) == 6:
+ # Node(classdef, ['class', 'name', '(', ')', ':', suite])
+ # 0 1 2 3 4 5
+ arglist = Node(syms.arglist, [])
+ node.insert_child(3, arglist)
+ elif len(node.children) == 4:
+ # Node(classdef, ['class', 'name', ':', suite])
+ # 0 1 2 3
+ arglist = Node(syms.arglist, [])
+ node.insert_child(2, Leaf(token.RPAR, u')'))
+ node.insert_child(2, arglist)
+ node.insert_child(2, Leaf(token.LPAR, u'('))
+ else:
+ raise ValueError("Unexpected class definition")
+
+ # now stick the metaclass in the arglist
+ meta_txt = last_metaclass.children[0].children[0]
+ meta_txt.value = 'metaclass'
+ orig_meta_prefix = meta_txt.prefix
+
+ if arglist.children:
+ arglist.append_child(Leaf(token.COMMA, u','))
+ meta_txt.prefix = u' '
+ else:
+ meta_txt.prefix = u''
+
+ # compact the expression "metaclass = Meta" -> "metaclass=Meta"
+ expr_stmt = last_metaclass.children[0]
+ assert expr_stmt.type == syms.expr_stmt
+ expr_stmt.children[1].prefix = u''
+ expr_stmt.children[2].prefix = u''
+
+ arglist.append_child(last_metaclass)
+
+ fixup_indent(suite)
+
+ # check for empty suite
+ if not suite.children:
+ # one-liner that was just __metaclass_
+ suite.remove()
+ pass_leaf = Leaf(text_type, u'pass')
+ pass_leaf.prefix = orig_meta_prefix
+ node.append_child(pass_leaf)
+ node.append_child(Leaf(token.NEWLINE, u'\n'))
+
+ elif len(suite.children) > 1 and \
+ (suite.children[-2].type == token.INDENT and
+ suite.children[-1].type == token.DEDENT):
+ # there was only one line in the class body and it was __metaclass__
+ pass_leaf = Leaf(text_type, u'pass')
+ suite.insert_child(-1, pass_leaf)
+ suite.insert_child(-1, Leaf(token.NEWLINE, u'\n'))
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_methodattrs.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_methodattrs.py
new file mode 100644
index 000000000000..f3c1ecfec153
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_methodattrs.py
@@ -0,0 +1,24 @@
+"""Fix bound method attributes (method.im_? -> method.__?__).
+"""
+# Author: Christian Heimes
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Name
+
+MAP = {
+ "im_func" : "__func__",
+ "im_self" : "__self__",
+ "im_class" : "__self__.__class__"
+ }
+
+class FixMethodattrs(fixer_base.BaseFix):
+ BM_compatible = True
+ PATTERN = """
+ power< any+ trailer< '.' attr=('im_func' | 'im_self' | 'im_class') > any* >
+ """
+
+ def transform(self, node, results):
+ attr = results["attr"][0]
+ new = unicode(MAP[attr.value])
+ attr.replace(Name(new, prefix=attr.prefix))
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_ne.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_ne.py
new file mode 100644
index 000000000000..7025980b48e5
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_ne.py
@@ -0,0 +1,23 @@
+# Copyright 2006 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer that turns <> into !=."""
+
+# Local imports
+from .. import pytree
+from ..pgen2 import token
+from .. import fixer_base
+
+
+class FixNe(fixer_base.BaseFix):
+ # This is so simple that we don't need the pattern compiler.
+
+ _accept_type = token.NOTEQUAL
+
+ def match(self, node):
+ # Override
+ return node.value == u"<>"
+
+ def transform(self, node, results):
+ new = pytree.Leaf(token.NOTEQUAL, u"!=", prefix=node.prefix)
+ return new
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_next.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_next.py
new file mode 100644
index 000000000000..f021a9bd70a4
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_next.py
@@ -0,0 +1,103 @@
+"""Fixer for it.next() -> next(it), per PEP 3114."""
+# Author: Collin Winter
+
+# Things that currently aren't covered:
+# - listcomp "next" names aren't warned
+# - "with" statement targets aren't checked
+
+# Local imports
+from ..pgen2 import token
+from ..pygram import python_symbols as syms
+from .. import fixer_base
+from ..fixer_util import Name, Call, find_binding
+
+bind_warning = "Calls to builtin next() possibly shadowed by global binding"
+
+
+class FixNext(fixer_base.BaseFix):
+ BM_compatible = True
+ PATTERN = """
+ power< base=any+ trailer< '.' attr='next' > trailer< '(' ')' > >
+ |
+ power< head=any+ trailer< '.' attr='next' > not trailer< '(' ')' > >
+ |
+ classdef< 'class' any+ ':'
+ suite< any*
+ funcdef< 'def'
+ name='next'
+ parameters< '(' NAME ')' > any+ >
+ any* > >
+ |
+ global=global_stmt< 'global' any* 'next' any* >
+ """
+
+ order = "pre" # Pre-order tree traversal
+
+ def start_tree(self, tree, filename):
+ super(FixNext, self).start_tree(tree, filename)
+
+ n = find_binding(u'next', tree)
+ if n:
+ self.warning(n, bind_warning)
+ self.shadowed_next = True
+ else:
+ self.shadowed_next = False
+
+ def transform(self, node, results):
+ assert results
+
+ base = results.get("base")
+ attr = results.get("attr")
+ name = results.get("name")
+
+ if base:
+ if self.shadowed_next:
+ attr.replace(Name(u"__next__", prefix=attr.prefix))
+ else:
+ base = [n.clone() for n in base]
+ base[0].prefix = u""
+ node.replace(Call(Name(u"next", prefix=node.prefix), base))
+ elif name:
+ n = Name(u"__next__", prefix=name.prefix)
+ name.replace(n)
+ elif attr:
+ # We don't do this transformation if we're assigning to "x.next".
+ # Unfortunately, it doesn't seem possible to do this in PATTERN,
+ # so it's being done here.
+ if is_assign_target(node):
+ head = results["head"]
+ if "".join([str(n) for n in head]).strip() == u'__builtin__':
+ self.warning(node, bind_warning)
+ return
+ attr.replace(Name(u"__next__"))
+ elif "global" in results:
+ self.warning(node, bind_warning)
+ self.shadowed_next = True
+
+
+### The following functions help test if node is part of an assignment
+### target.
+
+def is_assign_target(node):
+ assign = find_assign(node)
+ if assign is None:
+ return False
+
+ for child in assign.children:
+ if child.type == token.EQUAL:
+ return False
+ elif is_subtree(child, node):
+ return True
+ return False
+
+def find_assign(node):
+ if node.type == syms.expr_stmt:
+ return node
+ if node.type == syms.simple_stmt or node.parent is None:
+ return None
+ return find_assign(node.parent)
+
+def is_subtree(root, node):
+ if root == node:
+ return True
+ return any(is_subtree(c, node) for c in root.children)
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_nonzero.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_nonzero.py
new file mode 100644
index 000000000000..ba83478f818a
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_nonzero.py
@@ -0,0 +1,21 @@
+"""Fixer for __nonzero__ -> __bool__ methods."""
+# Author: Collin Winter
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Name, syms
+
+class FixNonzero(fixer_base.BaseFix):
+ BM_compatible = True
+ PATTERN = """
+ classdef< 'class' any+ ':'
+ suite< any*
+ funcdef< 'def' name='__nonzero__'
+ parameters< '(' NAME ')' > any+ >
+ any* > >
+ """
+
+ def transform(self, node, results):
+ name = results["name"]
+ new = Name(u"__bool__", prefix=name.prefix)
+ name.replace(new)
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_numliterals.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_numliterals.py
new file mode 100644
index 000000000000..b0c23f8041ad
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_numliterals.py
@@ -0,0 +1,28 @@
+"""Fixer that turns 1L into 1, 0755 into 0o755.
+"""
+# Copyright 2007 Georg Brandl.
+# Licensed to PSF under a Contributor Agreement.
+
+# Local imports
+from ..pgen2 import token
+from .. import fixer_base
+from ..fixer_util import Number
+
+
+class FixNumliterals(fixer_base.BaseFix):
+ # This is so simple that we don't need the pattern compiler.
+
+ _accept_type = token.NUMBER
+
+ def match(self, node):
+ # Override
+ return (node.value.startswith(u"0") or node.value[-1] in u"Ll")
+
+ def transform(self, node, results):
+ val = node.value
+ if val[-1] in u'Ll':
+ val = val[:-1]
+ elif val.startswith(u'0') and val.isdigit() and len(set(val)) > 1:
+ val = u"0o" + val[1:]
+
+ return Number(val, prefix=node.prefix)
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_operator.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_operator.py
new file mode 100644
index 000000000000..7bf2c0dd22c6
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_operator.py
@@ -0,0 +1,96 @@
+"""Fixer for operator functions.
+
+operator.isCallable(obj) -> hasattr(obj, '__call__')
+operator.sequenceIncludes(obj) -> operator.contains(obj)
+operator.isSequenceType(obj) -> isinstance(obj, collections.Sequence)
+operator.isMappingType(obj) -> isinstance(obj, collections.Mapping)
+operator.isNumberType(obj) -> isinstance(obj, numbers.Number)
+operator.repeat(obj, n) -> operator.mul(obj, n)
+operator.irepeat(obj, n) -> operator.imul(obj, n)
+"""
+
+# Local imports
+from lib2to3 import fixer_base
+from lib2to3.fixer_util import Call, Name, String, touch_import
+
+
+def invocation(s):
+ def dec(f):
+ f.invocation = s
+ return f
+ return dec
+
+
+class FixOperator(fixer_base.BaseFix):
+ BM_compatible = True
+ order = "pre"
+
+ methods = """
+ method=('isCallable'|'sequenceIncludes'
+ |'isSequenceType'|'isMappingType'|'isNumberType'
+ |'repeat'|'irepeat')
+ """
+ obj = "'(' obj=any ')'"
+ PATTERN = """
+ power< module='operator'
+ trailer< '.' %(methods)s > trailer< %(obj)s > >
+ |
+ power< %(methods)s trailer< %(obj)s > >
+ """ % dict(methods=methods, obj=obj)
+
+ def transform(self, node, results):
+ method = self._check_method(node, results)
+ if method is not None:
+ return method(node, results)
+
+ @invocation("operator.contains(%s)")
+ def _sequenceIncludes(self, node, results):
+ return self._handle_rename(node, results, u"contains")
+
+ @invocation("hasattr(%s, '__call__')")
+ def _isCallable(self, node, results):
+ obj = results["obj"]
+ args = [obj.clone(), String(u", "), String(u"'__call__'")]
+ return Call(Name(u"hasattr"), args, prefix=node.prefix)
+
+ @invocation("operator.mul(%s)")
+ def _repeat(self, node, results):
+ return self._handle_rename(node, results, u"mul")
+
+ @invocation("operator.imul(%s)")
+ def _irepeat(self, node, results):
+ return self._handle_rename(node, results, u"imul")
+
+ @invocation("isinstance(%s, collections.Sequence)")
+ def _isSequenceType(self, node, results):
+ return self._handle_type2abc(node, results, u"collections", u"Sequence")
+
+ @invocation("isinstance(%s, collections.Mapping)")
+ def _isMappingType(self, node, results):
+ return self._handle_type2abc(node, results, u"collections", u"Mapping")
+
+ @invocation("isinstance(%s, numbers.Number)")
+ def _isNumberType(self, node, results):
+ return self._handle_type2abc(node, results, u"numbers", u"Number")
+
+ def _handle_rename(self, node, results, name):
+ method = results["method"][0]
+ method.value = name
+ method.changed()
+
+ def _handle_type2abc(self, node, results, module, abc):
+ touch_import(None, module, node)
+ obj = results["obj"]
+ args = [obj.clone(), String(u", " + u".".join([module, abc]))]
+ return Call(Name(u"isinstance"), args, prefix=node.prefix)
+
+ def _check_method(self, node, results):
+ method = getattr(self, "_" + results["method"][0].value.encode("ascii"))
+ if callable(method):
+ if "module" in results:
+ return method
+ else:
+ sub = (unicode(results["obj"]),)
+ invocation_str = unicode(method.invocation) % sub
+ self.warning(node, u"You should use '%s' here." % invocation_str)
+ return None
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_paren.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_paren.py
new file mode 100644
index 000000000000..8650cd9078af
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_paren.py
@@ -0,0 +1,44 @@
+"""Fixer that addes parentheses where they are required
+
+This converts ``[x for x in 1, 2]`` to ``[x for x in (1, 2)]``."""
+
+# By Taek Joo Kim and Benjamin Peterson
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import LParen, RParen
+
+# XXX This doesn't support nested for loops like [x for x in 1, 2 for x in 1, 2]
+class FixParen(fixer_base.BaseFix):
+ BM_compatible = True
+
+ PATTERN = """
+ atom< ('[' | '(')
+ (listmaker< any
+ comp_for<
+ 'for' NAME 'in'
+ target=testlist_safe< any (',' any)+ [',']
+ >
+ [any]
+ >
+ >
+ |
+ testlist_gexp< any
+ comp_for<
+ 'for' NAME 'in'
+ target=testlist_safe< any (',' any)+ [',']
+ >
+ [any]
+ >
+ >)
+ (']' | ')') >
+ """
+
+ def transform(self, node, results):
+ target = results["target"]
+
+ lparen = LParen()
+ lparen.prefix = target.prefix
+ target.prefix = u"" # Make it hug the parentheses
+ target.insert_child(0, lparen)
+ target.append_child(RParen())
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_print.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_print.py
new file mode 100644
index 000000000000..98786b3ecdc5
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_print.py
@@ -0,0 +1,87 @@
+# Copyright 2006 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer for print.
+
+Change:
+ 'print' into 'print()'
+ 'print ...' into 'print(...)'
+ 'print ... ,' into 'print(..., end=" ")'
+ 'print >>x, ...' into 'print(..., file=x)'
+
+No changes are applied if print_function is imported from __future__
+
+"""
+
+# Local imports
+from .. import patcomp
+from .. import pytree
+from ..pgen2 import token
+from .. import fixer_base
+from ..fixer_util import Name, Call, Comma, String, is_tuple
+
+
+parend_expr = patcomp.compile_pattern(
+ """atom< '(' [atom|STRING|NAME] ')' >"""
+ )
+
+
+class FixPrint(fixer_base.BaseFix):
+
+ BM_compatible = True
+
+ PATTERN = """
+ simple_stmt< any* bare='print' any* > | print_stmt
+ """
+
+ def transform(self, node, results):
+ assert results
+
+ bare_print = results.get("bare")
+
+ if bare_print:
+ # Special-case print all by itself
+ bare_print.replace(Call(Name(u"print"), [],
+ prefix=bare_print.prefix))
+ return
+ assert node.children[0] == Name(u"print")
+ args = node.children[1:]
+ if len(args) == 1 and parend_expr.match(args[0]):
+ # We don't want to keep sticking parens around an
+ # already-parenthesised expression.
+ return
+
+ sep = end = file = None
+ if args and args[-1] == Comma():
+ args = args[:-1]
+ end = " "
+ if args and args[0] == pytree.Leaf(token.RIGHTSHIFT, u">>"):
+ assert len(args) >= 2
+ file = args[1].clone()
+ args = args[3:] # Strip a possible comma after the file expression
+ # Now synthesize a print(args, sep=..., end=..., file=...) node.
+ l_args = [arg.clone() for arg in args]
+ if l_args:
+ l_args[0].prefix = u""
+ if sep is not None or end is not None or file is not None:
+ if sep is not None:
+ self.add_kwarg(l_args, u"sep", String(repr(sep)))
+ if end is not None:
+ self.add_kwarg(l_args, u"end", String(repr(end)))
+ if file is not None:
+ self.add_kwarg(l_args, u"file", file)
+ n_stmt = Call(Name(u"print"), l_args)
+ n_stmt.prefix = node.prefix
+ return n_stmt
+
+ def add_kwarg(self, l_nodes, s_kwd, n_expr):
+ # XXX All this prefix-setting may lose comments (though rarely)
+ n_expr.prefix = u""
+ n_argument = pytree.Node(self.syms.argument,
+ (Name(s_kwd),
+ pytree.Leaf(token.EQUAL, u"="),
+ n_expr))
+ if l_nodes:
+ l_nodes.append(Comma())
+ n_argument.prefix = u" "
+ l_nodes.append(n_argument)
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_raise.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_raise.py
new file mode 100644
index 000000000000..b958ba0129de
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_raise.py
@@ -0,0 +1,90 @@
+"""Fixer for 'raise E, V, T'
+
+raise -> raise
+raise E -> raise E
+raise E, V -> raise E(V)
+raise E, V, T -> raise E(V).with_traceback(T)
+raise E, None, T -> raise E.with_traceback(T)
+
+raise (((E, E'), E''), E'''), V -> raise E(V)
+raise "foo", V, T -> warns about string exceptions
+
+
+CAVEATS:
+1) "raise E, V" will be incorrectly translated if V is an exception
+ instance. The correct Python 3 idiom is
+
+ raise E from V
+
+ but since we can't detect instance-hood by syntax alone and since
+ any client code would have to be changed as well, we don't automate
+ this.
+"""
+# Author: Collin Winter
+
+# Local imports
+from .. import pytree
+from ..pgen2 import token
+from .. import fixer_base
+from ..fixer_util import Name, Call, Attr, ArgList, is_tuple
+
+class FixRaise(fixer_base.BaseFix):
+
+ BM_compatible = True
+ PATTERN = """
+ raise_stmt< 'raise' exc=any [',' val=any [',' tb=any]] >
+ """
+
+ def transform(self, node, results):
+ syms = self.syms
+
+ exc = results["exc"].clone()
+ if exc.type == token.STRING:
+ msg = "Python 3 does not support string exceptions"
+ self.cannot_convert(node, msg)
+ return
+
+ # Python 2 supports
+ # raise ((((E1, E2), E3), E4), E5), V
+ # as a synonym for
+ # raise E1, V
+ # Since Python 3 will not support this, we recurse down any tuple
+ # literals, always taking the first element.
+ if is_tuple(exc):
+ while is_tuple(exc):
+ # exc.children[1:-1] is the unparenthesized tuple
+ # exc.children[1].children[0] is the first element of the tuple
+ exc = exc.children[1].children[0].clone()
+ exc.prefix = u" "
+
+ if "val" not in results:
+ # One-argument raise
+ new = pytree.Node(syms.raise_stmt, [Name(u"raise"), exc])
+ new.prefix = node.prefix
+ return new
+
+ val = results["val"].clone()
+ if is_tuple(val):
+ args = [c.clone() for c in val.children[1:-1]]
+ else:
+ val.prefix = u""
+ args = [val]
+
+ if "tb" in results:
+ tb = results["tb"].clone()
+ tb.prefix = u""
+
+ e = exc
+ # If there's a traceback and None is passed as the value, then don't
+ # add a call, since the user probably just wants to add a
+ # traceback. See issue #9661.
+ if val.type != token.NAME or val.value != u"None":
+ e = Call(exc, args)
+ with_tb = Attr(e, Name(u'with_traceback')) + [ArgList([tb])]
+ new = pytree.Node(syms.simple_stmt, [Name(u"raise")] + with_tb)
+ new.prefix = node.prefix
+ return new
+ else:
+ return pytree.Node(syms.raise_stmt,
+ [Name(u"raise"), Call(exc, args)],
+ prefix=node.prefix)
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_raw_input.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_raw_input.py
new file mode 100644
index 000000000000..3a73b81864e2
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_raw_input.py
@@ -0,0 +1,17 @@
+"""Fixer that changes raw_input(...) into input(...)."""
+# Author: Andre Roberge
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Name
+
+class FixRawInput(fixer_base.BaseFix):
+
+ BM_compatible = True
+ PATTERN = """
+ power< name='raw_input' trailer< '(' [any] ')' > any* >
+ """
+
+ def transform(self, node, results):
+ name = results["name"]
+ name.replace(Name(u"input", prefix=name.prefix))
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_reduce.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_reduce.py
new file mode 100644
index 000000000000..6bd785c1cd90
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_reduce.py
@@ -0,0 +1,35 @@
+# Copyright 2008 Armin Ronacher.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer for reduce().
+
+Makes sure reduce() is imported from the functools module if reduce is
+used in that module.
+"""
+
+from lib2to3 import fixer_base
+from lib2to3.fixer_util import touch_import
+
+
+
+class FixReduce(fixer_base.BaseFix):
+
+ BM_compatible = True
+ order = "pre"
+
+ PATTERN = """
+ power< 'reduce'
+ trailer< '('
+ arglist< (
+ (not(argument<any '=' any>) any ','
+ not(argument<any '=' any>) any) |
+ (not(argument<any '=' any>) any ','
+ not(argument<any '=' any>) any ','
+ not(argument<any '=' any>) any)
+ ) >
+ ')' >
+ >
+ """
+
+ def transform(self, node, results):
+ touch_import(u'functools', u'reduce', node)
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_renames.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_renames.py
new file mode 100644
index 000000000000..4bcce8c4ebdd
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_renames.py
@@ -0,0 +1,70 @@
+"""Fix incompatible renames
+
+Fixes:
+ * sys.maxint -> sys.maxsize
+"""
+# Author: Christian Heimes
+# based on Collin Winter's fix_import
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Name, attr_chain
+
+MAPPING = {"sys": {"maxint" : "maxsize"},
+ }
+LOOKUP = {}
+
+def alternates(members):
+ return "(" + "|".join(map(repr, members)) + ")"
+
+
+def build_pattern():
+ #bare = set()
+ for module, replace in MAPPING.items():
+ for old_attr, new_attr in replace.items():
+ LOOKUP[(module, old_attr)] = new_attr
+ #bare.add(module)
+ #bare.add(old_attr)
+ #yield """
+ # import_name< 'import' (module=%r
+ # | dotted_as_names< any* module=%r any* >) >
+ # """ % (module, module)
+ yield """
+ import_from< 'from' module_name=%r 'import'
+ ( attr_name=%r | import_as_name< attr_name=%r 'as' any >) >
+ """ % (module, old_attr, old_attr)
+ yield """
+ power< module_name=%r trailer< '.' attr_name=%r > any* >
+ """ % (module, old_attr)
+ #yield """bare_name=%s""" % alternates(bare)
+
+
+class FixRenames(fixer_base.BaseFix):
+ BM_compatible = True
+ PATTERN = "|".join(build_pattern())
+
+ order = "pre" # Pre-order tree traversal
+
+ # Don't match the node if it's within another match
+ def match(self, node):
+ match = super(FixRenames, self).match
+ results = match(node)
+ if results:
+ if any(match(obj) for obj in attr_chain(node, "parent")):
+ return False
+ return results
+ return False
+
+ #def start_tree(self, tree, filename):
+ # super(FixRenames, self).start_tree(tree, filename)
+ # self.replace = {}
+
+ def transform(self, node, results):
+ mod_name = results.get("module_name")
+ attr_name = results.get("attr_name")
+ #bare_name = results.get("bare_name")
+ #import_mod = results.get("module")
+
+ if mod_name and attr_name:
+ new_attr = unicode(LOOKUP[(mod_name.value, attr_name.value)])
+ attr_name.replace(Name(new_attr, prefix=attr_name.prefix))
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_repr.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_repr.py
new file mode 100644
index 000000000000..f34365647f0b
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_repr.py
@@ -0,0 +1,23 @@
+# Copyright 2006 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer that transforms `xyzzy` into repr(xyzzy)."""
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Call, Name, parenthesize
+
+
+class FixRepr(fixer_base.BaseFix):
+
+ BM_compatible = True
+ PATTERN = """
+ atom < '`' expr=any '`' >
+ """
+
+ def transform(self, node, results):
+ expr = results["expr"].clone()
+
+ if expr.type == self.syms.testlist1:
+ expr = parenthesize(expr)
+ return Call(Name(u"repr"), [expr], prefix=node.prefix)
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_set_literal.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_set_literal.py
new file mode 100644
index 000000000000..d3d38ec4e0ab
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_set_literal.py
@@ -0,0 +1,53 @@
+"""
+Optional fixer to transform set() calls to set literals.
+"""
+
+# Author: Benjamin Peterson
+
+from lib2to3 import fixer_base, pytree
+from lib2to3.fixer_util import token, syms
+
+
+
+class FixSetLiteral(fixer_base.BaseFix):
+
+ BM_compatible = True
+ explicit = True
+
+ PATTERN = """power< 'set' trailer< '('
+ (atom=atom< '[' (items=listmaker< any ((',' any)* [',']) >
+ |
+ single=any) ']' >
+ |
+ atom< '(' items=testlist_gexp< any ((',' any)* [',']) > ')' >
+ )
+ ')' > >
+ """
+
+ def transform(self, node, results):
+ single = results.get("single")
+ if single:
+ # Make a fake listmaker
+ fake = pytree.Node(syms.listmaker, [single.clone()])
+ single.replace(fake)
+ items = fake
+ else:
+ items = results["items"]
+
+ # Build the contents of the literal
+ literal = [pytree.Leaf(token.LBRACE, u"{")]
+ literal.extend(n.clone() for n in items.children)
+ literal.append(pytree.Leaf(token.RBRACE, u"}"))
+ # Set the prefix of the right brace to that of the ')' or ']'
+ literal[-1].prefix = items.next_sibling.prefix
+ maker = pytree.Node(syms.dictsetmaker, literal)
+ maker.prefix = node.prefix
+
+ # If the original was a one tuple, we need to remove the extra comma.
+ if len(maker.children) == 4:
+ n = maker.children[2]
+ n.remove()
+ maker.children[-1].prefix = n.prefix
+
+ # Finally, replace the set call with our shiny new literal.
+ return maker
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_standarderror.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_standarderror.py
new file mode 100644
index 000000000000..6cad51116d03
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_standarderror.py
@@ -0,0 +1,18 @@
+# Copyright 2007 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer for StandardError -> Exception."""
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Name
+
+
+class FixStandarderror(fixer_base.BaseFix):
+ BM_compatible = True
+ PATTERN = """
+ 'StandardError'
+ """
+
+ def transform(self, node, results):
+ return Name(u"Exception", prefix=node.prefix)
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_sys_exc.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_sys_exc.py
new file mode 100644
index 000000000000..2ecca2b53543
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_sys_exc.py
@@ -0,0 +1,30 @@
+"""Fixer for sys.exc_{type, value, traceback}
+
+sys.exc_type -> sys.exc_info()[0]
+sys.exc_value -> sys.exc_info()[1]
+sys.exc_traceback -> sys.exc_info()[2]
+"""
+
+# By Jeff Balogh and Benjamin Peterson
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Attr, Call, Name, Number, Subscript, Node, syms
+
+class FixSysExc(fixer_base.BaseFix):
+ # This order matches the ordering of sys.exc_info().
+ exc_info = [u"exc_type", u"exc_value", u"exc_traceback"]
+ BM_compatible = True
+ PATTERN = """
+ power< 'sys' trailer< dot='.' attribute=(%s) > >
+ """ % '|'.join("'%s'" % e for e in exc_info)
+
+ def transform(self, node, results):
+ sys_attr = results["attribute"][0]
+ index = Number(self.exc_info.index(sys_attr.value))
+
+ call = Call(Name(u"exc_info"), prefix=sys_attr.prefix)
+ attr = Attr(Name(u"sys"), call)
+ attr[1].children[0].prefix = results["dot"].prefix
+ attr.append(Subscript(index))
+ return Node(syms.power, attr, prefix=node.prefix)
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_throw.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_throw.py
new file mode 100644
index 000000000000..1468d89a4506
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_throw.py
@@ -0,0 +1,56 @@
+"""Fixer for generator.throw(E, V, T).
+
+g.throw(E) -> g.throw(E)
+g.throw(E, V) -> g.throw(E(V))
+g.throw(E, V, T) -> g.throw(E(V).with_traceback(T))
+
+g.throw("foo"[, V[, T]]) will warn about string exceptions."""
+# Author: Collin Winter
+
+# Local imports
+from .. import pytree
+from ..pgen2 import token
+from .. import fixer_base
+from ..fixer_util import Name, Call, ArgList, Attr, is_tuple
+
+class FixThrow(fixer_base.BaseFix):
+ BM_compatible = True
+ PATTERN = """
+ power< any trailer< '.' 'throw' >
+ trailer< '(' args=arglist< exc=any ',' val=any [',' tb=any] > ')' >
+ >
+ |
+ power< any trailer< '.' 'throw' > trailer< '(' exc=any ')' > >
+ """
+
+ def transform(self, node, results):
+ syms = self.syms
+
+ exc = results["exc"].clone()
+ if exc.type is token.STRING:
+ self.cannot_convert(node, "Python 3 does not support string exceptions")
+ return
+
+ # Leave "g.throw(E)" alone
+ val = results.get(u"val")
+ if val is None:
+ return
+
+ val = val.clone()
+ if is_tuple(val):
+ args = [c.clone() for c in val.children[1:-1]]
+ else:
+ val.prefix = u""
+ args = [val]
+
+ throw_args = results["args"]
+
+ if "tb" in results:
+ tb = results["tb"].clone()
+ tb.prefix = u""
+
+ e = Call(exc, args)
+ with_tb = Attr(e, Name(u'with_traceback')) + [ArgList([tb])]
+ throw_args.replace(pytree.Node(syms.power, with_tb))
+ else:
+ throw_args.replace(Call(exc, args))
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_tuple_params.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_tuple_params.py
new file mode 100644
index 000000000000..6361717dc54d
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_tuple_params.py
@@ -0,0 +1,175 @@
+"""Fixer for function definitions with tuple parameters.
+
+def func(((a, b), c), d):
+ ...
+
+ ->
+
+def func(x, d):
+ ((a, b), c) = x
+ ...
+
+It will also support lambdas:
+
+ lambda (x, y): x + y -> lambda t: t[0] + t[1]
+
+ # The parens are a syntax error in Python 3
+ lambda (x): x + y -> lambda x: x + y
+"""
+# Author: Collin Winter
+
+# Local imports
+from .. import pytree
+from ..pgen2 import token
+from .. import fixer_base
+from ..fixer_util import Assign, Name, Newline, Number, Subscript, syms
+
+def is_docstring(stmt):
+ return isinstance(stmt, pytree.Node) and \
+ stmt.children[0].type == token.STRING
+
+class FixTupleParams(fixer_base.BaseFix):
+ run_order = 4 #use a lower order since lambda is part of other
+ #patterns
+ BM_compatible = True
+
+ PATTERN = """
+ funcdef< 'def' any parameters< '(' args=any ')' >
+ ['->' any] ':' suite=any+ >
+ |
+ lambda=
+ lambdef< 'lambda' args=vfpdef< '(' inner=any ')' >
+ ':' body=any
+ >
+ """
+
+ def transform(self, node, results):
+ if "lambda" in results:
+ return self.transform_lambda(node, results)
+
+ new_lines = []
+ suite = results["suite"]
+ args = results["args"]
+ # This crap is so "def foo(...): x = 5; y = 7" is handled correctly.
+ # TODO(cwinter): suite-cleanup
+ if suite[0].children[1].type == token.INDENT:
+ start = 2
+ indent = suite[0].children[1].value
+ end = Newline()
+ else:
+ start = 0
+ indent = u"; "
+ end = pytree.Leaf(token.INDENT, u"")
+
+ # We need access to self for new_name(), and making this a method
+ # doesn't feel right. Closing over self and new_lines makes the
+ # code below cleaner.
+ def handle_tuple(tuple_arg, add_prefix=False):
+ n = Name(self.new_name())
+ arg = tuple_arg.clone()
+ arg.prefix = u""
+ stmt = Assign(arg, n.clone())
+ if add_prefix:
+ n.prefix = u" "
+ tuple_arg.replace(n)
+ new_lines.append(pytree.Node(syms.simple_stmt,
+ [stmt, end.clone()]))
+
+ if args.type == syms.tfpdef:
+ handle_tuple(args)
+ elif args.type == syms.typedargslist:
+ for i, arg in enumerate(args.children):
+ if arg.type == syms.tfpdef:
+ # Without add_prefix, the emitted code is correct,
+ # just ugly.
+ handle_tuple(arg, add_prefix=(i > 0))
+
+ if not new_lines:
+ return
+
+ # This isn't strictly necessary, but it plays nicely with other fixers.
+ # TODO(cwinter) get rid of this when children becomes a smart list
+ for line in new_lines:
+ line.parent = suite[0]
+
+ # TODO(cwinter) suite-cleanup
+ after = start
+ if start == 0:
+ new_lines[0].prefix = u" "
+ elif is_docstring(suite[0].children[start]):
+ new_lines[0].prefix = indent
+ after = start + 1
+
+ for line in new_lines:
+ line.parent = suite[0]
+ suite[0].children[after:after] = new_lines
+ for i in range(after+1, after+len(new_lines)+1):
+ suite[0].children[i].prefix = indent
+ suite[0].changed()
+
+ def transform_lambda(self, node, results):
+ args = results["args"]
+ body = results["body"]
+ inner = simplify_args(results["inner"])
+
+ # Replace lambda ((((x)))): x with lambda x: x
+ if inner.type == token.NAME:
+ inner = inner.clone()
+ inner.prefix = u" "
+ args.replace(inner)
+ return
+
+ params = find_params(args)
+ to_index = map_to_index(params)
+ tup_name = self.new_name(tuple_name(params))
+
+ new_param = Name(tup_name, prefix=u" ")
+ args.replace(new_param.clone())
+ for n in body.post_order():
+ if n.type == token.NAME and n.value in to_index:
+ subscripts = [c.clone() for c in to_index[n.value]]
+ new = pytree.Node(syms.power,
+ [new_param.clone()] + subscripts)
+ new.prefix = n.prefix
+ n.replace(new)
+
+
+### Helper functions for transform_lambda()
+
+def simplify_args(node):
+ if node.type in (syms.vfplist, token.NAME):
+ return node
+ elif node.type == syms.vfpdef:
+ # These look like vfpdef< '(' x ')' > where x is NAME
+ # or another vfpdef instance (leading to recursion).
+ while node.type == syms.vfpdef:
+ node = node.children[1]
+ return node
+ raise RuntimeError("Received unexpected node %s" % node)
+
+def find_params(node):
+ if node.type == syms.vfpdef:
+ return find_params(node.children[1])
+ elif node.type == token.NAME:
+ return node.value
+ return [find_params(c) for c in node.children if c.type != token.COMMA]
+
+def map_to_index(param_list, prefix=[], d=None):
+ if d is None:
+ d = {}
+ for i, obj in enumerate(param_list):
+ trailer = [Subscript(Number(unicode(i)))]
+ if isinstance(obj, list):
+ map_to_index(obj, trailer, d=d)
+ else:
+ d[obj] = prefix + trailer
+ return d
+
+def tuple_name(param_list):
+ l = []
+ for obj in param_list:
+ if isinstance(obj, list):
+ l.append(tuple_name(obj))
+ else:
+ l.append(obj)
+ return u"_".join(l)
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_types.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_types.py
new file mode 100644
index 000000000000..fc9d4959276a
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_types.py
@@ -0,0 +1,62 @@
+# Copyright 2007 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer for removing uses of the types module.
+
+These work for only the known names in the types module. The forms above
+can include types. or not. ie, It is assumed the module is imported either as:
+
+ import types
+ from types import ... # either * or specific types
+
+The import statements are not modified.
+
+There should be another fixer that handles at least the following constants:
+
+ type([]) -> list
+ type(()) -> tuple
+ type('') -> str
+
+"""
+
+# Local imports
+from ..pgen2 import token
+from .. import fixer_base
+from ..fixer_util import Name
+
+_TYPE_MAPPING = {
+ 'BooleanType' : 'bool',
+ 'BufferType' : 'memoryview',
+ 'ClassType' : 'type',
+ 'ComplexType' : 'complex',
+ 'DictType': 'dict',
+ 'DictionaryType' : 'dict',
+ 'EllipsisType' : 'type(Ellipsis)',
+ #'FileType' : 'io.IOBase',
+ 'FloatType': 'float',
+ 'IntType': 'int',
+ 'ListType': 'list',
+ 'LongType': 'int',
+ 'ObjectType' : 'object',
+ 'NoneType': 'type(None)',
+ 'NotImplementedType' : 'type(NotImplemented)',
+ 'SliceType' : 'slice',
+ 'StringType': 'bytes', # XXX ?
+ 'StringTypes' : 'str', # XXX ?
+ 'TupleType': 'tuple',
+ 'TypeType' : 'type',
+ 'UnicodeType': 'str',
+ 'XRangeType' : 'range',
+ }
+
+_pats = ["power< 'types' trailer< '.' name='%s' > >" % t for t in _TYPE_MAPPING]
+
+class FixTypes(fixer_base.BaseFix):
+ BM_compatible = True
+ PATTERN = '|'.join(_pats)
+
+ def transform(self, node, results):
+ new_value = unicode(_TYPE_MAPPING.get(results["name"].value))
+ if new_value:
+ return Name(new_value, prefix=node.prefix)
+ return None
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_unicode.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_unicode.py
new file mode 100644
index 000000000000..2d776f61051e
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_unicode.py
@@ -0,0 +1,42 @@
+r"""Fixer for unicode.
+
+* Changes unicode to str and unichr to chr.
+
+* If "...\u..." is not unicode literal change it into "...\\u...".
+
+* Change u"..." into "...".
+
+"""
+
+from ..pgen2 import token
+from .. import fixer_base
+
+_mapping = {u"unichr" : u"chr", u"unicode" : u"str"}
+
+class FixUnicode(fixer_base.BaseFix):
+ BM_compatible = True
+ PATTERN = "STRING | 'unicode' | 'unichr'"
+
+ def start_tree(self, tree, filename):
+ super(FixUnicode, self).start_tree(tree, filename)
+ self.unicode_literals = 'unicode_literals' in tree.future_features
+
+ def transform(self, node, results):
+ if node.type == token.NAME:
+ new = node.clone()
+ new.value = _mapping[node.value]
+ return new
+ elif node.type == token.STRING:
+ val = node.value
+ if not self.unicode_literals and val[0] in u'\'"' and u'\\' in val:
+ val = ur'\\'.join([
+ v.replace(u'\\u', ur'\\u').replace(u'\\U', ur'\\U')
+ for v in val.split(ur'\\')
+ ])
+ if val[0] in u'uU':
+ val = val[1:]
+ if val == node.value:
+ return node
+ new = node.clone()
+ new.value = val
+ return new
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_urllib.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_urllib.py
new file mode 100644
index 000000000000..34e1b2702ba0
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_urllib.py
@@ -0,0 +1,197 @@
+"""Fix changes imports of urllib which are now incompatible.
+ This is rather similar to fix_imports, but because of the more
+ complex nature of the fixing for urllib, it has its own fixer.
+"""
+# Author: Nick Edds
+
+# Local imports
+from lib2to3.fixes.fix_imports import alternates, FixImports
+from lib2to3 import fixer_base
+from lib2to3.fixer_util import (Name, Comma, FromImport, Newline,
+ find_indentation, Node, syms)
+
+MAPPING = {"urllib": [
+ ("urllib.request",
+ ["URLopener", "FancyURLopener", "urlretrieve",
+ "_urlopener", "urlopen", "urlcleanup",
+ "pathname2url", "url2pathname"]),
+ ("urllib.parse",
+ ["quote", "quote_plus", "unquote", "unquote_plus",
+ "urlencode", "splitattr", "splithost", "splitnport",
+ "splitpasswd", "splitport", "splitquery", "splittag",
+ "splittype", "splituser", "splitvalue", ]),
+ ("urllib.error",
+ ["ContentTooShortError"])],
+ "urllib2" : [
+ ("urllib.request",
+ ["urlopen", "install_opener", "build_opener",
+ "Request", "OpenerDirector", "BaseHandler",
+ "HTTPDefaultErrorHandler", "HTTPRedirectHandler",
+ "HTTPCookieProcessor", "ProxyHandler",
+ "HTTPPasswordMgr",
+ "HTTPPasswordMgrWithDefaultRealm",
+ "AbstractBasicAuthHandler",
+ "HTTPBasicAuthHandler", "ProxyBasicAuthHandler",
+ "AbstractDigestAuthHandler",
+ "HTTPDigestAuthHandler", "ProxyDigestAuthHandler",
+ "HTTPHandler", "HTTPSHandler", "FileHandler",
+ "FTPHandler", "CacheFTPHandler",
+ "UnknownHandler"]),
+ ("urllib.error",
+ ["URLError", "HTTPError"]),
+ ]
+}
+
+# Duplicate the url parsing functions for urllib2.
+MAPPING["urllib2"].append(MAPPING["urllib"][1])
+
+
+def build_pattern():
+ bare = set()
+ for old_module, changes in MAPPING.items():
+ for change in changes:
+ new_module, members = change
+ members = alternates(members)
+ yield """import_name< 'import' (module=%r
+ | dotted_as_names< any* module=%r any* >) >
+ """ % (old_module, old_module)
+ yield """import_from< 'from' mod_member=%r 'import'
+ ( member=%s | import_as_name< member=%s 'as' any > |
+ import_as_names< members=any* >) >
+ """ % (old_module, members, members)
+ yield """import_from< 'from' module_star=%r 'import' star='*' >
+ """ % old_module
+ yield """import_name< 'import'
+ dotted_as_name< module_as=%r 'as' any > >
+ """ % old_module
+ # bare_with_attr has a special significance for FixImports.match().
+ yield """power< bare_with_attr=%r trailer< '.' member=%s > any* >
+ """ % (old_module, members)
+
+
+class FixUrllib(FixImports):
+
+ def build_pattern(self):
+ return "|".join(build_pattern())
+
+ def transform_import(self, node, results):
+ """Transform for the basic import case. Replaces the old
+ import name with a comma separated list of its
+ replacements.
+ """
+ import_mod = results.get("module")
+ pref = import_mod.prefix
+
+ names = []
+
+ # create a Node list of the replacement modules
+ for name in MAPPING[import_mod.value][:-1]:
+ names.extend([Name(name[0], prefix=pref), Comma()])
+ names.append(Name(MAPPING[import_mod.value][-1][0], prefix=pref))
+ import_mod.replace(names)
+
+ def transform_member(self, node, results):
+ """Transform for imports of specific module elements. Replaces
+ the module to be imported from with the appropriate new
+ module.
+ """
+ mod_member = results.get("mod_member")
+ pref = mod_member.prefix
+ member = results.get("member")
+
+ # Simple case with only a single member being imported
+ if member:
+ # this may be a list of length one, or just a node
+ if isinstance(member, list):
+ member = member[0]
+ new_name = None
+ for change in MAPPING[mod_member.value]:
+ if member.value in change[1]:
+ new_name = change[0]
+ break
+ if new_name:
+ mod_member.replace(Name(new_name, prefix=pref))
+ else:
+ self.cannot_convert(node, "This is an invalid module element")
+
+ # Multiple members being imported
+ else:
+ # a dictionary for replacements, order matters
+ modules = []
+ mod_dict = {}
+ members = results["members"]
+ for member in members:
+ # we only care about the actual members
+ if member.type == syms.import_as_name:
+ as_name = member.children[2].value
+ member_name = member.children[0].value
+ else:
+ member_name = member.value
+ as_name = None
+ if member_name != u",":
+ for change in MAPPING[mod_member.value]:
+ if member_name in change[1]:
+ if change[0] not in mod_dict:
+ modules.append(change[0])
+ mod_dict.setdefault(change[0], []).append(member)
+
+ new_nodes = []
+ indentation = find_indentation(node)
+ first = True
+ def handle_name(name, prefix):
+ if name.type == syms.import_as_name:
+ kids = [Name(name.children[0].value, prefix=prefix),
+ name.children[1].clone(),
+ name.children[2].clone()]
+ return [Node(syms.import_as_name, kids)]
+ return [Name(name.value, prefix=prefix)]
+ for module in modules:
+ elts = mod_dict[module]
+ names = []
+ for elt in elts[:-1]:
+ names.extend(handle_name(elt, pref))
+ names.append(Comma())
+ names.extend(handle_name(elts[-1], pref))
+ new = FromImport(module, names)
+ if not first or node.parent.prefix.endswith(indentation):
+ new.prefix = indentation
+ new_nodes.append(new)
+ first = False
+ if new_nodes:
+ nodes = []
+ for new_node in new_nodes[:-1]:
+ nodes.extend([new_node, Newline()])
+ nodes.append(new_nodes[-1])
+ node.replace(nodes)
+ else:
+ self.cannot_convert(node, "All module elements are invalid")
+
+ def transform_dot(self, node, results):
+ """Transform for calls to module members in code."""
+ module_dot = results.get("bare_with_attr")
+ member = results.get("member")
+ new_name = None
+ if isinstance(member, list):
+ member = member[0]
+ for change in MAPPING[module_dot.value]:
+ if member.value in change[1]:
+ new_name = change[0]
+ break
+ if new_name:
+ module_dot.replace(Name(new_name,
+ prefix=module_dot.prefix))
+ else:
+ self.cannot_convert(node, "This is an invalid module element")
+
+ def transform(self, node, results):
+ if results.get("module"):
+ self.transform_import(node, results)
+ elif results.get("mod_member"):
+ self.transform_member(node, results)
+ elif results.get("bare_with_attr"):
+ self.transform_dot(node, results)
+ # Renaming and star imports are not supported for these modules.
+ elif results.get("module_star"):
+ self.cannot_convert(node, "Cannot handle star imports.")
+ elif results.get("module_as"):
+ self.cannot_convert(node, "This module is now multiple modules")
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_ws_comma.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_ws_comma.py
new file mode 100644
index 000000000000..37ff6244a937
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_ws_comma.py
@@ -0,0 +1,39 @@
+"""Fixer that changes 'a ,b' into 'a, b'.
+
+This also changes '{a :b}' into '{a: b}', but does not touch other
+uses of colons. It does not touch other uses of whitespace.
+
+"""
+
+from .. import pytree
+from ..pgen2 import token
+from .. import fixer_base
+
+class FixWsComma(fixer_base.BaseFix):
+
+ explicit = True # The user must ask for this fixers
+
+ PATTERN = """
+ any<(not(',') any)+ ',' ((not(',') any)+ ',')* [not(',') any]>
+ """
+
+ COMMA = pytree.Leaf(token.COMMA, u",")
+ COLON = pytree.Leaf(token.COLON, u":")
+ SEPS = (COMMA, COLON)
+
+ def transform(self, node, results):
+ new = node.clone()
+ comma = False
+ for child in new.children:
+ if child in self.SEPS:
+ prefix = child.prefix
+ if prefix.isspace() and u"\n" not in prefix:
+ child.prefix = u""
+ comma = True
+ else:
+ if comma:
+ prefix = child.prefix
+ if not prefix:
+ child.prefix = u" "
+ comma = False
+ return new
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_xrange.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_xrange.py
new file mode 100644
index 000000000000..f1436724b454
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_xrange.py
@@ -0,0 +1,73 @@
+# Copyright 2007 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer that changes xrange(...) into range(...)."""
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Name, Call, consuming_calls
+from .. import patcomp
+
+
+class FixXrange(fixer_base.BaseFix):
+ BM_compatible = True
+ PATTERN = """
+ power<
+ (name='range'|name='xrange') trailer< '(' args=any ')' >
+ rest=any* >
+ """
+
+ def start_tree(self, tree, filename):
+ super(FixXrange, self).start_tree(tree, filename)
+ self.transformed_xranges = set()
+
+ def finish_tree(self, tree, filename):
+ self.transformed_xranges = None
+
+ def transform(self, node, results):
+ name = results["name"]
+ if name.value == u"xrange":
+ return self.transform_xrange(node, results)
+ elif name.value == u"range":
+ return self.transform_range(node, results)
+ else:
+ raise ValueError(repr(name))
+
+ def transform_xrange(self, node, results):
+ name = results["name"]
+ name.replace(Name(u"range", prefix=name.prefix))
+ # This prevents the new range call from being wrapped in a list later.
+ self.transformed_xranges.add(id(node))
+
+ def transform_range(self, node, results):
+ if (id(node) not in self.transformed_xranges and
+ not self.in_special_context(node)):
+ range_call = Call(Name(u"range"), [results["args"].clone()])
+ # Encase the range call in list().
+ list_call = Call(Name(u"list"), [range_call],
+ prefix=node.prefix)
+ # Put things that were after the range() call after the list call.
+ for n in results["rest"]:
+ list_call.append_child(n)
+ return list_call
+
+ P1 = "power< func=NAME trailer< '(' node=any ')' > any* >"
+ p1 = patcomp.compile_pattern(P1)
+
+ P2 = """for_stmt< 'for' any 'in' node=any ':' any* >
+ | comp_for< 'for' any 'in' node=any any* >
+ | comparison< any 'in' node=any any*>
+ """
+ p2 = patcomp.compile_pattern(P2)
+
+ def in_special_context(self, node):
+ if node.parent is None:
+ return False
+ results = {}
+ if (node.parent.parent is not None and
+ self.p1.match(node.parent.parent, results) and
+ results["node"] is node):
+ # list(d.keys()) -> list(d.keys()), etc.
+ return results["func"].value in consuming_calls
+ # for ... in d.iterkeys() -> for ... in d.keys(), etc.
+ return self.p2.match(node.parent, results) and results["node"] is node
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_xreadlines.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_xreadlines.py
new file mode 100644
index 000000000000..f50b9a27558f
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_xreadlines.py
@@ -0,0 +1,25 @@
+"""Fix "for x in f.xreadlines()" -> "for x in f".
+
+This fixer will also convert g(f.xreadlines) into g(f.__iter__)."""
+# Author: Collin Winter
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Name
+
+
+class FixXreadlines(fixer_base.BaseFix):
+ BM_compatible = True
+ PATTERN = """
+ power< call=any+ trailer< '.' 'xreadlines' > trailer< '(' ')' > >
+ |
+ power< any+ trailer< '.' no_call='xreadlines' > >
+ """
+
+ def transform(self, node, results):
+ no_call = results.get("no_call")
+
+ if no_call:
+ no_call.replace(Name(u"__iter__", prefix=no_call.prefix))
+ else:
+ node.replace([x.clone() for x in results["call"]])
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_zip.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_zip.py
new file mode 100644
index 000000000000..c5d7b66d6739
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/fixes/fix_zip.py
@@ -0,0 +1,35 @@
+"""
+Fixer that changes zip(seq0, seq1, ...) into list(zip(seq0, seq1, ...)
+unless there exists a 'from future_builtins import zip' statement in the
+top-level namespace.
+
+We avoid the transformation if the zip() call is directly contained in
+iter(<>), list(<>), tuple(<>), sorted(<>), ...join(<>), or for V in <>:.
+"""
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Name, Call, in_special_context
+
+class FixZip(fixer_base.ConditionalFix):
+
+ BM_compatible = True
+ PATTERN = """
+ power< 'zip' args=trailer< '(' [any] ')' >
+ >
+ """
+
+ skip_on = "future_builtins.zip"
+
+ def transform(self, node, results):
+ if self.should_skip(node):
+ return
+
+ if in_special_context(node):
+ return None
+
+ new = node.clone()
+ new.prefix = u""
+ new = Call(Name(u"list"), [new])
+ new.prefix = node.prefix
+ return new
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/main.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/main.py
new file mode 100644
index 000000000000..ad0625e52730
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/main.py
@@ -0,0 +1,269 @@
+"""
+Main program for 2to3.
+"""
+
+from __future__ import with_statement
+
+import sys
+import os
+import difflib
+import logging
+import shutil
+import optparse
+
+from . import refactor
+
+
+def diff_texts(a, b, filename):
+ """Return a unified diff of two strings."""
+ a = a.splitlines()
+ b = b.splitlines()
+ return difflib.unified_diff(a, b, filename, filename,
+ "(original)", "(refactored)",
+ lineterm="")
+
+
+class StdoutRefactoringTool(refactor.MultiprocessRefactoringTool):
+ """
+ A refactoring tool that can avoid overwriting its input files.
+ Prints output to stdout.
+
+ Output files can optionally be written to a different directory and or
+ have an extra file suffix appended to their name for use in situations
+ where you do not want to replace the input files.
+ """
+
+ def __init__(self, fixers, options, explicit, nobackups, show_diffs,
+ input_base_dir='', output_dir='', append_suffix=''):
+ """
+ Args:
+ fixers: A list of fixers to import.
+ options: A dict with RefactoringTool configuration.
+ explicit: A list of fixers to run even if they are explicit.
+ nobackups: If true no backup '.bak' files will be created for those
+ files that are being refactored.
+ show_diffs: Should diffs of the refactoring be printed to stdout?
+ input_base_dir: The base directory for all input files. This class
+ will strip this path prefix off of filenames before substituting
+ it with output_dir. Only meaningful if output_dir is supplied.
+ All files processed by refactor() must start with this path.
+ output_dir: If supplied, all converted files will be written into
+ this directory tree instead of input_base_dir.
+ append_suffix: If supplied, all files output by this tool will have
+ this appended to their filename. Useful for changing .py to
+ .py3 for example by passing append_suffix='3'.
+ """
+ self.nobackups = nobackups
+ self.show_diffs = show_diffs
+ if input_base_dir and not input_base_dir.endswith(os.sep):
+ input_base_dir += os.sep
+ self._input_base_dir = input_base_dir
+ self._output_dir = output_dir
+ self._append_suffix = append_suffix
+ super(StdoutRefactoringTool, self).__init__(fixers, options, explicit)
+
+ def log_error(self, msg, *args, **kwargs):
+ self.errors.append((msg, args, kwargs))
+ self.logger.error(msg, *args, **kwargs)
+
+ def write_file(self, new_text, filename, old_text, encoding):
+ orig_filename = filename
+ if self._output_dir:
+ if filename.startswith(self._input_base_dir):
+ filename = os.path.join(self._output_dir,
+ filename[len(self._input_base_dir):])
+ else:
+ raise ValueError('filename %s does not start with the '
+ 'input_base_dir %s' % (
+ filename, self._input_base_dir))
+ if self._append_suffix:
+ filename += self._append_suffix
+ if orig_filename != filename:
+ output_dir = os.path.dirname(filename)
+ if not os.path.isdir(output_dir):
+ os.makedirs(output_dir)
+ self.log_message('Writing converted %s to %s.', orig_filename,
+ filename)
+ if not self.nobackups:
+ # Make backup
+ backup = filename + ".bak"
+ if os.path.lexists(backup):
+ try:
+ os.remove(backup)
+ except os.error, err:
+ self.log_message("Can't remove backup %s", backup)
+ try:
+ os.rename(filename, backup)
+ except os.error, err:
+ self.log_message("Can't rename %s to %s", filename, backup)
+ # Actually write the new file
+ write = super(StdoutRefactoringTool, self).write_file
+ write(new_text, filename, old_text, encoding)
+ if not self.nobackups:
+ shutil.copymode(backup, filename)
+ if orig_filename != filename:
+ # Preserve the file mode in the new output directory.
+ shutil.copymode(orig_filename, filename)
+
+ def print_output(self, old, new, filename, equal):
+ if equal:
+ self.log_message("No changes to %s", filename)
+ else:
+ self.log_message("Refactored %s", filename)
+ if self.show_diffs:
+ diff_lines = diff_texts(old, new, filename)
+ try:
+ if self.output_lock is not None:
+ with self.output_lock:
+ for line in diff_lines:
+ print line
+ sys.stdout.flush()
+ else:
+ for line in diff_lines:
+ print line
+ except UnicodeEncodeError:
+ warn("couldn't encode %s's diff for your terminal" %
+ (filename,))
+ return
+
+
+def warn(msg):
+ print >> sys.stderr, "WARNING: %s" % (msg,)
+
+
+def main(fixer_pkg, args=None):
+ """Main program.
+
+ Args:
+ fixer_pkg: the name of a package where the fixers are located.
+ args: optional; a list of command line arguments. If omitted,
+ sys.argv[1:] is used.
+
+ Returns a suggested exit status (0, 1, 2).
+ """
+ # Set up option parser
+ parser = optparse.OptionParser(usage="2to3 [options] file|dir ...")
+ parser.add_option("-d", "--doctests_only", action="store_true",
+ help="Fix up doctests only")
+ parser.add_option("-f", "--fix", action="append", default=[],
+ help="Each FIX specifies a transformation; default: all")
+ parser.add_option("-j", "--processes", action="store", default=1,
+ type="int", help="Run 2to3 concurrently")
+ parser.add_option("-x", "--nofix", action="append", default=[],
+ help="Prevent a transformation from being run")
+ parser.add_option("-l", "--list-fixes", action="store_true",
+ help="List available transformations")
+ parser.add_option("-p", "--print-function", action="store_true",
+ help="Modify the grammar so that print() is a function")
+ parser.add_option("-v", "--verbose", action="store_true",
+ help="More verbose logging")
+ parser.add_option("--no-diffs", action="store_true",
+ help="Don't show diffs of the refactoring")
+ parser.add_option("-w", "--write", action="store_true",
+ help="Write back modified files")
+ parser.add_option("-n", "--nobackups", action="store_true", default=False,
+ help="Don't write backups for modified files")
+ parser.add_option("-o", "--output-dir", action="store", type="str",
+ default="", help="Put output files in this directory "
+ "instead of overwriting the input files. Requires -n.")
+ parser.add_option("-W", "--write-unchanged-files", action="store_true",
+ help="Also write files even if no changes were required"
+ " (useful with --output-dir); implies -w.")
+ parser.add_option("--add-suffix", action="store", type="str", default="",
+ help="Append this string to all output filenames."
+ " Requires -n if non-empty. "
+ "ex: --add-suffix='3' will generate .py3 files.")
+
+ # Parse command line arguments
+ refactor_stdin = False
+ flags = {}
+ options, args = parser.parse_args(args)
+ if options.write_unchanged_files:
+ flags["write_unchanged_files"] = True
+ if not options.write:
+ warn("--write-unchanged-files/-W implies -w.")
+ options.write = True
+ # If we allowed these, the original files would be renamed to backup names
+ # but not replaced.
+ if options.output_dir and not options.nobackups:
+ parser.error("Can't use --output-dir/-o without -n.")
+ if options.add_suffix and not options.nobackups:
+ parser.error("Can't use --add-suffix without -n.")
+
+ if not options.write and options.no_diffs:
+ warn("not writing files and not printing diffs; that's not very useful")
+ if not options.write and options.nobackups:
+ parser.error("Can't use -n without -w")
+ if options.list_fixes:
+ print "Available transformations for the -f/--fix option:"
+ for fixname in refactor.get_all_fix_names(fixer_pkg):
+ print fixname
+ if not args:
+ return 0
+ if not args:
+ print >> sys.stderr, "At least one file or directory argument required."
+ print >> sys.stderr, "Use --help to show usage."
+ return 2
+ if "-" in args:
+ refactor_stdin = True
+ if options.write:
+ print >> sys.stderr, "Can't write to stdin."
+ return 2
+ if options.print_function:
+ flags["print_function"] = True
+
+ # Set up logging handler
+ level = logging.DEBUG if options.verbose else logging.INFO
+ logging.basicConfig(format='%(name)s: %(message)s', level=level)
+ logger = logging.getLogger('lib2to3.main')
+
+ # Initialize the refactoring tool
+ avail_fixes = set(refactor.get_fixers_from_package(fixer_pkg))
+ unwanted_fixes = set(fixer_pkg + ".fix_" + fix for fix in options.nofix)
+ explicit = set()
+ if options.fix:
+ all_present = False
+ for fix in options.fix:
+ if fix == "all":
+ all_present = True
+ else:
+ explicit.add(fixer_pkg + ".fix_" + fix)
+ requested = avail_fixes.union(explicit) if all_present else explicit
+ else:
+ requested = avail_fixes.union(explicit)
+ fixer_names = requested.difference(unwanted_fixes)
+ input_base_dir = os.path.commonprefix(args)
+ if (input_base_dir and not input_base_dir.endswith(os.sep)
+ and not os.path.isdir(input_base_dir)):
+ # One or more similar names were passed, their directory is the base.
+ # os.path.commonprefix() is ignorant of path elements, this corrects
+ # for that weird API.
+ input_base_dir = os.path.dirname(input_base_dir)
+ if options.output_dir:
+ input_base_dir = input_base_dir.rstrip(os.sep)
+ logger.info('Output in %r will mirror the input directory %r layout.',
+ options.output_dir, input_base_dir)
+ rt = StdoutRefactoringTool(
+ sorted(fixer_names), flags, sorted(explicit),
+ options.nobackups, not options.no_diffs,
+ input_base_dir=input_base_dir,
+ output_dir=options.output_dir,
+ append_suffix=options.add_suffix)
+
+ # Refactor all files and directories passed as arguments
+ if not rt.errors:
+ if refactor_stdin:
+ rt.refactor_stdin()
+ else:
+ try:
+ rt.refactor(args, options.write, options.doctests_only,
+ options.processes)
+ except refactor.MultiprocessingUnsupported:
+ assert options.processes > 1
+ print >> sys.stderr, "Sorry, -j isn't " \
+ "supported on this platform."
+ return 1
+ rt.summarize()
+
+ # Return error status (0 if rt.errors is zero)
+ return int(bool(rt.errors))
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/patcomp.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/patcomp.py
new file mode 100644
index 000000000000..093e5f9f8df0
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/patcomp.py
@@ -0,0 +1,205 @@
+# Copyright 2006 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Pattern compiler.
+
+The grammer is taken from PatternGrammar.txt.
+
+The compiler compiles a pattern to a pytree.*Pattern instance.
+"""
+
+__author__ = "Guido van Rossum <guido@python.org>"
+
+# Python imports
+import os
+import StringIO
+
+# Fairly local imports
+from .pgen2 import driver, literals, token, tokenize, parse, grammar
+
+# Really local imports
+from . import pytree
+from . import pygram
+
+# The pattern grammar file
+_PATTERN_GRAMMAR_FILE = os.path.join(os.path.dirname(__file__),
+ "PatternGrammar.txt")
+
+
+class PatternSyntaxError(Exception):
+ pass
+
+
+def tokenize_wrapper(input):
+ """Tokenizes a string suppressing significant whitespace."""
+ skip = set((token.NEWLINE, token.INDENT, token.DEDENT))
+ tokens = tokenize.generate_tokens(StringIO.StringIO(input).readline)
+ for quintuple in tokens:
+ type, value, start, end, line_text = quintuple
+ if type not in skip:
+ yield quintuple
+
+
+class PatternCompiler(object):
+
+ def __init__(self, grammar_file=_PATTERN_GRAMMAR_FILE):
+ """Initializer.
+
+ Takes an optional alternative filename for the pattern grammar.
+ """
+ self.grammar = driver.load_grammar(grammar_file)
+ self.syms = pygram.Symbols(self.grammar)
+ self.pygrammar = pygram.python_grammar
+ self.pysyms = pygram.python_symbols
+ self.driver = driver.Driver(self.grammar, convert=pattern_convert)
+
+ def compile_pattern(self, input, debug=False, with_tree=False):
+ """Compiles a pattern string to a nested pytree.*Pattern object."""
+ tokens = tokenize_wrapper(input)
+ try:
+ root = self.driver.parse_tokens(tokens, debug=debug)
+ except parse.ParseError as e:
+ raise PatternSyntaxError(str(e))
+ if with_tree:
+ return self.compile_node(root), root
+ else:
+ return self.compile_node(root)
+
+ def compile_node(self, node):
+ """Compiles a node, recursively.
+
+ This is one big switch on the node type.
+ """
+ # XXX Optimize certain Wildcard-containing-Wildcard patterns
+ # that can be merged
+ if node.type == self.syms.Matcher:
+ node = node.children[0] # Avoid unneeded recursion
+
+ if node.type == self.syms.Alternatives:
+ # Skip the odd children since they are just '|' tokens
+ alts = [self.compile_node(ch) for ch in node.children[::2]]
+ if len(alts) == 1:
+ return alts[0]
+ p = pytree.WildcardPattern([[a] for a in alts], min=1, max=1)
+ return p.optimize()
+
+ if node.type == self.syms.Alternative:
+ units = [self.compile_node(ch) for ch in node.children]
+ if len(units) == 1:
+ return units[0]
+ p = pytree.WildcardPattern([units], min=1, max=1)
+ return p.optimize()
+
+ if node.type == self.syms.NegatedUnit:
+ pattern = self.compile_basic(node.children[1:])
+ p = pytree.NegatedPattern(pattern)
+ return p.optimize()
+
+ assert node.type == self.syms.Unit
+
+ name = None
+ nodes = node.children
+ if len(nodes) >= 3 and nodes[1].type == token.EQUAL:
+ name = nodes[0].value
+ nodes = nodes[2:]
+ repeat = None
+ if len(nodes) >= 2 and nodes[-1].type == self.syms.Repeater:
+ repeat = nodes[-1]
+ nodes = nodes[:-1]
+
+ # Now we've reduced it to: STRING | NAME [Details] | (...) | [...]
+ pattern = self.compile_basic(nodes, repeat)
+
+ if repeat is not None:
+ assert repeat.type == self.syms.Repeater
+ children = repeat.children
+ child = children[0]
+ if child.type == token.STAR:
+ min = 0
+ max = pytree.HUGE
+ elif child.type == token.PLUS:
+ min = 1
+ max = pytree.HUGE
+ elif child.type == token.LBRACE:
+ assert children[-1].type == token.RBRACE
+ assert len(children) in (3, 5)
+ min = max = self.get_int(children[1])
+ if len(children) == 5:
+ max = self.get_int(children[3])
+ else:
+ assert False
+ if min != 1 or max != 1:
+ pattern = pattern.optimize()
+ pattern = pytree.WildcardPattern([[pattern]], min=min, max=max)
+
+ if name is not None:
+ pattern.name = name
+ return pattern.optimize()
+
+ def compile_basic(self, nodes, repeat=None):
+ # Compile STRING | NAME [Details] | (...) | [...]
+ assert len(nodes) >= 1
+ node = nodes[0]
+ if node.type == token.STRING:
+ value = unicode(literals.evalString(node.value))
+ return pytree.LeafPattern(_type_of_literal(value), value)
+ elif node.type == token.NAME:
+ value = node.value
+ if value.isupper():
+ if value not in TOKEN_MAP:
+ raise PatternSyntaxError("Invalid token: %r" % value)
+ if nodes[1:]:
+ raise PatternSyntaxError("Can't have details for token")
+ return pytree.LeafPattern(TOKEN_MAP[value])
+ else:
+ if value == "any":
+ type = None
+ elif not value.startswith("_"):
+ type = getattr(self.pysyms, value, None)
+ if type is None:
+ raise PatternSyntaxError("Invalid symbol: %r" % value)
+ if nodes[1:]: # Details present
+ content = [self.compile_node(nodes[1].children[1])]
+ else:
+ content = None
+ return pytree.NodePattern(type, content)
+ elif node.value == "(":
+ return self.compile_node(nodes[1])
+ elif node.value == "[":
+ assert repeat is None
+ subpattern = self.compile_node(nodes[1])
+ return pytree.WildcardPattern([[subpattern]], min=0, max=1)
+ assert False, node
+
+ def get_int(self, node):
+ assert node.type == token.NUMBER
+ return int(node.value)
+
+
+# Map named tokens to the type value for a LeafPattern
+TOKEN_MAP = {"NAME": token.NAME,
+ "STRING": token.STRING,
+ "NUMBER": token.NUMBER,
+ "TOKEN": None}
+
+
+def _type_of_literal(value):
+ if value[0].isalpha():
+ return token.NAME
+ elif value in grammar.opmap:
+ return grammar.opmap[value]
+ else:
+ return None
+
+
+def pattern_convert(grammar, raw_node_info):
+ """Converts raw node information to a Node or Leaf instance."""
+ type, value, context, children = raw_node_info
+ if children or type in grammar.number2symbol:
+ return pytree.Node(type, children, context=context)
+ else:
+ return pytree.Leaf(type, value, context=context)
+
+
+def compile_pattern(pattern):
+ return PatternCompiler().compile_pattern(pattern)
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/__init__.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/__init__.py
new file mode 100644
index 000000000000..af390484528d
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/__init__.py
@@ -0,0 +1,4 @@
+# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""The pgen2 package."""
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/conv.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/conv.py
new file mode 100644
index 000000000000..28fbb0b95f01
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/conv.py
@@ -0,0 +1,257 @@
+# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Convert graminit.[ch] spit out by pgen to Python code.
+
+Pgen is the Python parser generator. It is useful to quickly create a
+parser from a grammar file in Python's grammar notation. But I don't
+want my parsers to be written in C (yet), so I'm translating the
+parsing tables to Python data structures and writing a Python parse
+engine.
+
+Note that the token numbers are constants determined by the standard
+Python tokenizer. The standard token module defines these numbers and
+their names (the names are not used much). The token numbers are
+hardcoded into the Python tokenizer and into pgen. A Python
+implementation of the Python tokenizer is also available, in the
+standard tokenize module.
+
+On the other hand, symbol numbers (representing the grammar's
+non-terminals) are assigned by pgen based on the actual grammar
+input.
+
+Note: this module is pretty much obsolete; the pgen module generates
+equivalent grammar tables directly from the Grammar.txt input file
+without having to invoke the Python pgen C program.
+
+"""
+
+# Python imports
+import re
+
+# Local imports
+from pgen2 import grammar, token
+
+
+class Converter(grammar.Grammar):
+ """Grammar subclass that reads classic pgen output files.
+
+ The run() method reads the tables as produced by the pgen parser
+ generator, typically contained in two C files, graminit.h and
+ graminit.c. The other methods are for internal use only.
+
+ See the base class for more documentation.
+
+ """
+
+ def run(self, graminit_h, graminit_c):
+ """Load the grammar tables from the text files written by pgen."""
+ self.parse_graminit_h(graminit_h)
+ self.parse_graminit_c(graminit_c)
+ self.finish_off()
+
+ def parse_graminit_h(self, filename):
+ """Parse the .h file written by pgen. (Internal)
+
+ This file is a sequence of #define statements defining the
+ nonterminals of the grammar as numbers. We build two tables
+ mapping the numbers to names and back.
+
+ """
+ try:
+ f = open(filename)
+ except IOError, err:
+ print "Can't open %s: %s" % (filename, err)
+ return False
+ self.symbol2number = {}
+ self.number2symbol = {}
+ lineno = 0
+ for line in f:
+ lineno += 1
+ mo = re.match(r"^#define\s+(\w+)\s+(\d+)$", line)
+ if not mo and line.strip():
+ print "%s(%s): can't parse %s" % (filename, lineno,
+ line.strip())
+ else:
+ symbol, number = mo.groups()
+ number = int(number)
+ assert symbol not in self.symbol2number
+ assert number not in self.number2symbol
+ self.symbol2number[symbol] = number
+ self.number2symbol[number] = symbol
+ return True
+
+ def parse_graminit_c(self, filename):
+ """Parse the .c file written by pgen. (Internal)
+
+ The file looks as follows. The first two lines are always this:
+
+ #include "pgenheaders.h"
+ #include "grammar.h"
+
+ After that come four blocks:
+
+ 1) one or more state definitions
+ 2) a table defining dfas
+ 3) a table defining labels
+ 4) a struct defining the grammar
+
+ A state definition has the following form:
+ - one or more arc arrays, each of the form:
+ static arc arcs_<n>_<m>[<k>] = {
+ {<i>, <j>},
+ ...
+ };
+ - followed by a state array, of the form:
+ static state states_<s>[<t>] = {
+ {<k>, arcs_<n>_<m>},
+ ...
+ };
+
+ """
+ try:
+ f = open(filename)
+ except IOError, err:
+ print "Can't open %s: %s" % (filename, err)
+ return False
+ # The code below essentially uses f's iterator-ness!
+ lineno = 0
+
+ # Expect the two #include lines
+ lineno, line = lineno+1, f.next()
+ assert line == '#include "pgenheaders.h"\n', (lineno, line)
+ lineno, line = lineno+1, f.next()
+ assert line == '#include "grammar.h"\n', (lineno, line)
+
+ # Parse the state definitions
+ lineno, line = lineno+1, f.next()
+ allarcs = {}
+ states = []
+ while line.startswith("static arc "):
+ while line.startswith("static arc "):
+ mo = re.match(r"static arc arcs_(\d+)_(\d+)\[(\d+)\] = {$",
+ line)
+ assert mo, (lineno, line)
+ n, m, k = map(int, mo.groups())
+ arcs = []
+ for _ in range(k):
+ lineno, line = lineno+1, f.next()
+ mo = re.match(r"\s+{(\d+), (\d+)},$", line)
+ assert mo, (lineno, line)
+ i, j = map(int, mo.groups())
+ arcs.append((i, j))
+ lineno, line = lineno+1, f.next()
+ assert line == "};\n", (lineno, line)
+ allarcs[(n, m)] = arcs
+ lineno, line = lineno+1, f.next()
+ mo = re.match(r"static state states_(\d+)\[(\d+)\] = {$", line)
+ assert mo, (lineno, line)
+ s, t = map(int, mo.groups())
+ assert s == len(states), (lineno, line)
+ state = []
+ for _ in range(t):
+ lineno, line = lineno+1, f.next()
+ mo = re.match(r"\s+{(\d+), arcs_(\d+)_(\d+)},$", line)
+ assert mo, (lineno, line)
+ k, n, m = map(int, mo.groups())
+ arcs = allarcs[n, m]
+ assert k == len(arcs), (lineno, line)
+ state.append(arcs)
+ states.append(state)
+ lineno, line = lineno+1, f.next()
+ assert line == "};\n", (lineno, line)
+ lineno, line = lineno+1, f.next()
+ self.states = states
+
+ # Parse the dfas
+ dfas = {}
+ mo = re.match(r"static dfa dfas\[(\d+)\] = {$", line)
+ assert mo, (lineno, line)
+ ndfas = int(mo.group(1))
+ for i in range(ndfas):
+ lineno, line = lineno+1, f.next()
+ mo = re.match(r'\s+{(\d+), "(\w+)", (\d+), (\d+), states_(\d+),$',
+ line)
+ assert mo, (lineno, line)
+ symbol = mo.group(2)
+ number, x, y, z = map(int, mo.group(1, 3, 4, 5))
+ assert self.symbol2number[symbol] == number, (lineno, line)
+ assert self.number2symbol[number] == symbol, (lineno, line)
+ assert x == 0, (lineno, line)
+ state = states[z]
+ assert y == len(state), (lineno, line)
+ lineno, line = lineno+1, f.next()
+ mo = re.match(r'\s+("(?:\\\d\d\d)*")},$', line)
+ assert mo, (lineno, line)
+ first = {}
+ rawbitset = eval(mo.group(1))
+ for i, c in enumerate(rawbitset):
+ byte = ord(c)
+ for j in range(8):
+ if byte & (1<<j):
+ first[i*8 + j] = 1
+ dfas[number] = (state, first)
+ lineno, line = lineno+1, f.next()
+ assert line == "};\n", (lineno, line)
+ self.dfas = dfas
+
+ # Parse the labels
+ labels = []
+ lineno, line = lineno+1, f.next()
+ mo = re.match(r"static label labels\[(\d+)\] = {$", line)
+ assert mo, (lineno, line)
+ nlabels = int(mo.group(1))
+ for i in range(nlabels):
+ lineno, line = lineno+1, f.next()
+ mo = re.match(r'\s+{(\d+), (0|"\w+")},$', line)
+ assert mo, (lineno, line)
+ x, y = mo.groups()
+ x = int(x)
+ if y == "0":
+ y = None
+ else:
+ y = eval(y)
+ labels.append((x, y))
+ lineno, line = lineno+1, f.next()
+ assert line == "};\n", (lineno, line)
+ self.labels = labels
+
+ # Parse the grammar struct
+ lineno, line = lineno+1, f.next()
+ assert line == "grammar _PyParser_Grammar = {\n", (lineno, line)
+ lineno, line = lineno+1, f.next()
+ mo = re.match(r"\s+(\d+),$", line)
+ assert mo, (lineno, line)
+ ndfas = int(mo.group(1))
+ assert ndfas == len(self.dfas)
+ lineno, line = lineno+1, f.next()
+ assert line == "\tdfas,\n", (lineno, line)
+ lineno, line = lineno+1, f.next()
+ mo = re.match(r"\s+{(\d+), labels},$", line)
+ assert mo, (lineno, line)
+ nlabels = int(mo.group(1))
+ assert nlabels == len(self.labels), (lineno, line)
+ lineno, line = lineno+1, f.next()
+ mo = re.match(r"\s+(\d+)$", line)
+ assert mo, (lineno, line)
+ start = int(mo.group(1))
+ assert start in self.number2symbol, (lineno, line)
+ self.start = start
+ lineno, line = lineno+1, f.next()
+ assert line == "};\n", (lineno, line)
+ try:
+ lineno, line = lineno+1, f.next()
+ except StopIteration:
+ pass
+ else:
+ assert 0, (lineno, line)
+
+ def finish_off(self):
+ """Create additional useful structures. (Internal)."""
+ self.keywords = {} # map from keyword strings to arc labels
+ self.tokens = {} # map from numeric token values to arc labels
+ for ilabel, (type, value) in enumerate(self.labels):
+ if type == token.NAME and value is not None:
+ self.keywords[value] = ilabel
+ elif value is None:
+ self.tokens[type] = ilabel
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/driver.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/driver.py
new file mode 100644
index 000000000000..39dafb92accd
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/driver.py
@@ -0,0 +1,157 @@
+# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+# Modifications:
+# Copyright 2006 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Parser driver.
+
+This provides a high-level interface to parse a file into a syntax tree.
+
+"""
+
+__author__ = "Guido van Rossum <guido@python.org>"
+
+__all__ = ["Driver", "load_grammar"]
+
+# Python imports
+import codecs
+import os
+import logging
+import StringIO
+import sys
+
+# Pgen imports
+from . import grammar, parse, token, tokenize, pgen
+
+
+class Driver(object):
+
+ def __init__(self, grammar, convert=None, logger=None):
+ self.grammar = grammar
+ if logger is None:
+ logger = logging.getLogger()
+ self.logger = logger
+ self.convert = convert
+
+ def parse_tokens(self, tokens, debug=False):
+ """Parse a series of tokens and return the syntax tree."""
+ # XXX Move the prefix computation into a wrapper around tokenize.
+ p = parse.Parser(self.grammar, self.convert)
+ p.setup()
+ lineno = 1
+ column = 0
+ type = value = start = end = line_text = None
+ prefix = u""
+ for quintuple in tokens:
+ type, value, start, end, line_text = quintuple
+ if start != (lineno, column):
+ assert (lineno, column) <= start, ((lineno, column), start)
+ s_lineno, s_column = start
+ if lineno < s_lineno:
+ prefix += "\n" * (s_lineno - lineno)
+ lineno = s_lineno
+ column = 0
+ if column < s_column:
+ prefix += line_text[column:s_column]
+ column = s_column
+ if type in (tokenize.COMMENT, tokenize.NL):
+ prefix += value
+ lineno, column = end
+ if value.endswith("\n"):
+ lineno += 1
+ column = 0
+ continue
+ if type == token.OP:
+ type = grammar.opmap[value]
+ if debug:
+ self.logger.debug("%s %r (prefix=%r)",
+ token.tok_name[type], value, prefix)
+ if p.addtoken(type, value, (prefix, start)):
+ if debug:
+ self.logger.debug("Stop.")
+ break
+ prefix = ""
+ lineno, column = end
+ if value.endswith("\n"):
+ lineno += 1
+ column = 0
+ else:
+ # We never broke out -- EOF is too soon (how can this happen???)
+ raise parse.ParseError("incomplete input",
+ type, value, (prefix, start))
+ return p.rootnode
+
+ def parse_stream_raw(self, stream, debug=False):
+ """Parse a stream and return the syntax tree."""
+ tokens = tokenize.generate_tokens(stream.readline)
+ return self.parse_tokens(tokens, debug)
+
+ def parse_stream(self, stream, debug=False):
+ """Parse a stream and return the syntax tree."""
+ return self.parse_stream_raw(stream, debug)
+
+ def parse_file(self, filename, encoding=None, debug=False):
+ """Parse a file and return the syntax tree."""
+ stream = codecs.open(filename, "r", encoding)
+ try:
+ return self.parse_stream(stream, debug)
+ finally:
+ stream.close()
+
+ def parse_string(self, text, debug=False):
+ """Parse a string and return the syntax tree."""
+ tokens = tokenize.generate_tokens(StringIO.StringIO(text).readline)
+ return self.parse_tokens(tokens, debug)
+
+
+def load_grammar(gt="Grammar.txt", gp=None,
+ save=True, force=False, logger=None):
+ """Load the grammar (maybe from a pickle)."""
+ if logger is None:
+ logger = logging.getLogger()
+ if gp is None:
+ head, tail = os.path.splitext(gt)
+ if tail == ".txt":
+ tail = ""
+ gp = head + tail + ".".join(map(str, sys.version_info)) + ".pickle"
+ if force or not _newer(gp, gt):
+ logger.info("Generating grammar tables from %s", gt)
+ g = pgen.generate_grammar(gt)
+ if save:
+ logger.info("Writing grammar tables to %s", gp)
+ try:
+ g.dump(gp)
+ except IOError, e:
+ logger.info("Writing failed:"+str(e))
+ else:
+ g = grammar.Grammar()
+ g.load(gp)
+ return g
+
+
+def _newer(a, b):
+ """Inquire whether file a was written since file b."""
+ if not os.path.exists(a):
+ return False
+ if not os.path.exists(b):
+ return True
+ return os.path.getmtime(a) >= os.path.getmtime(b)
+
+
+def main(*args):
+ """Main program, when run as a script: produce grammar pickle files.
+
+ Calls load_grammar for each argument, a path to a grammar text file.
+ """
+ if not args:
+ args = sys.argv[1:]
+ logging.basicConfig(level=logging.INFO, stream=sys.stdout,
+ format='%(message)s')
+ for gt in args:
+ load_grammar(gt, save=True, force=True)
+ return True
+
+if __name__ == "__main__":
+ sys.exit(int(not main()))
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/grammar.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/grammar.py
new file mode 100644
index 000000000000..1aa5c4327803
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/grammar.py
@@ -0,0 +1,184 @@
+# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""This module defines the data structures used to represent a grammar.
+
+These are a bit arcane because they are derived from the data
+structures used by Python's 'pgen' parser generator.
+
+There's also a table here mapping operators to their names in the
+token module; the Python tokenize module reports all operators as the
+fallback token code OP, but the parser needs the actual token code.
+
+"""
+
+# Python imports
+import pickle
+
+# Local imports
+from . import token, tokenize
+
+
+class Grammar(object):
+ """Pgen parsing tables conversion class.
+
+ Once initialized, this class supplies the grammar tables for the
+ parsing engine implemented by parse.py. The parsing engine
+ accesses the instance variables directly. The class here does not
+ provide initialization of the tables; several subclasses exist to
+ do this (see the conv and pgen modules).
+
+ The load() method reads the tables from a pickle file, which is
+ much faster than the other ways offered by subclasses. The pickle
+ file is written by calling dump() (after loading the grammar
+ tables using a subclass). The report() method prints a readable
+ representation of the tables to stdout, for debugging.
+
+ The instance variables are as follows:
+
+ symbol2number -- a dict mapping symbol names to numbers. Symbol
+ numbers are always 256 or higher, to distinguish
+ them from token numbers, which are between 0 and
+ 255 (inclusive).
+
+ number2symbol -- a dict mapping numbers to symbol names;
+ these two are each other's inverse.
+
+ states -- a list of DFAs, where each DFA is a list of
+ states, each state is a list of arcs, and each
+ arc is a (i, j) pair where i is a label and j is
+ a state number. The DFA number is the index into
+ this list. (This name is slightly confusing.)
+ Final states are represented by a special arc of
+ the form (0, j) where j is its own state number.
+
+ dfas -- a dict mapping symbol numbers to (DFA, first)
+ pairs, where DFA is an item from the states list
+ above, and first is a set of tokens that can
+ begin this grammar rule (represented by a dict
+ whose values are always 1).
+
+ labels -- a list of (x, y) pairs where x is either a token
+ number or a symbol number, and y is either None
+ or a string; the strings are keywords. The label
+ number is the index in this list; label numbers
+ are used to mark state transitions (arcs) in the
+ DFAs.
+
+ start -- the number of the grammar's start symbol.
+
+ keywords -- a dict mapping keyword strings to arc labels.
+
+ tokens -- a dict mapping token numbers to arc labels.
+
+ """
+
+ def __init__(self):
+ self.symbol2number = {}
+ self.number2symbol = {}
+ self.states = []
+ self.dfas = {}
+ self.labels = [(0, "EMPTY")]
+ self.keywords = {}
+ self.tokens = {}
+ self.symbol2label = {}
+ self.start = 256
+
+ def dump(self, filename):
+ """Dump the grammar tables to a pickle file."""
+ f = open(filename, "wb")
+ pickle.dump(self.__dict__, f, 2)
+ f.close()
+
+ def load(self, filename):
+ """Load the grammar tables from a pickle file."""
+ f = open(filename, "rb")
+ d = pickle.load(f)
+ f.close()
+ self.__dict__.update(d)
+
+ def copy(self):
+ """
+ Copy the grammar.
+ """
+ new = self.__class__()
+ for dict_attr in ("symbol2number", "number2symbol", "dfas", "keywords",
+ "tokens", "symbol2label"):
+ setattr(new, dict_attr, getattr(self, dict_attr).copy())
+ new.labels = self.labels[:]
+ new.states = self.states[:]
+ new.start = self.start
+ return new
+
+ def report(self):
+ """Dump the grammar tables to standard output, for debugging."""
+ from pprint import pprint
+ print "s2n"
+ pprint(self.symbol2number)
+ print "n2s"
+ pprint(self.number2symbol)
+ print "states"
+ pprint(self.states)
+ print "dfas"
+ pprint(self.dfas)
+ print "labels"
+ pprint(self.labels)
+ print "start", self.start
+
+
+# Map from operator to number (since tokenize doesn't do this)
+
+opmap_raw = """
+( LPAR
+) RPAR
+[ LSQB
+] RSQB
+: COLON
+, COMMA
+; SEMI
++ PLUS
+- MINUS
+* STAR
+/ SLASH
+| VBAR
+& AMPER
+< LESS
+> GREATER
+= EQUAL
+. DOT
+% PERCENT
+` BACKQUOTE
+{ LBRACE
+} RBRACE
+@ AT
+== EQEQUAL
+!= NOTEQUAL
+<> NOTEQUAL
+<= LESSEQUAL
+>= GREATEREQUAL
+~ TILDE
+^ CIRCUMFLEX
+<< LEFTSHIFT
+>> RIGHTSHIFT
+** DOUBLESTAR
++= PLUSEQUAL
+-= MINEQUAL
+*= STAREQUAL
+/= SLASHEQUAL
+%= PERCENTEQUAL
+&= AMPEREQUAL
+|= VBAREQUAL
+^= CIRCUMFLEXEQUAL
+<<= LEFTSHIFTEQUAL
+>>= RIGHTSHIFTEQUAL
+**= DOUBLESTAREQUAL
+// DOUBLESLASH
+//= DOUBLESLASHEQUAL
+-> RARROW
+"""
+
+opmap = {}
+for line in opmap_raw.splitlines():
+ if line:
+ op, name = line.split()
+ opmap[op] = getattr(token, name)
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/literals.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/literals.py
new file mode 100644
index 000000000000..0b3948a54ead
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/literals.py
@@ -0,0 +1,60 @@
+# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Safely evaluate Python string literals without using eval()."""
+
+import re
+
+simple_escapes = {"a": "\a",
+ "b": "\b",
+ "f": "\f",
+ "n": "\n",
+ "r": "\r",
+ "t": "\t",
+ "v": "\v",
+ "'": "'",
+ '"': '"',
+ "\\": "\\"}
+
+def escape(m):
+ all, tail = m.group(0, 1)
+ assert all.startswith("\\")
+ esc = simple_escapes.get(tail)
+ if esc is not None:
+ return esc
+ if tail.startswith("x"):
+ hexes = tail[1:]
+ if len(hexes) < 2:
+ raise ValueError("invalid hex string escape ('\\%s')" % tail)
+ try:
+ i = int(hexes, 16)
+ except ValueError:
+ raise ValueError("invalid hex string escape ('\\%s')" % tail)
+ else:
+ try:
+ i = int(tail, 8)
+ except ValueError:
+ raise ValueError("invalid octal string escape ('\\%s')" % tail)
+ return chr(i)
+
+def evalString(s):
+ assert s.startswith("'") or s.startswith('"'), repr(s[:1])
+ q = s[0]
+ if s[:3] == q*3:
+ q = q*3
+ assert s.endswith(q), repr(s[-len(q):])
+ assert len(s) >= 2*len(q)
+ s = s[len(q):-len(q)]
+ return re.sub(r"\\(\'|\"|\\|[abfnrtv]|x.{0,2}|[0-7]{1,3})", escape, s)
+
+def test():
+ for i in range(256):
+ c = chr(i)
+ s = repr(c)
+ e = evalString(s)
+ if e != c:
+ print i, c, s, e
+
+
+if __name__ == "__main__":
+ test()
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/parse.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/parse.py
new file mode 100644
index 000000000000..6bebdbba7e52
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/parse.py
@@ -0,0 +1,201 @@
+# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Parser engine for the grammar tables generated by pgen.
+
+The grammar table must be loaded first.
+
+See Parser/parser.c in the Python distribution for additional info on
+how this parsing engine works.
+
+"""
+
+# Local imports
+from . import token
+
+class ParseError(Exception):
+ """Exception to signal the parser is stuck."""
+
+ def __init__(self, msg, type, value, context):
+ Exception.__init__(self, "%s: type=%r, value=%r, context=%r" %
+ (msg, type, value, context))
+ self.msg = msg
+ self.type = type
+ self.value = value
+ self.context = context
+
+class Parser(object):
+ """Parser engine.
+
+ The proper usage sequence is:
+
+ p = Parser(grammar, [converter]) # create instance
+ p.setup([start]) # prepare for parsing
+ <for each input token>:
+ if p.addtoken(...): # parse a token; may raise ParseError
+ break
+ root = p.rootnode # root of abstract syntax tree
+
+ A Parser instance may be reused by calling setup() repeatedly.
+
+ A Parser instance contains state pertaining to the current token
+ sequence, and should not be used concurrently by different threads
+ to parse separate token sequences.
+
+ See driver.py for how to get input tokens by tokenizing a file or
+ string.
+
+ Parsing is complete when addtoken() returns True; the root of the
+ abstract syntax tree can then be retrieved from the rootnode
+ instance variable. When a syntax error occurs, addtoken() raises
+ the ParseError exception. There is no error recovery; the parser
+ cannot be used after a syntax error was reported (but it can be
+ reinitialized by calling setup()).
+
+ """
+
+ def __init__(self, grammar, convert=None):
+ """Constructor.
+
+ The grammar argument is a grammar.Grammar instance; see the
+ grammar module for more information.
+
+ The parser is not ready yet for parsing; you must call the
+ setup() method to get it started.
+
+ The optional convert argument is a function mapping concrete
+ syntax tree nodes to abstract syntax tree nodes. If not
+ given, no conversion is done and the syntax tree produced is
+ the concrete syntax tree. If given, it must be a function of
+ two arguments, the first being the grammar (a grammar.Grammar
+ instance), and the second being the concrete syntax tree node
+ to be converted. The syntax tree is converted from the bottom
+ up.
+
+ A concrete syntax tree node is a (type, value, context, nodes)
+ tuple, where type is the node type (a token or symbol number),
+ value is None for symbols and a string for tokens, context is
+ None or an opaque value used for error reporting (typically a
+ (lineno, offset) pair), and nodes is a list of children for
+ symbols, and None for tokens.
+
+ An abstract syntax tree node may be anything; this is entirely
+ up to the converter function.
+
+ """
+ self.grammar = grammar
+ self.convert = convert or (lambda grammar, node: node)
+
+ def setup(self, start=None):
+ """Prepare for parsing.
+
+ This *must* be called before starting to parse.
+
+ The optional argument is an alternative start symbol; it
+ defaults to the grammar's start symbol.
+
+ You can use a Parser instance to parse any number of programs;
+ each time you call setup() the parser is reset to an initial
+ state determined by the (implicit or explicit) start symbol.
+
+ """
+ if start is None:
+ start = self.grammar.start
+ # Each stack entry is a tuple: (dfa, state, node).
+ # A node is a tuple: (type, value, context, children),
+ # where children is a list of nodes or None, and context may be None.
+ newnode = (start, None, None, [])
+ stackentry = (self.grammar.dfas[start], 0, newnode)
+ self.stack = [stackentry]
+ self.rootnode = None
+ self.used_names = set() # Aliased to self.rootnode.used_names in pop()
+
+ def addtoken(self, type, value, context):
+ """Add a token; return True iff this is the end of the program."""
+ # Map from token to label
+ ilabel = self.classify(type, value, context)
+ # Loop until the token is shifted; may raise exceptions
+ while True:
+ dfa, state, node = self.stack[-1]
+ states, first = dfa
+ arcs = states[state]
+ # Look for a state with this label
+ for i, newstate in arcs:
+ t, v = self.grammar.labels[i]
+ if ilabel == i:
+ # Look it up in the list of labels
+ assert t < 256
+ # Shift a token; we're done with it
+ self.shift(type, value, newstate, context)
+ # Pop while we are in an accept-only state
+ state = newstate
+ while states[state] == [(0, state)]:
+ self.pop()
+ if not self.stack:
+ # Done parsing!
+ return True
+ dfa, state, node = self.stack[-1]
+ states, first = dfa
+ # Done with this token
+ return False
+ elif t >= 256:
+ # See if it's a symbol and if we're in its first set
+ itsdfa = self.grammar.dfas[t]
+ itsstates, itsfirst = itsdfa
+ if ilabel in itsfirst:
+ # Push a symbol
+ self.push(t, self.grammar.dfas[t], newstate, context)
+ break # To continue the outer while loop
+ else:
+ if (0, state) in arcs:
+ # An accepting state, pop it and try something else
+ self.pop()
+ if not self.stack:
+ # Done parsing, but another token is input
+ raise ParseError("too much input",
+ type, value, context)
+ else:
+ # No success finding a transition
+ raise ParseError("bad input", type, value, context)
+
+ def classify(self, type, value, context):
+ """Turn a token into a label. (Internal)"""
+ if type == token.NAME:
+ # Keep a listing of all used names
+ self.used_names.add(value)
+ # Check for reserved words
+ ilabel = self.grammar.keywords.get(value)
+ if ilabel is not None:
+ return ilabel
+ ilabel = self.grammar.tokens.get(type)
+ if ilabel is None:
+ raise ParseError("bad token", type, value, context)
+ return ilabel
+
+ def shift(self, type, value, newstate, context):
+ """Shift a token. (Internal)"""
+ dfa, state, node = self.stack[-1]
+ newnode = (type, value, context, None)
+ newnode = self.convert(self.grammar, newnode)
+ if newnode is not None:
+ node[-1].append(newnode)
+ self.stack[-1] = (dfa, newstate, node)
+
+ def push(self, type, newdfa, newstate, context):
+ """Push a nonterminal. (Internal)"""
+ dfa, state, node = self.stack[-1]
+ newnode = (type, None, context, [])
+ self.stack[-1] = (dfa, newstate, node)
+ self.stack.append((newdfa, 0, newnode))
+
+ def pop(self):
+ """Pop a nonterminal. (Internal)"""
+ popdfa, popstate, popnode = self.stack.pop()
+ newnode = self.convert(self.grammar, popnode)
+ if newnode is not None:
+ if self.stack:
+ dfa, state, node = self.stack[-1]
+ node[-1].append(newnode)
+ else:
+ self.rootnode = newnode
+ self.rootnode.used_names = self.used_names
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/pgen.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/pgen.py
new file mode 100644
index 000000000000..63084a4cd5be
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/pgen.py
@@ -0,0 +1,386 @@
+# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+# Pgen imports
+from . import grammar, token, tokenize
+
+class PgenGrammar(grammar.Grammar):
+ pass
+
+class ParserGenerator(object):
+
+ def __init__(self, filename, stream=None):
+ close_stream = None
+ if stream is None:
+ stream = open(filename)
+ close_stream = stream.close
+ self.filename = filename
+ self.stream = stream
+ self.generator = tokenize.generate_tokens(stream.readline)
+ self.gettoken() # Initialize lookahead
+ self.dfas, self.startsymbol = self.parse()
+ if close_stream is not None:
+ close_stream()
+ self.first = {} # map from symbol name to set of tokens
+ self.addfirstsets()
+
+ def make_grammar(self):
+ c = PgenGrammar()
+ names = self.dfas.keys()
+ names.sort()
+ names.remove(self.startsymbol)
+ names.insert(0, self.startsymbol)
+ for name in names:
+ i = 256 + len(c.symbol2number)
+ c.symbol2number[name] = i
+ c.number2symbol[i] = name
+ for name in names:
+ dfa = self.dfas[name]
+ states = []
+ for state in dfa:
+ arcs = []
+ for label, next in state.arcs.iteritems():
+ arcs.append((self.make_label(c, label), dfa.index(next)))
+ if state.isfinal:
+ arcs.append((0, dfa.index(state)))
+ states.append(arcs)
+ c.states.append(states)
+ c.dfas[c.symbol2number[name]] = (states, self.make_first(c, name))
+ c.start = c.symbol2number[self.startsymbol]
+ return c
+
+ def make_first(self, c, name):
+ rawfirst = self.first[name]
+ first = {}
+ for label in rawfirst:
+ ilabel = self.make_label(c, label)
+ ##assert ilabel not in first # XXX failed on <> ... !=
+ first[ilabel] = 1
+ return first
+
+ def make_label(self, c, label):
+ # XXX Maybe this should be a method on a subclass of converter?
+ ilabel = len(c.labels)
+ if label[0].isalpha():
+ # Either a symbol name or a named token
+ if label in c.symbol2number:
+ # A symbol name (a non-terminal)
+ if label in c.symbol2label:
+ return c.symbol2label[label]
+ else:
+ c.labels.append((c.symbol2number[label], None))
+ c.symbol2label[label] = ilabel
+ return ilabel
+ else:
+ # A named token (NAME, NUMBER, STRING)
+ itoken = getattr(token, label, None)
+ assert isinstance(itoken, int), label
+ assert itoken in token.tok_name, label
+ if itoken in c.tokens:
+ return c.tokens[itoken]
+ else:
+ c.labels.append((itoken, None))
+ c.tokens[itoken] = ilabel
+ return ilabel
+ else:
+ # Either a keyword or an operator
+ assert label[0] in ('"', "'"), label
+ value = eval(label)
+ if value[0].isalpha():
+ # A keyword
+ if value in c.keywords:
+ return c.keywords[value]
+ else:
+ c.labels.append((token.NAME, value))
+ c.keywords[value] = ilabel
+ return ilabel
+ else:
+ # An operator (any non-numeric token)
+ itoken = grammar.opmap[value] # Fails if unknown token
+ if itoken in c.tokens:
+ return c.tokens[itoken]
+ else:
+ c.labels.append((itoken, None))
+ c.tokens[itoken] = ilabel
+ return ilabel
+
+ def addfirstsets(self):
+ names = self.dfas.keys()
+ names.sort()
+ for name in names:
+ if name not in self.first:
+ self.calcfirst(name)
+ #print name, self.first[name].keys()
+
+ def calcfirst(self, name):
+ dfa = self.dfas[name]
+ self.first[name] = None # dummy to detect left recursion
+ state = dfa[0]
+ totalset = {}
+ overlapcheck = {}
+ for label, next in state.arcs.iteritems():
+ if label in self.dfas:
+ if label in self.first:
+ fset = self.first[label]
+ if fset is None:
+ raise ValueError("recursion for rule %r" % name)
+ else:
+ self.calcfirst(label)
+ fset = self.first[label]
+ totalset.update(fset)
+ overlapcheck[label] = fset
+ else:
+ totalset[label] = 1
+ overlapcheck[label] = {label: 1}
+ inverse = {}
+ for label, itsfirst in overlapcheck.iteritems():
+ for symbol in itsfirst:
+ if symbol in inverse:
+ raise ValueError("rule %s is ambiguous; %s is in the"
+ " first sets of %s as well as %s" %
+ (name, symbol, label, inverse[symbol]))
+ inverse[symbol] = label
+ self.first[name] = totalset
+
+ def parse(self):
+ dfas = {}
+ startsymbol = None
+ # MSTART: (NEWLINE | RULE)* ENDMARKER
+ while self.type != token.ENDMARKER:
+ while self.type == token.NEWLINE:
+ self.gettoken()
+ # RULE: NAME ':' RHS NEWLINE
+ name = self.expect(token.NAME)
+ self.expect(token.OP, ":")
+ a, z = self.parse_rhs()
+ self.expect(token.NEWLINE)
+ #self.dump_nfa(name, a, z)
+ dfa = self.make_dfa(a, z)
+ #self.dump_dfa(name, dfa)
+ oldlen = len(dfa)
+ self.simplify_dfa(dfa)
+ newlen = len(dfa)
+ dfas[name] = dfa
+ #print name, oldlen, newlen
+ if startsymbol is None:
+ startsymbol = name
+ return dfas, startsymbol
+
+ def make_dfa(self, start, finish):
+ # To turn an NFA into a DFA, we define the states of the DFA
+ # to correspond to *sets* of states of the NFA. Then do some
+ # state reduction. Let's represent sets as dicts with 1 for
+ # values.
+ assert isinstance(start, NFAState)
+ assert isinstance(finish, NFAState)
+ def closure(state):
+ base = {}
+ addclosure(state, base)
+ return base
+ def addclosure(state, base):
+ assert isinstance(state, NFAState)
+ if state in base:
+ return
+ base[state] = 1
+ for label, next in state.arcs:
+ if label is None:
+ addclosure(next, base)
+ states = [DFAState(closure(start), finish)]
+ for state in states: # NB states grows while we're iterating
+ arcs = {}
+ for nfastate in state.nfaset:
+ for label, next in nfastate.arcs:
+ if label is not None:
+ addclosure(next, arcs.setdefault(label, {}))
+ for label, nfaset in arcs.iteritems():
+ for st in states:
+ if st.nfaset == nfaset:
+ break
+ else:
+ st = DFAState(nfaset, finish)
+ states.append(st)
+ state.addarc(st, label)
+ return states # List of DFAState instances; first one is start
+
+ def dump_nfa(self, name, start, finish):
+ print "Dump of NFA for", name
+ todo = [start]
+ for i, state in enumerate(todo):
+ print " State", i, state is finish and "(final)" or ""
+ for label, next in state.arcs:
+ if next in todo:
+ j = todo.index(next)
+ else:
+ j = len(todo)
+ todo.append(next)
+ if label is None:
+ print " -> %d" % j
+ else:
+ print " %s -> %d" % (label, j)
+
+ def dump_dfa(self, name, dfa):
+ print "Dump of DFA for", name
+ for i, state in enumerate(dfa):
+ print " State", i, state.isfinal and "(final)" or ""
+ for label, next in state.arcs.iteritems():
+ print " %s -> %d" % (label, dfa.index(next))
+
+ def simplify_dfa(self, dfa):
+ # This is not theoretically optimal, but works well enough.
+ # Algorithm: repeatedly look for two states that have the same
+ # set of arcs (same labels pointing to the same nodes) and
+ # unify them, until things stop changing.
+
+ # dfa is a list of DFAState instances
+ changes = True
+ while changes:
+ changes = False
+ for i, state_i in enumerate(dfa):
+ for j in range(i+1, len(dfa)):
+ state_j = dfa[j]
+ if state_i == state_j:
+ #print " unify", i, j
+ del dfa[j]
+ for state in dfa:
+ state.unifystate(state_j, state_i)
+ changes = True
+ break
+
+ def parse_rhs(self):
+ # RHS: ALT ('|' ALT)*
+ a, z = self.parse_alt()
+ if self.value != "|":
+ return a, z
+ else:
+ aa = NFAState()
+ zz = NFAState()
+ aa.addarc(a)
+ z.addarc(zz)
+ while self.value == "|":
+ self.gettoken()
+ a, z = self.parse_alt()
+ aa.addarc(a)
+ z.addarc(zz)
+ return aa, zz
+
+ def parse_alt(self):
+ # ALT: ITEM+
+ a, b = self.parse_item()
+ while (self.value in ("(", "[") or
+ self.type in (token.NAME, token.STRING)):
+ c, d = self.parse_item()
+ b.addarc(c)
+ b = d
+ return a, b
+
+ def parse_item(self):
+ # ITEM: '[' RHS ']' | ATOM ['+' | '*']
+ if self.value == "[":
+ self.gettoken()
+ a, z = self.parse_rhs()
+ self.expect(token.OP, "]")
+ a.addarc(z)
+ return a, z
+ else:
+ a, z = self.parse_atom()
+ value = self.value
+ if value not in ("+", "*"):
+ return a, z
+ self.gettoken()
+ z.addarc(a)
+ if value == "+":
+ return a, z
+ else:
+ return a, a
+
+ def parse_atom(self):
+ # ATOM: '(' RHS ')' | NAME | STRING
+ if self.value == "(":
+ self.gettoken()
+ a, z = self.parse_rhs()
+ self.expect(token.OP, ")")
+ return a, z
+ elif self.type in (token.NAME, token.STRING):
+ a = NFAState()
+ z = NFAState()
+ a.addarc(z, self.value)
+ self.gettoken()
+ return a, z
+ else:
+ self.raise_error("expected (...) or NAME or STRING, got %s/%s",
+ self.type, self.value)
+
+ def expect(self, type, value=None):
+ if self.type != type or (value is not None and self.value != value):
+ self.raise_error("expected %s/%s, got %s/%s",
+ type, value, self.type, self.value)
+ value = self.value
+ self.gettoken()
+ return value
+
+ def gettoken(self):
+ tup = self.generator.next()
+ while tup[0] in (tokenize.COMMENT, tokenize.NL):
+ tup = self.generator.next()
+ self.type, self.value, self.begin, self.end, self.line = tup
+ #print token.tok_name[self.type], repr(self.value)
+
+ def raise_error(self, msg, *args):
+ if args:
+ try:
+ msg = msg % args
+ except:
+ msg = " ".join([msg] + map(str, args))
+ raise SyntaxError(msg, (self.filename, self.end[0],
+ self.end[1], self.line))
+
+class NFAState(object):
+
+ def __init__(self):
+ self.arcs = [] # list of (label, NFAState) pairs
+
+ def addarc(self, next, label=None):
+ assert label is None or isinstance(label, str)
+ assert isinstance(next, NFAState)
+ self.arcs.append((label, next))
+
+class DFAState(object):
+
+ def __init__(self, nfaset, final):
+ assert isinstance(nfaset, dict)
+ assert isinstance(iter(nfaset).next(), NFAState)
+ assert isinstance(final, NFAState)
+ self.nfaset = nfaset
+ self.isfinal = final in nfaset
+ self.arcs = {} # map from label to DFAState
+
+ def addarc(self, next, label):
+ assert isinstance(label, str)
+ assert label not in self.arcs
+ assert isinstance(next, DFAState)
+ self.arcs[label] = next
+
+ def unifystate(self, old, new):
+ for label, next in self.arcs.iteritems():
+ if next is old:
+ self.arcs[label] = new
+
+ def __eq__(self, other):
+ # Equality test -- ignore the nfaset instance variable
+ assert isinstance(other, DFAState)
+ if self.isfinal != other.isfinal:
+ return False
+ # Can't just return self.arcs == other.arcs, because that
+ # would invoke this method recursively, with cycles...
+ if len(self.arcs) != len(other.arcs):
+ return False
+ for label, next in self.arcs.iteritems():
+ if next is not other.arcs.get(label):
+ return False
+ return True
+
+ __hash__ = None # For Py3 compatibility.
+
+def generate_grammar(filename="Grammar.txt"):
+ p = ParserGenerator(filename)
+ return p.make_grammar()
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/token.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/token.py
new file mode 100644
index 000000000000..61468b313e7d
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/token.py
@@ -0,0 +1,82 @@
+#! /usr/bin/env python
+
+"""Token constants (from "token.h")."""
+
+# Taken from Python (r53757) and modified to include some tokens
+# originally monkeypatched in by pgen2.tokenize
+
+#--start constants--
+ENDMARKER = 0
+NAME = 1
+NUMBER = 2
+STRING = 3
+NEWLINE = 4
+INDENT = 5
+DEDENT = 6
+LPAR = 7
+RPAR = 8
+LSQB = 9
+RSQB = 10
+COLON = 11
+COMMA = 12
+SEMI = 13
+PLUS = 14
+MINUS = 15
+STAR = 16
+SLASH = 17
+VBAR = 18
+AMPER = 19
+LESS = 20
+GREATER = 21
+EQUAL = 22
+DOT = 23
+PERCENT = 24
+BACKQUOTE = 25
+LBRACE = 26
+RBRACE = 27
+EQEQUAL = 28
+NOTEQUAL = 29
+LESSEQUAL = 30
+GREATEREQUAL = 31
+TILDE = 32
+CIRCUMFLEX = 33
+LEFTSHIFT = 34
+RIGHTSHIFT = 35
+DOUBLESTAR = 36
+PLUSEQUAL = 37
+MINEQUAL = 38
+STAREQUAL = 39
+SLASHEQUAL = 40
+PERCENTEQUAL = 41
+AMPEREQUAL = 42
+VBAREQUAL = 43
+CIRCUMFLEXEQUAL = 44
+LEFTSHIFTEQUAL = 45
+RIGHTSHIFTEQUAL = 46
+DOUBLESTAREQUAL = 47
+DOUBLESLASH = 48
+DOUBLESLASHEQUAL = 49
+AT = 50
+OP = 51
+COMMENT = 52
+NL = 53
+RARROW = 54
+ERRORTOKEN = 55
+N_TOKENS = 56
+NT_OFFSET = 256
+#--end constants--
+
+tok_name = {}
+for _name, _value in globals().items():
+ if type(_value) is type(0):
+ tok_name[_value] = _name
+
+
+def ISTERMINAL(x):
+ return x < NT_OFFSET
+
+def ISNONTERMINAL(x):
+ return x >= NT_OFFSET
+
+def ISEOF(x):
+ return x == ENDMARKER
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/tokenize.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/tokenize.py
new file mode 100644
index 000000000000..f6e0284c2f58
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pgen2/tokenize.py
@@ -0,0 +1,499 @@
+# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Python Software Foundation.
+# All rights reserved.
+
+"""Tokenization help for Python programs.
+
+generate_tokens(readline) is a generator that breaks a stream of
+text into Python tokens. It accepts a readline-like method which is called
+repeatedly to get the next line of input (or "" for EOF). It generates
+5-tuples with these members:
+
+ the token type (see token.py)
+ the token (a string)
+ the starting (row, column) indices of the token (a 2-tuple of ints)
+ the ending (row, column) indices of the token (a 2-tuple of ints)
+ the original line (string)
+
+It is designed to match the working of the Python tokenizer exactly, except
+that it produces COMMENT tokens for comments and gives type OP for all
+operators
+
+Older entry points
+ tokenize_loop(readline, tokeneater)
+ tokenize(readline, tokeneater=printtoken)
+are the same, except instead of generating tokens, tokeneater is a callback
+function to which the 5 fields described above are passed as 5 arguments,
+each time a new token is found."""
+
+__author__ = 'Ka-Ping Yee <ping@lfw.org>'
+__credits__ = \
+ 'GvR, ESR, Tim Peters, Thomas Wouters, Fred Drake, Skip Montanaro'
+
+import string, re
+from codecs import BOM_UTF8, lookup
+from lib2to3.pgen2.token import *
+
+from . import token
+__all__ = [x for x in dir(token) if x[0] != '_'] + ["tokenize",
+ "generate_tokens", "untokenize"]
+del token
+
+try:
+ bytes
+except NameError:
+ # Support bytes type in Python <= 2.5, so 2to3 turns itself into
+ # valid Python 3 code.
+ bytes = str
+
+def group(*choices): return '(' + '|'.join(choices) + ')'
+def any(*choices): return group(*choices) + '*'
+def maybe(*choices): return group(*choices) + '?'
+
+Whitespace = r'[ \f\t]*'
+Comment = r'#[^\r\n]*'
+Ignore = Whitespace + any(r'\\\r?\n' + Whitespace) + maybe(Comment)
+Name = r'[a-zA-Z_]\w*'
+
+Binnumber = r'0[bB][01]*'
+Hexnumber = r'0[xX][\da-fA-F]*[lL]?'
+Octnumber = r'0[oO]?[0-7]*[lL]?'
+Decnumber = r'[1-9]\d*[lL]?'
+Intnumber = group(Binnumber, Hexnumber, Octnumber, Decnumber)
+Exponent = r'[eE][-+]?\d+'
+Pointfloat = group(r'\d+\.\d*', r'\.\d+') + maybe(Exponent)
+Expfloat = r'\d+' + Exponent
+Floatnumber = group(Pointfloat, Expfloat)
+Imagnumber = group(r'\d+[jJ]', Floatnumber + r'[jJ]')
+Number = group(Imagnumber, Floatnumber, Intnumber)
+
+# Tail end of ' string.
+Single = r"[^'\\]*(?:\\.[^'\\]*)*'"
+# Tail end of " string.
+Double = r'[^"\\]*(?:\\.[^"\\]*)*"'
+# Tail end of ''' string.
+Single3 = r"[^'\\]*(?:(?:\\.|'(?!''))[^'\\]*)*'''"
+# Tail end of """ string.
+Double3 = r'[^"\\]*(?:(?:\\.|"(?!""))[^"\\]*)*"""'
+Triple = group("[ubUB]?[rR]?'''", '[ubUB]?[rR]?"""')
+# Single-line ' or " string.
+String = group(r"[uU]?[rR]?'[^\n'\\]*(?:\\.[^\n'\\]*)*'",
+ r'[uU]?[rR]?"[^\n"\\]*(?:\\.[^\n"\\]*)*"')
+
+# Because of leftmost-then-longest match semantics, be sure to put the
+# longest operators first (e.g., if = came before ==, == would get
+# recognized as two instances of =).
+Operator = group(r"\*\*=?", r">>=?", r"<<=?", r"<>", r"!=",
+ r"//=?", r"->",
+ r"[+\-*/%&|^=<>]=?",
+ r"~")
+
+Bracket = '[][(){}]'
+Special = group(r'\r?\n', r'[:;.,`@]')
+Funny = group(Operator, Bracket, Special)
+
+PlainToken = group(Number, Funny, String, Name)
+Token = Ignore + PlainToken
+
+# First (or only) line of ' or " string.
+ContStr = group(r"[uUbB]?[rR]?'[^\n'\\]*(?:\\.[^\n'\\]*)*" +
+ group("'", r'\\\r?\n'),
+ r'[uUbB]?[rR]?"[^\n"\\]*(?:\\.[^\n"\\]*)*' +
+ group('"', r'\\\r?\n'))
+PseudoExtras = group(r'\\\r?\n', Comment, Triple)
+PseudoToken = Whitespace + group(PseudoExtras, Number, Funny, ContStr, Name)
+
+tokenprog, pseudoprog, single3prog, double3prog = map(
+ re.compile, (Token, PseudoToken, Single3, Double3))
+endprogs = {"'": re.compile(Single), '"': re.compile(Double),
+ "'''": single3prog, '"""': double3prog,
+ "r'''": single3prog, 'r"""': double3prog,
+ "u'''": single3prog, 'u"""': double3prog,
+ "b'''": single3prog, 'b"""': double3prog,
+ "ur'''": single3prog, 'ur"""': double3prog,
+ "br'''": single3prog, 'br"""': double3prog,
+ "R'''": single3prog, 'R"""': double3prog,
+ "U'''": single3prog, 'U"""': double3prog,
+ "B'''": single3prog, 'B"""': double3prog,
+ "uR'''": single3prog, 'uR"""': double3prog,
+ "Ur'''": single3prog, 'Ur"""': double3prog,
+ "UR'''": single3prog, 'UR"""': double3prog,
+ "bR'''": single3prog, 'bR"""': double3prog,
+ "Br'''": single3prog, 'Br"""': double3prog,
+ "BR'''": single3prog, 'BR"""': double3prog,
+ 'r': None, 'R': None,
+ 'u': None, 'U': None,
+ 'b': None, 'B': None}
+
+triple_quoted = {}
+for t in ("'''", '"""',
+ "r'''", 'r"""', "R'''", 'R"""',
+ "u'''", 'u"""', "U'''", 'U"""',
+ "b'''", 'b"""', "B'''", 'B"""',
+ "ur'''", 'ur"""', "Ur'''", 'Ur"""',
+ "uR'''", 'uR"""', "UR'''", 'UR"""',
+ "br'''", 'br"""', "Br'''", 'Br"""',
+ "bR'''", 'bR"""', "BR'''", 'BR"""',):
+ triple_quoted[t] = t
+single_quoted = {}
+for t in ("'", '"',
+ "r'", 'r"', "R'", 'R"',
+ "u'", 'u"', "U'", 'U"',
+ "b'", 'b"', "B'", 'B"',
+ "ur'", 'ur"', "Ur'", 'Ur"',
+ "uR'", 'uR"', "UR'", 'UR"',
+ "br'", 'br"', "Br'", 'Br"',
+ "bR'", 'bR"', "BR'", 'BR"', ):
+ single_quoted[t] = t
+
+tabsize = 8
+
+class TokenError(Exception): pass
+
+class StopTokenizing(Exception): pass
+
+def printtoken(type, token, start, end, line): # for testing
+ (srow, scol) = start
+ (erow, ecol) = end
+ print "%d,%d-%d,%d:\t%s\t%s" % \
+ (srow, scol, erow, ecol, tok_name[type], repr(token))
+
+def tokenize(readline, tokeneater=printtoken):
+ """
+ The tokenize() function accepts two parameters: one representing the
+ input stream, and one providing an output mechanism for tokenize().
+
+ The first parameter, readline, must be a callable object which provides
+ the same interface as the readline() method of built-in file objects.
+ Each call to the function should return one line of input as a string.
+
+ The second parameter, tokeneater, must also be a callable object. It is
+ called once for each token, with five arguments, corresponding to the
+ tuples generated by generate_tokens().
+ """
+ try:
+ tokenize_loop(readline, tokeneater)
+ except StopTokenizing:
+ pass
+
+# backwards compatible interface
+def tokenize_loop(readline, tokeneater):
+ for token_info in generate_tokens(readline):
+ tokeneater(*token_info)
+
+class Untokenizer:
+
+ def __init__(self):
+ self.tokens = []
+ self.prev_row = 1
+ self.prev_col = 0
+
+ def add_whitespace(self, start):
+ row, col = start
+ assert row <= self.prev_row
+ col_offset = col - self.prev_col
+ if col_offset:
+ self.tokens.append(" " * col_offset)
+
+ def untokenize(self, iterable):
+ for t in iterable:
+ if len(t) == 2:
+ self.compat(t, iterable)
+ break
+ tok_type, token, start, end, line = t
+ self.add_whitespace(start)
+ self.tokens.append(token)
+ self.prev_row, self.prev_col = end
+ if tok_type in (NEWLINE, NL):
+ self.prev_row += 1
+ self.prev_col = 0
+ return "".join(self.tokens)
+
+ def compat(self, token, iterable):
+ startline = False
+ indents = []
+ toks_append = self.tokens.append
+ toknum, tokval = token
+ if toknum in (NAME, NUMBER):
+ tokval += ' '
+ if toknum in (NEWLINE, NL):
+ startline = True
+ for tok in iterable:
+ toknum, tokval = tok[:2]
+
+ if toknum in (NAME, NUMBER):
+ tokval += ' '
+
+ if toknum == INDENT:
+ indents.append(tokval)
+ continue
+ elif toknum == DEDENT:
+ indents.pop()
+ continue
+ elif toknum in (NEWLINE, NL):
+ startline = True
+ elif startline and indents:
+ toks_append(indents[-1])
+ startline = False
+ toks_append(tokval)
+
+cookie_re = re.compile(r'^[ \t\f]*#.*coding[:=][ \t]*([-\w.]+)')
+
+def _get_normal_name(orig_enc):
+ """Imitates get_normal_name in tokenizer.c."""
+ # Only care about the first 12 characters.
+ enc = orig_enc[:12].lower().replace("_", "-")
+ if enc == "utf-8" or enc.startswith("utf-8-"):
+ return "utf-8"
+ if enc in ("latin-1", "iso-8859-1", "iso-latin-1") or \
+ enc.startswith(("latin-1-", "iso-8859-1-", "iso-latin-1-")):
+ return "iso-8859-1"
+ return orig_enc
+
+def detect_encoding(readline):
+ """
+ The detect_encoding() function is used to detect the encoding that should
+ be used to decode a Python source file. It requires one argment, readline,
+ in the same way as the tokenize() generator.
+
+ It will call readline a maximum of twice, and return the encoding used
+ (as a string) and a list of any lines (left as bytes) it has read
+ in.
+
+ It detects the encoding from the presence of a utf-8 bom or an encoding
+ cookie as specified in pep-0263. If both a bom and a cookie are present, but
+ disagree, a SyntaxError will be raised. If the encoding cookie is an invalid
+ charset, raise a SyntaxError. Note that if a utf-8 bom is found,
+ 'utf-8-sig' is returned.
+
+ If no encoding is specified, then the default of 'utf-8' will be returned.
+ """
+ bom_found = False
+ encoding = None
+ default = 'utf-8'
+ def read_or_stop():
+ try:
+ return readline()
+ except StopIteration:
+ return bytes()
+
+ def find_cookie(line):
+ try:
+ line_string = line.decode('ascii')
+ except UnicodeDecodeError:
+ return None
+ match = cookie_re.match(line_string)
+ if not match:
+ return None
+ encoding = _get_normal_name(match.group(1))
+ try:
+ codec = lookup(encoding)
+ except LookupError:
+ # This behaviour mimics the Python interpreter
+ raise SyntaxError("unknown encoding: " + encoding)
+
+ if bom_found:
+ if codec.name != 'utf-8':
+ # This behaviour mimics the Python interpreter
+ raise SyntaxError('encoding problem: utf-8')
+ encoding += '-sig'
+ return encoding
+
+ first = read_or_stop()
+ if first.startswith(BOM_UTF8):
+ bom_found = True
+ first = first[3:]
+ default = 'utf-8-sig'
+ if not first:
+ return default, []
+
+ encoding = find_cookie(first)
+ if encoding:
+ return encoding, [first]
+
+ second = read_or_stop()
+ if not second:
+ return default, [first]
+
+ encoding = find_cookie(second)
+ if encoding:
+ return encoding, [first, second]
+
+ return default, [first, second]
+
+def untokenize(iterable):
+ """Transform tokens back into Python source code.
+
+ Each element returned by the iterable must be a token sequence
+ with at least two elements, a token number and token value. If
+ only two tokens are passed, the resulting output is poor.
+
+ Round-trip invariant for full input:
+ Untokenized source will match input source exactly
+
+ Round-trip invariant for limited intput:
+ # Output text will tokenize the back to the input
+ t1 = [tok[:2] for tok in generate_tokens(f.readline)]
+ newcode = untokenize(t1)
+ readline = iter(newcode.splitlines(1)).next
+ t2 = [tok[:2] for tokin generate_tokens(readline)]
+ assert t1 == t2
+ """
+ ut = Untokenizer()
+ return ut.untokenize(iterable)
+
+def generate_tokens(readline):
+ """
+ The generate_tokens() generator requires one argment, readline, which
+ must be a callable object which provides the same interface as the
+ readline() method of built-in file objects. Each call to the function
+ should return one line of input as a string. Alternately, readline
+ can be a callable function terminating with StopIteration:
+ readline = open(myfile).next # Example of alternate readline
+
+ The generator produces 5-tuples with these members: the token type; the
+ token string; a 2-tuple (srow, scol) of ints specifying the row and
+ column where the token begins in the source; a 2-tuple (erow, ecol) of
+ ints specifying the row and column where the token ends in the source;
+ and the line on which the token was found. The line passed is the
+ logical line; continuation lines are included.
+ """
+ lnum = parenlev = continued = 0
+ namechars, numchars = string.ascii_letters + '_', '0123456789'
+ contstr, needcont = '', 0
+ contline = None
+ indents = [0]
+
+ while 1: # loop over lines in stream
+ try:
+ line = readline()
+ except StopIteration:
+ line = ''
+ lnum = lnum + 1
+ pos, max = 0, len(line)
+
+ if contstr: # continued string
+ if not line:
+ raise TokenError, ("EOF in multi-line string", strstart)
+ endmatch = endprog.match(line)
+ if endmatch:
+ pos = end = endmatch.end(0)
+ yield (STRING, contstr + line[:end],
+ strstart, (lnum, end), contline + line)
+ contstr, needcont = '', 0
+ contline = None
+ elif needcont and line[-2:] != '\\\n' and line[-3:] != '\\\r\n':
+ yield (ERRORTOKEN, contstr + line,
+ strstart, (lnum, len(line)), contline)
+ contstr = ''
+ contline = None
+ continue
+ else:
+ contstr = contstr + line
+ contline = contline + line
+ continue
+
+ elif parenlev == 0 and not continued: # new statement
+ if not line: break
+ column = 0
+ while pos < max: # measure leading whitespace
+ if line[pos] == ' ': column = column + 1
+ elif line[pos] == '\t': column = (column//tabsize + 1)*tabsize
+ elif line[pos] == '\f': column = 0
+ else: break
+ pos = pos + 1
+ if pos == max: break
+
+ if line[pos] in '#\r\n': # skip comments or blank lines
+ if line[pos] == '#':
+ comment_token = line[pos:].rstrip('\r\n')
+ nl_pos = pos + len(comment_token)
+ yield (COMMENT, comment_token,
+ (lnum, pos), (lnum, pos + len(comment_token)), line)
+ yield (NL, line[nl_pos:],
+ (lnum, nl_pos), (lnum, len(line)), line)
+ else:
+ yield ((NL, COMMENT)[line[pos] == '#'], line[pos:],
+ (lnum, pos), (lnum, len(line)), line)
+ continue
+
+ if column > indents[-1]: # count indents or dedents
+ indents.append(column)
+ yield (INDENT, line[:pos], (lnum, 0), (lnum, pos), line)
+ while column < indents[-1]:
+ if column not in indents:
+ raise IndentationError(
+ "unindent does not match any outer indentation level",
+ ("<tokenize>", lnum, pos, line))
+ indents = indents[:-1]
+ yield (DEDENT, '', (lnum, pos), (lnum, pos), line)
+
+ else: # continued statement
+ if not line:
+ raise TokenError, ("EOF in multi-line statement", (lnum, 0))
+ continued = 0
+
+ while pos < max:
+ pseudomatch = pseudoprog.match(line, pos)
+ if pseudomatch: # scan for tokens
+ start, end = pseudomatch.span(1)
+ spos, epos, pos = (lnum, start), (lnum, end), end
+ token, initial = line[start:end], line[start]
+
+ if initial in numchars or \
+ (initial == '.' and token != '.'): # ordinary number
+ yield (NUMBER, token, spos, epos, line)
+ elif initial in '\r\n':
+ newline = NEWLINE
+ if parenlev > 0:
+ newline = NL
+ yield (newline, token, spos, epos, line)
+ elif initial == '#':
+ assert not token.endswith("\n")
+ yield (COMMENT, token, spos, epos, line)
+ elif token in triple_quoted:
+ endprog = endprogs[token]
+ endmatch = endprog.match(line, pos)
+ if endmatch: # all on one line
+ pos = endmatch.end(0)
+ token = line[start:pos]
+ yield (STRING, token, spos, (lnum, pos), line)
+ else:
+ strstart = (lnum, start) # multiple lines
+ contstr = line[start:]
+ contline = line
+ break
+ elif initial in single_quoted or \
+ token[:2] in single_quoted or \
+ token[:3] in single_quoted:
+ if token[-1] == '\n': # continued string
+ strstart = (lnum, start)
+ endprog = (endprogs[initial] or endprogs[token[1]] or
+ endprogs[token[2]])
+ contstr, needcont = line[start:], 1
+ contline = line
+ break
+ else: # ordinary string
+ yield (STRING, token, spos, epos, line)
+ elif initial in namechars: # ordinary name
+ yield (NAME, token, spos, epos, line)
+ elif initial == '\\': # continued stmt
+ # This yield is new; needed for better idempotency:
+ yield (NL, token, spos, (lnum, pos), line)
+ continued = 1
+ else:
+ if initial in '([{': parenlev = parenlev + 1
+ elif initial in ')]}': parenlev = parenlev - 1
+ yield (OP, token, spos, epos, line)
+ else:
+ yield (ERRORTOKEN, line[pos],
+ (lnum, pos), (lnum, pos+1), line)
+ pos = pos + 1
+
+ for indent in indents[1:]: # pop remaining indent levels
+ yield (DEDENT, '', (lnum, 0), (lnum, 0), '')
+ yield (ENDMARKER, '', (lnum, 0), (lnum, 0), '')
+
+if __name__ == '__main__': # testing
+ import sys
+ if len(sys.argv) > 1: tokenize(open(sys.argv[1]).readline)
+ else: tokenize(sys.stdin.readline)
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pygram.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pygram.py
new file mode 100644
index 000000000000..621ff24c9547
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pygram.py
@@ -0,0 +1,40 @@
+# Copyright 2006 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Export the Python grammar and symbols."""
+
+# Python imports
+import os
+
+# Local imports
+from .pgen2 import token
+from .pgen2 import driver
+from . import pytree
+
+# The grammar file
+_GRAMMAR_FILE = os.path.join(os.path.dirname(__file__), "Grammar.txt")
+_PATTERN_GRAMMAR_FILE = os.path.join(os.path.dirname(__file__),
+ "PatternGrammar.txt")
+
+
+class Symbols(object):
+
+ def __init__(self, grammar):
+ """Initializer.
+
+ Creates an attribute for each grammar symbol (nonterminal),
+ whose value is the symbol's type (an int >= 256).
+ """
+ for name, symbol in grammar.symbol2number.iteritems():
+ setattr(self, name, symbol)
+
+
+python_grammar = driver.load_grammar(_GRAMMAR_FILE)
+
+python_symbols = Symbols(python_grammar)
+
+python_grammar_no_print_statement = python_grammar.copy()
+del python_grammar_no_print_statement.keywords["print"]
+
+pattern_grammar = driver.load_grammar(_PATTERN_GRAMMAR_FILE)
+pattern_symbols = Symbols(pattern_grammar)
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pytree.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pytree.py
new file mode 100644
index 000000000000..179caca51f29
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/pytree.py
@@ -0,0 +1,887 @@
+# Copyright 2006 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""
+Python parse tree definitions.
+
+This is a very concrete parse tree; we need to keep every token and
+even the comments and whitespace between tokens.
+
+There's also a pattern matching implementation here.
+"""
+
+__author__ = "Guido van Rossum <guido@python.org>"
+
+import sys
+import warnings
+from StringIO import StringIO
+
+HUGE = 0x7FFFFFFF # maximum repeat count, default max
+
+_type_reprs = {}
+def type_repr(type_num):
+ global _type_reprs
+ if not _type_reprs:
+ from .pygram import python_symbols
+ # printing tokens is possible but not as useful
+ # from .pgen2 import token // token.__dict__.items():
+ for name, val in python_symbols.__dict__.items():
+ if type(val) == int: _type_reprs[val] = name
+ return _type_reprs.setdefault(type_num, type_num)
+
+class Base(object):
+
+ """
+ Abstract base class for Node and Leaf.
+
+ This provides some default functionality and boilerplate using the
+ template pattern.
+
+ A node may be a subnode of at most one parent.
+ """
+
+ # Default values for instance variables
+ type = None # int: token number (< 256) or symbol number (>= 256)
+ parent = None # Parent node pointer, or None
+ children = () # Tuple of subnodes
+ was_changed = False
+ was_checked = False
+
+ def __new__(cls, *args, **kwds):
+ """Constructor that prevents Base from being instantiated."""
+ assert cls is not Base, "Cannot instantiate Base"
+ return object.__new__(cls)
+
+ def __eq__(self, other):
+ """
+ Compare two nodes for equality.
+
+ This calls the method _eq().
+ """
+ if self.__class__ is not other.__class__:
+ return NotImplemented
+ return self._eq(other)
+
+ __hash__ = None # For Py3 compatibility.
+
+ def __ne__(self, other):
+ """
+ Compare two nodes for inequality.
+
+ This calls the method _eq().
+ """
+ if self.__class__ is not other.__class__:
+ return NotImplemented
+ return not self._eq(other)
+
+ def _eq(self, other):
+ """
+ Compare two nodes for equality.
+
+ This is called by __eq__ and __ne__. It is only called if the two nodes
+ have the same type. This must be implemented by the concrete subclass.
+ Nodes should be considered equal if they have the same structure,
+ ignoring the prefix string and other context information.
+ """
+ raise NotImplementedError
+
+ def clone(self):
+ """
+ Return a cloned (deep) copy of self.
+
+ This must be implemented by the concrete subclass.
+ """
+ raise NotImplementedError
+
+ def post_order(self):
+ """
+ Return a post-order iterator for the tree.
+
+ This must be implemented by the concrete subclass.
+ """
+ raise NotImplementedError
+
+ def pre_order(self):
+ """
+ Return a pre-order iterator for the tree.
+
+ This must be implemented by the concrete subclass.
+ """
+ raise NotImplementedError
+
+ def set_prefix(self, prefix):
+ """
+ Set the prefix for the node (see Leaf class).
+
+ DEPRECATED; use the prefix property directly.
+ """
+ warnings.warn("set_prefix() is deprecated; use the prefix property",
+ DeprecationWarning, stacklevel=2)
+ self.prefix = prefix
+
+ def get_prefix(self):
+ """
+ Return the prefix for the node (see Leaf class).
+
+ DEPRECATED; use the prefix property directly.
+ """
+ warnings.warn("get_prefix() is deprecated; use the prefix property",
+ DeprecationWarning, stacklevel=2)
+ return self.prefix
+
+ def replace(self, new):
+ """Replace this node with a new one in the parent."""
+ assert self.parent is not None, str(self)
+ assert new is not None
+ if not isinstance(new, list):
+ new = [new]
+ l_children = []
+ found = False
+ for ch in self.parent.children:
+ if ch is self:
+ assert not found, (self.parent.children, self, new)
+ if new is not None:
+ l_children.extend(new)
+ found = True
+ else:
+ l_children.append(ch)
+ assert found, (self.children, self, new)
+ self.parent.changed()
+ self.parent.children = l_children
+ for x in new:
+ x.parent = self.parent
+ self.parent = None
+
+ def get_lineno(self):
+ """Return the line number which generated the invocant node."""
+ node = self
+ while not isinstance(node, Leaf):
+ if not node.children:
+ return
+ node = node.children[0]
+ return node.lineno
+
+ def changed(self):
+ if self.parent:
+ self.parent.changed()
+ self.was_changed = True
+
+ def remove(self):
+ """
+ Remove the node from the tree. Returns the position of the node in its
+ parent's children before it was removed.
+ """
+ if self.parent:
+ for i, node in enumerate(self.parent.children):
+ if node is self:
+ self.parent.changed()
+ del self.parent.children[i]
+ self.parent = None
+ return i
+
+ @property
+ def next_sibling(self):
+ """
+ The node immediately following the invocant in their parent's children
+ list. If the invocant does not have a next sibling, it is None
+ """
+ if self.parent is None:
+ return None
+
+ # Can't use index(); we need to test by identity
+ for i, child in enumerate(self.parent.children):
+ if child is self:
+ try:
+ return self.parent.children[i+1]
+ except IndexError:
+ return None
+
+ @property
+ def prev_sibling(self):
+ """
+ The node immediately preceding the invocant in their parent's children
+ list. If the invocant does not have a previous sibling, it is None.
+ """
+ if self.parent is None:
+ return None
+
+ # Can't use index(); we need to test by identity
+ for i, child in enumerate(self.parent.children):
+ if child is self:
+ if i == 0:
+ return None
+ return self.parent.children[i-1]
+
+ def leaves(self):
+ for child in self.children:
+ for x in child.leaves():
+ yield x
+
+ def depth(self):
+ if self.parent is None:
+ return 0
+ return 1 + self.parent.depth()
+
+ def get_suffix(self):
+ """
+ Return the string immediately following the invocant node. This is
+ effectively equivalent to node.next_sibling.prefix
+ """
+ next_sib = self.next_sibling
+ if next_sib is None:
+ return u""
+ return next_sib.prefix
+
+ if sys.version_info < (3, 0):
+ def __str__(self):
+ return unicode(self).encode("ascii")
+
+class Node(Base):
+
+ """Concrete implementation for interior nodes."""
+
+ def __init__(self,type, children,
+ context=None,
+ prefix=None,
+ fixers_applied=None):
+ """
+ Initializer.
+
+ Takes a type constant (a symbol number >= 256), a sequence of
+ child nodes, and an optional context keyword argument.
+
+ As a side effect, the parent pointers of the children are updated.
+ """
+ assert type >= 256, type
+ self.type = type
+ self.children = list(children)
+ for ch in self.children:
+ assert ch.parent is None, repr(ch)
+ ch.parent = self
+ if prefix is not None:
+ self.prefix = prefix
+ if fixers_applied:
+ self.fixers_applied = fixers_applied[:]
+ else:
+ self.fixers_applied = None
+
+ def __repr__(self):
+ """Return a canonical string representation."""
+ return "%s(%s, %r)" % (self.__class__.__name__,
+ type_repr(self.type),
+ self.children)
+
+ def __unicode__(self):
+ """
+ Return a pretty string representation.
+
+ This reproduces the input source exactly.
+ """
+ return u"".join(map(unicode, self.children))
+
+ if sys.version_info > (3, 0):
+ __str__ = __unicode__
+
+ def _eq(self, other):
+ """Compare two nodes for equality."""
+ return (self.type, self.children) == (other.type, other.children)
+
+ def clone(self):
+ """Return a cloned (deep) copy of self."""
+ return Node(self.type, [ch.clone() for ch in self.children],
+ fixers_applied=self.fixers_applied)
+
+ def post_order(self):
+ """Return a post-order iterator for the tree."""
+ for child in self.children:
+ for node in child.post_order():
+ yield node
+ yield self
+
+ def pre_order(self):
+ """Return a pre-order iterator for the tree."""
+ yield self
+ for child in self.children:
+ for node in child.pre_order():
+ yield node
+
+ def _prefix_getter(self):
+ """
+ The whitespace and comments preceding this node in the input.
+ """
+ if not self.children:
+ return ""
+ return self.children[0].prefix
+
+ def _prefix_setter(self, prefix):
+ if self.children:
+ self.children[0].prefix = prefix
+
+ prefix = property(_prefix_getter, _prefix_setter)
+
+ def set_child(self, i, child):
+ """
+ Equivalent to 'node.children[i] = child'. This method also sets the
+ child's parent attribute appropriately.
+ """
+ child.parent = self
+ self.children[i].parent = None
+ self.children[i] = child
+ self.changed()
+
+ def insert_child(self, i, child):
+ """
+ Equivalent to 'node.children.insert(i, child)'. This method also sets
+ the child's parent attribute appropriately.
+ """
+ child.parent = self
+ self.children.insert(i, child)
+ self.changed()
+
+ def append_child(self, child):
+ """
+ Equivalent to 'node.children.append(child)'. This method also sets the
+ child's parent attribute appropriately.
+ """
+ child.parent = self
+ self.children.append(child)
+ self.changed()
+
+
+class Leaf(Base):
+
+ """Concrete implementation for leaf nodes."""
+
+ # Default values for instance variables
+ _prefix = "" # Whitespace and comments preceding this token in the input
+ lineno = 0 # Line where this token starts in the input
+ column = 0 # Column where this token tarts in the input
+
+ def __init__(self, type, value,
+ context=None,
+ prefix=None,
+ fixers_applied=[]):
+ """
+ Initializer.
+
+ Takes a type constant (a token number < 256), a string value, and an
+ optional context keyword argument.
+ """
+ assert 0 <= type < 256, type
+ if context is not None:
+ self._prefix, (self.lineno, self.column) = context
+ self.type = type
+ self.value = value
+ if prefix is not None:
+ self._prefix = prefix
+ self.fixers_applied = fixers_applied[:]
+
+ def __repr__(self):
+ """Return a canonical string representation."""
+ return "%s(%r, %r)" % (self.__class__.__name__,
+ self.type,
+ self.value)
+
+ def __unicode__(self):
+ """
+ Return a pretty string representation.
+
+ This reproduces the input source exactly.
+ """
+ return self.prefix + unicode(self.value)
+
+ if sys.version_info > (3, 0):
+ __str__ = __unicode__
+
+ def _eq(self, other):
+ """Compare two nodes for equality."""
+ return (self.type, self.value) == (other.type, other.value)
+
+ def clone(self):
+ """Return a cloned (deep) copy of self."""
+ return Leaf(self.type, self.value,
+ (self.prefix, (self.lineno, self.column)),
+ fixers_applied=self.fixers_applied)
+
+ def leaves(self):
+ yield self
+
+ def post_order(self):
+ """Return a post-order iterator for the tree."""
+ yield self
+
+ def pre_order(self):
+ """Return a pre-order iterator for the tree."""
+ yield self
+
+ def _prefix_getter(self):
+ """
+ The whitespace and comments preceding this token in the input.
+ """
+ return self._prefix
+
+ def _prefix_setter(self, prefix):
+ self.changed()
+ self._prefix = prefix
+
+ prefix = property(_prefix_getter, _prefix_setter)
+
+def convert(gr, raw_node):
+ """
+ Convert raw node information to a Node or Leaf instance.
+
+ This is passed to the parser driver which calls it whenever a reduction of a
+ grammar rule produces a new complete node, so that the tree is build
+ strictly bottom-up.
+ """
+ type, value, context, children = raw_node
+ if children or type in gr.number2symbol:
+ # If there's exactly one child, return that child instead of
+ # creating a new node.
+ if len(children) == 1:
+ return children[0]
+ return Node(type, children, context=context)
+ else:
+ return Leaf(type, value, context=context)
+
+
+class BasePattern(object):
+
+ """
+ A pattern is a tree matching pattern.
+
+ It looks for a specific node type (token or symbol), and
+ optionally for a specific content.
+
+ This is an abstract base class. There are three concrete
+ subclasses:
+
+ - LeafPattern matches a single leaf node;
+ - NodePattern matches a single node (usually non-leaf);
+ - WildcardPattern matches a sequence of nodes of variable length.
+ """
+
+ # Defaults for instance variables
+ type = None # Node type (token if < 256, symbol if >= 256)
+ content = None # Optional content matching pattern
+ name = None # Optional name used to store match in results dict
+
+ def __new__(cls, *args, **kwds):
+ """Constructor that prevents BasePattern from being instantiated."""
+ assert cls is not BasePattern, "Cannot instantiate BasePattern"
+ return object.__new__(cls)
+
+ def __repr__(self):
+ args = [type_repr(self.type), self.content, self.name]
+ while args and args[-1] is None:
+ del args[-1]
+ return "%s(%s)" % (self.__class__.__name__, ", ".join(map(repr, args)))
+
+ def optimize(self):
+ """
+ A subclass can define this as a hook for optimizations.
+
+ Returns either self or another node with the same effect.
+ """
+ return self
+
+ def match(self, node, results=None):
+ """
+ Does this pattern exactly match a node?
+
+ Returns True if it matches, False if not.
+
+ If results is not None, it must be a dict which will be
+ updated with the nodes matching named subpatterns.
+
+ Default implementation for non-wildcard patterns.
+ """
+ if self.type is not None and node.type != self.type:
+ return False
+ if self.content is not None:
+ r = None
+ if results is not None:
+ r = {}
+ if not self._submatch(node, r):
+ return False
+ if r:
+ results.update(r)
+ if results is not None and self.name:
+ results[self.name] = node
+ return True
+
+ def match_seq(self, nodes, results=None):
+ """
+ Does this pattern exactly match a sequence of nodes?
+
+ Default implementation for non-wildcard patterns.
+ """
+ if len(nodes) != 1:
+ return False
+ return self.match(nodes[0], results)
+
+ def generate_matches(self, nodes):
+ """
+ Generator yielding all matches for this pattern.
+
+ Default implementation for non-wildcard patterns.
+ """
+ r = {}
+ if nodes and self.match(nodes[0], r):
+ yield 1, r
+
+
+class LeafPattern(BasePattern):
+
+ def __init__(self, type=None, content=None, name=None):
+ """
+ Initializer. Takes optional type, content, and name.
+
+ The type, if given must be a token type (< 256). If not given,
+ this matches any *leaf* node; the content may still be required.
+
+ The content, if given, must be a string.
+
+ If a name is given, the matching node is stored in the results
+ dict under that key.
+ """
+ if type is not None:
+ assert 0 <= type < 256, type
+ if content is not None:
+ assert isinstance(content, basestring), repr(content)
+ self.type = type
+ self.content = content
+ self.name = name
+
+ def match(self, node, results=None):
+ """Override match() to insist on a leaf node."""
+ if not isinstance(node, Leaf):
+ return False
+ return BasePattern.match(self, node, results)
+
+ def _submatch(self, node, results=None):
+ """
+ Match the pattern's content to the node's children.
+
+ This assumes the node type matches and self.content is not None.
+
+ Returns True if it matches, False if not.
+
+ If results is not None, it must be a dict which will be
+ updated with the nodes matching named subpatterns.
+
+ When returning False, the results dict may still be updated.
+ """
+ return self.content == node.value
+
+
+class NodePattern(BasePattern):
+
+ wildcards = False
+
+ def __init__(self, type=None, content=None, name=None):
+ """
+ Initializer. Takes optional type, content, and name.
+
+ The type, if given, must be a symbol type (>= 256). If the
+ type is None this matches *any* single node (leaf or not),
+ except if content is not None, in which it only matches
+ non-leaf nodes that also match the content pattern.
+
+ The content, if not None, must be a sequence of Patterns that
+ must match the node's children exactly. If the content is
+ given, the type must not be None.
+
+ If a name is given, the matching node is stored in the results
+ dict under that key.
+ """
+ if type is not None:
+ assert type >= 256, type
+ if content is not None:
+ assert not isinstance(content, basestring), repr(content)
+ content = list(content)
+ for i, item in enumerate(content):
+ assert isinstance(item, BasePattern), (i, item)
+ if isinstance(item, WildcardPattern):
+ self.wildcards = True
+ self.type = type
+ self.content = content
+ self.name = name
+
+ def _submatch(self, node, results=None):
+ """
+ Match the pattern's content to the node's children.
+
+ This assumes the node type matches and self.content is not None.
+
+ Returns True if it matches, False if not.
+
+ If results is not None, it must be a dict which will be
+ updated with the nodes matching named subpatterns.
+
+ When returning False, the results dict may still be updated.
+ """
+ if self.wildcards:
+ for c, r in generate_matches(self.content, node.children):
+ if c == len(node.children):
+ if results is not None:
+ results.update(r)
+ return True
+ return False
+ if len(self.content) != len(node.children):
+ return False
+ for subpattern, child in zip(self.content, node.children):
+ if not subpattern.match(child, results):
+ return False
+ return True
+
+
+class WildcardPattern(BasePattern):
+
+ """
+ A wildcard pattern can match zero or more nodes.
+
+ This has all the flexibility needed to implement patterns like:
+
+ .* .+ .? .{m,n}
+ (a b c | d e | f)
+ (...)* (...)+ (...)? (...){m,n}
+
+ except it always uses non-greedy matching.
+ """
+
+ def __init__(self, content=None, min=0, max=HUGE, name=None):
+ """
+ Initializer.
+
+ Args:
+ content: optional sequence of subsequences of patterns;
+ if absent, matches one node;
+ if present, each subsequence is an alternative [*]
+ min: optional minimum number of times to match, default 0
+ max: optional maximum number of times to match, default HUGE
+ name: optional name assigned to this match
+
+ [*] Thus, if content is [[a, b, c], [d, e], [f, g, h]] this is
+ equivalent to (a b c | d e | f g h); if content is None,
+ this is equivalent to '.' in regular expression terms.
+ The min and max parameters work as follows:
+ min=0, max=maxint: .*
+ min=1, max=maxint: .+
+ min=0, max=1: .?
+ min=1, max=1: .
+ If content is not None, replace the dot with the parenthesized
+ list of alternatives, e.g. (a b c | d e | f g h)*
+ """
+ assert 0 <= min <= max <= HUGE, (min, max)
+ if content is not None:
+ content = tuple(map(tuple, content)) # Protect against alterations
+ # Check sanity of alternatives
+ assert len(content), repr(content) # Can't have zero alternatives
+ for alt in content:
+ assert len(alt), repr(alt) # Can have empty alternatives
+ self.content = content
+ self.min = min
+ self.max = max
+ self.name = name
+
+ def optimize(self):
+ """Optimize certain stacked wildcard patterns."""
+ subpattern = None
+ if (self.content is not None and
+ len(self.content) == 1 and len(self.content[0]) == 1):
+ subpattern = self.content[0][0]
+ if self.min == 1 and self.max == 1:
+ if self.content is None:
+ return NodePattern(name=self.name)
+ if subpattern is not None and self.name == subpattern.name:
+ return subpattern.optimize()
+ if (self.min <= 1 and isinstance(subpattern, WildcardPattern) and
+ subpattern.min <= 1 and self.name == subpattern.name):
+ return WildcardPattern(subpattern.content,
+ self.min*subpattern.min,
+ self.max*subpattern.max,
+ subpattern.name)
+ return self
+
+ def match(self, node, results=None):
+ """Does this pattern exactly match a node?"""
+ return self.match_seq([node], results)
+
+ def match_seq(self, nodes, results=None):
+ """Does this pattern exactly match a sequence of nodes?"""
+ for c, r in self.generate_matches(nodes):
+ if c == len(nodes):
+ if results is not None:
+ results.update(r)
+ if self.name:
+ results[self.name] = list(nodes)
+ return True
+ return False
+
+ def generate_matches(self, nodes):
+ """
+ Generator yielding matches for a sequence of nodes.
+
+ Args:
+ nodes: sequence of nodes
+
+ Yields:
+ (count, results) tuples where:
+ count: the match comprises nodes[:count];
+ results: dict containing named submatches.
+ """
+ if self.content is None:
+ # Shortcut for special case (see __init__.__doc__)
+ for count in xrange(self.min, 1 + min(len(nodes), self.max)):
+ r = {}
+ if self.name:
+ r[self.name] = nodes[:count]
+ yield count, r
+ elif self.name == "bare_name":
+ yield self._bare_name_matches(nodes)
+ else:
+ # The reason for this is that hitting the recursion limit usually
+ # results in some ugly messages about how RuntimeErrors are being
+ # ignored. We don't do this on non-CPython implementation because
+ # they don't have this problem.
+ if hasattr(sys, "getrefcount"):
+ save_stderr = sys.stderr
+ sys.stderr = StringIO()
+ try:
+ for count, r in self._recursive_matches(nodes, 0):
+ if self.name:
+ r[self.name] = nodes[:count]
+ yield count, r
+ except RuntimeError:
+ # We fall back to the iterative pattern matching scheme if the recursive
+ # scheme hits the recursion limit.
+ for count, r in self._iterative_matches(nodes):
+ if self.name:
+ r[self.name] = nodes[:count]
+ yield count, r
+ finally:
+ if hasattr(sys, "getrefcount"):
+ sys.stderr = save_stderr
+
+ def _iterative_matches(self, nodes):
+ """Helper to iteratively yield the matches."""
+ nodelen = len(nodes)
+ if 0 >= self.min:
+ yield 0, {}
+
+ results = []
+ # generate matches that use just one alt from self.content
+ for alt in self.content:
+ for c, r in generate_matches(alt, nodes):
+ yield c, r
+ results.append((c, r))
+
+ # for each match, iterate down the nodes
+ while results:
+ new_results = []
+ for c0, r0 in results:
+ # stop if the entire set of nodes has been matched
+ if c0 < nodelen and c0 <= self.max:
+ for alt in self.content:
+ for c1, r1 in generate_matches(alt, nodes[c0:]):
+ if c1 > 0:
+ r = {}
+ r.update(r0)
+ r.update(r1)
+ yield c0 + c1, r
+ new_results.append((c0 + c1, r))
+ results = new_results
+
+ def _bare_name_matches(self, nodes):
+ """Special optimized matcher for bare_name."""
+ count = 0
+ r = {}
+ done = False
+ max = len(nodes)
+ while not done and count < max:
+ done = True
+ for leaf in self.content:
+ if leaf[0].match(nodes[count], r):
+ count += 1
+ done = False
+ break
+ r[self.name] = nodes[:count]
+ return count, r
+
+ def _recursive_matches(self, nodes, count):
+ """Helper to recursively yield the matches."""
+ assert self.content is not None
+ if count >= self.min:
+ yield 0, {}
+ if count < self.max:
+ for alt in self.content:
+ for c0, r0 in generate_matches(alt, nodes):
+ for c1, r1 in self._recursive_matches(nodes[c0:], count+1):
+ r = {}
+ r.update(r0)
+ r.update(r1)
+ yield c0 + c1, r
+
+
+class NegatedPattern(BasePattern):
+
+ def __init__(self, content=None):
+ """
+ Initializer.
+
+ The argument is either a pattern or None. If it is None, this
+ only matches an empty sequence (effectively '$' in regex
+ lingo). If it is not None, this matches whenever the argument
+ pattern doesn't have any matches.
+ """
+ if content is not None:
+ assert isinstance(content, BasePattern), repr(content)
+ self.content = content
+
+ def match(self, node):
+ # We never match a node in its entirety
+ return False
+
+ def match_seq(self, nodes):
+ # We only match an empty sequence of nodes in its entirety
+ return len(nodes) == 0
+
+ def generate_matches(self, nodes):
+ if self.content is None:
+ # Return a match if there is an empty sequence
+ if len(nodes) == 0:
+ yield 0, {}
+ else:
+ # Return a match if the argument pattern has no matches
+ for c, r in self.content.generate_matches(nodes):
+ return
+ yield 0, {}
+
+
+def generate_matches(patterns, nodes):
+ """
+ Generator yielding matches for a sequence of patterns and nodes.
+
+ Args:
+ patterns: a sequence of patterns
+ nodes: a sequence of nodes
+
+ Yields:
+ (count, results) tuples where:
+ count: the entire sequence of patterns matches nodes[:count];
+ results: dict containing named submatches.
+ """
+ if not patterns:
+ yield 0, {}
+ else:
+ p, rest = patterns[0], patterns[1:]
+ for c0, r0 in p.generate_matches(nodes):
+ if not rest:
+ yield c0, r0
+ else:
+ for c1, r1 in generate_matches(rest, nodes[c0:]):
+ r = {}
+ r.update(r0)
+ r.update(r1)
+ yield c0 + c1, r
diff --git a/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/refactor.py b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/refactor.py
new file mode 100644
index 000000000000..a4c168df9e0d
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/lib2to3/lib2to3/refactor.py
@@ -0,0 +1,747 @@
+# Copyright 2006 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Refactoring framework.
+
+Used as a main program, this can refactor any number of files and/or
+recursively descend down directories. Imported as a module, this
+provides infrastructure to write your own refactoring tool.
+"""
+
+from __future__ import with_statement
+
+__author__ = "Guido van Rossum <guido@python.org>"
+
+
+# Python imports
+import os
+import sys
+import logging
+import operator
+import collections
+import StringIO
+from itertools import chain
+
+# Local imports
+from .pgen2 import driver, tokenize, token
+from .fixer_util import find_root
+from . import pytree, pygram
+from . import btm_utils as bu
+from . import btm_matcher as bm
+
+
+def get_all_fix_names(fixer_pkg, remove_prefix=True):
+ """Return a sorted list of all available fix names in the given package."""
+ pkg = __import__(fixer_pkg, [], [], ["*"])
+ fixer_dir = os.path.dirname(pkg.__file__)
+ fix_names = []
+ for name in sorted(os.listdir(fixer_dir)):
+ if name.startswith("fix_") and name.endswith(".py"):
+ if remove_prefix:
+ name = name[4:]
+ fix_names.append(name[:-3])
+ return fix_names
+
+
+class _EveryNode(Exception):
+ pass
+
+
+def _get_head_types(pat):
+ """ Accepts a pytree Pattern Node and returns a set
+ of the pattern types which will match first. """
+
+ if isinstance(pat, (pytree.NodePattern, pytree.LeafPattern)):
+ # NodePatters must either have no type and no content
+ # or a type and content -- so they don't get any farther
+ # Always return leafs
+ if pat.type is None:
+ raise _EveryNode
+ return set([pat.type])
+
+ if isinstance(pat, pytree.NegatedPattern):
+ if pat.content:
+ return _get_head_types(pat.content)
+ raise _EveryNode # Negated Patterns don't have a type
+
+ if isinstance(pat, pytree.WildcardPattern):
+ # Recurse on each node in content
+ r = set()
+ for p in pat.content:
+ for x in p:
+ r.update(_get_head_types(x))
+ return r
+
+ raise Exception("Oh no! I don't understand pattern %s" %(pat))
+
+
+def _get_headnode_dict(fixer_list):
+ """ Accepts a list of fixers and returns a dictionary
+ of head node type --> fixer list. """
+ head_nodes = collections.defaultdict(list)
+ every = []
+ for fixer in fixer_list:
+ if fixer.pattern:
+ try:
+ heads = _get_head_types(fixer.pattern)
+ except _EveryNode:
+ every.append(fixer)
+ else:
+ for node_type in heads:
+ head_nodes[node_type].append(fixer)
+ else:
+ if fixer._accept_type is not None:
+ head_nodes[fixer._accept_type].append(fixer)
+ else:
+ every.append(fixer)
+ for node_type in chain(pygram.python_grammar.symbol2number.itervalues(),
+ pygram.python_grammar.tokens):
+ head_nodes[node_type].extend(every)
+ return dict(head_nodes)
+
+
+def get_fixers_from_package(pkg_name):
+ """
+ Return the fully qualified names for fixers in the package pkg_name.
+ """
+ return [pkg_name + "." + fix_name
+ for fix_name in get_all_fix_names(pkg_name, False)]
+
+def _identity(obj):
+ return obj
+
+if sys.version_info < (3, 0):
+ import codecs
+ _open_with_encoding = codecs.open
+ # codecs.open doesn't translate newlines sadly.
+ def _from_system_newlines(input):
+ return input.replace(u"\r\n", u"\n")
+ def _to_system_newlines(input):
+ if os.linesep != "\n":
+ return input.replace(u"\n", os.linesep)
+ else:
+ return input
+else:
+ _open_with_encoding = open
+ _from_system_newlines = _identity
+ _to_system_newlines = _identity
+
+
+def _detect_future_features(source):
+ have_docstring = False
+ gen = tokenize.generate_tokens(StringIO.StringIO(source).readline)
+ def advance():
+ tok = gen.next()
+ return tok[0], tok[1]
+ ignore = frozenset((token.NEWLINE, tokenize.NL, token.COMMENT))
+ features = set()
+ try:
+ while True:
+ tp, value = advance()
+ if tp in ignore:
+ continue
+ elif tp == token.STRING:
+ if have_docstring:
+ break
+ have_docstring = True
+ elif tp == token.NAME and value == u"from":
+ tp, value = advance()
+ if tp != token.NAME or value != u"__future__":
+ break
+ tp, value = advance()
+ if tp != token.NAME or value != u"import":
+ break
+ tp, value = advance()
+ if tp == token.OP and value == u"(":
+ tp, value = advance()
+ while tp == token.NAME:
+ features.add(value)
+ tp, value = advance()
+ if tp != token.OP or value != u",":
+ break
+ tp, value = advance()
+ else:
+ break
+ except StopIteration:
+ pass
+ return frozenset(features)
+
+
+class FixerError(Exception):
+ """A fixer could not be loaded."""
+
+
+class RefactoringTool(object):
+
+ _default_options = {"print_function" : False,
+ "write_unchanged_files" : False}
+
+ CLASS_PREFIX = "Fix" # The prefix for fixer classes
+ FILE_PREFIX = "fix_" # The prefix for modules with a fixer within
+
+ def __init__(self, fixer_names, options=None, explicit=None):
+ """Initializer.
+
+ Args:
+ fixer_names: a list of fixers to import
+ options: an dict with configuration.
+ explicit: a list of fixers to run even if they are explicit.
+ """
+ self.fixers = fixer_names
+ self.explicit = explicit or []
+ self.options = self._default_options.copy()
+ if options is not None:
+ self.options.update(options)
+ if self.options["print_function"]:
+ self.grammar = pygram.python_grammar_no_print_statement
+ else:
+ self.grammar = pygram.python_grammar
+ # When this is True, the refactor*() methods will call write_file() for
+ # files processed even if they were not changed during refactoring. If
+ # and only if the refactor method's write parameter was True.
+ self.write_unchanged_files = self.options.get("write_unchanged_files")
+ self.errors = []
+ self.logger = logging.getLogger("RefactoringTool")
+ self.fixer_log = []
+ self.wrote = False
+ self.driver = driver.Driver(self.grammar,
+ convert=pytree.convert,
+ logger=self.logger)
+ self.pre_order, self.post_order = self.get_fixers()
+
+
+ self.files = [] # List of files that were or should be modified
+
+ self.BM = bm.BottomMatcher()
+ self.bmi_pre_order = [] # Bottom Matcher incompatible fixers
+ self.bmi_post_order = []
+
+ for fixer in chain(self.post_order, self.pre_order):
+ if fixer.BM_compatible:
+ self.BM.add_fixer(fixer)
+ # remove fixers that will be handled by the bottom-up
+ # matcher
+ elif fixer in self.pre_order:
+ self.bmi_pre_order.append(fixer)
+ elif fixer in self.post_order:
+ self.bmi_post_order.append(fixer)
+
+ self.bmi_pre_order_heads = _get_headnode_dict(self.bmi_pre_order)
+ self.bmi_post_order_heads = _get_headnode_dict(self.bmi_post_order)
+
+
+
+ def get_fixers(self):
+ """Inspects the options to load the requested patterns and handlers.
+
+ Returns:
+ (pre_order, post_order), where pre_order is the list of fixers that
+ want a pre-order AST traversal, and post_order is the list that want
+ post-order traversal.
+ """
+ pre_order_fixers = []
+ post_order_fixers = []
+ for fix_mod_path in self.fixers:
+ mod = __import__(fix_mod_path, {}, {}, ["*"])
+ fix_name = fix_mod_path.rsplit(".", 1)[-1]
+ if fix_name.startswith(self.FILE_PREFIX):
+ fix_name = fix_name[len(self.FILE_PREFIX):]
+ parts = fix_name.split("_")
+ class_name = self.CLASS_PREFIX + "".join([p.title() for p in parts])
+ try:
+ fix_class = getattr(mod, class_name)
+ except AttributeError:
+ raise FixerError("Can't find %s.%s" % (fix_name, class_name))
+ fixer = fix_class(self.options, self.fixer_log)
+ if fixer.explicit and self.explicit is not True and \
+ fix_mod_path not in self.explicit:
+ self.log_message("Skipping implicit fixer: %s", fix_name)
+ continue
+
+ self.log_debug("Adding transformation: %s", fix_name)
+ if fixer.order == "pre":
+ pre_order_fixers.append(fixer)
+ elif fixer.order == "post":
+ post_order_fixers.append(fixer)
+ else:
+ raise FixerError("Illegal fixer order: %r" % fixer.order)
+
+ key_func = operator.attrgetter("run_order")
+ pre_order_fixers.sort(key=key_func)
+ post_order_fixers.sort(key=key_func)
+ return (pre_order_fixers, post_order_fixers)
+
+ def log_error(self, msg, *args, **kwds):
+ """Called when an error occurs."""
+ raise
+
+ def log_message(self, msg, *args):
+ """Hook to log a message."""
+ if args:
+ msg = msg % args
+ self.logger.info(msg)
+
+ def log_debug(self, msg, *args):
+ if args:
+ msg = msg % args
+ self.logger.debug(msg)
+
+ def print_output(self, old_text, new_text, filename, equal):
+ """Called with the old version, new version, and filename of a
+ refactored file."""
+ pass
+
+ def refactor(self, items, write=False, doctests_only=False):
+ """Refactor a list of files and directories."""
+
+ for dir_or_file in items:
+ if os.path.isdir(dir_or_file):
+ self.refactor_dir(dir_or_file, write, doctests_only)
+ else:
+ self.refactor_file(dir_or_file, write, doctests_only)
+
+ def refactor_dir(self, dir_name, write=False, doctests_only=False):
+ """Descends down a directory and refactor every Python file found.
+
+ Python files are assumed to have a .py extension.
+
+ Files and subdirectories starting with '.' are skipped.
+ """
+ py_ext = os.extsep + "py"
+ for dirpath, dirnames, filenames in os.walk(dir_name):
+ self.log_debug("Descending into %s", dirpath)
+ dirnames.sort()
+ filenames.sort()
+ for name in filenames:
+ if (not name.startswith(".") and
+ os.path.splitext(name)[1] == py_ext):
+ fullname = os.path.join(dirpath, name)
+ self.refactor_file(fullname, write, doctests_only)
+ # Modify dirnames in-place to remove subdirs with leading dots
+ dirnames[:] = [dn for dn in dirnames if not dn.startswith(".")]
+
+ def _read_python_source(self, filename):
+ """
+ Do our best to decode a Python source file correctly.
+ """
+ try:
+ f = open(filename, "rb")
+ except IOError as err:
+ self.log_error("Can't open %s: %s", filename, err)
+ return None, None
+ try:
+ encoding = tokenize.detect_encoding(f.readline)[0]
+ finally:
+ f.close()
+ with _open_with_encoding(filename, "r", encoding=encoding) as f:
+ return _from_system_newlines(f.read()), encoding
+
+ def refactor_file(self, filename, write=False, doctests_only=False):
+ """Refactors a file."""
+ input, encoding = self._read_python_source(filename)
+ if input is None:
+ # Reading the file failed.
+ return
+ input += u"\n" # Silence certain parse errors
+ if doctests_only:
+ self.log_debug("Refactoring doctests in %s", filename)
+ output = self.refactor_docstring(input, filename)
+ if self.write_unchanged_files or output != input:
+ self.processed_file(output, filename, input, write, encoding)
+ else:
+ self.log_debug("No doctest changes in %s", filename)
+ else:
+ tree = self.refactor_string(input, filename)
+ if self.write_unchanged_files or (tree and tree.was_changed):
+ # The [:-1] is to take off the \n we added earlier
+ self.processed_file(unicode(tree)[:-1], filename,
+ write=write, encoding=encoding)
+ else:
+ self.log_debug("No changes in %s", filename)
+
+ def refactor_string(self, data, name):
+ """Refactor a given input string.
+
+ Args:
+ data: a string holding the code to be refactored.
+ name: a human-readable name for use in error/log messages.
+
+ Returns:
+ An AST corresponding to the refactored input stream; None if
+ there were errors during the parse.
+ """
+ features = _detect_future_features(data)
+ if "print_function" in features:
+ self.driver.grammar = pygram.python_grammar_no_print_statement
+ try:
+ tree = self.driver.parse_string(data)
+ except Exception as err:
+ self.log_error("Can't parse %s: %s: %s",
+ name, err.__class__.__name__, err)
+ return
+ finally:
+ self.driver.grammar = self.grammar
+ tree.future_features = features
+ self.log_debug("Refactoring %s", name)
+ self.refactor_tree(tree, name)
+ return tree
+
+ def refactor_stdin(self, doctests_only=False):
+ input = sys.stdin.read()
+ if doctests_only:
+ self.log_debug("Refactoring doctests in stdin")
+ output = self.refactor_docstring(input, "<stdin>")
+ if self.write_unchanged_files or output != input:
+ self.processed_file(output, "<stdin>", input)
+ else:
+ self.log_debug("No doctest changes in stdin")
+ else:
+ tree = self.refactor_string(input, "<stdin>")
+ if self.write_unchanged_files or (tree and tree.was_changed):
+ self.processed_file(unicode(tree), "<stdin>", input)
+ else:
+ self.log_debug("No changes in stdin")
+
+ def refactor_tree(self, tree, name):
+ """Refactors a parse tree (modifying the tree in place).
+
+ For compatible patterns the bottom matcher module is
+ used. Otherwise the tree is traversed node-to-node for
+ matches.
+
+ Args:
+ tree: a pytree.Node instance representing the root of the tree
+ to be refactored.
+ name: a human-readable name for this tree.
+
+ Returns:
+ True if the tree was modified, False otherwise.
+ """
+
+ for fixer in chain(self.pre_order, self.post_order):
+ fixer.start_tree(tree, name)
+
+ #use traditional matching for the incompatible fixers
+ self.traverse_by(self.bmi_pre_order_heads, tree.pre_order())
+ self.traverse_by(self.bmi_post_order_heads, tree.post_order())
+
+ # obtain a set of candidate nodes
+ match_set = self.BM.run(tree.leaves())
+
+ while any(match_set.values()):
+ for fixer in self.BM.fixers:
+ if fixer in match_set and match_set[fixer]:
+ #sort by depth; apply fixers from bottom(of the AST) to top
+ match_set[fixer].sort(key=pytree.Base.depth, reverse=True)
+
+ if fixer.keep_line_order:
+ #some fixers(eg fix_imports) must be applied
+ #with the original file's line order
+ match_set[fixer].sort(key=pytree.Base.get_lineno)
+
+ for node in list(match_set[fixer]):
+ if node in match_set[fixer]:
+ match_set[fixer].remove(node)
+
+ try:
+ find_root(node)
+ except ValueError:
+ # this node has been cut off from a
+ # previous transformation ; skip
+ continue
+
+ if node.fixers_applied and fixer in node.fixers_applied:
+ # do not apply the same fixer again
+ continue
+
+ results = fixer.match(node)
+
+ if results:
+ new = fixer.transform(node, results)
+ if new is not None:
+ node.replace(new)
+ #new.fixers_applied.append(fixer)
+ for node in new.post_order():
+ # do not apply the fixer again to
+ # this or any subnode
+ if not node.fixers_applied:
+ node.fixers_applied = []
+ node.fixers_applied.append(fixer)
+
+ # update the original match set for
+ # the added code
+ new_matches = self.BM.run(new.leaves())
+ for fxr in new_matches:
+ if not fxr in match_set:
+ match_set[fxr]=[]
+
+ match_set[fxr].extend(new_matches[fxr])
+
+ for fixer in chain(self.pre_order, self.post_order):
+ fixer.finish_tree(tree, name)
+ return tree.was_changed
+
+ def traverse_by(self, fixers, traversal):
+ """Traverse an AST, applying a set of fixers to each node.
+
+ This is a helper method for refactor_tree().
+
+ Args:
+ fixers: a list of fixer instances.
+ traversal: a generator that yields AST nodes.
+
+ Returns:
+ None
+ """
+ if not fixers:
+ return
+ for node in traversal:
+ for fixer in fixers[node.type]:
+ results = fixer.match(node)
+ if results:
+ new = fixer.transform(node, results)
+ if new is not None:
+ node.replace(new)
+ node = new
+
+ def processed_file(self, new_text, filename, old_text=None, write=False,
+ encoding=None):
+ """
+ Called when a file has been refactored and there may be changes.
+ """
+ self.files.append(filename)
+ if old_text is None:
+ old_text = self._read_python_source(filename)[0]
+ if old_text is None:
+ return
+ equal = old_text == new_text
+ self.print_output(old_text, new_text, filename, equal)
+ if equal:
+ self.log_debug("No changes to %s", filename)
+ if not self.write_unchanged_files:
+ return
+ if write:
+ self.write_file(new_text, filename, old_text, encoding)
+ else:
+ self.log_debug("Not writing changes to %s", filename)
+
+ def write_file(self, new_text, filename, old_text, encoding=None):
+ """Writes a string to a file.
+
+ It first shows a unified diff between the old text and the new text, and
+ then rewrites the file; the latter is only done if the write option is
+ set.
+ """
+ try:
+ f = _open_with_encoding(filename, "w", encoding=encoding)
+ except os.error as err:
+ self.log_error("Can't create %s: %s", filename, err)
+ return
+ try:
+ f.write(_to_system_newlines(new_text))
+ except os.error as err:
+ self.log_error("Can't write %s: %s", filename, err)
+ finally:
+ f.close()
+ self.log_debug("Wrote changes to %s", filename)
+ self.wrote = True
+
+ PS1 = ">>> "
+ PS2 = "... "
+
+ def refactor_docstring(self, input, filename):
+ """Refactors a docstring, looking for doctests.
+
+ This returns a modified version of the input string. It looks
+ for doctests, which start with a ">>>" prompt, and may be
+ continued with "..." prompts, as long as the "..." is indented
+ the same as the ">>>".
+
+ (Unfortunately we can't use the doctest module's parser,
+ since, like most parsers, it is not geared towards preserving
+ the original source.)
+ """
+ result = []
+ block = None
+ block_lineno = None
+ indent = None
+ lineno = 0
+ for line in input.splitlines(True):
+ lineno += 1
+ if line.lstrip().startswith(self.PS1):
+ if block is not None:
+ result.extend(self.refactor_doctest(block, block_lineno,
+ indent, filename))
+ block_lineno = lineno
+ block = [line]
+ i = line.find(self.PS1)
+ indent = line[:i]
+ elif (indent is not None and
+ (line.startswith(indent + self.PS2) or
+ line == indent + self.PS2.rstrip() + u"\n")):
+ block.append(line)
+ else:
+ if block is not None:
+ result.extend(self.refactor_doctest(block, block_lineno,
+ indent, filename))
+ block = None
+ indent = None
+ result.append(line)
+ if block is not None:
+ result.extend(self.refactor_doctest(block, block_lineno,
+ indent, filename))
+ return u"".join(result)
+
+ def refactor_doctest(self, block, lineno, indent, filename):
+ """Refactors one doctest.
+
+ A doctest is given as a block of lines, the first of which starts
+ with ">>>" (possibly indented), while the remaining lines start
+ with "..." (identically indented).
+
+ """
+ try:
+ tree = self.parse_block(block, lineno, indent)
+ except Exception as err:
+ if self.logger.isEnabledFor(logging.DEBUG):
+ for line in block:
+ self.log_debug("Source: %s", line.rstrip(u"\n"))
+ self.log_error("Can't parse docstring in %s line %s: %s: %s",
+ filename, lineno, err.__class__.__name__, err)
+ return block
+ if self.refactor_tree(tree, filename):
+ new = unicode(tree).splitlines(True)
+ # Undo the adjustment of the line numbers in wrap_toks() below.
+ clipped, new = new[:lineno-1], new[lineno-1:]
+ assert clipped == [u"\n"] * (lineno-1), clipped
+ if not new[-1].endswith(u"\n"):
+ new[-1] += u"\n"
+ block = [indent + self.PS1 + new.pop(0)]
+ if new:
+ block += [indent + self.PS2 + line for line in new]
+ return block
+
+ def summarize(self):
+ if self.wrote:
+ were = "were"
+ else:
+ were = "need to be"
+ if not self.files:
+ self.log_message("No files %s modified.", were)
+ else:
+ self.log_message("Files that %s modified:", were)
+ for file in self.files:
+ self.log_message(file)
+ if self.fixer_log:
+ self.log_message("Warnings/messages while refactoring:")
+ for message in self.fixer_log:
+ self.log_message(message)
+ if self.errors:
+ if len(self.errors) == 1:
+ self.log_message("There was 1 error:")
+ else:
+ self.log_message("There were %d errors:", len(self.errors))
+ for msg, args, kwds in self.errors:
+ self.log_message(msg, *args, **kwds)
+
+ def parse_block(self, block, lineno, indent):
+ """Parses a block into a tree.
+
+ This is necessary to get correct line number / offset information
+ in the parser diagnostics and embedded into the parse tree.
+ """
+ tree = self.driver.parse_tokens(self.wrap_toks(block, lineno, indent))
+ tree.future_features = frozenset()
+ return tree
+
+ def wrap_toks(self, block, lineno, indent):
+ """Wraps a tokenize stream to systematically modify start/end."""
+ tokens = tokenize.generate_tokens(self.gen_lines(block, indent).next)
+ for type, value, (line0, col0), (line1, col1), line_text in tokens:
+ line0 += lineno - 1
+ line1 += lineno - 1
+ # Don't bother updating the columns; this is too complicated
+ # since line_text would also have to be updated and it would
+ # still break for tokens spanning lines. Let the user guess
+ # that the column numbers for doctests are relative to the
+ # end of the prompt string (PS1 or PS2).
+ yield type, value, (line0, col0), (line1, col1), line_text
+
+
+ def gen_lines(self, block, indent):
+ """Generates lines as expected by tokenize from a list of lines.
+
+ This strips the first len(indent + self.PS1) characters off each line.
+ """
+ prefix1 = indent + self.PS1
+ prefix2 = indent + self.PS2
+ prefix = prefix1
+ for line in block:
+ if line.startswith(prefix):
+ yield line[len(prefix):]
+ elif line == prefix.rstrip() + u"\n":
+ yield u"\n"
+ else:
+ raise AssertionError("line=%r, prefix=%r" % (line, prefix))
+ prefix = prefix2
+ while True:
+ yield ""
+
+
+class MultiprocessingUnsupported(Exception):
+ pass
+
+
+class MultiprocessRefactoringTool(RefactoringTool):
+
+ def __init__(self, *args, **kwargs):
+ super(MultiprocessRefactoringTool, self).__init__(*args, **kwargs)
+ self.queue = None
+ self.output_lock = None
+
+ def refactor(self, items, write=False, doctests_only=False,
+ num_processes=1):
+ if num_processes == 1:
+ return super(MultiprocessRefactoringTool, self).refactor(
+ items, write, doctests_only)
+ try:
+ import multiprocessing
+ except ImportError:
+ raise MultiprocessingUnsupported
+ if self.queue is not None:
+ raise RuntimeError("already doing multiple processes")
+ self.queue = multiprocessing.JoinableQueue()
+ self.output_lock = multiprocessing.Lock()
+ processes = [multiprocessing.Process(target=self._child)
+ for i in xrange(num_processes)]
+ try:
+ for p in processes:
+ p.start()
+ super(MultiprocessRefactoringTool, self).refactor(items, write,
+ doctests_only)
+ finally:
+ self.queue.join()
+ for i in xrange(num_processes):
+ self.queue.put(None)
+ for p in processes:
+ if p.is_alive():
+ p.join()
+ self.queue = None
+
+ def _child(self):
+ task = self.queue.get()
+ while task is not None:
+ args, kwargs = task
+ try:
+ super(MultiprocessRefactoringTool, self).refactor_file(
+ *args, **kwargs)
+ finally:
+ self.queue.task_done()
+ task = self.queue.get()
+
+ def refactor_file(self, *args, **kwargs):
+ if self.queue is not None:
+ self.queue.put((args, kwargs))
+ else:
+ return super(MultiprocessRefactoringTool, self).refactor_file(
+ *args, **kwargs)
diff --git a/python/helpers/pydev/third_party/pep8/pep8.py b/python/helpers/pydev/third_party/pep8/pep8.py
new file mode 100644
index 000000000000..d907066d1822
--- /dev/null
+++ b/python/helpers/pydev/third_party/pep8/pep8.py
@@ -0,0 +1,1959 @@
+#!/usr/bin/env python
+# pep8.py - Check Python source code formatting, according to PEP 8
+# Copyright (C) 2006-2009 Johann C. Rocholl <johann@rocholl.net>
+# Copyright (C) 2009-2014 Florent Xicluna <florent.xicluna@gmail.com>
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation files
+# (the "Software"), to deal in the Software without restriction,
+# including without limitation the rights to use, copy, modify, merge,
+# publish, distribute, sublicense, and/or sell copies of the Software,
+# and to permit persons to whom the Software is furnished to do so,
+# subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+r"""
+Check Python source code formatting, according to PEP 8.
+
+For usage and a list of options, try this:
+$ python pep8.py -h
+
+This program and its regression test suite live here:
+http://github.com/jcrocholl/pep8
+
+Groups of errors and warnings:
+E errors
+W warnings
+100 indentation
+200 whitespace
+300 blank lines
+400 imports
+500 line length
+600 deprecation
+700 statements
+900 syntax error
+"""
+from __future__ import with_statement
+
+__version__ = '1.6.0a0'
+
+import os
+import sys
+import re
+import time
+import inspect
+import keyword
+import tokenize
+from optparse import OptionParser
+from fnmatch import fnmatch
+try:
+ from configparser import RawConfigParser
+ from io import TextIOWrapper
+except ImportError:
+ from ConfigParser import RawConfigParser
+
+DEFAULT_EXCLUDE = '.svn,CVS,.bzr,.hg,.git,__pycache__'
+DEFAULT_IGNORE = 'E123,E226,E24,E704'
+if sys.platform == 'win32':
+ DEFAULT_CONFIG = os.path.expanduser(r'~\.pep8')
+else:
+ DEFAULT_CONFIG = os.path.join(os.getenv('XDG_CONFIG_HOME') or
+ os.path.expanduser('~/.config'), 'pep8')
+PROJECT_CONFIG = ('setup.cfg', 'tox.ini', '.pep8')
+TESTSUITE_PATH = os.path.join(os.path.dirname(__file__), 'testsuite')
+MAX_LINE_LENGTH = 79
+REPORT_FORMAT = {
+ 'default': '%(path)s:%(row)d:%(col)d: %(code)s %(text)s',
+ 'pylint': '%(path)s:%(row)d: [%(code)s] %(text)s',
+}
+
+PyCF_ONLY_AST = 1024
+SINGLETONS = frozenset(['False', 'None', 'True'])
+KEYWORDS = frozenset(keyword.kwlist + ['print']) - SINGLETONS
+UNARY_OPERATORS = frozenset(['>>', '**', '*', '+', '-'])
+ARITHMETIC_OP = frozenset(['**', '*', '/', '//', '+', '-'])
+WS_OPTIONAL_OPERATORS = ARITHMETIC_OP.union(['^', '&', '|', '<<', '>>', '%'])
+WS_NEEDED_OPERATORS = frozenset([
+ '**=', '*=', '/=', '//=', '+=', '-=', '!=', '<>', '<', '>',
+ '%=', '^=', '&=', '|=', '==', '<=', '>=', '<<=', '>>=', '='])
+WHITESPACE = frozenset(' \t')
+NEWLINE = frozenset([tokenize.NL, tokenize.NEWLINE])
+SKIP_TOKENS = NEWLINE.union([tokenize.INDENT, tokenize.DEDENT])
+# ERRORTOKEN is triggered by backticks in Python 3
+SKIP_COMMENTS = SKIP_TOKENS.union([tokenize.COMMENT, tokenize.ERRORTOKEN])
+BENCHMARK_KEYS = ['directories', 'files', 'logical lines', 'physical lines']
+
+INDENT_REGEX = re.compile(r'([ \t]*)')
+RAISE_COMMA_REGEX = re.compile(r'raise\s+\w+\s*,')
+RERAISE_COMMA_REGEX = re.compile(r'raise\s+\w+\s*,.*,\s*\w+\s*$')
+ERRORCODE_REGEX = re.compile(r'\b[A-Z]\d{3}\b')
+DOCSTRING_REGEX = re.compile(r'u?r?["\']')
+EXTRANEOUS_WHITESPACE_REGEX = re.compile(r'[[({] | []}),;:]')
+WHITESPACE_AFTER_COMMA_REGEX = re.compile(r'[,;:]\s*(?: |\t)')
+COMPARE_SINGLETON_REGEX = re.compile(r'([=!]=)\s*(None|False|True)')
+COMPARE_NEGATIVE_REGEX = re.compile(r'\b(not)\s+[^[({ ]+\s+(in|is)\s')
+COMPARE_TYPE_REGEX = re.compile(r'(?:[=!]=|is(?:\s+not)?)\s*type(?:s.\w+Type'
+ r'|\s*\(\s*([^)]*[^ )])\s*\))')
+KEYWORD_REGEX = re.compile(r'(\s*)\b(?:%s)\b(\s*)' % r'|'.join(KEYWORDS))
+OPERATOR_REGEX = re.compile(r'(?:[^,\s])(\s*)(?:[-+*/|!<=>%&^]+)(\s*)')
+LAMBDA_REGEX = re.compile(r'\blambda\b')
+HUNK_REGEX = re.compile(r'^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@.*$')
+
+# Work around Python < 2.6 behaviour, which does not generate NL after
+# a comment which is on a line by itself.
+COMMENT_WITH_NL = tokenize.generate_tokens(['#\n'].pop).send(None)[1] == '#\n'
+
+
+##############################################################################
+# Plugins (check functions) for physical lines
+##############################################################################
+
+
+def tabs_or_spaces(physical_line, indent_char):
+ r"""Never mix tabs and spaces.
+
+ The most popular way of indenting Python is with spaces only. The
+ second-most popular way is with tabs only. Code indented with a mixture
+ of tabs and spaces should be converted to using spaces exclusively. When
+ invoking the Python command line interpreter with the -t option, it issues
+ warnings about code that illegally mixes tabs and spaces. When using -tt
+ these warnings become errors. These options are highly recommended!
+
+ Okay: if a == 0:\n a = 1\n b = 1
+ E101: if a == 0:\n a = 1\n\tb = 1
+ """
+ indent = INDENT_REGEX.match(physical_line).group(1)
+ for offset, char in enumerate(indent):
+ if char != indent_char:
+ return offset, "E101 indentation contains mixed spaces and tabs"
+
+
+def tabs_obsolete(physical_line):
+ r"""For new projects, spaces-only are strongly recommended over tabs.
+
+ Okay: if True:\n return
+ W191: if True:\n\treturn
+ """
+ indent = INDENT_REGEX.match(physical_line).group(1)
+ if '\t' in indent:
+ return indent.index('\t'), "W191 indentation contains tabs"
+
+
+def trailing_whitespace(physical_line):
+ r"""Trailing whitespace is superfluous.
+
+ The warning returned varies on whether the line itself is blank, for easier
+ filtering for those who want to indent their blank lines.
+
+ Okay: spam(1)\n#
+ W291: spam(1) \n#
+ W293: class Foo(object):\n \n bang = 12
+ """
+ physical_line = physical_line.rstrip('\n') # chr(10), newline
+ physical_line = physical_line.rstrip('\r') # chr(13), carriage return
+ physical_line = physical_line.rstrip('\x0c') # chr(12), form feed, ^L
+ stripped = physical_line.rstrip(' \t\v')
+ if physical_line != stripped:
+ if stripped:
+ return len(stripped), "W291 trailing whitespace"
+ else:
+ return 0, "W293 blank line contains whitespace"
+
+
+def trailing_blank_lines(physical_line, lines, line_number, total_lines):
+ r"""Trailing blank lines are superfluous.
+
+ Okay: spam(1)
+ W391: spam(1)\n
+
+ However the last line should end with a new line (warning W292).
+ """
+ if line_number == total_lines:
+ stripped_last_line = physical_line.rstrip()
+ if not stripped_last_line:
+ return 0, "W391 blank line at end of file"
+ if stripped_last_line == physical_line:
+ return len(physical_line), "W292 no newline at end of file"
+
+
+def maximum_line_length(physical_line, max_line_length, multiline):
+ r"""Limit all lines to a maximum of 79 characters.
+
+ There are still many devices around that are limited to 80 character
+ lines; plus, limiting windows to 80 characters makes it possible to have
+ several windows side-by-side. The default wrapping on such devices looks
+ ugly. Therefore, please limit all lines to a maximum of 79 characters.
+ For flowing long blocks of text (docstrings or comments), limiting the
+ length to 72 characters is recommended.
+
+ Reports error E501.
+ """
+ line = physical_line.rstrip()
+ length = len(line)
+ if length > max_line_length and not noqa(line):
+ # Special case for long URLs in multi-line docstrings or comments,
+ # but still report the error when the 72 first chars are whitespaces.
+ chunks = line.split()
+ if ((len(chunks) == 1 and multiline) or
+ (len(chunks) == 2 and chunks[0] == '#')) and \
+ len(line) - len(chunks[-1]) < max_line_length - 7:
+ return
+ if hasattr(line, 'decode'): # Python 2
+ # The line could contain multi-byte characters
+ try:
+ length = len(line.decode('utf-8'))
+ except UnicodeError:
+ pass
+ if length > max_line_length:
+ return (max_line_length, "E501 line too long "
+ "(%d > %d characters)" % (length, max_line_length))
+
+
+##############################################################################
+# Plugins (check functions) for logical lines
+##############################################################################
+
+
+def blank_lines(logical_line, blank_lines, indent_level, line_number,
+ blank_before, previous_logical, previous_indent_level):
+ r"""Separate top-level function and class definitions with two blank lines.
+
+ Method definitions inside a class are separated by a single blank line.
+
+ Extra blank lines may be used (sparingly) to separate groups of related
+ functions. Blank lines may be omitted between a bunch of related
+ one-liners (e.g. a set of dummy implementations).
+
+ Use blank lines in functions, sparingly, to indicate logical sections.
+
+ Okay: def a():\n pass\n\n\ndef b():\n pass
+ Okay: def a():\n pass\n\n\n# Foo\n# Bar\n\ndef b():\n pass
+
+ E301: class Foo:\n b = 0\n def bar():\n pass
+ E302: def a():\n pass\n\ndef b(n):\n pass
+ E303: def a():\n pass\n\n\n\ndef b(n):\n pass
+ E303: def a():\n\n\n\n pass
+ E304: @decorator\n\ndef a():\n pass
+ """
+ if line_number < 3 and not previous_logical:
+ return # Don't expect blank lines before the first line
+ if previous_logical.startswith('@'):
+ if blank_lines:
+ yield 0, "E304 blank lines found after function decorator"
+ elif blank_lines > 2 or (indent_level and blank_lines == 2):
+ yield 0, "E303 too many blank lines (%d)" % blank_lines
+ elif logical_line.startswith(('def ', 'class ', '@')):
+ if indent_level:
+ if not (blank_before or previous_indent_level < indent_level or
+ DOCSTRING_REGEX.match(previous_logical)):
+ yield 0, "E301 expected 1 blank line, found 0"
+ elif blank_before != 2:
+ yield 0, "E302 expected 2 blank lines, found %d" % blank_before
+
+
+def extraneous_whitespace(logical_line):
+ r"""Avoid extraneous whitespace.
+
+ Avoid extraneous whitespace in these situations:
+ - Immediately inside parentheses, brackets or braces.
+ - Immediately before a comma, semicolon, or colon.
+
+ Okay: spam(ham[1], {eggs: 2})
+ E201: spam( ham[1], {eggs: 2})
+ E201: spam(ham[ 1], {eggs: 2})
+ E201: spam(ham[1], { eggs: 2})
+ E202: spam(ham[1], {eggs: 2} )
+ E202: spam(ham[1 ], {eggs: 2})
+ E202: spam(ham[1], {eggs: 2 })
+
+ E203: if x == 4: print x, y; x, y = y , x
+ E203: if x == 4: print x, y ; x, y = y, x
+ E203: if x == 4 : print x, y; x, y = y, x
+ """
+ line = logical_line
+ for match in EXTRANEOUS_WHITESPACE_REGEX.finditer(line):
+ text = match.group()
+ char = text.strip()
+ found = match.start()
+ if text == char + ' ':
+ # assert char in '([{'
+ yield found + 1, "E201 whitespace after '%s'" % char
+ elif line[found - 1] != ',':
+ code = ('E202' if char in '}])' else 'E203') # if char in ',;:'
+ yield found, "%s whitespace before '%s'" % (code, char)
+
+
+def whitespace_around_keywords(logical_line):
+ r"""Avoid extraneous whitespace around keywords.
+
+ Okay: True and False
+ E271: True and False
+ E272: True and False
+ E273: True and\tFalse
+ E274: True\tand False
+ """
+ for match in KEYWORD_REGEX.finditer(logical_line):
+ before, after = match.groups()
+
+ if '\t' in before:
+ yield match.start(1), "E274 tab before keyword"
+ elif len(before) > 1:
+ yield match.start(1), "E272 multiple spaces before keyword"
+
+ if '\t' in after:
+ yield match.start(2), "E273 tab after keyword"
+ elif len(after) > 1:
+ yield match.start(2), "E271 multiple spaces after keyword"
+
+
+def missing_whitespace(logical_line):
+ r"""Each comma, semicolon or colon should be followed by whitespace.
+
+ Okay: [a, b]
+ Okay: (3,)
+ Okay: a[1:4]
+ Okay: a[:4]
+ Okay: a[1:]
+ Okay: a[1:4:2]
+ E231: ['a','b']
+ E231: foo(bar,baz)
+ E231: [{'a':'b'}]
+ """
+ line = logical_line
+ for index in range(len(line) - 1):
+ char = line[index]
+ if char in ',;:' and line[index + 1] not in WHITESPACE:
+ before = line[:index]
+ if char == ':' and before.count('[') > before.count(']') and \
+ before.rfind('{') < before.rfind('['):
+ continue # Slice syntax, no space required
+ if char == ',' and line[index + 1] == ')':
+ continue # Allow tuple with only one element: (3,)
+ yield index, "E231 missing whitespace after '%s'" % char
+
+
+def indentation(logical_line, previous_logical, indent_char,
+ indent_level, previous_indent_level):
+ r"""Use 4 spaces per indentation level.
+
+ For really old code that you don't want to mess up, you can continue to
+ use 8-space tabs.
+
+ Okay: a = 1
+ Okay: if a == 0:\n a = 1
+ E111: a = 1
+ E114: # a = 1
+
+ Okay: for item in items:\n pass
+ E112: for item in items:\npass
+ E115: for item in items:\n# Hi\n pass
+
+ Okay: a = 1\nb = 2
+ E113: a = 1\n b = 2
+ E116: a = 1\n # b = 2
+ """
+ c = 0 if logical_line else 3
+ tmpl = "E11%d %s" if logical_line else "E11%d %s (comment)"
+ if indent_level % 4:
+ yield 0, tmpl % (1 + c, "indentation is not a multiple of four")
+ indent_expect = previous_logical.endswith(':')
+ if indent_expect and indent_level <= previous_indent_level:
+ yield 0, tmpl % (2 + c, "expected an indented block")
+ elif not indent_expect and indent_level > previous_indent_level:
+ yield 0, tmpl % (3 + c, "unexpected indentation")
+
+
+def continued_indentation(logical_line, tokens, indent_level, hang_closing,
+ indent_char, noqa, verbose):
+ r"""Continuation lines indentation.
+
+ Continuation lines should align wrapped elements either vertically
+ using Python's implicit line joining inside parentheses, brackets
+ and braces, or using a hanging indent.
+
+ When using a hanging indent these considerations should be applied:
+ - there should be no arguments on the first line, and
+ - further indentation should be used to clearly distinguish itself as a
+ continuation line.
+
+ Okay: a = (\n)
+ E123: a = (\n )
+
+ Okay: a = (\n 42)
+ E121: a = (\n 42)
+ E122: a = (\n42)
+ E123: a = (\n 42\n )
+ E124: a = (24,\n 42\n)
+ E125: if (\n b):\n pass
+ E126: a = (\n 42)
+ E127: a = (24,\n 42)
+ E128: a = (24,\n 42)
+ E129: if (a or\n b):\n pass
+ E131: a = (\n 42\n 24)
+ """
+ first_row = tokens[0][2][0]
+ nrows = 1 + tokens[-1][2][0] - first_row
+ if noqa or nrows == 1:
+ return
+
+ # indent_next tells us whether the next block is indented; assuming
+ # that it is indented by 4 spaces, then we should not allow 4-space
+ # indents on the final continuation line; in turn, some other
+ # indents are allowed to have an extra 4 spaces.
+ indent_next = logical_line.endswith(':')
+
+ row = depth = 0
+ valid_hangs = (4,) if indent_char != '\t' else (4, 8)
+ # remember how many brackets were opened on each line
+ parens = [0] * nrows
+ # relative indents of physical lines
+ rel_indent = [0] * nrows
+ # for each depth, collect a list of opening rows
+ open_rows = [[0]]
+ # for each depth, memorize the hanging indentation
+ hangs = [None]
+ # visual indents
+ indent_chances = {}
+ last_indent = tokens[0][2]
+ visual_indent = None
+ # for each depth, memorize the visual indent column
+ indent = [last_indent[1]]
+ if verbose >= 3:
+ print(">>> " + tokens[0][4].rstrip())
+
+ for token_type, text, start, end, line in tokens:
+
+ newline = row < start[0] - first_row
+ if newline:
+ row = start[0] - first_row
+ newline = not last_token_multiline and token_type not in NEWLINE
+
+ if newline:
+ # this is the beginning of a continuation line.
+ last_indent = start
+ if verbose >= 3:
+ print("... " + line.rstrip())
+
+ # record the initial indent.
+ rel_indent[row] = expand_indent(line) - indent_level
+
+ # identify closing bracket
+ close_bracket = (token_type == tokenize.OP and text in ']})')
+
+ # is the indent relative to an opening bracket line?
+ for open_row in reversed(open_rows[depth]):
+ hang = rel_indent[row] - rel_indent[open_row]
+ hanging_indent = hang in valid_hangs
+ if hanging_indent:
+ break
+ if hangs[depth]:
+ hanging_indent = (hang == hangs[depth])
+ # is there any chance of visual indent?
+ visual_indent = (not close_bracket and hang > 0 and
+ indent_chances.get(start[1]))
+
+ if close_bracket and indent[depth]:
+ # closing bracket for visual indent
+ if start[1] != indent[depth]:
+ yield (start, "E124 closing bracket does not match "
+ "visual indentation")
+ elif close_bracket and not hang:
+ # closing bracket matches indentation of opening bracket's line
+ if hang_closing:
+ yield start, "E133 closing bracket is missing indentation"
+ elif indent[depth] and start[1] < indent[depth]:
+ if visual_indent is not True:
+ # visual indent is broken
+ yield (start, "E128 continuation line "
+ "under-indented for visual indent")
+ elif hanging_indent or (indent_next and rel_indent[row] == 8):
+ # hanging indent is verified
+ if close_bracket and not hang_closing:
+ yield (start, "E123 closing bracket does not match "
+ "indentation of opening bracket's line")
+ hangs[depth] = hang
+ elif visual_indent is True:
+ # visual indent is verified
+ indent[depth] = start[1]
+ elif visual_indent in (text, str):
+ # ignore token lined up with matching one from a previous line
+ pass
+ else:
+ # indent is broken
+ if hang <= 0:
+ error = "E122", "missing indentation or outdented"
+ elif indent[depth]:
+ error = "E127", "over-indented for visual indent"
+ elif not close_bracket and hangs[depth]:
+ error = "E131", "unaligned for hanging indent"
+ else:
+ hangs[depth] = hang
+ if hang > 4:
+ error = "E126", "over-indented for hanging indent"
+ else:
+ error = "E121", "under-indented for hanging indent"
+ yield start, "%s continuation line %s" % error
+
+ # look for visual indenting
+ if (parens[row] and token_type not in (tokenize.NL, tokenize.COMMENT)
+ and not indent[depth]):
+ indent[depth] = start[1]
+ indent_chances[start[1]] = True
+ if verbose >= 4:
+ print("bracket depth %s indent to %s" % (depth, start[1]))
+ # deal with implicit string concatenation
+ elif (token_type in (tokenize.STRING, tokenize.COMMENT) or
+ text in ('u', 'ur', 'b', 'br')):
+ indent_chances[start[1]] = str
+ # special case for the "if" statement because len("if (") == 4
+ elif not indent_chances and not row and not depth and text == 'if':
+ indent_chances[end[1] + 1] = True
+ elif text == ':' and line[end[1]:].isspace():
+ open_rows[depth].append(row)
+
+ # keep track of bracket depth
+ if token_type == tokenize.OP:
+ if text in '([{':
+ depth += 1
+ indent.append(0)
+ hangs.append(None)
+ if len(open_rows) == depth:
+ open_rows.append([])
+ open_rows[depth].append(row)
+ parens[row] += 1
+ if verbose >= 4:
+ print("bracket depth %s seen, col %s, visual min = %s" %
+ (depth, start[1], indent[depth]))
+ elif text in ')]}' and depth > 0:
+ # parent indents should not be more than this one
+ prev_indent = indent.pop() or last_indent[1]
+ hangs.pop()
+ for d in range(depth):
+ if indent[d] > prev_indent:
+ indent[d] = 0
+ for ind in list(indent_chances):
+ if ind >= prev_indent:
+ del indent_chances[ind]
+ del open_rows[depth + 1:]
+ depth -= 1
+ if depth:
+ indent_chances[indent[depth]] = True
+ for idx in range(row, -1, -1):
+ if parens[idx]:
+ parens[idx] -= 1
+ break
+ assert len(indent) == depth + 1
+ if start[1] not in indent_chances:
+ # allow to line up tokens
+ indent_chances[start[1]] = text
+
+ last_token_multiline = (start[0] != end[0])
+ if last_token_multiline:
+ rel_indent[end[0] - first_row] = rel_indent[row]
+
+ if indent_next and expand_indent(line) == indent_level + 4:
+ pos = (start[0], indent[0] + 4)
+ if visual_indent:
+ code = "E129 visually indented line"
+ else:
+ code = "E125 continuation line"
+ yield pos, "%s with same indent as next logical line" % code
+
+
+def whitespace_before_parameters(logical_line, tokens):
+ r"""Avoid extraneous whitespace.
+
+ Avoid extraneous whitespace in the following situations:
+ - before the open parenthesis that starts the argument list of a
+ function call.
+ - before the open parenthesis that starts an indexing or slicing.
+
+ Okay: spam(1)
+ E211: spam (1)
+
+ Okay: dict['key'] = list[index]
+ E211: dict ['key'] = list[index]
+ E211: dict['key'] = list [index]
+ """
+ prev_type, prev_text, __, prev_end, __ = tokens[0]
+ for index in range(1, len(tokens)):
+ token_type, text, start, end, __ = tokens[index]
+ if (token_type == tokenize.OP and
+ text in '([' and
+ start != prev_end and
+ (prev_type == tokenize.NAME or prev_text in '}])') and
+ # Syntax "class A (B):" is allowed, but avoid it
+ (index < 2 or tokens[index - 2][1] != 'class') and
+ # Allow "return (a.foo for a in range(5))"
+ not keyword.iskeyword(prev_text)):
+ yield prev_end, "E211 whitespace before '%s'" % text
+ prev_type = token_type
+ prev_text = text
+ prev_end = end
+
+
+def whitespace_around_operator(logical_line):
+ r"""Avoid extraneous whitespace around an operator.
+
+ Okay: a = 12 + 3
+ E221: a = 4 + 5
+ E222: a = 4 + 5
+ E223: a = 4\t+ 5
+ E224: a = 4 +\t5
+ """
+ for match in OPERATOR_REGEX.finditer(logical_line):
+ before, after = match.groups()
+
+ if '\t' in before:
+ yield match.start(1), "E223 tab before operator"
+ elif len(before) > 1:
+ yield match.start(1), "E221 multiple spaces before operator"
+
+ if '\t' in after:
+ yield match.start(2), "E224 tab after operator"
+ elif len(after) > 1:
+ yield match.start(2), "E222 multiple spaces after operator"
+
+
+def missing_whitespace_around_operator(logical_line, tokens):
+ r"""Surround operators with a single space on either side.
+
+ - Always surround these binary operators with a single space on
+ either side: assignment (=), augmented assignment (+=, -= etc.),
+ comparisons (==, <, >, !=, <=, >=, in, not in, is, is not),
+ Booleans (and, or, not).
+
+ - If operators with different priorities are used, consider adding
+ whitespace around the operators with the lowest priorities.
+
+ Okay: i = i + 1
+ Okay: submitted += 1
+ Okay: x = x * 2 - 1
+ Okay: hypot2 = x * x + y * y
+ Okay: c = (a + b) * (a - b)
+ Okay: foo(bar, key='word', *args, **kwargs)
+ Okay: alpha[:-i]
+
+ E225: i=i+1
+ E225: submitted +=1
+ E225: x = x /2 - 1
+ E225: z = x **y
+ E226: c = (a+b) * (a-b)
+ E226: hypot2 = x*x + y*y
+ E227: c = a|b
+ E228: msg = fmt%(errno, errmsg)
+ """
+ parens = 0
+ need_space = False
+ prev_type = tokenize.OP
+ prev_text = prev_end = None
+ for token_type, text, start, end, line in tokens:
+ if token_type in SKIP_COMMENTS:
+ continue
+ if text in ('(', 'lambda'):
+ parens += 1
+ elif text == ')':
+ parens -= 1
+ if need_space:
+ if start != prev_end:
+ # Found a (probably) needed space
+ if need_space is not True and not need_space[1]:
+ yield (need_space[0],
+ "E225 missing whitespace around operator")
+ need_space = False
+ elif text == '>' and prev_text in ('<', '-'):
+ # Tolerate the "<>" operator, even if running Python 3
+ # Deal with Python 3's annotated return value "->"
+ pass
+ else:
+ if need_space is True or need_space[1]:
+ # A needed trailing space was not found
+ yield prev_end, "E225 missing whitespace around operator"
+ else:
+ code, optype = 'E226', 'arithmetic'
+ if prev_text == '%':
+ code, optype = 'E228', 'modulo'
+ elif prev_text not in ARITHMETIC_OP:
+ code, optype = 'E227', 'bitwise or shift'
+ yield (need_space[0], "%s missing whitespace "
+ "around %s operator" % (code, optype))
+ need_space = False
+ elif token_type == tokenize.OP and prev_end is not None:
+ if text == '=' and parens:
+ # Allow keyword args or defaults: foo(bar=None).
+ pass
+ elif text in WS_NEEDED_OPERATORS:
+ need_space = True
+ elif text in UNARY_OPERATORS:
+ # Check if the operator is being used as a binary operator
+ # Allow unary operators: -123, -x, +1.
+ # Allow argument unpacking: foo(*args, **kwargs).
+ if (prev_text in '}])' if prev_type == tokenize.OP
+ else prev_text not in KEYWORDS):
+ need_space = None
+ elif text in WS_OPTIONAL_OPERATORS:
+ need_space = None
+
+ if need_space is None:
+ # Surrounding space is optional, but ensure that
+ # trailing space matches opening space
+ need_space = (prev_end, start != prev_end)
+ elif need_space and start == prev_end:
+ # A needed opening space was not found
+ yield prev_end, "E225 missing whitespace around operator"
+ need_space = False
+ prev_type = token_type
+ prev_text = text
+ prev_end = end
+
+
+def whitespace_around_comma(logical_line):
+ r"""Avoid extraneous whitespace after a comma or a colon.
+
+ Note: these checks are disabled by default
+
+ Okay: a = (1, 2)
+ E241: a = (1, 2)
+ E242: a = (1,\t2)
+ """
+ line = logical_line
+ for m in WHITESPACE_AFTER_COMMA_REGEX.finditer(line):
+ found = m.start() + 1
+ if '\t' in m.group():
+ yield found, "E242 tab after '%s'" % m.group()[0]
+ else:
+ yield found, "E241 multiple spaces after '%s'" % m.group()[0]
+
+
+def whitespace_around_named_parameter_equals(logical_line, tokens):
+ r"""Don't use spaces around the '=' sign in function arguments.
+
+ Don't use spaces around the '=' sign when used to indicate a
+ keyword argument or a default parameter value.
+
+ Okay: def complex(real, imag=0.0):
+ Okay: return magic(r=real, i=imag)
+ Okay: boolean(a == b)
+ Okay: boolean(a != b)
+ Okay: boolean(a <= b)
+ Okay: boolean(a >= b)
+
+ E251: def complex(real, imag = 0.0):
+ E251: return magic(r = real, i = imag)
+ """
+ parens = 0
+ no_space = False
+ prev_end = None
+ message = "E251 unexpected spaces around keyword / parameter equals"
+ for token_type, text, start, end, line in tokens:
+ if token_type == tokenize.NL:
+ continue
+ if no_space:
+ no_space = False
+ if start != prev_end:
+ yield (prev_end, message)
+ elif token_type == tokenize.OP:
+ if text == '(':
+ parens += 1
+ elif text == ')':
+ parens -= 1
+ elif parens and text == '=':
+ no_space = True
+ if start != prev_end:
+ yield (prev_end, message)
+ prev_end = end
+
+
+def whitespace_before_comment(logical_line, tokens):
+ r"""Separate inline comments by at least two spaces.
+
+ An inline comment is a comment on the same line as a statement. Inline
+ comments should be separated by at least two spaces from the statement.
+ They should start with a # and a single space.
+
+ Each line of a block comment starts with a # and a single space
+ (unless it is indented text inside the comment).
+
+ Okay: x = x + 1 # Increment x
+ Okay: x = x + 1 # Increment x
+ Okay: # Block comment
+ E261: x = x + 1 # Increment x
+ E262: x = x + 1 #Increment x
+ E262: x = x + 1 # Increment x
+ E265: #Block comment
+ E266: ### Block comment
+ """
+ prev_end = (0, 0)
+ for token_type, text, start, end, line in tokens:
+ if token_type == tokenize.COMMENT:
+ inline_comment = line[:start[1]].strip()
+ if inline_comment:
+ if prev_end[0] == start[0] and start[1] < prev_end[1] + 2:
+ yield (prev_end,
+ "E261 at least two spaces before inline comment")
+ symbol, sp, comment = text.partition(' ')
+ bad_prefix = symbol not in '#:' and (symbol.lstrip('#')[:1] or '#')
+ if inline_comment:
+ if bad_prefix or comment[:1] in WHITESPACE:
+ yield start, "E262 inline comment should start with '# '"
+ elif bad_prefix and (bad_prefix != '!' or start[0] > 1):
+ if bad_prefix != '#':
+ yield start, "E265 block comment should start with '# '"
+ elif comment:
+ yield start, "E266 too many leading '#' for block comment"
+ elif token_type != tokenize.NL:
+ prev_end = end
+
+
+def imports_on_separate_lines(logical_line):
+ r"""Imports should usually be on separate lines.
+
+ Okay: import os\nimport sys
+ E401: import sys, os
+
+ Okay: from subprocess import Popen, PIPE
+ Okay: from myclas import MyClass
+ Okay: from foo.bar.yourclass import YourClass
+ Okay: import myclass
+ Okay: import foo.bar.yourclass
+ """
+ line = logical_line
+ if line.startswith('import '):
+ found = line.find(',')
+ if -1 < found and ';' not in line[:found]:
+ yield found, "E401 multiple imports on one line"
+
+
+def compound_statements(logical_line):
+ r"""Compound statements (on the same line) are generally discouraged.
+
+ While sometimes it's okay to put an if/for/while with a small body
+ on the same line, never do this for multi-clause statements.
+ Also avoid folding such long lines!
+
+ Always use a def statement instead of an assignment statement that
+ binds a lambda expression directly to a name.
+
+ Okay: if foo == 'blah':\n do_blah_thing()
+ Okay: do_one()
+ Okay: do_two()
+ Okay: do_three()
+
+ E701: if foo == 'blah': do_blah_thing()
+ E701: for x in lst: total += x
+ E701: while t < 10: t = delay()
+ E701: if foo == 'blah': do_blah_thing()
+ E701: else: do_non_blah_thing()
+ E701: try: something()
+ E701: finally: cleanup()
+ E701: if foo == 'blah': one(); two(); three()
+ E702: do_one(); do_two(); do_three()
+ E703: do_four(); # useless semicolon
+ E704: def f(x): return 2*x
+ E731: f = lambda x: 2*x
+ """
+ line = logical_line
+ last_char = len(line) - 1
+ found = line.find(':')
+ while -1 < found < last_char:
+ before = line[:found]
+ if ((before.count('{') <= before.count('}') and # {'a': 1} (dict)
+ before.count('[') <= before.count(']') and # [1:2] (slice)
+ before.count('(') <= before.count(')'))): # (annotation)
+ if LAMBDA_REGEX.search(before):
+ yield 0, "E731 do not assign a lambda expression, use a def"
+ break
+ if before.startswith('def '):
+ yield 0, "E704 multiple statements on one line (def)"
+ else:
+ yield found, "E701 multiple statements on one line (colon)"
+ found = line.find(':', found + 1)
+ found = line.find(';')
+ while -1 < found:
+ if found < last_char:
+ yield found, "E702 multiple statements on one line (semicolon)"
+ else:
+ yield found, "E703 statement ends with a semicolon"
+ found = line.find(';', found + 1)
+
+
+def explicit_line_join(logical_line, tokens):
+ r"""Avoid explicit line join between brackets.
+
+ The preferred way of wrapping long lines is by using Python's implied line
+ continuation inside parentheses, brackets and braces. Long lines can be
+ broken over multiple lines by wrapping expressions in parentheses. These
+ should be used in preference to using a backslash for line continuation.
+
+ E502: aaa = [123, \\n 123]
+ E502: aaa = ("bbb " \\n "ccc")
+
+ Okay: aaa = [123,\n 123]
+ Okay: aaa = ("bbb "\n "ccc")
+ Okay: aaa = "bbb " \\n "ccc"
+ """
+ prev_start = prev_end = parens = 0
+ for token_type, text, start, end, line in tokens:
+ if start[0] != prev_start and parens and backslash:
+ yield backslash, "E502 the backslash is redundant between brackets"
+ if end[0] != prev_end:
+ if line.rstrip('\r\n').endswith('\\'):
+ backslash = (end[0], len(line.splitlines()[-1]) - 1)
+ else:
+ backslash = None
+ prev_start = prev_end = end[0]
+ else:
+ prev_start = start[0]
+ if token_type == tokenize.OP:
+ if text in '([{':
+ parens += 1
+ elif text in ')]}':
+ parens -= 1
+
+
+def comparison_to_singleton(logical_line, noqa):
+ r"""Comparison to singletons should use "is" or "is not".
+
+ Comparisons to singletons like None should always be done
+ with "is" or "is not", never the equality operators.
+
+ Okay: if arg is not None:
+ E711: if arg != None:
+ E712: if arg == True:
+
+ Also, beware of writing if x when you really mean if x is not None --
+ e.g. when testing whether a variable or argument that defaults to None was
+ set to some other value. The other value might have a type (such as a
+ container) that could be false in a boolean context!
+ """
+ match = not noqa and COMPARE_SINGLETON_REGEX.search(logical_line)
+ if match:
+ same = (match.group(1) == '==')
+ singleton = match.group(2)
+ msg = "'if cond is %s:'" % (('' if same else 'not ') + singleton)
+ if singleton in ('None',):
+ code = 'E711'
+ else:
+ code = 'E712'
+ nonzero = ((singleton == 'True' and same) or
+ (singleton == 'False' and not same))
+ msg += " or 'if %scond:'" % ('' if nonzero else 'not ')
+ yield match.start(1), ("%s comparison to %s should be %s" %
+ (code, singleton, msg))
+
+
+def comparison_negative(logical_line):
+ r"""Negative comparison should be done using "not in" and "is not".
+
+ Okay: if x not in y:\n pass
+ Okay: assert (X in Y or X is Z)
+ Okay: if not (X in Y):\n pass
+ Okay: zz = x is not y
+ E713: Z = not X in Y
+ E713: if not X.B in Y:\n pass
+ E714: if not X is Y:\n pass
+ E714: Z = not X.B is Y
+ """
+ match = COMPARE_NEGATIVE_REGEX.search(logical_line)
+ if match:
+ pos = match.start(1)
+ if match.group(2) == 'in':
+ yield pos, "E713 test for membership should be 'not in'"
+ else:
+ yield pos, "E714 test for object identity should be 'is not'"
+
+
+def comparison_type(logical_line):
+ r"""Object type comparisons should always use isinstance().
+
+ Do not compare types directly.
+
+ Okay: if isinstance(obj, int):
+ E721: if type(obj) is type(1):
+
+ When checking if an object is a string, keep in mind that it might be a
+ unicode string too! In Python 2.3, str and unicode have a common base
+ class, basestring, so you can do:
+
+ Okay: if isinstance(obj, basestring):
+ Okay: if type(a1) is type(b1):
+ """
+ match = COMPARE_TYPE_REGEX.search(logical_line)
+ if match:
+ inst = match.group(1)
+ if inst and isidentifier(inst) and inst not in SINGLETONS:
+ return # Allow comparison for types which are not obvious
+ yield match.start(), "E721 do not compare types, use 'isinstance()'"
+
+
+def python_3000_has_key(logical_line, noqa):
+ r"""The {}.has_key() method is removed in Python 3: use the 'in' operator.
+
+ Okay: if "alph" in d:\n print d["alph"]
+ W601: assert d.has_key('alph')
+ """
+ pos = logical_line.find('.has_key(')
+ if pos > -1 and not noqa:
+ yield pos, "W601 .has_key() is deprecated, use 'in'"
+
+
+def python_3000_raise_comma(logical_line):
+ r"""When raising an exception, use "raise ValueError('message')".
+
+ The older form is removed in Python 3.
+
+ Okay: raise DummyError("Message")
+ W602: raise DummyError, "Message"
+ """
+ match = RAISE_COMMA_REGEX.match(logical_line)
+ if match and not RERAISE_COMMA_REGEX.match(logical_line):
+ yield match.end() - 1, "W602 deprecated form of raising exception"
+
+
+def python_3000_not_equal(logical_line):
+ r"""New code should always use != instead of <>.
+
+ The older syntax is removed in Python 3.
+
+ Okay: if a != 'no':
+ W603: if a <> 'no':
+ """
+ pos = logical_line.find('<>')
+ if pos > -1:
+ yield pos, "W603 '<>' is deprecated, use '!='"
+
+
+def python_3000_backticks(logical_line):
+ r"""Backticks are removed in Python 3: use repr() instead.
+
+ Okay: val = repr(1 + 2)
+ W604: val = `1 + 2`
+ """
+ pos = logical_line.find('`')
+ if pos > -1:
+ yield pos, "W604 backticks are deprecated, use 'repr()'"
+
+
+##############################################################################
+# Helper functions
+##############################################################################
+
+
+if '' == ''.encode():
+ # Python 2: implicit encoding.
+ def readlines(filename):
+ """Read the source code."""
+ with open(filename, 'rU') as f:
+ return f.readlines()
+ isidentifier = re.compile(r'[a-zA-Z_]\w*').match
+ stdin_get_value = sys.stdin.read
+else:
+ # Python 3
+ def readlines(filename):
+ """Read the source code."""
+ try:
+ with open(filename, 'rb') as f:
+ (coding, lines) = tokenize.detect_encoding(f.readline)
+ f = TextIOWrapper(f, coding, line_buffering=True)
+ return [l.decode(coding) for l in lines] + f.readlines()
+ except (LookupError, SyntaxError, UnicodeError):
+ # Fall back if file encoding is improperly declared
+ with open(filename, encoding='latin-1') as f:
+ return f.readlines()
+ isidentifier = str.isidentifier
+
+ def stdin_get_value():
+ return TextIOWrapper(sys.stdin.buffer, errors='ignore').read()
+noqa = re.compile(r'# no(?:qa|pep8)\b', re.I).search
+
+
+def expand_indent(line):
+ r"""Return the amount of indentation.
+
+ Tabs are expanded to the next multiple of 8.
+
+ >>> expand_indent(' ')
+ 4
+ >>> expand_indent('\t')
+ 8
+ >>> expand_indent(' \t')
+ 8
+ >>> expand_indent(' \t')
+ 16
+ """
+ if '\t' not in line:
+ return len(line) - len(line.lstrip())
+ result = 0
+ for char in line:
+ if char == '\t':
+ result = result // 8 * 8 + 8
+ elif char == ' ':
+ result += 1
+ else:
+ break
+ return result
+
+
+def mute_string(text):
+ """Replace contents with 'xxx' to prevent syntax matching.
+
+ >>> mute_string('"abc"')
+ '"xxx"'
+ >>> mute_string("'''abc'''")
+ "'''xxx'''"
+ >>> mute_string("r'abc'")
+ "r'xxx'"
+ """
+ # String modifiers (e.g. u or r)
+ start = text.index(text[-1]) + 1
+ end = len(text) - 1
+ # Triple quotes
+ if text[-3:] in ('"""', "'''"):
+ start += 2
+ end -= 2
+ return text[:start] + 'x' * (end - start) + text[end:]
+
+
+def parse_udiff(diff, patterns=None, parent='.'):
+ """Return a dictionary of matching lines."""
+ # For each file of the diff, the entry key is the filename,
+ # and the value is a set of row numbers to consider.
+ rv = {}
+ path = nrows = None
+ for line in diff.splitlines():
+ if nrows:
+ if line[:1] != '-':
+ nrows -= 1
+ continue
+ if line[:3] == '@@ ':
+ hunk_match = HUNK_REGEX.match(line)
+ (row, nrows) = [int(g or '1') for g in hunk_match.groups()]
+ rv[path].update(range(row, row + nrows))
+ elif line[:3] == '+++':
+ path = line[4:].split('\t', 1)[0]
+ if path[:2] == 'b/':
+ path = path[2:]
+ rv[path] = set()
+ return dict([(os.path.join(parent, path), rows)
+ for (path, rows) in rv.items()
+ if rows and filename_match(path, patterns)])
+
+
+def normalize_paths(value, parent=os.curdir):
+ """Parse a comma-separated list of paths.
+
+ Return a list of absolute paths.
+ """
+ if not value or isinstance(value, list):
+ return value
+ paths = []
+ for path in value.split(','):
+ if '/' in path:
+ path = os.path.abspath(os.path.join(parent, path))
+ paths.append(path.rstrip('/'))
+ return paths
+
+
+def filename_match(filename, patterns, default=True):
+ """Check if patterns contains a pattern that matches filename.
+
+ If patterns is unspecified, this always returns True.
+ """
+ if not patterns:
+ return default
+ return any(fnmatch(filename, pattern) for pattern in patterns)
+
+
+if COMMENT_WITH_NL:
+ def _is_eol_token(token):
+ return (token[0] in NEWLINE or
+ (token[0] == tokenize.COMMENT and token[1] == token[4]))
+else:
+ def _is_eol_token(token):
+ return token[0] in NEWLINE
+
+
+##############################################################################
+# Framework to run all checks
+##############################################################################
+
+
+_checks = {'physical_line': {}, 'logical_line': {}, 'tree': {}}
+
+
+def register_check(check, codes=None):
+ """Register a new check object."""
+ def _add_check(check, kind, codes, args):
+ if check in _checks[kind]:
+ _checks[kind][check][0].extend(codes or [])
+ else:
+ _checks[kind][check] = (codes or [''], args)
+ if inspect.isfunction(check):
+ args = inspect.getargspec(check)[0]
+ if args and args[0] in ('physical_line', 'logical_line'):
+ if codes is None:
+ codes = ERRORCODE_REGEX.findall(check.__doc__ or '')
+ _add_check(check, args[0], codes, args)
+ elif inspect.isclass(check):
+ if inspect.getargspec(check.__init__)[0][:2] == ['self', 'tree']:
+ _add_check(check, 'tree', codes, None)
+
+
+def init_checks_registry():
+ """Register all globally visible functions.
+
+ The first argument name is either 'physical_line' or 'logical_line'.
+ """
+ mod = inspect.getmodule(register_check)
+ for (name, function) in inspect.getmembers(mod, inspect.isfunction):
+ register_check(function)
+init_checks_registry()
+
+
+class Checker(object):
+ """Load a Python source file, tokenize it, check coding style."""
+
+ def __init__(self, filename=None, lines=None,
+ options=None, report=None, **kwargs):
+ if options is None:
+ options = StyleGuide(kwargs).options
+ else:
+ assert not kwargs
+ self._io_error = None
+ self._physical_checks = options.physical_checks
+ self._logical_checks = options.logical_checks
+ self._ast_checks = options.ast_checks
+ self.max_line_length = options.max_line_length
+ self.multiline = False # in a multiline string?
+ self.hang_closing = options.hang_closing
+ self.verbose = options.verbose
+ self.filename = filename
+ if filename is None:
+ self.filename = 'stdin'
+ self.lines = lines or []
+ elif filename == '-':
+ self.filename = 'stdin'
+ self.lines = stdin_get_value().splitlines(True)
+ elif lines is None:
+ try:
+ self.lines = readlines(filename)
+ except IOError:
+ (exc_type, exc) = sys.exc_info()[:2]
+ self._io_error = '%s: %s' % (exc_type.__name__, exc)
+ self.lines = []
+ else:
+ self.lines = lines
+ if self.lines:
+ ord0 = ord(self.lines[0][0])
+ if ord0 in (0xef, 0xfeff): # Strip the UTF-8 BOM
+ if ord0 == 0xfeff:
+ self.lines[0] = self.lines[0][1:]
+ elif self.lines[0][:3] == '\xef\xbb\xbf':
+ self.lines[0] = self.lines[0][3:]
+ self.report = report or options.report
+ self.report_error = self.report.error
+
+ def report_invalid_syntax(self):
+ """Check if the syntax is valid."""
+ (exc_type, exc) = sys.exc_info()[:2]
+ if len(exc.args) > 1:
+ offset = exc.args[1]
+ if len(offset) > 2:
+ offset = offset[1:3]
+ else:
+ offset = (1, 0)
+ self.report_error(offset[0], offset[1] or 0,
+ 'E901 %s: %s' % (exc_type.__name__, exc.args[0]),
+ self.report_invalid_syntax)
+
+ def readline(self):
+ """Get the next line from the input buffer."""
+ if self.line_number >= self.total_lines:
+ return ''
+ line = self.lines[self.line_number]
+ self.line_number += 1
+ if self.indent_char is None and line[:1] in WHITESPACE:
+ self.indent_char = line[0]
+ return line
+
+ def run_check(self, check, argument_names):
+ """Run a check plugin."""
+ arguments = []
+ for name in argument_names:
+ arguments.append(getattr(self, name))
+ return check(*arguments)
+
+ def check_physical(self, line):
+ """Run all physical checks on a raw input line."""
+ self.physical_line = line
+ for name, check, argument_names in self._physical_checks:
+ result = self.run_check(check, argument_names)
+ if result is not None:
+ (offset, text) = result
+ self.report_error(self.line_number, offset, text, check)
+ if text[:4] == 'E101':
+ self.indent_char = line[0]
+
+ def build_tokens_line(self):
+ """Build a logical line from tokens."""
+ logical = []
+ comments = []
+ length = 0
+ prev_row = prev_col = mapping = None
+ for token_type, text, start, end, line in self.tokens:
+ if token_type in SKIP_TOKENS:
+ continue
+ if not mapping:
+ mapping = [(0, start)]
+ if token_type == tokenize.COMMENT:
+ comments.append(text)
+ continue
+ if token_type == tokenize.STRING:
+ text = mute_string(text)
+ if prev_row:
+ (start_row, start_col) = start
+ if prev_row != start_row: # different row
+ prev_text = self.lines[prev_row - 1][prev_col - 1]
+ if prev_text == ',' or (prev_text not in '{[('
+ and text not in '}])'):
+ text = ' ' + text
+ elif prev_col != start_col: # different column
+ text = line[prev_col:start_col] + text
+ logical.append(text)
+ length += len(text)
+ mapping.append((length, end))
+ (prev_row, prev_col) = end
+ self.logical_line = ''.join(logical)
+ self.noqa = comments and noqa(''.join(comments))
+ return mapping
+
+ def check_logical(self):
+ """Build a line from tokens and run all logical checks on it."""
+ self.report.increment_logical_line()
+ mapping = self.build_tokens_line()
+ (start_row, start_col) = mapping[0][1]
+ start_line = self.lines[start_row - 1]
+ self.indent_level = expand_indent(start_line[:start_col])
+ if self.blank_before < self.blank_lines:
+ self.blank_before = self.blank_lines
+ if self.verbose >= 2:
+ print(self.logical_line[:80].rstrip())
+ for name, check, argument_names in self._logical_checks:
+ if self.verbose >= 4:
+ print(' ' + name)
+ for offset, text in self.run_check(check, argument_names) or ():
+ if not isinstance(offset, tuple):
+ for token_offset, pos in mapping:
+ if offset <= token_offset:
+ break
+ offset = (pos[0], pos[1] + offset - token_offset)
+ self.report_error(offset[0], offset[1], text, check)
+ if self.logical_line:
+ self.previous_indent_level = self.indent_level
+ self.previous_logical = self.logical_line
+ self.blank_lines = 0
+ self.tokens = []
+
+ def check_ast(self):
+ """Build the file's AST and run all AST checks."""
+ try:
+ tree = compile(''.join(self.lines), '', 'exec', PyCF_ONLY_AST)
+ except (SyntaxError, TypeError):
+ return self.report_invalid_syntax()
+ for name, cls, __ in self._ast_checks:
+ checker = cls(tree, self.filename)
+ for lineno, offset, text, check in checker.run():
+ if not self.lines or not noqa(self.lines[lineno - 1]):
+ self.report_error(lineno, offset, text, check)
+
+ def generate_tokens(self):
+ """Tokenize the file, run physical line checks and yield tokens."""
+ if self._io_error:
+ self.report_error(1, 0, 'E902 %s' % self._io_error, readlines)
+ tokengen = tokenize.generate_tokens(self.readline)
+ try:
+ for token in tokengen:
+ if token[2][0] > self.total_lines:
+ return
+ self.maybe_check_physical(token)
+ yield token
+ except (SyntaxError, tokenize.TokenError):
+ self.report_invalid_syntax()
+
+ def maybe_check_physical(self, token):
+ """If appropriate (based on token), check current physical line(s)."""
+ # Called after every token, but act only on end of line.
+ if _is_eol_token(token):
+ # Obviously, a newline token ends a single physical line.
+ self.check_physical(token[4])
+ elif token[0] == tokenize.STRING and '\n' in token[1]:
+ # Less obviously, a string that contains newlines is a
+ # multiline string, either triple-quoted or with internal
+ # newlines backslash-escaped. Check every physical line in the
+ # string *except* for the last one: its newline is outside of
+ # the multiline string, so we consider it a regular physical
+ # line, and will check it like any other physical line.
+ #
+ # Subtleties:
+ # - we don't *completely* ignore the last line; if it contains
+ # the magical "# noqa" comment, we disable all physical
+ # checks for the entire multiline string
+ # - have to wind self.line_number back because initially it
+ # points to the last line of the string, and we want
+ # check_physical() to give accurate feedback
+ if noqa(token[4]):
+ return
+ self.multiline = True
+ self.line_number = token[2][0]
+ for line in token[1].split('\n')[:-1]:
+ self.check_physical(line + '\n')
+ self.line_number += 1
+ self.multiline = False
+
+ def check_all(self, expected=None, line_offset=0):
+ """Run all checks on the input file."""
+ self.report.init_file(self.filename, self.lines, expected, line_offset)
+ self.total_lines = len(self.lines)
+ if self._ast_checks:
+ self.check_ast()
+ self.line_number = 0
+ self.indent_char = None
+ self.indent_level = self.previous_indent_level = 0
+ self.previous_logical = ''
+ self.tokens = []
+ self.blank_lines = self.blank_before = 0
+ parens = 0
+ for token in self.generate_tokens():
+ self.tokens.append(token)
+ token_type, text = token[0:2]
+ if self.verbose >= 3:
+ if token[2][0] == token[3][0]:
+ pos = '[%s:%s]' % (token[2][1] or '', token[3][1])
+ else:
+ pos = 'l.%s' % token[3][0]
+ print('l.%s\t%s\t%s\t%r' %
+ (token[2][0], pos, tokenize.tok_name[token[0]], text))
+ if token_type == tokenize.OP:
+ if text in '([{':
+ parens += 1
+ elif text in '}])':
+ parens -= 1
+ elif not parens:
+ if token_type in NEWLINE:
+ if token_type == tokenize.NEWLINE:
+ self.check_logical()
+ self.blank_before = 0
+ elif len(self.tokens) == 1:
+ # The physical line contains only this token.
+ self.blank_lines += 1
+ del self.tokens[0]
+ else:
+ self.check_logical()
+ elif COMMENT_WITH_NL and token_type == tokenize.COMMENT:
+ if len(self.tokens) == 1:
+ # The comment also ends a physical line
+ token = list(token)
+ token[1] = text.rstrip('\r\n')
+ token[3] = (token[2][0], token[2][1] + len(token[1]))
+ self.tokens = [tuple(token)]
+ self.check_logical()
+ if self.tokens:
+ self.check_physical(self.lines[-1])
+ self.check_logical()
+ return self.report.get_file_results()
+
+
+class BaseReport(object):
+ """Collect the results of the checks."""
+
+ print_filename = False
+
+ def __init__(self, options):
+ self._benchmark_keys = options.benchmark_keys
+ self._ignore_code = options.ignore_code
+ # Results
+ self.elapsed = 0
+ self.total_errors = 0
+ self.counters = dict.fromkeys(self._benchmark_keys, 0)
+ self.messages = {}
+
+ def start(self):
+ """Start the timer."""
+ self._start_time = time.time()
+
+ def stop(self):
+ """Stop the timer."""
+ self.elapsed = time.time() - self._start_time
+
+ def init_file(self, filename, lines, expected, line_offset):
+ """Signal a new file."""
+ self.filename = filename
+ self.lines = lines
+ self.expected = expected or ()
+ self.line_offset = line_offset
+ self.file_errors = 0
+ self.counters['files'] += 1
+ self.counters['physical lines'] += len(lines)
+
+ def increment_logical_line(self):
+ """Signal a new logical line."""
+ self.counters['logical lines'] += 1
+
+ def error(self, line_number, offset, text, check):
+ """Report an error, according to options."""
+ code = text[:4]
+ if self._ignore_code(code):
+ return
+ if code in self.counters:
+ self.counters[code] += 1
+ else:
+ self.counters[code] = 1
+ self.messages[code] = text[5:]
+ # Don't care about expected errors or warnings
+ if code in self.expected:
+ return
+ if self.print_filename and not self.file_errors:
+ print(self.filename)
+ self.file_errors += 1
+ self.total_errors += 1
+ return code
+
+ def get_file_results(self):
+ """Return the count of errors and warnings for this file."""
+ return self.file_errors
+
+ def get_count(self, prefix=''):
+ """Return the total count of errors and warnings."""
+ return sum([self.counters[key]
+ for key in self.messages if key.startswith(prefix)])
+
+ def get_statistics(self, prefix=''):
+ """Get statistics for message codes that start with the prefix.
+
+ prefix='' matches all errors and warnings
+ prefix='E' matches all errors
+ prefix='W' matches all warnings
+ prefix='E4' matches all errors that have to do with imports
+ """
+ return ['%-7s %s %s' % (self.counters[key], key, self.messages[key])
+ for key in sorted(self.messages) if key.startswith(prefix)]
+
+ def print_statistics(self, prefix=''):
+ """Print overall statistics (number of errors and warnings)."""
+ for line in self.get_statistics(prefix):
+ print(line)
+
+ def print_benchmark(self):
+ """Print benchmark numbers."""
+ print('%-7.2f %s' % (self.elapsed, 'seconds elapsed'))
+ if self.elapsed:
+ for key in self._benchmark_keys:
+ print('%-7d %s per second (%d total)' %
+ (self.counters[key] / self.elapsed, key,
+ self.counters[key]))
+
+
+class FileReport(BaseReport):
+ """Collect the results of the checks and print only the filenames."""
+ print_filename = True
+
+
+class StandardReport(BaseReport):
+ """Collect and print the results of the checks."""
+
+ def __init__(self, options):
+ super(StandardReport, self).__init__(options)
+ self._fmt = REPORT_FORMAT.get(options.format.lower(),
+ options.format)
+ self._repeat = options.repeat
+ self._show_source = options.show_source
+ self._show_pep8 = options.show_pep8
+
+ def init_file(self, filename, lines, expected, line_offset):
+ """Signal a new file."""
+ self._deferred_print = []
+ return super(StandardReport, self).init_file(
+ filename, lines, expected, line_offset)
+
+ def error(self, line_number, offset, text, check):
+ """Report an error, according to options."""
+ code = super(StandardReport, self).error(line_number, offset,
+ text, check)
+ if code and (self.counters[code] == 1 or self._repeat):
+ self._deferred_print.append(
+ (line_number, offset, code, text[5:], check.__doc__))
+ return code
+
+ def get_file_results(self):
+ """Print the result and return the overall count for this file."""
+ self._deferred_print.sort()
+ for line_number, offset, code, text, doc in self._deferred_print:
+ print(self._fmt % {
+ 'path': self.filename,
+ 'row': self.line_offset + line_number, 'col': offset + 1,
+ 'code': code, 'text': text,
+ })
+ if self._show_source:
+ if line_number > len(self.lines):
+ line = ''
+ else:
+ line = self.lines[line_number - 1]
+ print(line.rstrip())
+ print(re.sub(r'\S', ' ', line[:offset]) + '^')
+ if self._show_pep8 and doc:
+ print(' ' + doc.strip())
+ return self.file_errors
+
+
+class DiffReport(StandardReport):
+ """Collect and print the results for the changed lines only."""
+
+ def __init__(self, options):
+ super(DiffReport, self).__init__(options)
+ self._selected = options.selected_lines
+
+ def error(self, line_number, offset, text, check):
+ if line_number not in self._selected[self.filename]:
+ return
+ return super(DiffReport, self).error(line_number, offset, text, check)
+
+
+class StyleGuide(object):
+ """Initialize a PEP-8 instance with few options."""
+
+ def __init__(self, *args, **kwargs):
+ # build options from the command line
+ self.checker_class = kwargs.pop('checker_class', Checker)
+ parse_argv = kwargs.pop('parse_argv', False)
+ config_file = kwargs.pop('config_file', None)
+ parser = kwargs.pop('parser', None)
+ # build options from dict
+ options_dict = dict(*args, **kwargs)
+ arglist = None if parse_argv else options_dict.get('paths', None)
+ options, self.paths = process_options(
+ arglist, parse_argv, config_file, parser)
+ if options_dict:
+ options.__dict__.update(options_dict)
+ if 'paths' in options_dict:
+ self.paths = options_dict['paths']
+
+ self.runner = self.input_file
+ self.options = options
+
+ if not options.reporter:
+ options.reporter = BaseReport if options.quiet else StandardReport
+
+ options.select = tuple(options.select or ())
+ if not (options.select or options.ignore or
+ options.testsuite or options.doctest) and DEFAULT_IGNORE:
+ # The default choice: ignore controversial checks
+ options.ignore = tuple(DEFAULT_IGNORE.split(','))
+ else:
+ # Ignore all checks which are not explicitly selected
+ options.ignore = ('',) if options.select else tuple(options.ignore)
+ options.benchmark_keys = BENCHMARK_KEYS[:]
+ options.ignore_code = self.ignore_code
+ options.physical_checks = self.get_checks('physical_line')
+ options.logical_checks = self.get_checks('logical_line')
+ options.ast_checks = self.get_checks('tree')
+ self.init_report()
+
+ def init_report(self, reporter=None):
+ """Initialize the report instance."""
+ self.options.report = (reporter or self.options.reporter)(self.options)
+ return self.options.report
+
+ def check_files(self, paths=None):
+ """Run all checks on the paths."""
+ if paths is None:
+ paths = self.paths
+ report = self.options.report
+ runner = self.runner
+ report.start()
+ try:
+ for path in paths:
+ if os.path.isdir(path):
+ self.input_dir(path)
+ elif not self.excluded(path):
+ runner(path)
+ except KeyboardInterrupt:
+ print('... stopped')
+ report.stop()
+ return report
+
+ def input_file(self, filename, lines=None, expected=None, line_offset=0):
+ """Run all checks on a Python source file."""
+ if self.options.verbose:
+ print('checking %s' % filename)
+ fchecker = self.checker_class(
+ filename, lines=lines, options=self.options)
+ return fchecker.check_all(expected=expected, line_offset=line_offset)
+
+ def input_dir(self, dirname):
+ """Check all files in this directory and all subdirectories."""
+ dirname = dirname.rstrip('/')
+ if self.excluded(dirname):
+ return 0
+ counters = self.options.report.counters
+ verbose = self.options.verbose
+ filepatterns = self.options.filename
+ runner = self.runner
+ for root, dirs, files in os.walk(dirname):
+ if verbose:
+ print('directory ' + root)
+ counters['directories'] += 1
+ for subdir in sorted(dirs):
+ if self.excluded(subdir, root):
+ dirs.remove(subdir)
+ for filename in sorted(files):
+ # contain a pattern that matches?
+ if ((filename_match(filename, filepatterns) and
+ not self.excluded(filename, root))):
+ runner(os.path.join(root, filename))
+
+ def excluded(self, filename, parent=None):
+ """Check if the file should be excluded.
+
+ Check if 'options.exclude' contains a pattern that matches filename.
+ """
+ if not self.options.exclude:
+ return False
+ basename = os.path.basename(filename)
+ if filename_match(basename, self.options.exclude):
+ return True
+ if parent:
+ filename = os.path.join(parent, filename)
+ filename = os.path.abspath(filename)
+ return filename_match(filename, self.options.exclude)
+
+ def ignore_code(self, code):
+ """Check if the error code should be ignored.
+
+ If 'options.select' contains a prefix of the error code,
+ return False. Else, if 'options.ignore' contains a prefix of
+ the error code, return True.
+ """
+ if len(code) < 4 and any(s.startswith(code)
+ for s in self.options.select):
+ return False
+ return (code.startswith(self.options.ignore) and
+ not code.startswith(self.options.select))
+
+ def get_checks(self, argument_name):
+ """Get all the checks for this category.
+
+ Find all globally visible functions where the first argument name
+ starts with argument_name and which contain selected tests.
+ """
+ checks = []
+ for check, attrs in _checks[argument_name].items():
+ (codes, args) = attrs
+ if any(not (code and self.ignore_code(code)) for code in codes):
+ checks.append((check.__name__, check, args))
+ return sorted(checks)
+
+
+def get_parser(prog='pep8', version=__version__):
+ parser = OptionParser(prog=prog, version=version,
+ usage="%prog [options] input ...")
+ parser.config_options = [
+ 'exclude', 'filename', 'select', 'ignore', 'max-line-length',
+ 'hang-closing', 'count', 'format', 'quiet', 'show-pep8',
+ 'show-source', 'statistics', 'verbose']
+ parser.add_option('-v', '--verbose', default=0, action='count',
+ help="print status messages, or debug with -vv")
+ parser.add_option('-q', '--quiet', default=0, action='count',
+ help="report only file names, or nothing with -qq")
+ parser.add_option('-r', '--repeat', default=True, action='store_true',
+ help="(obsolete) show all occurrences of the same error")
+ parser.add_option('--first', action='store_false', dest='repeat',
+ help="show first occurrence of each error")
+ parser.add_option('--exclude', metavar='patterns', default=DEFAULT_EXCLUDE,
+ help="exclude files or directories which match these "
+ "comma separated patterns (default: %default)")
+ parser.add_option('--filename', metavar='patterns', default='*.py',
+ help="when parsing directories, only check filenames "
+ "matching these comma separated patterns "
+ "(default: %default)")
+ parser.add_option('--select', metavar='errors', default='',
+ help="select errors and warnings (e.g. E,W6)")
+ parser.add_option('--ignore', metavar='errors', default='',
+ help="skip errors and warnings (e.g. E4,W)")
+ parser.add_option('--show-source', action='store_true',
+ help="show source code for each error")
+ parser.add_option('--show-pep8', action='store_true',
+ help="show text of PEP 8 for each error "
+ "(implies --first)")
+ parser.add_option('--statistics', action='store_true',
+ help="count errors and warnings")
+ parser.add_option('--count', action='store_true',
+ help="print total number of errors and warnings "
+ "to standard error and set exit code to 1 if "
+ "total is not null")
+ parser.add_option('--max-line-length', type='int', metavar='n',
+ default=MAX_LINE_LENGTH,
+ help="set maximum allowed line length "
+ "(default: %default)")
+ parser.add_option('--hang-closing', action='store_true',
+ help="hang closing bracket instead of matching "
+ "indentation of opening bracket's line")
+ parser.add_option('--format', metavar='format', default='default',
+ help="set the error format [default|pylint|<custom>]")
+ parser.add_option('--diff', action='store_true',
+ help="report only lines changed according to the "
+ "unified diff received on STDIN")
+ group = parser.add_option_group("Testing Options")
+ if os.path.exists(TESTSUITE_PATH):
+ group.add_option('--testsuite', metavar='dir',
+ help="run regression tests from dir")
+ group.add_option('--doctest', action='store_true',
+ help="run doctest on myself")
+ group.add_option('--benchmark', action='store_true',
+ help="measure processing speed")
+ return parser
+
+
+def read_config(options, args, arglist, parser):
+ """Read both user configuration and local configuration."""
+ config = RawConfigParser()
+
+ user_conf = options.config
+ if user_conf and os.path.isfile(user_conf):
+ if options.verbose:
+ print('user configuration: %s' % user_conf)
+ config.read(user_conf)
+
+ local_dir = os.curdir
+ parent = tail = args and os.path.abspath(os.path.commonprefix(args))
+ while tail:
+ if config.read([os.path.join(parent, fn) for fn in PROJECT_CONFIG]):
+ local_dir = parent
+ if options.verbose:
+ print('local configuration: in %s' % parent)
+ break
+ (parent, tail) = os.path.split(parent)
+
+ pep8_section = parser.prog
+ if config.has_section(pep8_section):
+ option_list = dict([(o.dest, o.type or o.action)
+ for o in parser.option_list])
+
+ # First, read the default values
+ (new_options, __) = parser.parse_args([])
+
+ # Second, parse the configuration
+ for opt in config.options(pep8_section):
+ if opt.replace('_', '-') not in parser.config_options:
+ print(" unknown option '%s' ignored" % opt)
+ continue
+ if options.verbose > 1:
+ print(" %s = %s" % (opt, config.get(pep8_section, opt)))
+ normalized_opt = opt.replace('-', '_')
+ opt_type = option_list[normalized_opt]
+ if opt_type in ('int', 'count'):
+ value = config.getint(pep8_section, opt)
+ elif opt_type == 'string':
+ value = config.get(pep8_section, opt)
+ if normalized_opt == 'exclude':
+ value = normalize_paths(value, local_dir)
+ else:
+ assert opt_type in ('store_true', 'store_false')
+ value = config.getboolean(pep8_section, opt)
+ setattr(new_options, normalized_opt, value)
+
+ # Third, overwrite with the command-line options
+ (options, __) = parser.parse_args(arglist, values=new_options)
+ options.doctest = options.testsuite = False
+ return options
+
+
+def process_options(arglist=None, parse_argv=False, config_file=None,
+ parser=None):
+ """Process options passed either via arglist or via command line args."""
+ if not parser:
+ parser = get_parser()
+ if not parser.has_option('--config'):
+ if config_file is True:
+ config_file = DEFAULT_CONFIG
+ group = parser.add_option_group("Configuration", description=(
+ "The project options are read from the [%s] section of the "
+ "tox.ini file or the setup.cfg file located in any parent folder "
+ "of the path(s) being processed. Allowed options are: %s." %
+ (parser.prog, ', '.join(parser.config_options))))
+ group.add_option('--config', metavar='path', default=config_file,
+ help="user config file location (default: %default)")
+ # Don't read the command line if the module is used as a library.
+ if not arglist and not parse_argv:
+ arglist = []
+ # If parse_argv is True and arglist is None, arguments are
+ # parsed from the command line (sys.argv)
+ (options, args) = parser.parse_args(arglist)
+ options.reporter = None
+
+ if options.ensure_value('testsuite', False):
+ args.append(options.testsuite)
+ elif not options.ensure_value('doctest', False):
+ if parse_argv and not args:
+ if options.diff or any(os.path.exists(name)
+ for name in PROJECT_CONFIG):
+ args = ['.']
+ else:
+ parser.error('input not specified')
+ options = read_config(options, args, arglist, parser)
+ options.reporter = parse_argv and options.quiet == 1 and FileReport
+
+ options.filename = options.filename and options.filename.split(',')
+ options.exclude = normalize_paths(options.exclude)
+ options.select = options.select and options.select.split(',')
+ options.ignore = options.ignore and options.ignore.split(',')
+
+ if options.diff:
+ options.reporter = DiffReport
+ stdin = stdin_get_value()
+ options.selected_lines = parse_udiff(stdin, options.filename, args[0])
+ args = sorted(options.selected_lines)
+
+ return options, args
+
+
+def _main():
+ """Parse options and run checks on Python source."""
+ import signal
+
+ # Handle "Broken pipe" gracefully
+ try:
+ signal.signal(signal.SIGPIPE, lambda signum, frame: sys.exit(1))
+ except AttributeError:
+ pass # not supported on Windows
+
+ pep8style = StyleGuide(parse_argv=True, config_file=True)
+ options = pep8style.options
+ if options.doctest or options.testsuite:
+ from testsuite.support import run_tests
+ report = run_tests(pep8style)
+ else:
+ report = pep8style.check_files()
+ if options.statistics:
+ report.print_statistics()
+ if options.benchmark:
+ report.print_benchmark()
+ if options.testsuite and not options.quiet:
+ report.print_results()
+ if report.total_errors:
+ if options.count:
+ sys.stderr.write(str(report.total_errors) + '\n')
+ sys.exit(1)
+
+if __name__ == '__main__':
+ _main() \ No newline at end of file
diff --git a/python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/__init__.py b/python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/__init__.py
new file mode 100644
index 000000000000..3b927b4db451
--- /dev/null
+++ b/python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/__init__.py
@@ -0,0 +1,518 @@
+#@PydevCodeAnalysisIgnore
+"""create and manipulate C data types in Python"""
+
+import os as _os, sys as _sys
+from itertools import chain as _chain
+
+# special developer support to use ctypes from the CVS sandbox,
+# without installing it
+# XXX Remove this for the python core version
+_magicfile = _os.path.join(_os.path.dirname(__file__), ".CTYPES_DEVEL")
+if _os.path.isfile(_magicfile):
+ execfile(_magicfile)
+del _magicfile
+
+__version__ = "0.9.9.6"
+
+from _ctypes import Union, Structure, Array
+from _ctypes import _Pointer
+from _ctypes import CFuncPtr as _CFuncPtr
+from _ctypes import __version__ as _ctypes_version
+from _ctypes import RTLD_LOCAL, RTLD_GLOBAL
+from _ctypes import ArgumentError
+
+from struct import calcsize as _calcsize
+
+if __version__ != _ctypes_version:
+ raise Exception, ("Version number mismatch", __version__, _ctypes_version)
+
+if _os.name in ("nt", "ce"):
+ from _ctypes import FormatError
+
+from _ctypes import FUNCFLAG_CDECL as _FUNCFLAG_CDECL, \
+ FUNCFLAG_PYTHONAPI as _FUNCFLAG_PYTHONAPI
+
+"""
+WINOLEAPI -> HRESULT
+WINOLEAPI_(type)
+
+STDMETHODCALLTYPE
+
+STDMETHOD(name)
+STDMETHOD_(type, name)
+
+STDAPICALLTYPE
+"""
+
+def create_string_buffer(init, size=None):
+ """create_string_buffer(aString) -> character array
+ create_string_buffer(anInteger) -> character array
+ create_string_buffer(aString, anInteger) -> character array
+ """
+ if isinstance(init, (str, unicode)):
+ if size is None:
+ size = len(init) + 1
+ buftype = c_char * size
+ buf = buftype()
+ buf.value = init
+ return buf
+ elif isinstance(init, (int, long)):
+ buftype = c_char * init
+ buf = buftype()
+ return buf
+ raise TypeError, init
+
+def c_buffer(init, size=None):
+## "deprecated, use create_string_buffer instead"
+## import warnings
+## warnings.warn("c_buffer is deprecated, use create_string_buffer instead",
+## DeprecationWarning, stacklevel=2)
+ return create_string_buffer(init, size)
+
+_c_functype_cache = {}
+def CFUNCTYPE(restype, *argtypes):
+ """CFUNCTYPE(restype, *argtypes) -> function prototype.
+
+ restype: the result type
+ argtypes: a sequence specifying the argument types
+
+ The function prototype can be called in three ways to create a
+ callable object:
+
+ prototype(integer address) -> foreign function
+ prototype(callable) -> create and return a C callable function from callable
+ prototype(integer index, method name[, paramflags]) -> foreign function calling a COM method
+ prototype((ordinal number, dll object)[, paramflags]) -> foreign function exported by ordinal
+ prototype((function name, dll object)[, paramflags]) -> foreign function exported by name
+ """
+ try:
+ return _c_functype_cache[(restype, argtypes)]
+ except KeyError:
+ class CFunctionType(_CFuncPtr):
+ _argtypes_ = argtypes
+ _restype_ = restype
+ _flags_ = _FUNCFLAG_CDECL
+ _c_functype_cache[(restype, argtypes)] = CFunctionType
+ return CFunctionType
+
+if _os.name in ("nt", "ce"):
+ from _ctypes import LoadLibrary as _dlopen
+ from _ctypes import FUNCFLAG_STDCALL as _FUNCFLAG_STDCALL
+ if _os.name == "ce":
+ # 'ce' doesn't have the stdcall calling convention
+ _FUNCFLAG_STDCALL = _FUNCFLAG_CDECL
+
+ _win_functype_cache = {}
+ def WINFUNCTYPE(restype, *argtypes):
+ # docstring set later (very similar to CFUNCTYPE.__doc__)
+ try:
+ return _win_functype_cache[(restype, argtypes)]
+ except KeyError:
+ class WinFunctionType(_CFuncPtr):
+ _argtypes_ = argtypes
+ _restype_ = restype
+ _flags_ = _FUNCFLAG_STDCALL
+ _win_functype_cache[(restype, argtypes)] = WinFunctionType
+ return WinFunctionType
+ if WINFUNCTYPE.__doc__:
+ WINFUNCTYPE.__doc__ = CFUNCTYPE.__doc__.replace("CFUNCTYPE", "WINFUNCTYPE")
+
+elif _os.name == "posix":
+ from _ctypes import dlopen as _dlopen #@UnresolvedImport
+
+from _ctypes import sizeof, byref, addressof, alignment
+from _ctypes import _SimpleCData
+
+class py_object(_SimpleCData):
+ _type_ = "O"
+
+class c_short(_SimpleCData):
+ _type_ = "h"
+
+class c_ushort(_SimpleCData):
+ _type_ = "H"
+
+class c_long(_SimpleCData):
+ _type_ = "l"
+
+class c_ulong(_SimpleCData):
+ _type_ = "L"
+
+if _calcsize("i") == _calcsize("l"):
+ # if int and long have the same size, make c_int an alias for c_long
+ c_int = c_long
+ c_uint = c_ulong
+else:
+ class c_int(_SimpleCData):
+ _type_ = "i"
+
+ class c_uint(_SimpleCData):
+ _type_ = "I"
+
+class c_float(_SimpleCData):
+ _type_ = "f"
+
+class c_double(_SimpleCData):
+ _type_ = "d"
+
+if _calcsize("l") == _calcsize("q"):
+ # if long and long long have the same size, make c_longlong an alias for c_long
+ c_longlong = c_long
+ c_ulonglong = c_ulong
+else:
+ class c_longlong(_SimpleCData):
+ _type_ = "q"
+
+ class c_ulonglong(_SimpleCData):
+ _type_ = "Q"
+ ## def from_param(cls, val):
+ ## return ('d', float(val), val)
+ ## from_param = classmethod(from_param)
+
+class c_ubyte(_SimpleCData):
+ _type_ = "B"
+c_ubyte.__ctype_le__ = c_ubyte.__ctype_be__ = c_ubyte
+# backward compatibility:
+##c_uchar = c_ubyte
+
+class c_byte(_SimpleCData):
+ _type_ = "b"
+c_byte.__ctype_le__ = c_byte.__ctype_be__ = c_byte
+
+class c_char(_SimpleCData):
+ _type_ = "c"
+c_char.__ctype_le__ = c_char.__ctype_be__ = c_char
+
+class c_char_p(_SimpleCData):
+ _type_ = "z"
+
+class c_void_p(_SimpleCData):
+ _type_ = "P"
+c_voidp = c_void_p # backwards compatibility (to a bug)
+
+# This cache maps types to pointers to them.
+_pointer_type_cache = {}
+
+def POINTER(cls):
+ try:
+ return _pointer_type_cache[cls]
+ except KeyError:
+ pass
+ if type(cls) is str:
+ klass = type(_Pointer)("LP_%s" % cls,
+ (_Pointer,),
+ {})
+ _pointer_type_cache[id(klass)] = klass
+ return klass
+ else:
+ name = "LP_%s" % cls.__name__
+ klass = type(_Pointer)(name,
+ (_Pointer,),
+ {'_type_': cls})
+ _pointer_type_cache[cls] = klass
+ return klass
+
+try:
+ from _ctypes import set_conversion_mode
+except ImportError:
+ pass
+else:
+ if _os.name in ("nt", "ce"):
+ set_conversion_mode("mbcs", "ignore")
+ else:
+ set_conversion_mode("ascii", "strict")
+
+ class c_wchar_p(_SimpleCData):
+ _type_ = "Z"
+
+ class c_wchar(_SimpleCData):
+ _type_ = "u"
+
+ POINTER(c_wchar).from_param = c_wchar_p.from_param #_SimpleCData.c_wchar_p_from_param
+
+ def create_unicode_buffer(init, size=None):
+ """create_unicode_buffer(aString) -> character array
+ create_unicode_buffer(anInteger) -> character array
+ create_unicode_buffer(aString, anInteger) -> character array
+ """
+ if isinstance(init, (str, unicode)):
+ if size is None:
+ size = len(init) + 1
+ buftype = c_wchar * size
+ buf = buftype()
+ buf.value = init
+ return buf
+ elif isinstance(init, (int, long)):
+ buftype = c_wchar * init
+ buf = buftype()
+ return buf
+ raise TypeError, init
+
+POINTER(c_char).from_param = c_char_p.from_param #_SimpleCData.c_char_p_from_param
+
+# XXX Deprecated
+def SetPointerType(pointer, cls):
+ if _pointer_type_cache.get(cls, None) is not None:
+ raise RuntimeError, \
+ "This type already exists in the cache"
+ if not _pointer_type_cache.has_key(id(pointer)):
+ raise RuntimeError, \
+ "What's this???"
+ pointer.set_type(cls)
+ _pointer_type_cache[cls] = pointer
+ del _pointer_type_cache[id(pointer)]
+
+
+def pointer(inst):
+ return POINTER(type(inst))(inst)
+
+# XXX Deprecated
+def ARRAY(typ, len):
+ return typ * len
+
+################################################################
+
+
+class CDLL(object):
+ """An instance of this class represents a loaded dll/shared
+ library, exporting functions using the standard C calling
+ convention (named 'cdecl' on Windows).
+
+ The exported functions can be accessed as attributes, or by
+ indexing with the function name. Examples:
+
+ <obj>.qsort -> callable object
+ <obj>['qsort'] -> callable object
+
+ Calling the functions releases the Python GIL during the call and
+ reaquires it afterwards.
+ """
+ class _FuncPtr(_CFuncPtr):
+ _flags_ = _FUNCFLAG_CDECL
+ _restype_ = c_int # default, can be overridden in instances
+
+ def __init__(self, name, mode=RTLD_LOCAL, handle=None):
+ self._name = name
+ if handle is None:
+ self._handle = _dlopen(self._name, mode)
+ else:
+ self._handle = handle
+
+ def __repr__(self):
+ return "<%s '%s', handle %x at %x>" % \
+ (self.__class__.__name__, self._name,
+ (self._handle & (_sys.maxint * 2 + 1)),
+ id(self))
+
+ def __getattr__(self, name):
+ if name.startswith('__') and name.endswith('__'):
+ raise AttributeError, name
+ return self.__getitem__(name)
+
+ def __getitem__(self, name_or_ordinal):
+ func = self._FuncPtr((name_or_ordinal, self))
+ if not isinstance(name_or_ordinal, (int, long)):
+ func.__name__ = name_or_ordinal
+ setattr(self, name_or_ordinal, func)
+ return func
+
+class PyDLL(CDLL):
+ """This class represents the Python library itself. It allows to
+ access Python API functions. The GIL is not released, and
+ Python exceptions are handled correctly.
+ """
+ class _FuncPtr(_CFuncPtr):
+ _flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
+ _restype_ = c_int # default, can be overridden in instances
+
+if _os.name in ("nt", "ce"):
+
+ class WinDLL(CDLL):
+ """This class represents a dll exporting functions using the
+ Windows stdcall calling convention.
+ """
+ class _FuncPtr(_CFuncPtr):
+ _flags_ = _FUNCFLAG_STDCALL
+ _restype_ = c_int # default, can be overridden in instances
+
+ # XXX Hm, what about HRESULT as normal parameter?
+ # Mustn't it derive from c_long then?
+ from _ctypes import _check_HRESULT, _SimpleCData
+ class HRESULT(_SimpleCData):
+ _type_ = "l"
+ # _check_retval_ is called with the function's result when it
+ # is used as restype. It checks for the FAILED bit, and
+ # raises a WindowsError if it is set.
+ #
+ # The _check_retval_ method is implemented in C, so that the
+ # method definition itself is not included in the traceback
+ # when it raises an error - that is what we want (and Python
+ # doesn't have a way to raise an exception in the caller's
+ # frame).
+ _check_retval_ = _check_HRESULT
+
+ class OleDLL(CDLL):
+ """This class represents a dll exporting functions using the
+ Windows stdcall calling convention, and returning HRESULT.
+ HRESULT error values are automatically raised as WindowsError
+ exceptions.
+ """
+ class _FuncPtr(_CFuncPtr):
+ _flags_ = _FUNCFLAG_STDCALL
+ _restype_ = HRESULT
+
+class LibraryLoader(object):
+ def __init__(self, dlltype):
+ self._dlltype = dlltype
+
+ def __getattr__(self, name):
+ if name[0] == '_':
+ raise AttributeError(name)
+ dll = self._dlltype(name)
+ setattr(self, name, dll)
+ return dll
+
+ def __getitem__(self, name):
+ return getattr(self, name)
+
+ def LoadLibrary(self, name):
+ return self._dlltype(name)
+
+cdll = LibraryLoader(CDLL)
+pydll = LibraryLoader(PyDLL)
+
+if _os.name in ("nt", "ce"):
+ pythonapi = PyDLL("python dll", None, _sys.dllhandle)
+elif _sys.platform == "cygwin":
+ pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2])
+else:
+ pythonapi = PyDLL(None)
+
+
+if _os.name in ("nt", "ce"):
+ windll = LibraryLoader(WinDLL)
+ oledll = LibraryLoader(OleDLL)
+
+ if _os.name == "nt":
+ GetLastError = windll.kernel32.GetLastError
+ else:
+ GetLastError = windll.coredll.GetLastError
+
+ def WinError(code=None, descr=None):
+ if code is None:
+ code = GetLastError()
+ if descr is None:
+ descr = FormatError(code).strip()
+ return WindowsError(code, descr)
+
+_pointer_type_cache[None] = c_void_p
+
+if sizeof(c_uint) == sizeof(c_void_p):
+ c_size_t = c_uint
+elif sizeof(c_ulong) == sizeof(c_void_p):
+ c_size_t = c_ulong
+
+# functions
+
+from _ctypes import _memmove_addr, _memset_addr, _string_at_addr, _cast_addr
+
+## void *memmove(void *, const void *, size_t);
+memmove = CFUNCTYPE(c_void_p, c_void_p, c_void_p, c_size_t)(_memmove_addr)
+
+## void *memset(void *, int, size_t)
+memset = CFUNCTYPE(c_void_p, c_void_p, c_int, c_size_t)(_memset_addr)
+
+def PYFUNCTYPE(restype, *argtypes):
+ class CFunctionType(_CFuncPtr):
+ _argtypes_ = argtypes
+ _restype_ = restype
+ _flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
+ return CFunctionType
+_cast = PYFUNCTYPE(py_object, c_void_p, py_object)(_cast_addr)
+
+def cast(obj, typ):
+ result = _cast(obj, typ)
+ result.__keepref = obj
+ return result
+
+_string_at = CFUNCTYPE(py_object, c_void_p, c_int)(_string_at_addr)
+def string_at(ptr, size=0):
+ """string_at(addr[, size]) -> string
+
+ Return the string at addr."""
+ return _string_at(ptr, size)
+
+try:
+ from _ctypes import _wstring_at_addr
+except ImportError:
+ pass
+else:
+ _wstring_at = CFUNCTYPE(py_object, c_void_p, c_int)(_wstring_at_addr)
+ def wstring_at(ptr, size=0):
+ """wstring_at(addr[, size]) -> string
+
+ Return the string at addr."""
+ return _wstring_at(ptr, size)
+
+
+if _os.name == "nt": # COM stuff
+ def DllGetClassObject(rclsid, riid, ppv):
+ # First ask ctypes.com.server than comtypes.server for the
+ # class object.
+
+ # trick py2exe by doing dynamic imports
+ result = -2147221231 # CLASS_E_CLASSNOTAVAILABLE
+ try:
+ ctcom = __import__("ctypes.com.server", globals(), locals(), ['*'])
+ except ImportError:
+ pass
+ else:
+ result = ctcom.DllGetClassObject(rclsid, riid, ppv)
+
+ if result == -2147221231: # CLASS_E_CLASSNOTAVAILABLE
+ try:
+ ccom = __import__("comtypes.server", globals(), locals(), ['*'])
+ except ImportError:
+ pass
+ else:
+ result = ccom.DllGetClassObject(rclsid, riid, ppv)
+
+ return result
+
+ def DllCanUnloadNow():
+ # First ask ctypes.com.server than comtypes.server if we can unload or not.
+ # trick py2exe by doing dynamic imports
+ result = 0 # S_OK
+ try:
+ ctcom = __import__("ctypes.com.server", globals(), locals(), ['*'])
+ except ImportError:
+ pass
+ else:
+ result = ctcom.DllCanUnloadNow()
+ if result != 0: # != S_OK
+ return result
+
+ try:
+ ccom = __import__("comtypes.server", globals(), locals(), ['*'])
+ except ImportError:
+ return result
+ try:
+ return ccom.DllCanUnloadNow()
+ except AttributeError:
+ pass
+ return result
+
+from ctypes._endian import BigEndianStructure, LittleEndianStructure
+
+# Fill in specifically-sized types
+c_int8 = c_byte
+c_uint8 = c_ubyte
+for kind in [c_short, c_int, c_long, c_longlong]:
+ if sizeof(kind) == 2: c_int16 = kind
+ elif sizeof(kind) == 4: c_int32 = kind
+ elif sizeof(kind) == 8: c_int64 = kind
+for kind in [c_ushort, c_uint, c_ulong, c_ulonglong]:
+ if sizeof(kind) == 2: c_uint16 = kind
+ elif sizeof(kind) == 4: c_uint32 = kind
+ elif sizeof(kind) == 8: c_uint64 = kind
+del(kind)
diff --git a/python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/_ctypes.dll b/python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/_ctypes.dll
new file mode 100644
index 000000000000..238e869a5a04
--- /dev/null
+++ b/python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/_ctypes.dll
Binary files differ
diff --git a/python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/_endian.py b/python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/_endian.py
new file mode 100644
index 000000000000..7de037600717
--- /dev/null
+++ b/python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/_endian.py
@@ -0,0 +1,58 @@
+#@PydevCodeAnalysisIgnore
+import sys
+from ctypes import *
+
+_array_type = type(c_int * 3)
+
+def _other_endian(typ):
+ """Return the type with the 'other' byte order. Simple types like
+ c_int and so on already have __ctype_be__ and __ctype_le__
+ attributes which contain the types, for more complicated types
+ only arrays are supported.
+ """
+ try:
+ return getattr(typ, _OTHER_ENDIAN)
+ except AttributeError:
+ if type(typ) == _array_type:
+ return _other_endian(typ._type_) * typ._length_
+ raise TypeError("This type does not support other endian: %s" % typ)
+
+class _swapped_meta(type(Structure)):
+ def __setattr__(self, attrname, value):
+ if attrname == "_fields_":
+ fields = []
+ for desc in value:
+ name = desc[0]
+ typ = desc[1]
+ rest = desc[2:]
+ fields.append((name, _other_endian(typ)) + rest)
+ value = fields
+ super(_swapped_meta, self).__setattr__(attrname, value)
+
+################################################################
+
+# Note: The Structure metaclass checks for the *presence* (not the
+# value!) of a _swapped_bytes_ attribute to determine the bit order in
+# structures containing bit fields.
+
+if sys.byteorder == "little":
+ _OTHER_ENDIAN = "__ctype_be__"
+
+ LittleEndianStructure = Structure
+
+ class BigEndianStructure(Structure):
+ """Structure with big endian byte order"""
+ __metaclass__ = _swapped_meta
+ _swappedbytes_ = None
+
+elif sys.byteorder == "big":
+ _OTHER_ENDIAN = "__ctype_le__"
+
+ BigEndianStructure = Structure
+ class LittleEndianStructure(Structure):
+ """Structure with little endian byte order"""
+ __metaclass__ = _swapped_meta
+ _swappedbytes_ = None
+
+else:
+ raise RuntimeError("Invalid byteorder")
diff --git a/python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/ctypes-README.txt b/python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/ctypes-README.txt
new file mode 100644
index 000000000000..bf8de1e8767e
--- /dev/null
+++ b/python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/ctypes-README.txt
@@ -0,0 +1,134 @@
+(Note: this is a compiled distribution of ctypes, compiled for cygwin
+ to allow using the cygwin conversions directly from interpreterInfo. The tests
+ have been removed to reduce the added size. It is only used by PyDev on cygwin).
+
+Overview
+
+ ctypes is a ffi (Foreign Function Interface) package for Python.
+
+ It allows to call functions exposed from dlls/shared libraries and
+ has extensive facilities to create, access and manipulate simpole
+ and complicated C data types transparently from Python - in other
+ words: wrap libraries in pure Python.
+
+ ctypes runs on Windows, MacOS X, Linux, Solaris, FreeBSD. It may
+ also run on other systems, provided that libffi supports this
+ platform.
+
+ On Windows, ctypes contains (the beginning of) a COM framework
+ mainly targetted to use and implement custom COM interfaces.
+
+
+News
+
+ ctypes now uses the same code base and libffi on all platforms.
+ For easier installation, the libffi sources are now included in
+ the source distribution - no need to find, build, and install a
+ compatible libffi version.
+
+
+Requirements
+
+ ctypes 0.9 requires Python 2.3 or higher, since it makes intensive
+ use of the new type system.
+
+ ctypes uses libffi, which is copyright Red Hat, Inc. Complete
+ license see below.
+
+
+Installation
+
+ Windows
+
+ On Windows, it is the easiest to download the executable
+ installer for your Python version and execute this.
+
+ Installation from source
+
+ Separate source distributions are available for windows and
+ non-windows systems. Please use the .zip file for Windows (it
+ contains the ctypes.com framework), and use the .tar.gz file
+ for non-Windows systems (it contains the complete
+ cross-platform libffi sources).
+
+ To install ctypes from source, unpack the distribution, enter
+ the ctypes-0.9.x source directory, and enter
+
+ python setup.py build
+
+ This will build the Python extension modules. A C compiler is
+ required. On OS X, the segment attribute live_support must be
+ defined. If your compiler doesn't know about it, upgrade or
+ set the environment variable CCASFLAGS="-Dno_live_support".
+
+ To run the supplied tests, enter
+
+ python setup.py test
+
+ To install ctypes, enter
+
+ python setup.py install --help
+
+ to see the avaibable options, and finally
+
+ python setup.py install [options]
+
+
+ For Windows CE, a project file is provided in
+ wince\_ctypes.vcw. MS embedded Visual C 4.0 is required to
+ build the extension modules.
+
+
+Additional notes
+
+ Current version: 0.9.9.3
+
+ Homepage: http://starship.python.net/crew/theller/ctypes.html
+
+
+ctypes license
+
+ Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2006 Thomas Heller
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation files
+ (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+
+libffi license
+
+ libffi - Copyright (c) 1996-2003 Red Hat, Inc.
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation files
+ (the ``Software''), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/macholib/.cvsignore b/python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/macholib/.cvsignore
new file mode 100644
index 000000000000..0d20b6487c61
--- /dev/null
+++ b/python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/macholib/.cvsignore
@@ -0,0 +1 @@
+*.pyc
diff --git a/python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/macholib/__init__.py b/python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/macholib/__init__.py
new file mode 100644
index 000000000000..5621defccd61
--- /dev/null
+++ b/python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/macholib/__init__.py
@@ -0,0 +1,9 @@
+"""
+Enough Mach-O to make your head spin.
+
+See the relevant header files in /usr/include/mach-o
+
+And also Apple's documentation.
+"""
+
+__version__ = '1.0'
diff --git a/python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/macholib/dyld.py b/python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/macholib/dyld.py
new file mode 100644
index 000000000000..85073aac11ec
--- /dev/null
+++ b/python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/macholib/dyld.py
@@ -0,0 +1,167 @@
+#@PydevCodeAnalysisIgnore
+"""
+dyld emulation
+"""
+
+import os
+from framework import framework_info
+from dylib import dylib_info
+from itertools import *
+
+__all__ = [
+ 'dyld_find', 'framework_find',
+ 'framework_info', 'dylib_info',
+]
+
+# These are the defaults as per man dyld(1)
+#
+DEFAULT_FRAMEWORK_FALLBACK = [
+ os.path.expanduser("~/Library/Frameworks"),
+ "/Library/Frameworks",
+ "/Network/Library/Frameworks",
+ "/System/Library/Frameworks",
+]
+
+DEFAULT_LIBRARY_FALLBACK = [
+ os.path.expanduser("~/lib"),
+ "/usr/local/lib",
+ "/lib",
+ "/usr/lib",
+]
+
+def ensure_utf8(s):
+ """Not all of PyObjC and Python understand unicode paths very well yet"""
+ if isinstance(s, unicode):
+ return s.encode('utf8')
+ return s
+
+def dyld_env(env, var):
+ if env is None:
+ env = os.environ
+ rval = env.get(var)
+ if rval is None:
+ return []
+ return rval.split(':')
+
+def dyld_image_suffix(env=None):
+ if env is None:
+ env = os.environ
+ return env.get('DYLD_IMAGE_SUFFIX')
+
+def dyld_framework_path(env=None):
+ return dyld_env(env, 'DYLD_FRAMEWORK_PATH')
+
+def dyld_library_path(env=None):
+ return dyld_env(env, 'DYLD_LIBRARY_PATH')
+
+def dyld_fallback_framework_path(env=None):
+ return dyld_env(env, 'DYLD_FALLBACK_FRAMEWORK_PATH')
+
+def dyld_fallback_library_path(env=None):
+ return dyld_env(env, 'DYLD_FALLBACK_LIBRARY_PATH')
+
+def dyld_image_suffix_search(iterator, env=None):
+ """For a potential path iterator, add DYLD_IMAGE_SUFFIX semantics"""
+ suffix = dyld_image_suffix(env)
+ if suffix is None:
+ return iterator
+ def _inject(iterator=iterator, suffix=suffix):
+ for path in iterator:
+ if path.endswith('.dylib'):
+ yield path[:-len('.dylib')] + suffix + '.dylib'
+ else:
+ yield path + suffix
+ yield path
+ return _inject()
+
+def dyld_override_search(name, env=None):
+ # If DYLD_FRAMEWORK_PATH is set and this dylib_name is a
+ # framework name, use the first file that exists in the framework
+ # path if any. If there is none go on to search the DYLD_LIBRARY_PATH
+ # if any.
+
+ framework = framework_info(name)
+
+ if framework is not None:
+ for path in dyld_framework_path(env):
+ yield os.path.join(path, framework['name'])
+
+ # If DYLD_LIBRARY_PATH is set then use the first file that exists
+ # in the path. If none use the original name.
+ for path in dyld_library_path(env):
+ yield os.path.join(path, os.path.basename(name))
+
+def dyld_executable_path_search(name, executable_path=None):
+ # If we haven't done any searching and found a library and the
+ # dylib_name starts with "@executable_path/" then construct the
+ # library name.
+ if name.startswith('@executable_path/') and executable_path is not None:
+ yield os.path.join(executable_path, name[len('@executable_path/'):])
+
+def dyld_default_search(name, env=None):
+ yield name
+
+ framework = framework_info(name)
+
+ if framework is not None:
+ fallback_framework_path = dyld_fallback_framework_path(env)
+ for path in fallback_framework_path:
+ yield os.path.join(path, framework['name'])
+
+ fallback_library_path = dyld_fallback_library_path(env)
+ for path in fallback_library_path:
+ yield os.path.join(path, os.path.basename(name))
+
+ if framework is not None and not fallback_framework_path:
+ for path in DEFAULT_FRAMEWORK_FALLBACK:
+ yield os.path.join(path, framework['name'])
+
+ if not fallback_library_path:
+ for path in DEFAULT_LIBRARY_FALLBACK:
+ yield os.path.join(path, os.path.basename(name))
+
+def dyld_find(name, executable_path=None, env=None):
+ """
+ Find a library or framework using dyld semantics
+ """
+ name = ensure_utf8(name)
+ executable_path = ensure_utf8(executable_path)
+ for path in dyld_image_suffix_search(chain(
+ dyld_override_search(name, env),
+ dyld_executable_path_search(name, executable_path),
+ dyld_default_search(name, env),
+ ), env):
+ if os.path.isfile(path):
+ return path
+ raise ValueError, "dylib %s could not be found" % (name,)
+
+def framework_find(fn, executable_path=None, env=None):
+ """
+ Find a framework using dyld semantics in a very loose manner.
+
+ Will take input such as:
+ Python
+ Python.framework
+ Python.framework/Versions/Current
+ """
+ try:
+ return dyld_find(fn, executable_path=executable_path, env=env)
+ except ValueError:
+ pass
+ fmwk_index = fn.rfind('.framework')
+ if fmwk_index == -1:
+ fmwk_index = len(fn)
+ fn += '.framework'
+ fn = os.path.join(fn, os.path.basename(fn[:fmwk_index]))
+ try:
+ return dyld_find(fn, executable_path=executable_path, env=env)
+ except ValueError:
+ raise e
+
+def test_dyld_find():
+ env = {}
+ assert dyld_find('libSystem.dylib') == '/usr/lib/libSystem.dylib'
+ assert dyld_find('System.framework/System') == '/System/Library/Frameworks/System.framework/System'
+
+if __name__ == '__main__':
+ test_dyld_find()
diff --git a/python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/macholib/dylib.py b/python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/macholib/dylib.py
new file mode 100644
index 000000000000..aa107507bd4a
--- /dev/null
+++ b/python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/macholib/dylib.py
@@ -0,0 +1,63 @@
+"""
+Generic dylib path manipulation
+"""
+
+import re
+
+__all__ = ['dylib_info']
+
+DYLIB_RE = re.compile(r"""(?x)
+(?P<location>^.*)(?:^|/)
+(?P<name>
+ (?P<shortname>\w+?)
+ (?:\.(?P<version>[^._]+))?
+ (?:_(?P<suffix>[^._]+))?
+ \.dylib$
+)
+""")
+
+def dylib_info(filename):
+ """
+ A dylib name can take one of the following four forms:
+ Location/Name.SomeVersion_Suffix.dylib
+ Location/Name.SomeVersion.dylib
+ Location/Name_Suffix.dylib
+ Location/Name.dylib
+
+ returns None if not found or a mapping equivalent to:
+ dict(
+ location='Location',
+ name='Name.SomeVersion_Suffix.dylib',
+ shortname='Name',
+ version='SomeVersion',
+ suffix='Suffix',
+ )
+
+ Note that SomeVersion and Suffix are optional and may be None
+ if not present.
+ """
+ is_dylib = DYLIB_RE.match(filename)
+ if not is_dylib:
+ return None
+ return is_dylib.groupdict()
+
+
+def test_dylib_info():
+ def d(location=None, name=None, shortname=None, version=None, suffix=None):
+ return dict(
+ location=location,
+ name=name,
+ shortname=shortname,
+ version=version,
+ suffix=suffix
+ )
+ assert dylib_info('completely/invalid') is None
+ assert dylib_info('completely/invalide_debug') is None
+ assert dylib_info('P/Foo.dylib') == d('P', 'Foo.dylib', 'Foo')
+ assert dylib_info('P/Foo_debug.dylib') == d('P', 'Foo_debug.dylib', 'Foo', suffix='debug')
+ assert dylib_info('P/Foo.A.dylib') == d('P', 'Foo.A.dylib', 'Foo', 'A')
+ assert dylib_info('P/Foo_debug.A.dylib') == d('P', 'Foo_debug.A.dylib', 'Foo_debug', 'A')
+ assert dylib_info('P/Foo.A_debug.dylib') == d('P', 'Foo.A_debug.dylib', 'Foo', 'A', 'debug')
+
+if __name__ == '__main__':
+ test_dylib_info()
diff --git a/python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/macholib/framework.py b/python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/macholib/framework.py
new file mode 100644
index 000000000000..ad6ed554ba0c
--- /dev/null
+++ b/python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/macholib/framework.py
@@ -0,0 +1,65 @@
+"""
+Generic framework path manipulation
+"""
+
+import re
+
+__all__ = ['framework_info']
+
+STRICT_FRAMEWORK_RE = re.compile(r"""(?x)
+(?P<location>^.*)(?:^|/)
+(?P<name>
+ (?P<shortname>\w+).framework/
+ (?:Versions/(?P<version>[^/]+)/)?
+ (?P=shortname)
+ (?:_(?P<suffix>[^_]+))?
+)$
+""")
+
+def framework_info(filename):
+ """
+ A framework name can take one of the following four forms:
+ Location/Name.framework/Versions/SomeVersion/Name_Suffix
+ Location/Name.framework/Versions/SomeVersion/Name
+ Location/Name.framework/Name_Suffix
+ Location/Name.framework/Name
+
+ returns None if not found, or a mapping equivalent to:
+ dict(
+ location='Location',
+ name='Name.framework/Versions/SomeVersion/Name_Suffix',
+ shortname='Name',
+ version='SomeVersion',
+ suffix='Suffix',
+ )
+
+ Note that SomeVersion and Suffix are optional and may be None
+ if not present
+ """
+ is_framework = STRICT_FRAMEWORK_RE.match(filename)
+ if not is_framework:
+ return None
+ return is_framework.groupdict()
+
+def test_framework_info():
+ def d(location=None, name=None, shortname=None, version=None, suffix=None):
+ return dict(
+ location=location,
+ name=name,
+ shortname=shortname,
+ version=version,
+ suffix=suffix
+ )
+ assert framework_info('completely/invalid') is None
+ assert framework_info('completely/invalid/_debug') is None
+ assert framework_info('P/F.framework') is None
+ assert framework_info('P/F.framework/_debug') is None
+ assert framework_info('P/F.framework/F') == d('P', 'F.framework/F', 'F')
+ assert framework_info('P/F.framework/F_debug') == d('P', 'F.framework/F_debug', 'F', suffix='debug')
+ assert framework_info('P/F.framework/Versions') is None
+ assert framework_info('P/F.framework/Versions/A') is None
+ assert framework_info('P/F.framework/Versions/A/F') == d('P', 'F.framework/Versions/A/F', 'F', 'A')
+ assert framework_info('P/F.framework/Versions/A/F_debug') == d('P', 'F.framework/Versions/A/F_debug', 'F', 'A', 'debug')
+
+if __name__ == '__main__':
+ test_framework_info()
diff --git a/python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/util.py b/python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/util.py
new file mode 100644
index 000000000000..6db0cfbb5ecc
--- /dev/null
+++ b/python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/util.py
@@ -0,0 +1,124 @@
+#@PydevCodeAnalysisIgnore
+import sys, os
+import ctypes
+
+# find_library(name) returns the pathname of a library, or None.
+if os.name == "nt":
+ def find_library(name):
+ # See MSDN for the REAL search order.
+ for directory in os.environ['PATH'].split(os.pathsep):
+ fname = os.path.join(directory, name)
+ if os.path.exists(fname):
+ return fname
+ if fname.lower().endswith(".dll"):
+ continue
+ fname = fname + ".dll"
+ if os.path.exists(fname):
+ return fname
+ return None
+
+if os.name == "ce":
+ # search path according to MSDN:
+ # - absolute path specified by filename
+ # - The .exe launch directory
+ # - the Windows directory
+ # - ROM dll files (where are they?)
+ # - OEM specified search path: HKLM\Loader\SystemPath
+ def find_library(name):
+ return name
+
+if os.name == "posix" and sys.platform == "darwin":
+ from ctypes.macholib.dyld import dyld_find as _dyld_find
+ def find_library(name):
+ possible = ['lib%s.dylib' % name,
+ '%s.dylib' % name,
+ '%s.framework/%s' % (name, name)]
+ for name in possible:
+ try:
+ return _dyld_find(name)
+ except ValueError:
+ continue
+ return None
+
+elif os.name == "posix":
+ # Andreas Degert's find functions, using gcc, /sbin/ldconfig, objdump
+ import re, tempfile
+
+ def _findLib_gcc(name):
+ expr = '[^\(\)\s]*lib%s\.[^\(\)\s]*' % name
+ cmd = 'if type gcc &>/dev/null; then CC=gcc; else CC=cc; fi;' \
+ '$CC -Wl,-t -o /dev/null 2>&1 -l' + name
+ try:
+ fdout, outfile = tempfile.mkstemp()
+ fd = os.popen(cmd)
+ trace = fd.read()
+ err = fd.close()
+ finally:
+ try:
+ os.unlink(outfile)
+ except OSError, e:
+ import errno
+ if e.errno != errno.ENOENT:
+ raise
+ res = re.search(expr, trace)
+ if not res:
+ return None
+ return res.group(0)
+
+ def _findLib_ld(name):
+ expr = '/[^\(\)\s]*lib%s\.[^\(\)\s]*' % name
+ res = re.search(expr, os.popen('/sbin/ldconfig -p 2>/dev/null').read())
+ if not res:
+ # Hm, this works only for libs needed by the python executable.
+ cmd = 'ldd %s 2>/dev/null' % sys.executable
+ res = re.search(expr, os.popen(cmd).read())
+ if not res:
+ return None
+ return res.group(0)
+
+ def _get_soname(f):
+ cmd = "objdump -p -j .dynamic 2>/dev/null " + f
+ res = re.search(r'\sSONAME\s+([^\s]+)', os.popen(cmd).read())
+ if not res:
+ return None
+ return res.group(1)
+
+ def find_library(name):
+ lib = _findLib_ld(name) or _findLib_gcc(name)
+ if not lib:
+ return None
+ return _get_soname(lib)
+
+################################################################
+# test code
+
+def test():
+ from ctypes import cdll
+ if os.name == "nt":
+ sys.stdout.write('%s\n' % (cdll.msvcrt,))
+ sys.stdout.write('%s\n' % (cdll.load("msvcrt"),))
+ sys.stdout.write('%s\n' % (find_library("msvcrt"),))
+
+ if os.name == "posix":
+ # find and load_version
+ sys.stdout.write('%s\n' % (find_library("m"),))
+ sys.stdout.write('%s\n' % (find_library("c"),))
+ sys.stdout.write('%s\n' % (find_library("bz2"),))
+
+ # getattr
+## print_ cdll.m
+## print_ cdll.bz2
+
+ # load
+ if sys.platform == "darwin":
+ sys.stdout.write('%s\n' % (cdll.LoadLibrary("libm.dylib"),))
+ sys.stdout.write('%s\n' % (cdll.LoadLibrary("libcrypto.dylib"),))
+ sys.stdout.write('%s\n' % (cdll.LoadLibrary("libSystem.dylib"),))
+ sys.stdout.write('%s\n' % (cdll.LoadLibrary("System.framework/System"),))
+ else:
+ sys.stdout.write('%s\n' % (cdll.LoadLibrary("libm.so"),))
+ sys.stdout.write('%s\n' % (cdll.LoadLibrary("libcrypt.so"),))
+ sys.stdout.write('%s\n' % (find_library("crypt"),))
+
+if __name__ == "__main__":
+ test()
diff --git a/python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/wintypes.py b/python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/wintypes.py
new file mode 100644
index 000000000000..d31f11e2bab8
--- /dev/null
+++ b/python/helpers/pydev/third_party/wrapped_for_pydev/ctypes/wintypes.py
@@ -0,0 +1,98 @@
+#@PydevCodeAnalysisIgnore
+# XXX This module needs cleanup.
+
+from ctypes import *
+
+DWORD = c_ulong
+WORD = c_ushort
+BYTE = c_byte
+
+ULONG = c_ulong
+LONG = c_long
+
+LARGE_INTEGER = c_longlong
+ULARGE_INTEGER = c_ulonglong
+
+
+HANDLE = c_ulong # in the header files: void *
+
+HWND = HANDLE
+HDC = HANDLE
+HMODULE = HANDLE
+HINSTANCE = HANDLE
+HRGN = HANDLE
+HTASK = HANDLE
+HKEY = HANDLE
+HPEN = HANDLE
+HGDIOBJ = HANDLE
+HMENU = HANDLE
+
+LCID = DWORD
+
+WPARAM = c_uint
+LPARAM = c_long
+
+BOOL = c_long
+VARIANT_BOOL = c_short
+
+LPCOLESTR = LPOLESTR = OLESTR = c_wchar_p
+LPCWSTR = LPWSTR = c_wchar_p
+
+LPCSTR = LPSTR = c_char_p
+
+class RECT(Structure):
+ _fields_ = [("left", c_long),
+ ("top", c_long),
+ ("right", c_long),
+ ("bottom", c_long)]
+RECTL = RECT
+
+class POINT(Structure):
+ _fields_ = [("x", c_long),
+ ("y", c_long)]
+POINTL = POINT
+
+class SIZE(Structure):
+ _fields_ = [("cx", c_long),
+ ("cy", c_long)]
+SIZEL = SIZE
+
+def RGB(red, green, blue):
+ return red + (green << 8) + (blue << 16)
+
+class FILETIME(Structure):
+ _fields_ = [("dwLowDateTime", DWORD),
+ ("dwHighDateTime", DWORD)]
+
+class MSG(Structure):
+ _fields_ = [("hWnd", HWND),
+ ("message", c_uint),
+ ("wParam", WPARAM),
+ ("lParam", LPARAM),
+ ("time", DWORD),
+ ("pt", POINT)]
+MAX_PATH = 260
+
+class WIN32_FIND_DATAA(Structure):
+ _fields_ = [("dwFileAttributes", DWORD),
+ ("ftCreationTime", FILETIME),
+ ("ftLastAccessTime", FILETIME),
+ ("ftLastWriteTime", FILETIME),
+ ("nFileSizeHigh", DWORD),
+ ("nFileSizeLow", DWORD),
+ ("dwReserved0", DWORD),
+ ("dwReserved1", DWORD),
+ ("cFileName", c_char * MAX_PATH),
+ ("cAlternameFileName", c_char * 14)]
+
+class WIN32_FIND_DATAW(Structure):
+ _fields_ = [("dwFileAttributes", DWORD),
+ ("ftCreationTime", FILETIME),
+ ("ftLastAccessTime", FILETIME),
+ ("ftLastWriteTime", FILETIME),
+ ("nFileSizeHigh", DWORD),
+ ("nFileSizeLow", DWORD),
+ ("dwReserved0", DWORD),
+ ("dwReserved1", DWORD),
+ ("cFileName", c_wchar * MAX_PATH),
+ ("cAlternameFileName", c_wchar * 14)]
diff --git a/python/helpers/pydev/third_party/wrapped_for_pydev/not_in_default_pythonpath.txt b/python/helpers/pydev/third_party/wrapped_for_pydev/not_in_default_pythonpath.txt
new file mode 100644
index 000000000000..24084e9d174c
--- /dev/null
+++ b/python/helpers/pydev/third_party/wrapped_for_pydev/not_in_default_pythonpath.txt
@@ -0,0 +1 @@
+The wrapped_for_pydev folder is not in the default pythonpath... (no __init__.py file) \ No newline at end of file
diff --git a/python/helpers/rest_formatter.py b/python/helpers/rest_formatter.py
index e3575f8d147f..a1d176cd3f8f 100644
--- a/python/helpers/rest_formatter.py
+++ b/python/helpers/rest_formatter.py
@@ -1,4 +1,5 @@
import sys
+import re
from docutils.core import publish_string
from docutils import nodes
from docutils.nodes import Text
@@ -54,6 +55,53 @@ class RestHTMLTranslator(_EpydocHTMLTranslator):
self.body.append("</a>")
HTMLTranslator.depart_field_body(self, node)
+ def visit_reference(self, node):
+ atts = {}
+ if 'refuri' in node:
+ atts['href'] = node['refuri']
+ if self.settings.cloak_email_addresses and atts['href'].startswith('mailto:'):
+ atts['href'] = self.cloak_mailto(atts['href'])
+ self.in_mailto = True
+ # atts['class'] += ' external'
+ else:
+ assert 'refid' in node, 'References must have "refuri" or "refid" attribute.'
+ atts['href'] = '#' + node['refid']
+ atts['class'] += ' internal'
+ if not isinstance(node.parent, nodes.TextElement):
+ assert len(node) == 1 and isinstance(node[0], nodes.image)
+ atts['class'] += ' image-reference'
+ self.body.append(self.starttag(node, 'a', '', **atts))
+
+ def starttag(self, node, tagname, suffix='\n', **attributes):
+ attr_dicts = [attributes]
+ if isinstance(node, nodes.Node):
+ attr_dicts.append(node.attributes)
+ if isinstance(node, dict):
+ attr_dicts.append(node)
+ # Munge each attribute dictionary. Unfortunately, we need to
+ # iterate through attributes one at a time because some
+ # versions of docutils don't case-normalize attributes.
+ for attr_dict in attr_dicts:
+ for (key, val) in attr_dict.items():
+ # Prefix all CSS classes with "rst-"; and prefix all
+ # names with "rst-" to avoid conflicts.
+ if key.lower() in ('class', 'id', 'name'):
+ attr_dict[key] = 'rst-%s' % val
+ elif key.lower() in ('classes', 'ids', 'names'):
+ attr_dict[key] = ['rst-%s' % cls for cls in val]
+ elif key.lower() == 'href':
+ if attr_dict[key][:1]=='#':
+ attr_dict[key] = '#rst-%s' % attr_dict[key][1:]
+ else:
+ pass
+ # For headings, use class="heading"
+ if re.match(r'^h\d+$', tagname):
+ attributes['class'] = ' '.join([attributes.get('class',''),
+ 'heading']).strip()
+
+ return HTMLTranslator.starttag(self, node, tagname, suffix,
+ **attributes)
+
def visit_field_list(self, node):
fields = {}
diff --git a/python/ide/src/com/jetbrains/python/PyIdeCommonOptionsForm.java b/python/ide/src/com/jetbrains/python/PyIdeCommonOptionsForm.java
index 3b590371e610..79c35527e673 100644
--- a/python/ide/src/com/jetbrains/python/PyIdeCommonOptionsForm.java
+++ b/python/ide/src/com/jetbrains/python/PyIdeCommonOptionsForm.java
@@ -15,6 +15,7 @@
*/
package com.jetbrains.python;
+import com.intellij.application.options.ModulesComboBox;
import com.intellij.execution.configuration.EnvironmentVariablesComponent;
import com.intellij.execution.util.PathMappingsComponent;
import com.intellij.ide.util.PropertiesComponent;
@@ -26,7 +27,6 @@ import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.SdkModel;
import com.intellij.openapi.projectRoots.impl.SdkListCellRenderer;
import com.intellij.openapi.roots.ModuleRootManager;
-import com.intellij.application.options.ModulesComboBox;
import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectSdksModel;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
diff --git a/python/ide/src/com/jetbrains/python/configuration/PyContentEntriesModuleConfigurable.java b/python/ide/src/com/jetbrains/python/configuration/PyContentEntriesModuleConfigurable.java
index bcbebc3b2639..ca00208c3c88 100644
--- a/python/ide/src/com/jetbrains/python/configuration/PyContentEntriesModuleConfigurable.java
+++ b/python/ide/src/com/jetbrains/python/configuration/PyContentEntriesModuleConfigurable.java
@@ -1,60 +1,29 @@
package com.jetbrains.python.configuration;
import com.intellij.facet.impl.DefaultFacetsProvider;
-import com.intellij.openapi.Disposable;
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.actionSystem.CustomShortcutSet;
-import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.impl.ModuleConfigurationStateImpl;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SearchableConfigurable;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.roots.ContentEntry;
-import com.intellij.openapi.roots.ContentFolder;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootManager;
-import com.intellij.openapi.roots.impl.ContentEntryImpl;
-import com.intellij.openapi.roots.impl.ContentFolderBaseImpl;
-import com.intellij.openapi.roots.ui.configuration.*;
-import com.intellij.openapi.roots.ui.configuration.actions.ContentEntryEditingAction;
-import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.roots.ui.configuration.DefaultModulesProvider;
+import com.intellij.openapi.roots.ui.configuration.FacetsProvider;
import com.intellij.openapi.util.Computable;
-import com.intellij.openapi.util.Disposer;
-import com.intellij.openapi.vfs.VfsUtilCore;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.openapi.vfs.pointers.VirtualFilePointer;
-import com.intellij.openapi.vfs.pointers.VirtualFilePointerListener;
-import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager;
-import com.intellij.ui.JBColor;
-import com.intellij.util.EventDispatcher;
-import com.intellij.util.containers.MultiMap;
-import com.jetbrains.python.templateLanguages.TemplatesService;
-import icons.PythonIcons;
+import com.jetbrains.python.module.PyContentEntriesEditor;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.model.java.JavaSourceRootType;
-import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
import javax.swing.*;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
-import javax.swing.tree.TreeCellRenderer;
import java.awt.*;
-import java.awt.event.InputEvent;
-import java.awt.event.KeyEvent;
-import java.util.ArrayList;
-import java.util.List;
public class PyContentEntriesModuleConfigurable extends SearchableConfigurable.Parent.Abstract {
- private static final Color TEMPLATES_COLOR = JBColor.MAGENTA;
-
private final Module myModule;
private final JPanel myTopPanel = new JPanel(new BorderLayout());
protected ModifiableRootModel myModifiableModel;
- protected MyCommonContentEntriesEditor myEditor;
+ protected PyContentEntriesEditor myEditor;
public PyContentEntriesModuleConfigurable(final Module module) {
myModule = module;
@@ -108,8 +77,8 @@ public class PyContentEntriesModuleConfigurable extends SearchableConfigurable.P
myTopPanel.add(component, BorderLayout.CENTER);
}
- protected MyCommonContentEntriesEditor createEditor(@NotNull Module module, @NotNull ModuleConfigurationStateImpl state) {
- return new MyCommonContentEntriesEditor(module, state, JavaSourceRootType.SOURCE);
+ protected PyContentEntriesEditor createEditor(@NotNull Module module, @NotNull ModuleConfigurationStateImpl state) {
+ return new PyContentEntriesEditor(module, state, JavaSourceRootType.SOURCE);
}
@Override
@@ -171,314 +140,4 @@ public class PyContentEntriesModuleConfigurable extends SearchableConfigurable.P
return "python.project.structure";
}
- private static class MyContentEntryTreeEditor extends ContentEntryTreeEditor {
-
- private final ChangeListener myListener = new ChangeListener() {
- @Override
- public void stateChanged(ChangeEvent e) {
- update();
- }
- };
-
- public MyContentEntryTreeEditor(Project project, List<ModuleSourceRootEditHandler<?>> handlers) {
- super(project, handlers);
- }
-
- @Override
- public void setContentEntryEditor(ContentEntryEditor newEditor) {
- MyCommonContentEntriesEditor.MyContentEntryEditor existingEditor = getContentEntryEditor();
- if (Comparing.equal(existingEditor, newEditor)) {
- return;
- }
- if (existingEditor != null) {
- existingEditor.removeListener(myListener);
- }
- if (newEditor != null) {
- ((MyCommonContentEntriesEditor.MyContentEntryEditor)newEditor).addListener(myListener);
- }
- super.setContentEntryEditor(newEditor);
- }
-
- @Override
- public MyCommonContentEntriesEditor.MyContentEntryEditor getContentEntryEditor() {
- return (MyCommonContentEntriesEditor.MyContentEntryEditor)super.getContentEntryEditor();
- }
-
- @Override
- protected void createEditingActions() {
- super.createEditingActions();
-
- ContentEntryEditingAction a = new ContentEntryEditingAction(myTree) {
- {
- final Presentation templatePresentation = getTemplatePresentation();
- templatePresentation.setText("Templates");
- templatePresentation.setDescription("Template Folders");
- templatePresentation.setIcon(PythonIcons.Python.TemplateRoot);
- }
-
- @Override
- public boolean isSelected(AnActionEvent e) {
- final VirtualFile[] selectedFiles = getSelectedFiles();
- return selectedFiles.length != 0 && getContentEntryEditor().hasTemplateRoot(selectedFiles[0]);
- }
-
- @Override
- public void setSelected(AnActionEvent e, boolean isSelected) {
- final VirtualFile[] selectedFiles = getSelectedFiles();
- assert selectedFiles.length != 0;
-
- for (VirtualFile selectedFile : selectedFiles) {
- boolean wasSelected = getContentEntryEditor().hasTemplateRoot(selectedFile);
- if (isSelected) {
- if (!wasSelected) {
- getContentEntryEditor().addTemplateRoot(selectedFile);
- }
- }
- else {
- if (wasSelected) {
- getContentEntryEditor().removeTemplateRoot(selectedFile);
- }
- }
- }
- }
- };
- myEditingActionsGroup.add(a);
- a.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_R, InputEvent.ALT_MASK)), myTree);
- }
-
- @Override
- protected TreeCellRenderer getContentEntryCellRenderer() {
- return new ContentEntryTreeCellRenderer(this, getEditHandlers()) {
- @Override
- protected Icon updateIcon(final ContentEntry entry, final VirtualFile file, final Icon originalIcon) {
- if (getContentEntryEditor().hasTemplateRoot(file)) {
- return PythonIcons.Python.TemplateRoot;
- }
- return super.updateIcon(entry, file, originalIcon);
- }
- };
- }
- }
-
- protected static class MyCommonContentEntriesEditor extends CommonContentEntriesEditor {
- private final MultiMap<ContentEntry, VirtualFilePointer> myTemplateRoots = new MultiMap<ContentEntry, VirtualFilePointer>();
- private final Module myModule;
- private Disposable myFilePointersDisposable;
-
- private final VirtualFilePointerListener DUMMY_LISTENER = new VirtualFilePointerListener() {
- @Override
- public void beforeValidityChanged(@NotNull VirtualFilePointer[] pointers) {
- }
-
- @Override
- public void validityChanged(@NotNull VirtualFilePointer[] pointers) {
- }
- };
-
- public MyCommonContentEntriesEditor(Module module,
- ModuleConfigurationStateImpl moduleConfigurationState,
- JpsModuleSourceRootType<?>... rootTypes) {
- super(module.getName(), moduleConfigurationState, rootTypes);
- myModule = module;
- reset();
- }
-
- @Override
- protected ContentEntryTreeEditor createContentEntryTreeEditor(Project project) {
- return new MyContentEntryTreeEditor(project, getEditHandlers());
- }
-
- @Override
- protected List<ContentEntry> addContentEntries(VirtualFile[] files) {
- List<ContentEntry> entries = super.addContentEntries(files);
- addContentEntryPanels(entries.toArray(new ContentEntry[entries.size()]));
- return entries;
- }
-
- @Override
- public void reset() {
- if (myFilePointersDisposable != null) {
- Disposer.dispose(myFilePointersDisposable);
- }
- myTemplateRoots.clear();
-
- myFilePointersDisposable = Disposer.newDisposable();
- final TemplatesService instance = TemplatesService.getInstance(myModule);
- if (instance != null) {
- final List<VirtualFile> folders = instance.getTemplateFolders();
- for (VirtualFile folder : folders) {
- ContentEntry contentEntry = findContentEntryForFile(folder);
- if (contentEntry != null) {
- myTemplateRoots.putValue(contentEntry, VirtualFilePointerManager.getInstance().create(folder, myFilePointersDisposable,
- DUMMY_LISTENER));
- }
- }
- }
-
- if (myRootTreeEditor != null) {
- ContentEntryEditor editor = myRootTreeEditor.getContentEntryEditor();
- if(editor!=null) editor.update();
- myRootTreeEditor.update();
- }
- }
-
- @Nullable
- private ContentEntry findContentEntryForFile(VirtualFile virtualFile) {
- for (ContentEntry contentEntry : getModel().getContentEntries()) {
- final VirtualFile file = contentEntry.getFile();
- if (file != null && VfsUtilCore.isAncestor(file, virtualFile, false)) {
- return contentEntry;
- }
- }
- return null;
- }
-
- @Override
- public void disposeUIResources() {
- super.disposeUIResources();
- if (myFilePointersDisposable != null) {
- Disposer.dispose(myFilePointersDisposable);
- }
- }
-
- @Override
- public void apply() throws ConfigurationException {
- super.apply();
- List<VirtualFile> templateRoots = getCurrentState();
- TemplatesService.getInstance(myModule).setTemplateFolders(templateRoots.toArray(new VirtualFile[templateRoots.size()]));
- }
-
- private List<VirtualFile> getCurrentState() {
- List<VirtualFile> result = new ArrayList<VirtualFile>();
- for (ContentEntry entry : myTemplateRoots.keySet()) {
- for (VirtualFilePointer filePointer : myTemplateRoots.get(entry)) {
- result.add(filePointer.getFile());
- }
- }
- return result;
- }
-
- @Override
- public boolean isModified() {
- if (super.isModified()) return true;
- final TemplatesService templatesService = TemplatesService.getInstance(myModule);
- if (templatesService != null) {
- List<VirtualFile> original = templatesService.getTemplateFolders();
- List<VirtualFile> current = getCurrentState();
-
- if (!Comparing.haveEqualElements(original, current)) return true;
-
- }
- return false;
- }
-
- @Override
- protected MyContentEntryEditor createContentEntryEditor(String contentEntryUrl) {
- return new MyContentEntryEditor(contentEntryUrl, getEditHandlers());
- }
-
- protected class MyContentEntryEditor extends ContentEntryEditor {
- private final EventDispatcher<ChangeListener> myEventDispatcher = EventDispatcher.create(ChangeListener.class);
-
- public MyContentEntryEditor(String contentEntryUrl, List<ModuleSourceRootEditHandler<?>> handlers) {
- super(contentEntryUrl, handlers);
- }
-
- @Override
- protected ModifiableRootModel getModel() {
- return MyCommonContentEntriesEditor.this.getModel();
- }
-
- public void addListener(ChangeListener changeListener) {
- myEventDispatcher.addListener(changeListener);
- }
-
- public void removeListener(ChangeListener changeListener) {
- myEventDispatcher.removeListener(changeListener);
- }
-
- @Override
- protected ContentRootPanel createContentRootPane() {
- return new MyContentRootPanel();
- }
-
- @Override
- public void deleteContentFolder(ContentEntry contentEntry, ContentFolder folder) {
- if (folder instanceof TemplateRootFolder) {
- final VirtualFile file = folder.getFile();
- if (file != null) {
- removeTemplateRoot(file);
- }
- }
- else {
- super.deleteContentFolder(contentEntry, folder);
- }
- }
-
- public void addTemplateRoot(@NotNull final VirtualFile file) {
- final VirtualFilePointer root = VirtualFilePointerManager.getInstance().create(file, myFilePointersDisposable, DUMMY_LISTENER);
- myTemplateRoots.putValue(getContentEntry(), root);
- myEventDispatcher.getMulticaster().stateChanged(new ChangeEvent(this));
- update();
- }
-
- public void removeTemplateRoot(@NotNull final VirtualFile file) {
- final VirtualFilePointer root = getTemplateRoot(file);
- if (root != null) {
- myTemplateRoots.remove(getContentEntry(), root);
- myEventDispatcher.getMulticaster().stateChanged(new ChangeEvent(this));
- update();
- }
- }
-
- public boolean hasTemplateRoot(@NotNull final VirtualFile file) {
- return getTemplateRoot(file) != null;
- }
-
- @Nullable
- public VirtualFilePointer getTemplateRoot(@NotNull final VirtualFile file) {
- for (VirtualFilePointer filePointer : myTemplateRoots.get(getContentEntry())) {
- if (Comparing.equal(filePointer.getFile(), file)) {
- return filePointer;
- }
- }
- return null;
- }
-
- protected class MyContentRootPanel extends ContentRootPanel {
- public MyContentRootPanel() {
- super(MyContentEntryEditor.this, getEditHandlers());
- }
-
- @Override
- @NotNull
- protected ContentEntryImpl getContentEntry() {
- //noinspection ConstantConditions
- return (ContentEntryImpl)MyContentEntryEditor.this.getContentEntry();
- }
-
- @Override
- protected void addFolderGroupComponents() {
- super.addFolderGroupComponents();
- if (!myTemplateRoots.get(getContentEntry()).isEmpty()) {
- final List<TemplateRootFolder> folders = new ArrayList<TemplateRootFolder>(myTemplateRoots.size());
- for (VirtualFilePointer root : myTemplateRoots.get(getContentEntry())) {
- folders.add(new TemplateRootFolder(root, getContentEntry()));
- }
- final JComponent sourcesComponent = createFolderGroupComponent("Template Folders",
- folders.toArray(new ContentFolder[folders.size()]),
- TEMPLATES_COLOR, null);
- this.add(sourcesComponent, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH,
- GridBagConstraints.HORIZONTAL, new Insets(0, 0, 10, 0), 0, 0));
- }
- }
- }
- }
- }
-
- private static class TemplateRootFolder extends ContentFolderBaseImpl {
- protected TemplateRootFolder(@NotNull VirtualFilePointer filePointer, @NotNull ContentEntryImpl contentEntry) {
- super(filePointer, contentEntry);
- }
- }
}
diff --git a/python/ide/src/com/jetbrains/python/configuration/PythonPathEditor.java b/python/ide/src/com/jetbrains/python/configuration/PythonPathEditor.java
index 33169a79d267..0512bb051bf7 100644
--- a/python/ide/src/com/jetbrains/python/configuration/PythonPathEditor.java
+++ b/python/ide/src/com/jetbrains/python/configuration/PythonPathEditor.java
@@ -126,7 +126,7 @@ public class PythonPathEditor extends SdkPathEditor {
@Override
protected void addToolbarButtons(ToolbarDecorator toolbarDecorator) {
- AnActionButton reloadButton = new AnActionButton("Reload List of Paths", AllIcons.Actions.Refresh) {
+ AnActionButton reloadButton = new AnActionButton("Reload list of paths", AllIcons.Actions.Refresh) {
@Override
public void actionPerformed(AnActionEvent e) {
onReloadButtonClicked();
diff --git a/python/ide/src/com/jetbrains/python/configuration/PythonSdkDetailsDialog.java b/python/ide/src/com/jetbrains/python/configuration/PythonSdkDetailsDialog.java
index b0ca6dbff65f..213b0e1e69d5 100644
--- a/python/ide/src/com/jetbrains/python/configuration/PythonSdkDetailsDialog.java
+++ b/python/ide/src/com/jetbrains/python/configuration/PythonSdkDetailsDialog.java
@@ -435,7 +435,7 @@ public class PythonSdkDetailsDialog extends DialogWrapper {
private class ShowPathButton extends AnActionButton implements DumbAware {
public ShowPathButton() {
- super("Show path for the selected interpreter", AllIcons.Actions.ShowAsTree);
+ super("Show paths for the selected interpreter", AllIcons.Actions.ShowAsTree);
}
@Override
diff --git a/python/ide/src/com/jetbrains/python/newProject/actions/AbstractProjectSettingsStep.java b/python/ide/src/com/jetbrains/python/newProject/actions/AbstractProjectSettingsStep.java
index dd68cdb6ed2f..1ad9cf7ececc 100644
--- a/python/ide/src/com/jetbrains/python/newProject/actions/AbstractProjectSettingsStep.java
+++ b/python/ide/src/com/jetbrains/python/newProject/actions/AbstractProjectSettingsStep.java
@@ -61,6 +61,7 @@ import java.util.List;
abstract public class AbstractProjectSettingsStep extends AbstractActionWithPanel implements DumbAware {
protected final DirectoryProjectGenerator myProjectGenerator;
private final NullableConsumer<AbstractProjectSettingsStep> myCallback;
+ private final boolean myIsWelcomeScreen;
private PythonSdkChooserCombo mySdkCombo;
private boolean myInstallFramework;
private TextFieldWithBrowseButton myLocationField;
@@ -70,10 +71,13 @@ abstract public class AbstractProjectSettingsStep extends AbstractActionWithPane
private AnAction myCreateAction;
private Sdk mySdk;
- public AbstractProjectSettingsStep(DirectoryProjectGenerator projectGenerator, NullableConsumer<AbstractProjectSettingsStep> callback) {
+ public AbstractProjectSettingsStep(DirectoryProjectGenerator projectGenerator,
+ NullableConsumer<AbstractProjectSettingsStep> callback,
+ boolean isWelcomeScreen) {
super();
myProjectGenerator = projectGenerator;
myCallback = callback;
+ myIsWelcomeScreen = isWelcomeScreen;
myProjectDirectory = FileUtil.findSequentNonexistentFile(new File(ProjectUtil.getBaseDir()), "untitled", "");
if (myProjectGenerator instanceof WebProjectTemplate) {
((WebProjectTemplate)myProjectGenerator).getPeer().addSettingsStateListener(new WebProjectGenerator.SettingsStateListener() {
@@ -109,17 +113,12 @@ abstract public class AbstractProjectSettingsStep extends AbstractActionWithPane
@Override
public JPanel createPanel() {
final JPanel basePanel = createBasePanel();
- final JPanel mainPanel = new JPanel(new BorderLayout()) {
- @Override
- protected void paintComponent(Graphics g) {
- myLocationField.requestFocus();
- }
- };
+ final JPanel mainPanel = new JPanel(new BorderLayout());
final JPanel scrollPanel = new JPanel(new BorderLayout());
final DirectoryProjectGenerator[] generators = Extensions.getExtensions(DirectoryProjectGenerator.EP_NAME);
- final int height = generators.length == 0 ? 150 : 400;
+ final int height = generators.length == 0 && !myIsWelcomeScreen ? 150 : 400;
mainPanel.setPreferredSize(new Dimension(mainPanel.getPreferredSize().width, height));
myErrorLabel = new JLabel("");
myErrorLabel.setForeground(JBColor.RED);
@@ -273,6 +272,7 @@ abstract public class AbstractProjectSettingsStep extends AbstractActionWithPane
}
public boolean checkValid() {
+ if (myLocationField == null) return true;
final String projectName = myLocationField.getText();
setErrorText(null);
myInstallFramework = false;
@@ -367,22 +367,6 @@ abstract public class AbstractProjectSettingsStep extends AbstractActionWithPane
myErrorLabel.setForeground(MessageType.WARNING.getTitleForeground());
}
- public void selectCompatiblePython() {
- //DirectoryProjectGenerator generator = getProjectGenerator();
- //if (generator instanceof PyFrameworkProjectGenerator && !((PyFrameworkProjectGenerator)generator).supportsPython3()) {
- // Sdk sdk = getSdk();
- // if (sdk != null && PythonSdkType.getLanguageLevelForSdk(sdk).isPy3K()) {
- // Sdk python2Sdk = PythonSdkType.findPython2Sdk(null);
- // if (python2Sdk != null) {
- // mySdkCombo.getComboBox().setSelectedItem(python2Sdk);
- // mySdkCombo.getComboBox().revalidate();
- // mySdkCombo.getComboBox().repaint();
- //
- // }
- // }
- //}
- }
-
private static boolean acceptsRemoteSdk(DirectoryProjectGenerator generator) {
if (generator instanceof PyFrameworkProjectGenerator) {
return ((PyFrameworkProjectGenerator)generator).acceptsRemoteSdk();
diff --git a/python/ide/src/com/jetbrains/python/newProject/actions/GenerateProjectCallback.java b/python/ide/src/com/jetbrains/python/newProject/actions/GenerateProjectCallback.java
new file mode 100644
index 000000000000..2aa9a391512f
--- /dev/null
+++ b/python/ide/src/com/jetbrains/python/newProject/actions/GenerateProjectCallback.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jetbrains.python.newProject.actions;
+
+import com.intellij.ide.GeneralSettings;
+import com.intellij.ide.util.projectWizard.WebProjectTemplate;
+import com.intellij.internal.statistic.UsageTrigger;
+import com.intellij.internal.statistic.beans.ConvertUsagesUtil;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectManager;
+import com.intellij.openapi.projectRoots.ProjectJdkTable;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.projectRoots.SdkAdditionalData;
+import com.intellij.openapi.projectRoots.impl.SdkConfigurationUtil;
+import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectSdksModel;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.platform.DirectoryProjectGenerator;
+import com.intellij.platform.PlatformProjectOpenProcessor;
+import com.intellij.projectImport.ProjectOpenedCallback;
+import com.intellij.util.NullableConsumer;
+import com.jetbrains.python.configuration.PyConfigurableInterpreterList;
+import com.jetbrains.python.newProject.PyNewProjectSettings;
+import com.jetbrains.python.newProject.PythonProjectGenerator;
+import com.jetbrains.python.sdk.PyDetectedSdk;
+import com.jetbrains.python.sdk.PySdkService;
+import com.jetbrains.python.sdk.PythonSdkAdditionalData;
+import com.jetbrains.python.sdk.PythonSdkType;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.util.List;
+
+public class GenerateProjectCallback implements NullableConsumer<AbstractProjectSettingsStep> {
+ private static final Logger LOG = Logger.getInstance(GenerateProjectCallback.class);
+ @Nullable private final Runnable myRunnable;
+
+ public GenerateProjectCallback(@Nullable final Runnable runnable) {
+
+ myRunnable = runnable;
+ }
+
+ @Override
+ public void consume(@Nullable AbstractProjectSettingsStep settingsStep) {
+ if (myRunnable != null) {
+ myRunnable.run();
+ }
+ if (settingsStep == null) return;
+
+ Sdk sdk = settingsStep.getSdk();
+ final Project project = ProjectManager.getInstance().getDefaultProject();
+ final ProjectSdksModel model = PyConfigurableInterpreterList.getInstance(project).getModel();
+ if (sdk instanceof PyDetectedSdk) {
+ final String name = sdk.getName();
+ VirtualFile sdkHome = ApplicationManager.getApplication().runWriteAction(new Computable<VirtualFile>() {
+ @Override
+ public VirtualFile compute() {
+ return LocalFileSystem.getInstance().refreshAndFindFileByPath(name);
+ }
+ });
+ PySdkService.getInstance().solidifySdk(sdk);
+ sdk = SdkConfigurationUtil.setupSdk(ProjectJdkTable.getInstance().getAllJdks(), sdkHome, PythonSdkType.getInstance(), true, null,
+ null);
+ model.addSdk(sdk);
+ settingsStep.setSdk(sdk);
+ try {
+ model.apply();
+ }
+ catch (ConfigurationException exception) {
+ LOG.error("Error adding detected python interpreter " + exception.getMessage());
+ }
+ }
+ Project newProject = generateProject(project, settingsStep);
+ if (newProject != null) {
+ SdkConfigurationUtil.setDirectoryProjectSdk(newProject, sdk);
+ final List<Sdk> sdks = PythonSdkType.getAllSdks();
+ for (Sdk s : sdks) {
+ final SdkAdditionalData additionalData = s.getSdkAdditionalData();
+ if (additionalData instanceof PythonSdkAdditionalData) {
+ ((PythonSdkAdditionalData)additionalData).reassociateWithCreatedProject(newProject);
+ }
+ }
+ }
+ }
+
+ @Nullable
+ private Project generateProject(@NotNull final Project project, @NotNull final AbstractProjectSettingsStep settings) {
+ final DirectoryProjectGenerator generator = settings.getProjectGenerator();
+ final File location = new File(settings.getProjectLocation());
+ if (!location.exists() && !location.mkdirs()) {
+ Messages.showErrorDialog(project, "Cannot create directory '" + location + "'", "Create Project");
+ return null;
+ }
+
+ final VirtualFile baseDir = ApplicationManager.getApplication().runWriteAction(new Computable<VirtualFile>() {
+ public VirtualFile compute() {
+ return LocalFileSystem.getInstance().refreshAndFindFileByIoFile(location);
+ }
+ });
+ LOG.assertTrue(baseDir != null, "Couldn't find '" + location + "' in VFS");
+ baseDir.refresh(false, true);
+
+ if (baseDir.getChildren().length > 0) {
+ int rc = Messages.showYesNoDialog(project,
+ "The directory '" + location +
+ "' is not empty. Would you like to create a project from existing sources instead?",
+ "Create New Project", Messages.getQuestionIcon());
+ if (rc == Messages.YES) {
+ return PlatformProjectOpenProcessor.getInstance().doOpenProject(baseDir, null, false);
+ }
+ }
+
+ String generatorName = generator == null ? "empty" : ConvertUsagesUtil.ensureProperKey(generator.getName());
+ UsageTrigger.trigger("NewDirectoryProjectAction." + generatorName);
+
+ GeneralSettings.getInstance().setLastProjectCreationLocation(location.getParent());
+
+ return PlatformProjectOpenProcessor.doOpenProject(baseDir, null, false, -1, new ProjectOpenedCallback() {
+ @Override
+ public void projectOpened(Project project, Module module) {
+ if (generator != null) {
+ Object projectSettings = null;
+ if (generator instanceof PythonProjectGenerator) {
+ projectSettings = ((PythonProjectGenerator)generator).getProjectSettings();
+ }
+ else if (generator instanceof WebProjectTemplate) {
+ projectSettings = ((WebProjectTemplate)generator).getPeer().getSettings();
+ }
+ if (projectSettings instanceof PyNewProjectSettings) {
+ ((PyNewProjectSettings)projectSettings).setSdk(settings.getSdk());
+ ((PyNewProjectSettings)projectSettings).setInstallFramework(settings.installFramework());
+ }
+ //noinspection unchecked
+ generator.generateProject(project, baseDir, projectSettings, module);
+ }
+ }
+ }, false);
+ }
+}
diff --git a/python/ide/src/com/jetbrains/python/newProject/actions/PluginSpecificProjectsStep.java b/python/ide/src/com/jetbrains/python/newProject/actions/PluginSpecificProjectsStep.java
index a0c5f6e52fbf..ca0f3608a5d9 100644
--- a/python/ide/src/com/jetbrains/python/newProject/actions/PluginSpecificProjectsStep.java
+++ b/python/ide/src/com/jetbrains/python/newProject/actions/PluginSpecificProjectsStep.java
@@ -27,11 +27,11 @@ import java.util.List;
public class PluginSpecificProjectsStep extends DefaultActionGroup implements DumbAware {
public PluginSpecificProjectsStep(@NotNull final NullableConsumer<AbstractProjectSettingsStep> callback,
- @NotNull final List<DirectoryProjectGenerator> projectGenerators) {
+ @NotNull final List<DirectoryProjectGenerator> projectGenerators, boolean isWelcomeScreen) {
super("Plugin-specific", true);
getTemplatePresentation().setIcon(AllIcons.Nodes.PluginLogo);
for (DirectoryProjectGenerator generator : projectGenerators) {
- add(new ProjectSpecificAction(callback, generator));
+ add(new ProjectSpecificAction(callback, generator, isWelcomeScreen));
}
}
}
diff --git a/python/ide/src/com/jetbrains/python/newProject/actions/ProjectSpecificAction.java b/python/ide/src/com/jetbrains/python/newProject/actions/ProjectSpecificAction.java
index 4397a090b253..fbb65f0fbe9e 100644
--- a/python/ide/src/com/jetbrains/python/newProject/actions/ProjectSpecificAction.java
+++ b/python/ide/src/com/jetbrains/python/newProject/actions/ProjectSpecificAction.java
@@ -28,10 +28,16 @@ public class ProjectSpecificAction extends DefaultActionGroup implements DumbAwa
private final ProjectSpecificSettingsStep mySettings;
public ProjectSpecificAction(@NotNull final NullableConsumer<AbstractProjectSettingsStep> callback,
- @NotNull final DirectoryProjectGenerator projectGenerator) {
- super(projectGenerator.getName(), true);
+ @NotNull final DirectoryProjectGenerator projectGenerator, boolean isWelcomeScreen) {
+ this(callback, projectGenerator, projectGenerator.getName(), isWelcomeScreen);
+ }
+
+ public ProjectSpecificAction(@NotNull final NullableConsumer<AbstractProjectSettingsStep> callback,
+ @NotNull final DirectoryProjectGenerator projectGenerator,
+ @NotNull final String name, boolean isWelcomeScreen) {
+ super(name, true);
getTemplatePresentation().setIcon(projectGenerator.getLogo());
- mySettings = new ProjectSpecificSettingsStep(projectGenerator, callback);
+ mySettings = new ProjectSpecificSettingsStep(projectGenerator, callback, isWelcomeScreen);
add(mySettings);
}
diff --git a/python/ide/src/com/jetbrains/python/newProject/actions/ProjectSpecificSettingsStep.java b/python/ide/src/com/jetbrains/python/newProject/actions/ProjectSpecificSettingsStep.java
index 5e60601399bb..b85a06e0daa6 100644
--- a/python/ide/src/com/jetbrains/python/newProject/actions/ProjectSpecificSettingsStep.java
+++ b/python/ide/src/com/jetbrains/python/newProject/actions/ProjectSpecificSettingsStep.java
@@ -31,8 +31,8 @@ import javax.swing.*;
public class ProjectSpecificSettingsStep extends AbstractProjectSettingsStep implements DumbAware {
public ProjectSpecificSettingsStep(@NotNull final DirectoryProjectGenerator projectGenerator,
- @NotNull final NullableConsumer<AbstractProjectSettingsStep> callback) {
- super(projectGenerator, callback);
+ @NotNull final NullableConsumer<AbstractProjectSettingsStep> callback, boolean isWelcomeScreen) {
+ super(projectGenerator, callback, isWelcomeScreen);
}
@Override
diff --git a/python/ide/src/com/jetbrains/python/newProject/actions/PyCharmNewProjectStep.java b/python/ide/src/com/jetbrains/python/newProject/actions/PyCharmNewProjectStep.java
index 4f9f1074df68..0628c6d829c1 100644
--- a/python/ide/src/com/jetbrains/python/newProject/actions/PyCharmNewProjectStep.java
+++ b/python/ide/src/com/jetbrains/python/newProject/actions/PyCharmNewProjectStep.java
@@ -16,153 +16,33 @@
package com.jetbrains.python.newProject.actions;
import com.google.common.collect.Lists;
-import com.intellij.ide.GeneralSettings;
-import com.intellij.ide.util.projectWizard.WebProjectTemplate;
-import com.intellij.internal.statistic.UsageTrigger;
-import com.intellij.internal.statistic.beans.ConvertUsagesUtil;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
-import com.intellij.openapi.module.Module;
-import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.DumbAware;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.project.ProjectManager;
-import com.intellij.openapi.projectRoots.ProjectJdkTable;
-import com.intellij.openapi.projectRoots.Sdk;
-import com.intellij.openapi.projectRoots.SdkAdditionalData;
-import com.intellij.openapi.projectRoots.impl.SdkConfigurationUtil;
-import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectSdksModel;
-import com.intellij.openapi.ui.Messages;
-import com.intellij.openapi.util.Computable;
-import com.intellij.openapi.vfs.LocalFileSystem;
-import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.platform.DirectoryProjectGenerator;
-import com.intellij.platform.PlatformProjectOpenProcessor;
-import com.intellij.projectImport.ProjectOpenedCallback;
import com.intellij.util.NullableConsumer;
-import com.jetbrains.python.configuration.PyConfigurableInterpreterList;
import com.jetbrains.python.newProject.PyFrameworkProjectGenerator;
-import com.jetbrains.python.newProject.PyNewProjectSettings;
import com.jetbrains.python.newProject.PythonBaseProjectGenerator;
import com.jetbrains.python.newProject.PythonProjectGenerator;
-import com.jetbrains.python.sdk.PyDetectedSdk;
-import com.jetbrains.python.sdk.PySdkService;
-import com.jetbrains.python.sdk.PythonSdkAdditionalData;
-import com.jetbrains.python.sdk.PythonSdkType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.io.File;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
public class PyCharmNewProjectStep extends DefaultActionGroup implements DumbAware {
- private static final Logger LOG = Logger.getInstance(PyCharmNewProjectStep.class);
public PyCharmNewProjectStep(@NotNull final String name, @Nullable final Runnable runnable) {
- super(name, true);
-
- final NullableConsumer<AbstractProjectSettingsStep> callback = new NullableConsumer<AbstractProjectSettingsStep>() {
- @Override
- public void consume(@Nullable AbstractProjectSettingsStep settingsStep) {
- if (runnable != null)
- runnable.run();
- if (settingsStep == null) return;
-
- Sdk sdk = settingsStep.getSdk();
- final Project project = ProjectManager.getInstance().getDefaultProject();
- final ProjectSdksModel model = PyConfigurableInterpreterList.getInstance(project).getModel();
- if (sdk instanceof PyDetectedSdk) {
- final String name = sdk.getName();
- VirtualFile sdkHome = ApplicationManager.getApplication().runWriteAction(new Computable<VirtualFile>() {
- @Override
- public VirtualFile compute() {
- return LocalFileSystem.getInstance().refreshAndFindFileByPath(name);
- }
- });
- PySdkService.getInstance().solidifySdk(sdk);
- sdk = SdkConfigurationUtil.setupSdk(ProjectJdkTable.getInstance().getAllJdks(), sdkHome, PythonSdkType.getInstance(), true, null,
- null);
- model.addSdk(sdk);
- settingsStep.setSdk(sdk);
- try {
- model.apply();
- }
- catch (ConfigurationException exception) {
- LOG.error("Error adding detected python interpreter " + exception.getMessage());
- }
- }
- Project newProject = generateProject(project, settingsStep);
- if (newProject != null) {
- SdkConfigurationUtil.setDirectoryProjectSdk(newProject, sdk);
- final List<Sdk> sdks = PythonSdkType.getAllSdks();
- for (Sdk s : sdks) {
- final SdkAdditionalData additionalData = s.getSdkAdditionalData();
- if (additionalData instanceof PythonSdkAdditionalData) {
- ((PythonSdkAdditionalData)additionalData).reassociateWithCreatedProject(newProject);
- }
- }
- }
- }
-
- @Nullable
- private Project generateProject(@NotNull final Project project, @NotNull final AbstractProjectSettingsStep settings) {
- final DirectoryProjectGenerator generator = settings.getProjectGenerator();
- final File location = new File(settings.getProjectLocation());
- if (!location.exists() && !location.mkdirs()) {
- Messages.showErrorDialog(project, "Cannot create directory '" + location + "'", "Create Project");
- return null;
- }
-
- final VirtualFile baseDir = ApplicationManager.getApplication().runWriteAction(new Computable<VirtualFile>() {
- public VirtualFile compute() {
- return LocalFileSystem.getInstance().refreshAndFindFileByIoFile(location);
- }
- });
- LOG.assertTrue(baseDir != null, "Couldn't find '" + location + "' in VFS");
- baseDir.refresh(false, true);
-
- if (baseDir.getChildren().length > 0) {
- int rc = Messages.showYesNoDialog(project,
- "The directory '" + location +
- "' is not empty. Would you like to create a project from existing sources instead?",
- "Create New Project", Messages.getQuestionIcon());
- if (rc == Messages.YES) {
- return PlatformProjectOpenProcessor.getInstance().doOpenProject(baseDir, null, false);
- }
- }
+ this(name, runnable, false);
+ }
- String generatorName = generator == null ? "empty" : ConvertUsagesUtil.ensureProperKey(generator.getName());
- UsageTrigger.trigger("NewDirectoryProjectAction." + generatorName);
+ public PyCharmNewProjectStep(@NotNull final String name, @Nullable final Runnable runnable, boolean isWelcomeScreen) {
+ super(name, true);
- GeneralSettings.getInstance().setLastProjectCreationLocation(location.getParent());
+ final NullableConsumer<AbstractProjectSettingsStep> callback = new GenerateProjectCallback(runnable);
- return PlatformProjectOpenProcessor.doOpenProject(baseDir, null, false, -1, new ProjectOpenedCallback() {
- @Override
- public void projectOpened(Project project, Module module) {
- if (generator != null) {
- Object projectSettings = null;
- if (generator instanceof PythonProjectGenerator)
- projectSettings = ((PythonProjectGenerator)generator).getProjectSettings();
- else if (generator instanceof WebProjectTemplate) {
- projectSettings = ((WebProjectTemplate)generator).getPeer().getSettings();
- }
- if (projectSettings instanceof PyNewProjectSettings) {
- ((PyNewProjectSettings)projectSettings).setSdk(settings.getSdk());
- ((PyNewProjectSettings)projectSettings).setInstallFramework(settings.installFramework());
- }
- //noinspection unchecked
- generator.generateProject(project, baseDir, projectSettings, module);
- }
- }
- }, false);
- }
- };
-
- final ProjectSpecificAction action = new ProjectSpecificAction(callback, new PythonBaseProjectGenerator());
+ final ProjectSpecificAction action = new ProjectSpecificAction(callback, new PythonBaseProjectGenerator(), isWelcomeScreen);
add(action);
final DirectoryProjectGenerator[] generators = Extensions.getExtensions(DirectoryProjectGenerator.EP_NAME);
@@ -181,19 +61,17 @@ public class PyCharmNewProjectStep extends DefaultActionGroup implements DumbAwa
List<DirectoryProjectGenerator> pluginSpecificGenerators = Lists.newArrayList();
for (DirectoryProjectGenerator generator : generators) {
if (generator instanceof PythonProjectGenerator)
- add(new ProjectSpecificAction(callback, generator));
+ add(new ProjectSpecificAction(callback, generator, isWelcomeScreen));
else
pluginSpecificGenerators.add(generator);
}
if (!pluginSpecificGenerators.isEmpty()) {
- add(new PluginSpecificProjectsStep(callback, pluginSpecificGenerators));
+ add(new PluginSpecificProjectsStep(callback, pluginSpecificGenerators, isWelcomeScreen));
}
}
public PyCharmNewProjectStep() {
- this("Select Project Type", null);
-
+ this("Select Project Type", null, true);
}
-
}
diff --git a/python/openapi/src/com/jetbrains/python/run/PythonRunConfigurationParams.java b/python/openapi/src/com/jetbrains/python/run/PythonRunConfigurationParams.java
index 80ca3ce1a4ef..adb1c31e6134 100644
--- a/python/openapi/src/com/jetbrains/python/run/PythonRunConfigurationParams.java
+++ b/python/openapi/src/com/jetbrains/python/run/PythonRunConfigurationParams.java
@@ -28,5 +28,8 @@ public interface PythonRunConfigurationParams {
String getScriptParameters();
void setScriptParameters(String scriptParameters);
+
+ boolean showCommandLineAfterwards();
+ void setShowCommandLineAfterwards(boolean showCommandLineAfterwards);
}
diff --git a/python/pluginSrc/com/jetbrains/python/module/PythonModuleConfigurationEditorProvider.java b/python/pluginSrc/com/jetbrains/python/module/PythonModuleConfigurationEditorProvider.java
index 01203480eae4..50b79c717112 100644
--- a/python/pluginSrc/com/jetbrains/python/module/PythonModuleConfigurationEditorProvider.java
+++ b/python/pluginSrc/com/jetbrains/python/module/PythonModuleConfigurationEditorProvider.java
@@ -15,15 +15,16 @@
*/
package com.jetbrains.python.module;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleConfigurationEditor;
import com.intellij.openapi.module.ModuleType;
+import com.intellij.openapi.roots.ui.configuration.DefaultModuleConfigurationEditorFactory;
import com.intellij.openapi.roots.ui.configuration.ModuleConfigurationEditorProvider;
import com.intellij.openapi.roots.ui.configuration.ModuleConfigurationState;
-import com.intellij.openapi.roots.ui.configuration.DefaultModuleConfigurationEditorFactory;
-import com.intellij.openapi.module.ModuleConfigurationEditor;
-import com.intellij.openapi.module.Module;
+import org.jetbrains.jps.model.java.JavaSourceRootType;
-import java.util.List;
import java.util.ArrayList;
+import java.util.List;
/**
* @author yole
@@ -34,7 +35,7 @@ public class PythonModuleConfigurationEditorProvider implements ModuleConfigurat
if (!(ModuleType.get(module) instanceof PythonModuleType)) return ModuleConfigurationEditor.EMPTY;
final DefaultModuleConfigurationEditorFactory editorFactory = DefaultModuleConfigurationEditorFactory.getInstance();
final List<ModuleConfigurationEditor> editors = new ArrayList<ModuleConfigurationEditor>();
- editors.add(editorFactory.createModuleContentRootsEditor(state));
+ editors.add(new PyContentEntriesEditor(module, state, JavaSourceRootType.SOURCE));
editors.add(editorFactory.createClasspathEditor(state));
return editors.toArray(new ModuleConfigurationEditor[editors.size()]);
}
diff --git a/python/psi-api/src/com/jetbrains/python/psi/PyAnnotation.java b/python/psi-api/src/com/jetbrains/python/psi/PyAnnotation.java
index a6182fb2eb65..71dc7286d84b 100644
--- a/python/psi-api/src/com/jetbrains/python/psi/PyAnnotation.java
+++ b/python/psi-api/src/com/jetbrains/python/psi/PyAnnotation.java
@@ -22,9 +22,7 @@ import org.jetbrains.annotations.Nullable;
/**
* @author yole
*/
-public interface PyAnnotation extends PyElement, StubBasedPsiElement<PyAnnotationStub> {
- PyExpression getValue();
-
+public interface PyAnnotation extends PyTypedElement, StubBasedPsiElement<PyAnnotationStub> {
@Nullable
- PyClass resolveToClass();
+ PyExpression getValue();
}
diff --git a/python/psi-api/src/com/jetbrains/python/psi/PyTargetExpression.java b/python/psi-api/src/com/jetbrains/python/psi/PyTargetExpression.java
index 0b67d85d3dc3..399b8f8a7bac 100644
--- a/python/psi-api/src/com/jetbrains/python/psi/PyTargetExpression.java
+++ b/python/psi-api/src/com/jetbrains/python/psi/PyTargetExpression.java
@@ -28,7 +28,7 @@ import org.jetbrains.annotations.Nullable;
* @author yole
*/
public interface PyTargetExpression extends PyQualifiedExpression, PsiNamedElement, PsiNameIdentifierOwner, PyDocStringOwner,
- StubBasedPsiElement<PyTargetExpressionStub> {
+ PyQualifiedNameOwner, StubBasedPsiElement<PyTargetExpressionStub> {
PyTargetExpression[] EMPTY_ARRAY = new PyTargetExpression[0];
/**
diff --git a/python/pydevSrc/com/jetbrains/python/debugger/IPyDebugProcess.java b/python/pydevSrc/com/jetbrains/python/debugger/IPyDebugProcess.java
index 1714f711cbcf..ab6ccfab0bc6 100644
--- a/python/pydevSrc/com/jetbrains/python/debugger/IPyDebugProcess.java
+++ b/python/pydevSrc/com/jetbrains/python/debugger/IPyDebugProcess.java
@@ -23,4 +23,6 @@ public interface IPyDebugProcess extends PyFrameAccessor {
int handleDebugPort(int port) throws IOException;
void recordSignature(PySignature signature);
+
+ void showConsole(PyThreadInfo thread);
}
diff --git a/python/pydevSrc/com/jetbrains/python/debugger/pydev/AbstractCommand.java b/python/pydevSrc/com/jetbrains/python/debugger/pydev/AbstractCommand.java
index efa86d495d95..15bb76b6c3d1 100644
--- a/python/pydevSrc/com/jetbrains/python/debugger/pydev/AbstractCommand.java
+++ b/python/pydevSrc/com/jetbrains/python/debugger/pydev/AbstractCommand.java
@@ -33,6 +33,8 @@ public abstract class AbstractCommand<T> {
public static final int SMART_STEP_INTO = 128;
public static final int EXIT = 129;
public static final int CALL_SIGNATURE_TRACE = 130;
+ public static final int SHOW_CONSOLE = 142;
+ public static final int ERROR = 901;
public static final int VERSION = 501;
public static final String NEW_LINE_CHAR = "@_@NEW_LINE_CHAR@_@";
@@ -180,6 +182,10 @@ public abstract class AbstractCommand<T> {
return command == EXIT;
}
+ public static boolean isErrorEvent(int command) {
+ return command == ERROR;
+ }
+
protected static class Payload {
private final StringBuilder myBuilder = new StringBuilder();
private static final char SEPARATOR = '\t';
diff --git a/python/pydevSrc/com/jetbrains/python/debugger/pydev/AbstractThreadCommand.java b/python/pydevSrc/com/jetbrains/python/debugger/pydev/AbstractThreadCommand.java
index 690d893bb274..b235b78bbf96 100644
--- a/python/pydevSrc/com/jetbrains/python/debugger/pydev/AbstractThreadCommand.java
+++ b/python/pydevSrc/com/jetbrains/python/debugger/pydev/AbstractThreadCommand.java
@@ -18,11 +18,11 @@ public abstract class AbstractThreadCommand<T> extends AbstractCommand<T> {
return command == CREATE_THREAD ||
command == KILL_THREAD ||
command == RESUME_THREAD ||
- command == SUSPEND_THREAD;
+ command == SUSPEND_THREAD ||
+ command == SHOW_CONSOLE;
}
public String getThreadId() {
return myThreadId;
}
-
}
diff --git a/python/pydevSrc/com/jetbrains/python/debugger/pydev/RemoteDebugger.java b/python/pydevSrc/com/jetbrains/python/debugger/pydev/RemoteDebugger.java
index 5f962b259142..df33148edb10 100644
--- a/python/pydevSrc/com/jetbrains/python/debugger/pydev/RemoteDebugger.java
+++ b/python/pydevSrc/com/jetbrains/python/debugger/pydev/RemoteDebugger.java
@@ -396,7 +396,8 @@ public class RemoteDebugger implements ProcessDebugger {
if (type != null) {
final RemoveBreakpointCommand command = new RemoveBreakpointCommand(this, type, file, line);
execute(command); // remove temp. breakpoint
- } else {
+ }
+ else {
LOG.error("Temp breakpoint not found for " + file + ":" + line);
}
}
@@ -474,6 +475,9 @@ public class RemoteDebugger implements ProcessDebugger {
else if (AbstractCommand.isCallSignatureTrace(frame.getCommand())) {
recordCallSignature(ProtocolParser.parseCallSignature(frame.getPayload()));
}
+ else if (AbstractCommand.isErrorEvent(frame.getCommand())) {
+ LOG.error("Error response from debugger: " + frame.getPayload());
+ }
else {
placeResponse(frame.getSequence(), frame);
}
@@ -530,6 +534,19 @@ public class RemoteDebugger implements ProcessDebugger {
}
break;
}
+ case AbstractCommand.SHOW_CONSOLE: {
+ final PyThreadInfo event = parseThreadEvent(frame);
+ PyThreadInfo thread = myThreads.get(event.getId());
+ if (thread == null) {
+ myThreads.put(event.getId(), event);
+ thread = event;
+ }
+ thread.updateState(PyThreadInfo.State.SUSPENDED, event.getFrames());
+ thread.setStopReason(event.getStopReason());
+ thread.setMessage(event.getMessage());
+ myDebugProcess.showConsole(thread);
+ break;
+ }
}
}
diff --git a/python/rest/gen/com/jetbrains/rest/lexer/_RestFlexLexer.java b/python/rest/gen/com/jetbrains/rest/lexer/_RestFlexLexer.java
index 8fa7e54aa9ae..f79403df4acb 100644
--- a/python/rest/gen/com/jetbrains/rest/lexer/_RestFlexLexer.java
+++ b/python/rest/gen/com/jetbrains/rest/lexer/_RestFlexLexer.java
@@ -1,4 +1,4 @@
-/* The following code was generated by JFlex 1.4.3 on 4/26/14 12:40 PM */
+/* The following code was generated by JFlex 1.4.3 on 8/25/14 1:56 PM */
package com.jetbrains.rest.lexer;
@@ -11,8 +11,8 @@ import com.jetbrains.rest.RestTokenTypes;
/**
* This class is a scanner generated by
* <a href="http://www.jflex.de/">JFlex</a> 1.4.3
- * on 4/26/14 12:40 PM from the specification file
- * <tt>/Users/ignatov/src/ultimate/tools/lexer/../../community/python/rest/src/com/jetbrains/rest/lexer/rest.flex</tt>
+ * on 8/25/14 1:56 PM from the specification file
+ * <tt>/home/ktisha/IDEA/tools/lexer/../../community/python/rest/src/com/jetbrains/rest/lexer/rest.flex</tt>
*/
public class _RestFlexLexer implements FlexLexer, RestTokenTypes {
/** initial size of the lookahead buffer */
@@ -1293,7 +1293,7 @@ public class _RestFlexLexer implements FlexLexer, RestTokenTypes {
"\1\232\21\42\1\0\1\33\1\0\1\42\1\33\1\42"+
"\7\0\1\164\1\0\1\165\1\33\4\0\1\33\6\0"+
"\4\42\1\233\22\42\1\0\1\33\1\0\1\42\1\33"+
- "\1\42\12\0\1\33\4\0\1\33\6\0\27\56\1\0"+
+ "\1\42\12\0\1\33\4\0\1\56\6\0\27\56\1\0"+
"\1\234\1\0\1\56\1\33\1\56\12\0\1\33\4\0"+
"\1\33\1\235\1\0\1\236\3\0\27\237\1\0\1\33"+
"\1\0\1\237\1\33\1\240\1\241\2\0\1\242\1\243"+
diff --git a/python/rest/src/com/jetbrains/rest/lexer/rest.flex b/python/rest/src/com/jetbrains/rest/lexer/rest.flex
index ee0b33108d4e..354779fcc48a 100644
--- a/python/rest/src/com/jetbrains/rest/lexer/rest.flex
+++ b/python/rest/src/com/jetbrains/rest/lexer/rest.flex
@@ -170,7 +170,7 @@ ANY= .|\n
{USUAL_TYPES}"::" { yybegin(IN_VALUE); return DIRECTIVE;}
{HIGHLIGHT_TYPES}"::" { yybegin(IN_HIGHLIGHT); return CUSTOM_DIRECTIVE;}
[0-9A-Za-z\-:]*"::" { yybegin(IN_VALUE); return CUSTOM_DIRECTIVE;}
-"|"[0-9A-Za-z]*"|" { return SUBSTITUTION;}
+"|"[0-9A-Za-z_]*"|" { return SUBSTITUTION;}
[0-9A-Za-z_\[|.]* { yybegin(IN_COMMENT); return COMMENT;}
{CRLF}{2} { yybegin(INIT); return COMMENT;}
{SPACE}*{CRLF}+ { return WHITESPACE; }
diff --git a/python/rest/src/com/jetbrains/rest/parsing/RestParser.java b/python/rest/src/com/jetbrains/rest/parsing/RestParser.java
index 791d94d02a75..1df9fc1eca0d 100644
--- a/python/rest/src/com/jetbrains/rest/parsing/RestParser.java
+++ b/python/rest/src/com/jetbrains/rest/parsing/RestParser.java
@@ -95,7 +95,7 @@ public class RestParser implements PsiParser {
listMarker.drop();
}
- private void parseMarkup(PsiBuilder builder) {
+ private static void parseMarkup(PsiBuilder builder) {
PsiBuilder.Marker marker = builder.mark();
IElementType type = builder.getTokenType();
if (type == RestTokenTypes.SUBSTITUTION) {
@@ -131,19 +131,19 @@ public class RestParser implements PsiParser {
}
}
- private void gotoNextWhiteSpaces(PsiBuilder builder) {
+ private static void gotoNextWhiteSpaces(PsiBuilder builder) {
while(!"\n".equals(builder.getTokenText()) && !(builder.getTokenType() == RestTokenTypes.TITLE) && !builder.eof() && (builder.getTokenType() != null)) {
builder.advanceLexer();
}
}
- private void skipBlankLines(PsiBuilder builder) {
+ private static void skipBlankLines(PsiBuilder builder) {
while("\n".equals(builder.getTokenText()) && !builder.eof() && (builder.getTokenType() != null)) {
builder.advanceLexer();
}
}
- private void parseDirective(PsiBuilder builder, String white, PsiBuilder.Marker marker) {
+ private static void parseDirective(PsiBuilder builder, String white, PsiBuilder.Marker marker) {
gotoNextWhiteSpaces(builder);
if (builder.getTokenType() != RestTokenTypes.WHITESPACE) {
builder.advanceLexer();
@@ -157,7 +157,6 @@ public class RestParser implements PsiParser {
}
else {
marker.done(RestElementTypes.DIRECTIVE_BLOCK);
- return;
}
}
}
diff --git a/python/src/META-INF/pycharm-core.xml b/python/src/META-INF/pycharm-core.xml
index 4732ad084b32..a9f7824b5340 100644
--- a/python/src/META-INF/pycharm-core.xml
+++ b/python/src/META-INF/pycharm-core.xml
@@ -8,6 +8,9 @@
</xi:include>
<xi:include href="/META-INF/RegExpPlugin.xml" xpointer="xpointer(/idea-plugin/*)"/>
<xi:include href="/META-INF/SpellCheckerPlugin.xml" xpointer="xpointer(/idea-plugin/*)"/>
+ <xi:include href="/META-INF/RemoteServers.xml" xpointer="xpointer(/idea-plugin/*)">
+ <xi:fallback/>
+ </xi:include>
<application-components>
<component>
diff --git a/python/src/META-INF/python-core.xml b/python/src/META-INF/python-core.xml
index 292237aac6ac..7adbc46c189c 100644
--- a/python/src/META-INF/python-core.xml
+++ b/python/src/META-INF/python-core.xml
@@ -589,6 +589,9 @@
<pyClassMembersProvider implementation="com.jetbrains.python.codeInsight.userSkeletons.PyUserSkeletonsClassMembersProvider"/>
<typeProvider implementation="com.jetbrains.python.codeInsight.userSkeletons.PyUserSkeletonsTypeProvider"/>
+ <!-- typing -->
+ <typeProvider implementation="com.jetbrains.python.codeInsight.PyTypingTypeProvider"/>
+
<typeProvider implementation="com.jetbrains.python.debugger.PyCallSignatureTypeProvider"/>
<pyReferenceResolveProvider implementation="com.jetbrains.python.psi.resolve.PythonBuiltinReferenceResolveProvider"/>
diff --git a/python/src/com/jetbrains/python/codeInsight/PyTypingTypeProvider.java b/python/src/com/jetbrains/python/codeInsight/PyTypingTypeProvider.java
new file mode 100644
index 000000000000..f03befac6c14
--- /dev/null
+++ b/python/src/com/jetbrains/python/codeInsight/PyTypingTypeProvider.java
@@ -0,0 +1,375 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jetbrains.python.codeInsight;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiPolyVariantReference;
+import com.intellij.psi.util.QualifiedName;
+import com.jetbrains.python.PyNames;
+import com.jetbrains.python.psi.*;
+import com.jetbrains.python.psi.impl.PyExpressionCodeFragmentImpl;
+import com.jetbrains.python.psi.impl.PyPsiUtils;
+import com.jetbrains.python.psi.resolve.PyResolveContext;
+import com.jetbrains.python.psi.types.*;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author vlan
+ */
+public class PyTypingTypeProvider extends PyTypeProviderBase {
+ private static ImmutableMap<String, String> BUILTIN_COLLECTIONS = ImmutableMap.<String, String>builder()
+ .put("typing.List", "list")
+ .put("typing.Dict", "dict")
+ .put("typing.Set", PyNames.SET)
+ .put("typing.Tuple", PyNames.TUPLE)
+ .build();
+
+ private static ImmutableSet<String> GENERIC_CLASSES = ImmutableSet.<String>builder()
+ .add("typing.Generic")
+ .add("typing.AbstractGeneric")
+ .add("typing.Protocol")
+ .build();
+
+ public PyType getParameterType(@NotNull PyNamedParameter param, @NotNull PyFunction func, @NotNull TypeEvalContext context) {
+ final PyAnnotation annotation = param.getAnnotation();
+ if (annotation != null) {
+ // XXX: Requires switching from stub to AST
+ final PyExpression value = annotation.getValue();
+ if (value != null) {
+ return getTypingType(value, context);
+ }
+ }
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public PyType getReturnType(@NotNull Callable callable, @NotNull TypeEvalContext context) {
+ if (callable instanceof PyFunction) {
+ final PyFunction function = (PyFunction)callable;
+ final PyAnnotation annotation = function.getAnnotation();
+ if (annotation != null) {
+ // XXX: Requires switching from stub to AST
+ final PyExpression value = annotation.getValue();
+ if (value != null) {
+ return getTypingType(value, context);
+ }
+ }
+ final PyType constructorType = getGenericConstructorType(function, context);
+ if (constructorType != null) {
+ return constructorType;
+ }
+ }
+ return null;
+ }
+
+ @Nullable
+ private static PyType getGenericConstructorType(@NotNull PyFunction function, @NotNull TypeEvalContext context) {
+ if (PyUtil.isInit(function)) {
+ final PyClass cls = function.getContainingClass();
+ if (cls != null) {
+ final List<PyGenericType> genericTypes = collectGenericTypes(cls, context);
+
+ final PyType elementType;
+ if (genericTypes.size() == 1) {
+ elementType = genericTypes.get(0);
+ }
+ else if (genericTypes.size() > 1) {
+ elementType = PyTupleType.create(cls, genericTypes.toArray(new PyType[genericTypes.size()]));
+ }
+ else {
+ elementType = null;
+ }
+
+ if (elementType != null) {
+ return new PyCollectionTypeImpl(cls, false, elementType);
+ }
+ }
+ }
+ return null;
+ }
+
+ @NotNull
+ private static List<PyGenericType> collectGenericTypes(@NotNull PyClass cls, @NotNull TypeEvalContext context) {
+ boolean isGeneric = false;
+ for (PyClass ancestor : cls.getAncestorClasses(context)) {
+ if (GENERIC_CLASSES.contains(ancestor.getQualifiedName())) {
+ isGeneric = true;
+ break;
+ }
+ }
+ if (isGeneric) {
+ final ArrayList<PyGenericType> results = new ArrayList<PyGenericType>();
+ // XXX: Requires switching from stub to AST
+ for (PyExpression expr : cls.getSuperClassExpressions()) {
+ if (expr instanceof PySubscriptionExpression) {
+ final PyExpression indexExpr = ((PySubscriptionExpression)expr).getIndexExpression();
+ if (indexExpr != null) {
+ final PyGenericType genericType = getGenericType(indexExpr, context);
+ if (genericType != null) {
+ results.add(genericType);
+ }
+ }
+ }
+ }
+ return results;
+ }
+ return Collections.emptyList();
+ }
+
+ @Nullable
+ private static PyType getTypingType(@NotNull PyExpression expression, @NotNull TypeEvalContext context) {
+ final PyType unionType = getUnionType(expression, context);
+ if (unionType != null) {
+ return unionType;
+ }
+ final PyType parameterizedType = getParameterizedType(expression, context);
+ if (parameterizedType != null) {
+ return parameterizedType;
+ }
+ final PyType builtinCollection = getBuiltinCollection(expression, context);
+ if (builtinCollection != null) {
+ return builtinCollection;
+ }
+ final PyType genericType = getGenericType(expression, context);
+ if (genericType != null) {
+ return genericType;
+ }
+ final PyType functionType = getFunctionType(expression, context);
+ if (functionType != null) {
+ return functionType;
+ }
+ final PyType stringBasedType = getStringBasedType(expression, context);
+ if (stringBasedType != null) {
+ return stringBasedType;
+ }
+ return null;
+ }
+
+ @Nullable
+ private static PyType getStringBasedType(@NotNull PyExpression expression, @NotNull TypeEvalContext context) {
+ if (expression instanceof PyStringLiteralExpression) {
+ // XXX: Requires switching from stub to AST
+ final String contents = ((PyStringLiteralExpression)expression).getStringValue();
+ final Project project = expression.getProject();
+ final PyExpressionCodeFragmentImpl codeFragment = new PyExpressionCodeFragmentImpl(project, "dummy.py", contents, false);
+ codeFragment.setContext(expression.getContainingFile());
+ final PsiElement element = codeFragment.getFirstChild();
+ if (element instanceof PyExpressionStatement) {
+ final PyExpression dummyExpr = ((PyExpressionStatement)element).getExpression();
+ return getType(dummyExpr, context);
+ }
+ }
+ return null;
+ }
+
+ @Nullable
+ private static PyType getFunctionType(@NotNull PyExpression expression, @NotNull TypeEvalContext context) {
+ if (expression instanceof PySubscriptionExpression) {
+ final PySubscriptionExpression subscriptionExpr = (PySubscriptionExpression)expression;
+ final PyExpression operand = subscriptionExpr.getOperand();
+ final String operandName = resolveToQualifiedName(operand, context);
+ if ("typing.Function".equals(operandName)) {
+ final PyExpression indexExpr = subscriptionExpr.getIndexExpression();
+ if (indexExpr instanceof PyTupleExpression) {
+ final PyTupleExpression tupleExpr = (PyTupleExpression)indexExpr;
+ final PyExpression[] elements = tupleExpr.getElements();
+ if (elements.length == 2) {
+ final PyExpression parametersExpr = elements[0];
+ if (parametersExpr instanceof PyListLiteralExpression) {
+ final List<PyCallableParameter> parameters = new ArrayList<PyCallableParameter>();
+ final PyListLiteralExpression listExpr = (PyListLiteralExpression)parametersExpr;
+ for (PyExpression argExpr : listExpr.getElements()) {
+ parameters.add(new PyCallableParameterImpl(null, getType(argExpr, context)));
+ }
+ final PyExpression returnTypeExpr = elements[1];
+ final PyType returnType = getType(returnTypeExpr, context);
+ return new PyCallableTypeImpl(parameters, returnType);
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ @Nullable
+ private static PyType getUnionType(@NotNull PyExpression expression, @NotNull TypeEvalContext context) {
+ if (expression instanceof PySubscriptionExpression) {
+ final PySubscriptionExpression subscriptionExpr = (PySubscriptionExpression)expression;
+ final PyExpression operand = subscriptionExpr.getOperand();
+ final String operandName = resolveToQualifiedName(operand, context);
+ if ("typing.Union".equals(operandName)) {
+ return PyUnionType.union(getIndexTypes(subscriptionExpr, context));
+ }
+ }
+ return null;
+ }
+
+ @Nullable
+ private static PyGenericType getGenericType(@NotNull PyExpression expression, @NotNull TypeEvalContext context) {
+ final PsiElement resolved = resolve(expression, context);
+ if (resolved instanceof PyTargetExpression) {
+ final PyTargetExpression targetExpr = (PyTargetExpression)resolved;
+ final QualifiedName calleeName = targetExpr.getCalleeName();
+ if (calleeName != null && "typevar".equals(calleeName.toString())) {
+ // XXX: Requires switching from stub to AST
+ final PyExpression assigned = targetExpr.findAssignedValue();
+ if (assigned instanceof PyCallExpression) {
+ final PyCallExpression assignedCall = (PyCallExpression)assigned;
+ final PyExpression callee = assignedCall.getCallee();
+ if (callee != null) {
+ final String calleeQName = resolveToQualifiedName(callee, context);
+ if ("typing.typevar".equals(calleeQName)) {
+ final PyExpression[] arguments = assignedCall.getArguments();
+ if (arguments.length > 0) {
+ final PyExpression firstArgument = arguments[0];
+ if (firstArgument instanceof PyStringLiteralExpression) {
+ final String name = ((PyStringLiteralExpression)firstArgument).getStringValue();
+ if (name != null) {
+ return new PyGenericType(name, getGenericTypeBound(arguments, context));
+ }
+ }
+ }
+ }
+
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ @Nullable
+ private static PyType getGenericTypeBound(@NotNull PyExpression[] typeVarArguments, @NotNull TypeEvalContext context) {
+ final List<PyType> types = new ArrayList<PyType>();
+ if (typeVarArguments.length > 1) {
+ final PyExpression secondArgument = typeVarArguments[1];
+ if (secondArgument instanceof PyKeywordArgument) {
+ final PyKeywordArgument valuesArgument = (PyKeywordArgument)secondArgument;
+ final PyExpression valueExpr = PyPsiUtils.flattenParens(valuesArgument.getValueExpression());
+ if (valueExpr instanceof PyTupleExpression) {
+ final PyTupleExpression tupleExpr = (PyTupleExpression)valueExpr;
+ for (PyExpression expr : tupleExpr.getElements()) {
+ types.add(getType(expr, context));
+ }
+ }
+ }
+ }
+ return PyUnionType.union(types);
+ }
+
+ @NotNull
+ private static List<PyType> getIndexTypes(@NotNull PySubscriptionExpression expression, @NotNull TypeEvalContext context) {
+ final List<PyType> types = new ArrayList<PyType>();
+ final PyExpression indexExpr = expression.getIndexExpression();
+ if (indexExpr instanceof PyTupleExpression) {
+ final PyTupleExpression tupleExpr = (PyTupleExpression)indexExpr;
+ for (PyExpression expr : tupleExpr.getElements()) {
+ types.add(getType(expr, context));
+ }
+ }
+ return types;
+ }
+
+ @Nullable
+ private static PyType getParameterizedType(@NotNull PyExpression expression, @NotNull TypeEvalContext context) {
+ if (expression instanceof PySubscriptionExpression) {
+ final PySubscriptionExpression subscriptionExpr = (PySubscriptionExpression)expression;
+ final PyExpression operand = subscriptionExpr.getOperand();
+ final PyExpression indexExpr = subscriptionExpr.getIndexExpression();
+ final PyType operandType = getType(operand, context);
+ if (operandType instanceof PyClassType) {
+ final PyClass cls = ((PyClassType)operandType).getPyClass();
+ if (PyNames.TUPLE.equals(cls.getQualifiedName())) {
+ final List<PyType> indexTypes = getIndexTypes(subscriptionExpr, context);
+ return PyTupleType.create(expression, indexTypes.toArray(new PyType[indexTypes.size()]));
+ }
+ else if (indexExpr != null) {
+ final PyType indexType = context.getType(indexExpr);
+ return new PyCollectionTypeImpl(cls, false, indexType);
+ }
+ }
+ }
+ return null;
+ }
+
+ @Nullable
+ private static PyType getBuiltinCollection(@NotNull PyExpression expression, @NotNull TypeEvalContext context) {
+ final String collectionName = resolveToQualifiedName(expression, context);
+ final String builtinName = BUILTIN_COLLECTIONS.get(collectionName);
+ return builtinName != null ? PyTypeParser.getTypeByName(expression, builtinName) : null;
+ }
+
+ @Nullable
+ private static PyType getType(@NotNull PyExpression expression, @NotNull TypeEvalContext context) {
+ // It is possible to replace PyAnnotation.getType() with this implementation
+ final PyType typingType = getTypingType(expression, context);
+ if (typingType != null) {
+ return typingType;
+ }
+ final PyType type = context.getType(expression);
+ if (type instanceof PyClassLikeType) {
+ final PyClassLikeType classType = (PyClassLikeType)type;
+ if (classType.isDefinition()) {
+ return classType.toInstance();
+ }
+ }
+ else if (type instanceof PyNoneType) {
+ return type;
+ }
+ return null;
+ }
+
+ @Nullable
+ private static PsiElement resolve(@NotNull PyExpression expression, @NotNull TypeEvalContext context) {
+ if (expression instanceof PyReferenceOwner) {
+ final PyReferenceOwner referenceOwner = (PyReferenceOwner)expression;
+ final PyResolveContext resolveContext = PyResolveContext.noImplicits().withTypeEvalContext(context);
+ final PsiPolyVariantReference reference = referenceOwner.getReference(resolveContext);
+ final PsiElement element = reference.resolve();
+ if (element instanceof PyFunction) {
+ final PyFunction function = (PyFunction)element;
+ if (PyUtil.isInit(function)) {
+ final PyClass cls = function.getContainingClass();
+ if (cls != null) {
+ return cls;
+ }
+ }
+ }
+ return element;
+ }
+ return null;
+ }
+
+ @Nullable
+ private static String resolveToQualifiedName(@NotNull PyExpression expression, @NotNull TypeEvalContext context) {
+ final PsiElement element = resolve(expression, context);
+ if (element instanceof PyQualifiedNameOwner) {
+ final PyQualifiedNameOwner qualifiedNameOwner = (PyQualifiedNameOwner)element;
+ return qualifiedNameOwner.getQualifiedName();
+ }
+ return null;
+ }
+}
diff --git a/python/src/com/jetbrains/python/codeInsight/highlighting/PyHighlightExitPointsHandlerFactory.java b/python/src/com/jetbrains/python/codeInsight/highlighting/PyHighlightExitPointsHandlerFactory.java
index d0bc9dcbc7ca..27522d6e7f53 100644
--- a/python/src/com/jetbrains/python/codeInsight/highlighting/PyHighlightExitPointsHandlerFactory.java
+++ b/python/src/com/jetbrains/python/codeInsight/highlighting/PyHighlightExitPointsHandlerFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,30 +15,26 @@
*/
package com.jetbrains.python.codeInsight.highlighting;
-import com.intellij.codeInsight.TargetElementUtilBase;
import com.intellij.codeInsight.highlighting.HighlightUsagesHandlerBase;
-import com.intellij.codeInsight.highlighting.HighlightUsagesHandlerFactory;
+import com.intellij.codeInsight.highlighting.HighlightUsagesHandlerFactoryBase;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiTreeUtil;
import com.jetbrains.python.psi.PyExpression;
import com.jetbrains.python.psi.PyReturnStatement;
+import org.jetbrains.annotations.NotNull;
/**
* @author oleg
*/
-public class PyHighlightExitPointsHandlerFactory implements HighlightUsagesHandlerFactory {
- public HighlightUsagesHandlerBase createHighlightUsagesHandler(final Editor editor, final PsiFile file) {
- int offset = TargetElementUtilBase.adjustOffset(file, editor.getDocument(), editor.getCaretModel().getOffset());
- PsiElement target = file.findElementAt(offset);
- if (target != null) {
- final PyReturnStatement returnStatement = PsiTreeUtil.getParentOfType(target, PyReturnStatement.class);
- if (returnStatement != null) {
- final PyExpression returnExpr = returnStatement.getExpression();
- if (returnExpr == null || !PsiTreeUtil.isAncestor(returnExpr, target, false)) {
- return new PyHighlightExitPointsHandler(editor, file, target);
- }
+public class PyHighlightExitPointsHandlerFactory extends HighlightUsagesHandlerFactoryBase {
+ public HighlightUsagesHandlerBase createHighlightUsagesHandler(@NotNull Editor editor, @NotNull PsiFile file, @NotNull PsiElement target) {
+ final PyReturnStatement returnStatement = PsiTreeUtil.getParentOfType(target, PyReturnStatement.class);
+ if (returnStatement != null) {
+ final PyExpression returnExpr = returnStatement.getExpression();
+ if (returnExpr == null || !PsiTreeUtil.isAncestor(returnExpr, target, false)) {
+ return new PyHighlightExitPointsHandler(editor, file, target);
}
}
return null;
diff --git a/python/src/com/jetbrains/python/codeInsight/intentions/ImportToImportFromIntention.java b/python/src/com/jetbrains/python/codeInsight/intentions/ImportToImportFromIntention.java
index fc35833473f8..e76240cefb1f 100644
--- a/python/src/com/jetbrains/python/codeInsight/intentions/ImportToImportFromIntention.java
+++ b/python/src/com/jetbrains/python/codeInsight/intentions/ImportToImportFromIntention.java
@@ -57,10 +57,11 @@ public class ImportToImportFromIntention implements IntentionAction {
private PsiElement myReferee = null;
private PyImportElement myImportElement = null;
private Collection<PsiReference> myReferences = null;
- private boolean myHasModuleReference = false; // is anything that resolves to our imported module is just an exact reference to that module
+ private boolean myHasModuleReference = false;
+ // is anything that resolves to our imported module is just an exact reference to that module
private int myRelativeLevel; // true if "from ... import"
- public IntentionState(Editor editor, PsiFile file) {
+ public IntentionState(@NotNull Editor editor, @NotNull PsiFile file) {
boolean available = false;
myImportElement = findImportElement(editor, file);
if (myImportElement != null) {
@@ -70,10 +71,10 @@ public class ImportToImportFromIntention implements IntentionAction {
available = true;
}
else if (parent instanceof PyFromImportStatement) {
- PyFromImportStatement from_import = (PyFromImportStatement)parent;
- final int relative_level = from_import.getRelativeLevel();
- if (from_import.isValid() && relative_level > 0 && from_import.getImportSource() == null) {
- myRelativeLevel = relative_level;
+ final PyFromImportStatement fromImport = (PyFromImportStatement)parent;
+ final int relativeLevel = fromImport.getRelativeLevel();
+ if (fromImport.isValid() && relativeLevel > 0 && fromImport.getImportSource() == null) {
+ myRelativeLevel = relativeLevel;
available = true;
}
}
@@ -92,25 +93,27 @@ public class ImportToImportFromIntention implements IntentionAction {
assert myImportElement != null : "isAvailable() must have returned true, but myImportElement is null";
// usages of imported name are qualifiers; what they refer to?
- PyReferenceExpression reference = myImportElement.getImportReferenceExpression();
- if (reference != null) {
- myModuleName = PyPsiUtils.toPath(reference);
+ final PyReferenceExpression importReference = myImportElement.getImportReferenceExpression();
+ if (importReference != null) {
+ myModuleName = PyPsiUtils.toPath(importReference);
myQualifierName = myImportElement.getVisibleName();
- myReferee = reference.getReference().resolve();
+ myReferee = importReference.getReference().resolve();
myHasModuleReference = false;
if (myReferee != null && myModuleName != null && myQualifierName != null) {
final Collection<PsiReference> references = new ArrayList<PsiReference>();
PsiTreeUtil.processElements(file, new PsiElementProcessor() {
public boolean execute(@NotNull PsiElement element) {
if (element instanceof PyReferenceExpression && PsiTreeUtil.getParentOfType(element, PyImportElement.class) == null) {
- PyReferenceExpression ref = (PyReferenceExpression)element;
+ final PyReferenceExpression ref = (PyReferenceExpression)element;
if (myQualifierName.equals(PyPsiUtils.toPath(ref))) { // filter out other names that might resolve to our target
- PsiElement parent_elt = ref.getParent();
- if (parent_elt instanceof PyQualifiedExpression) { // really qualified by us, not just referencing?
- PsiElement resolved = ref.getReference().resolve();
+ final PsiElement parentElt = ref.getParent();
+ if (parentElt instanceof PyQualifiedExpression) { // really qualified by us, not just referencing?
+ final PsiElement resolved = ref.getReference().resolve();
if (resolved == myReferee) references.add(ref.getReference());
}
- else myHasModuleReference = true;
+ else {
+ myHasModuleReference = true;
+ }
}
}
return true;
@@ -123,68 +126,70 @@ public class ImportToImportFromIntention implements IntentionAction {
public void invoke() {
assert myImportElement != null : "isAvailable() must have returned true, but myImportElement is null";
- PyUtil.sure(myImportElement.getImportReferenceExpression());
- Project project = myImportElement.getProject();
+ sure(myImportElement.getImportReferenceExpression());
+ final Project project = myImportElement.getProject();
+
+ final PyElementGenerator generator = PyElementGenerator.getInstance(project);
+ final LanguageLevel languageLevel = LanguageLevel.forElement(myImportElement);
// usages of imported name are qualifiers; what they refer to?
try {
// remember names and make them drop qualifiers
- Set<String> used_names = new HashSet<String>();
+ final Set<String> usedNames = new HashSet<String>();
for (PsiReference ref : myReferences) {
- PsiElement elt = ref.getElement();
- PsiElement parent_elt = elt.getParent();
- used_names.add(sure(PyUtil.sure(parent_elt).getLastChild()).getText()); // TODO: find ident node more properly
+ final PsiElement elt = ref.getElement();
+ final PsiElement parentElt = elt.getParent();
+ // TODO: find ident node more properly
+ final String nameUsed = sure(sure(parentElt).getLastChild()).getText();
+ usedNames.add(nameUsed);
if (!FileModificationService.getInstance().preparePsiElementForWrite(elt)) {
return;
}
- PsiElement next_elt = elt.getNextSibling();
- if (next_elt != null && ".".equals(next_elt.getText())) next_elt.delete();
- elt.delete();
+ assert parentElt instanceof PyReferenceExpression;
+ final PyElement newReference = generator.createExpressionFromText(languageLevel, nameUsed);
+ parentElt.replace(newReference);
}
// create a separate import stmt for the module
- PsiElement importer = myImportElement.getParent();
- PyStatement import_statement;
- PyImportElement[] import_elements;
+ final PsiElement importer = myImportElement.getParent();
+ final PyStatement importStatement;
+ final PyImportElement[] importElements;
if (importer instanceof PyImportStatement) {
- import_statement = (PyImportStatement)importer;
- import_elements = ((PyImportStatement)import_statement).getImportElements();
+ importStatement = (PyImportStatement)importer;
+ importElements = ((PyImportStatement)importStatement).getImportElements();
}
else if (importer instanceof PyFromImportStatement) {
- import_statement = (PyFromImportStatement)importer;
- import_elements = ((PyFromImportStatement)import_statement).getImportElements();
+ importStatement = (PyFromImportStatement)importer;
+ importElements = ((PyFromImportStatement)importStatement).getImportElements();
}
else {
throw new IncorrectOperationException("Not an import at all");
}
- PyElementGenerator generator = PyElementGenerator.getInstance(project);
- StringBuilder builder = new StringBuilder("from ").append(getDots()).append(myModuleName).append(" import ");
- builder.append(StringUtil.join(used_names, ", "));
- PyFromImportStatement from_import_stmt =
- generator.createFromText(LanguageLevel.getDefault(), PyFromImportStatement.class, builder.toString());
- PsiElement parent = import_statement.getParent();
+ final PyFromImportStatement newImportStatement =
+ generator.createFromImportStatement(languageLevel, getDots() + myModuleName, StringUtil.join(usedNames, ", "), null);
+ final PsiElement parent = importStatement.getParent();
sure(parent);
sure(parent.isValid());
- if (import_elements.length == 1) {
+ if (importElements.length == 1) {
if (myHasModuleReference) {
- parent.addAfter(from_import_stmt, import_statement); // add 'import from': we need the module imported as is
+ parent.addAfter(newImportStatement, importStatement); // add 'import from': we need the module imported as is
}
else { // replace entire existing import
- sure(parent.getNode()).replaceChild(sure(import_statement.getNode()), sure(from_import_stmt.getNode()));
+ sure(parent.getNode()).replaceChild(sure(importStatement.getNode()), sure(newImportStatement.getNode()));
// import_statement.replace(from_import_stmt);
}
}
else {
if (!myHasModuleReference) {
// cut the module out of import, add a from-import.
- for (PyImportElement pie : import_elements) {
+ for (PyImportElement pie : importElements) {
if (pie == myImportElement) {
PyUtil.removeListNode(pie);
break;
}
}
}
- parent.addAfter(from_import_stmt, import_statement);
+ parent.addAfter(newImportStatement, importStatement);
}
}
catch (IncorrectOperationException ignored) {
@@ -193,18 +198,24 @@ public class ImportToImportFromIntention implements IntentionAction {
}
+ @NotNull
public String getText() {
- String module_name = "?";
+ String moduleName = "?";
if (myImportElement != null) {
- PyReferenceExpression reference = myImportElement.getImportReferenceExpression();
- if (reference != null) module_name = PyPsiUtils.toPath(reference);
+ final PyReferenceExpression reference = myImportElement.getImportReferenceExpression();
+ if (reference != null) {
+ moduleName = PyPsiUtils.toPath(reference);
+ }
}
- return PyBundle.message("INTN.convert.to.from.$0.import.$1", getDots()+module_name, "...");
+ return PyBundle.message("INTN.convert.to.from.$0.import.$1", getDots() + moduleName, "...");
}
+ @NotNull
private String getDots() {
String dots = "";
- for (int i=0; i<myRelativeLevel; i+=1) dots += "."; // this generally runs 1-2 times, so it's cheaper than allocating a StringBuilder
+ for (int i = 0; i < myRelativeLevel; i += 1) {
+ dots += "."; // this generally runs 1-2 times, so it's cheaper than allocating a StringBuilder
+ }
return dots;
}
}
@@ -222,10 +233,15 @@ public class ImportToImportFromIntention implements IntentionAction {
}
@Nullable
- private static PyImportElement findImportElement(Editor editor, PsiFile file) {
- PyImportElement import_elt = PsiTreeUtil.getParentOfType(file.findElementAt(editor.getCaretModel().getOffset()), PyImportElement.class);
- if (import_elt != null && import_elt.isValid()) return import_elt;
- else return null;
+ private static PyImportElement findImportElement(@NotNull Editor editor, @NotNull PsiFile file) {
+ final PsiElement elementAtCaret = file.findElementAt(editor.getCaretModel().getOffset());
+ final PyImportElement importElement = PsiTreeUtil.getParentOfType(elementAtCaret, PyImportElement.class);
+ if (importElement != null && importElement.isValid()) {
+ return importElement;
+ }
+ else {
+ return null;
+ }
}
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
@@ -233,7 +249,7 @@ public class ImportToImportFromIntention implements IntentionAction {
return false;
}
- IntentionState state = new IntentionState(editor, file);
+ final IntentionState state = new IntentionState(editor, file);
if (state.isAvailable()) {
myText = state.getText();
return true;
@@ -242,7 +258,7 @@ public class ImportToImportFromIntention implements IntentionAction {
}
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
- IntentionState state = new IntentionState(editor, file);
+ final IntentionState state = new IntentionState(editor, file);
state.invoke();
}
diff --git a/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java b/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java
index 7acfc9716fea..ca7ec65f9908 100644
--- a/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java
+++ b/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java
@@ -69,6 +69,7 @@ public class PyGenerateDocstringIntention extends BaseIntentionAction {
if (function == null || statementList != null) {
return false;
}
+ if (!elementAt.equals(function.getNameNode())) return false;
return isAvailableForFunction(project, function);
}
diff --git a/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java b/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java
index 48a42753ebe5..e11f3e01e916 100644
--- a/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java
+++ b/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java
@@ -143,7 +143,7 @@ public class PyOverrideImplementUtil {
return;
}
new WriteCommandAction(pyClass.getProject(), pyClass.getContainingFile()) {
- protected void run(final Result result) throws Throwable {
+ protected void run(@NotNull final Result result) throws Throwable {
write(pyClass, membersToOverride, editor, implement);
}
}.execute();
@@ -173,9 +173,7 @@ public class PyOverrideImplementUtil {
PyPsiUtils.removeRedundantPass(statementList);
if (element != null) {
final PyStatementList targetStatementList = element.getStatementList();
- final int start = targetStatementList != null
- ? targetStatementList.getTextRange().getStartOffset()
- : element.getTextRange().getStartOffset();
+ final int start = targetStatementList.getTextRange().getStartOffset();
editor.getCaretModel().moveToOffset(start);
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
editor.getSelectionModel().setSelection(start, element.getTextRange().getEndOffset());
@@ -238,7 +236,7 @@ public class PyOverrideImplementUtil {
PsiElement outerClass = PsiTreeUtil.getParentOfType(pyClass, PyClass.class, true, PyFunction.class);
String className = pyClass.getName();
final List<String> nameResult = Lists.newArrayList(className);
- while(outerClass instanceof PyClass) {
+ while(outerClass != null) {
nameResult.add(0, ((PyClass)outerClass).getName());
outerClass = PsiTreeUtil.getParentOfType(outerClass, PyClass.class, true, PyFunction.class);
}
diff --git a/python/src/com/jetbrains/python/console/PyConsoleOptions.java b/python/src/com/jetbrains/python/console/PyConsoleOptions.java
index 59ae6875d1e9..2f8eb5ee3949 100644
--- a/python/src/com/jetbrains/python/console/PyConsoleOptions.java
+++ b/python/src/com/jetbrains/python/console/PyConsoleOptions.java
@@ -146,6 +146,7 @@ public class PyConsoleOptions implements PersistentStateComponent<PyConsoleOptio
form.setUseModuleSdk(myUseModuleSdk);
form.addContentRoots(myAddContentRoots);
form.addSourceRoots(myAddSourceRoots);
+
boolean moduleWasAutoselected = false;
if (form.isUseModuleSdk() != myUseModuleSdk) {
myUseModuleSdk = form.isUseModuleSdk();
diff --git a/python/src/com/jetbrains/python/console/PyDebugConsoleBuilder.java b/python/src/com/jetbrains/python/console/PyDebugConsoleBuilder.java
index a99b9332c00d..7fbd432ebf2c 100644
--- a/python/src/com/jetbrains/python/console/PyDebugConsoleBuilder.java
+++ b/python/src/com/jetbrains/python/console/PyDebugConsoleBuilder.java
@@ -37,7 +37,7 @@ public class PyDebugConsoleBuilder extends TextConsoleBuilder {
public PyDebugConsoleBuilder(final Project project, @Nullable Sdk sdk) {
myProject = project;
- this.mySdk = sdk;
+ mySdk = sdk;
}
public ConsoleView getConsole() {
diff --git a/python/src/com/jetbrains/python/console/PydevConsoleRunner.java b/python/src/com/jetbrains/python/console/PydevConsoleRunner.java
index b3ebacd83ae3..c710fd0abf4e 100644
--- a/python/src/com/jetbrains/python/console/PydevConsoleRunner.java
+++ b/python/src/com/jetbrains/python/console/PydevConsoleRunner.java
@@ -125,10 +125,10 @@ public class PydevConsoleRunner extends AbstractConsoleRunnerWithHistory<PythonC
private Sdk mySdk;
@NotNull private CommandLineArgumentsProvider myCommandLineArgumentsProvider;
- private int[] myPorts;
+ protected int[] myPorts;
private PydevConsoleCommunication myPydevConsoleCommunication;
private PyConsoleProcessHandler myProcessHandler;
- private PydevConsoleExecuteActionHandler myConsoleExecuteActionHandler;
+ protected PydevConsoleExecuteActionHandler myConsoleExecuteActionHandler;
private List<ConsoleListener> myConsoleListeners = ContainerUtil.createLockFreeCopyOnWriteList();
private final PyConsoleType myConsoleType;
private Map<String, String> myEnvironmentVariables;
@@ -146,9 +146,9 @@ public class PydevConsoleRunner extends AbstractConsoleRunnerWithHistory<PythonC
private String myConsoleTitle = null;
public PydevConsoleRunner(@NotNull final Project project,
- @NotNull Sdk sdk, @NotNull final PyConsoleType consoleType,
- @Nullable final String workingDir,
- Map<String, String> environmentVariables, String ... statementsToExecute) {
+ @NotNull Sdk sdk, @NotNull final PyConsoleType consoleType,
+ @Nullable final String workingDir,
+ Map<String, String> environmentVariables, String... statementsToExecute) {
super(project, consoleType.getTitle(), workingDir);
mySdk = sdk;
myConsoleType = consoleType;
@@ -281,6 +281,30 @@ public class PydevConsoleRunner extends AbstractConsoleRunnerWithHistory<PythonC
return actions;
}
+ public void runSync() {
+ myPorts = findAvailablePorts(getProject(), myConsoleType);
+
+ assert myPorts != null;
+
+ myCommandLineArgumentsProvider = createCommandLineArgumentsProvider(mySdk, myEnvironmentVariables, myPorts);
+
+ try {
+ super.initAndRun();
+ }
+ catch (ExecutionException e) {
+ LOG.warn("Error running console", e);
+ ExecutionHelper.showErrors(getProject(), Arrays.<Exception>asList(e), "Python Console", null);
+ }
+
+ ProgressManager.getInstance().run(new Task.Backgroundable(getProject(), "Connecting to console", false) {
+ @Override
+ public void run(@NotNull final ProgressIndicator indicator) {
+ indicator.setText("Connecting to console...");
+ connect(myStatementsToExecute);
+ }
+ });
+ }
+
public void run() {
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
@@ -337,9 +361,9 @@ public class PydevConsoleRunner extends AbstractConsoleRunnerWithHistory<PythonC
return ports;
}
- private static CommandLineArgumentsProvider createCommandLineArgumentsProvider(final Sdk sdk,
- final Map<String, String> environmentVariables,
- int[] ports) {
+ protected CommandLineArgumentsProvider createCommandLineArgumentsProvider(final Sdk sdk,
+ final Map<String, String> environmentVariables,
+ int[] ports) {
final ArrayList<String> args = new ArrayList<String>();
args.add(sdk.getHomePath());
final String versionString = sdk.getVersionString();
@@ -518,8 +542,11 @@ public class PydevConsoleRunner extends AbstractConsoleRunnerWithHistory<PythonC
public void initAndRun(final String... statements2execute) throws ExecutionException {
super.initAndRun();
- if (handshake()) {
+ connect(statements2execute);
+ }
+ public void connect(final String[] statements2execute) {
+ if (handshake()) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
diff --git a/python/src/com/jetbrains/python/debugger/PyDebugProcess.java b/python/src/com/jetbrains/python/debugger/PyDebugProcess.java
index cff49fb1f0d8..cdea41298a4e 100644
--- a/python/src/com/jetbrains/python/debugger/PyDebugProcess.java
+++ b/python/src/com/jetbrains/python/debugger/PyDebugProcess.java
@@ -17,6 +17,7 @@ package com.jetbrains.python.debugger;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
+import com.intellij.execution.console.DuplexConsoleView;
import com.intellij.execution.process.ProcessEvent;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.process.ProcessListener;
@@ -35,6 +36,7 @@ import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.remote.RemoteProcessHandlerBase;
+import com.intellij.util.ui.UIUtil;
import com.intellij.xdebugger.*;
import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.intellij.xdebugger.breakpoints.XBreakpointHandler;
@@ -43,6 +45,7 @@ import com.intellij.xdebugger.breakpoints.XLineBreakpoint;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
import com.intellij.xdebugger.frame.XValueChildrenList;
import com.intellij.xdebugger.stepping.XSmartStepIntoHandler;
+import com.jetbrains.python.console.PythonDebugLanguageConsoleView;
import com.jetbrains.python.console.pydev.PydevCompletionVariant;
import com.jetbrains.python.debugger.pydev.*;
import com.jetbrains.python.run.PythonProcessHandler;
@@ -84,6 +87,7 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr
private final XSmartStepIntoHandler<?> mySmartStepIntoHandler;
private boolean myWaitingForConnection = false;
private PyStackFrame myStackFrameBeforeResume;
+ private PyStackFrame myConsoleContextFrame = null;
public PyDebugProcess(final @NotNull XDebugSession session,
@NotNull final ServerSocket serverSocket,
@@ -285,6 +289,19 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr
PySignatureCacheManager.getInstance(getSession().getProject()).recordSignature(myPositionConverter.convertSignature(signature));
}
+ @Override
+ public void showConsole(PyThreadInfo thread) {
+ myConsoleContextFrame = new PyExecutionStack(this, thread).getTopFrame();
+ if (myExecutionConsole instanceof PythonDebugLanguageConsoleView) {
+ UIUtil.invokeLaterIfNeeded(new Runnable() {
+ @Override
+ public void run() {
+ ((PythonDebugLanguageConsoleView)myExecutionConsole).enableConsole(false);
+ }
+ });
+ }
+ }
+
protected void afterConnect() {
}
@@ -545,6 +562,11 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr
}
final PyStackFrame frame = (PyStackFrame)getSession().getCurrentStackFrame();
+
+ if (frame == null && myConsoleContextFrame != null) {
+ return myConsoleContextFrame;
+ }
+
if (frame == null) {
throw new PyDebuggerException("Process is running");
}
diff --git a/python/src/com/jetbrains/python/debugger/PyExecutionStack.java b/python/src/com/jetbrains/python/debugger/PyExecutionStack.java
index ed48f09a99ca..7d9aba3608c2 100644
--- a/python/src/com/jetbrains/python/debugger/PyExecutionStack.java
+++ b/python/src/com/jetbrains/python/debugger/PyExecutionStack.java
@@ -37,7 +37,7 @@ public class PyExecutionStack extends XExecutionStack {
}
@Override
- public XStackFrame getTopFrame() {
+ public PyStackFrame getTopFrame() {
if (myTopFrame == null) {
final List<PyStackFrameInfo> frames = myThreadInfo.getFrames();
if (frames != null) {
diff --git a/python/src/com/jetbrains/python/documentation/PythonDocumentationProvider.java b/python/src/com/jetbrains/python/documentation/PythonDocumentationProvider.java
index 55bc1e4c5446..913ed65f1e53 100644
--- a/python/src/com/jetbrains/python/documentation/PythonDocumentationProvider.java
+++ b/python/src/com/jetbrains/python/documentation/PythonDocumentationProvider.java
@@ -34,6 +34,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.util.QualifiedName;
import com.intellij.util.Function;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.codeInsight.PyCodeInsightSettings;
@@ -44,13 +45,16 @@ import com.jetbrains.python.debugger.PySignatureCacheManager;
import com.jetbrains.python.debugger.PySignatureUtil;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.PyBuiltinCache;
-import com.intellij.psi.util.QualifiedName;
import com.jetbrains.python.psi.resolve.QualifiedNameFinder;
-import com.jetbrains.python.psi.types.*;
+import com.jetbrains.python.psi.types.PyClassType;
+import com.jetbrains.python.psi.types.PyType;
+import com.jetbrains.python.psi.types.PyTypeParser;
+import com.jetbrains.python.psi.types.TypeEvalContext;
import com.jetbrains.python.toolbox.ChainIterable;
import com.jetbrains.python.toolbox.FP;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.HeadMethod;
+import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -414,8 +418,10 @@ public class PythonDocumentationProvider extends AbstractDocumentationProvider i
return true;
}
HttpClient client = new HttpClient();
- client.setTimeout(5 * 1000);
- client.setConnectionTimeout(5 * 1000);
+ HttpConnectionManagerParams params = client.getHttpConnectionManager().getParams();
+ params.setSoTimeout(5 * 1000);
+ params.setConnectionTimeout(5 * 1000);
+
try {
HeadMethod method = new HeadMethod(url);
int rc = client.executeMethod(method);
@@ -618,9 +624,7 @@ public class PythonDocumentationProvider extends AbstractDocumentationProvider i
if (checkReturn) {
RaiseVisitor visitor = new RaiseVisitor();
PyStatementList statementList = element.getStatementList();
- if (statementList != null) {
- statementList.accept(visitor);
- }
+ statementList.accept(visitor);
if (visitor.myHasReturn) {
builder.append(prefix).append("return:").append(offset);
if (PyCodeInsightSettings.getInstance().INSERT_TYPE_DOCSTUB) {
diff --git a/python/src/com/jetbrains/python/documentation/doctest/PyDocstringVisitorFilter.java b/python/src/com/jetbrains/python/documentation/doctest/PyDocstringVisitorFilter.java
index e79d52cb1685..71af6aa30fea 100644
--- a/python/src/com/jetbrains/python/documentation/doctest/PyDocstringVisitorFilter.java
+++ b/python/src/com/jetbrains/python/documentation/doctest/PyDocstringVisitorFilter.java
@@ -43,7 +43,7 @@ public class PyDocstringVisitorFilter implements PythonVisitorFilter {
visitorClass == PyByteLiteralInspection.class || visitorClass == PyNonAsciiCharInspection.class ||
visitorClass == PyPackageRequirementsInspection.class || visitorClass == PyMandatoryEncodingInspection.class ||
visitorClass == PyInterpreterInspection.class || visitorClass == PyDocstringTypesInspection.class ||
- visitorClass == PySingleQuotedDocstringInspection.class) {
+ visitorClass == PySingleQuotedDocstringInspection.class || visitorClass == PyClassHasNoInitInspection.class) {
return false;
}
//annotators
diff --git a/python/src/com/jetbrains/python/formatter/PythonFormattingModelBuilder.java b/python/src/com/jetbrains/python/formatter/PythonFormattingModelBuilder.java
index aee9e53adff6..4b71d6abec25 100644
--- a/python/src/com/jetbrains/python/formatter/PythonFormattingModelBuilder.java
+++ b/python/src/com/jetbrains/python/formatter/PythonFormattingModelBuilder.java
@@ -46,13 +46,13 @@ public class PythonFormattingModelBuilder implements FormattingModelBuilderEx, C
public FormattingModel createModel(@NotNull PsiElement element,
@NotNull CodeStyleSettings settings,
@NotNull FormattingMode mode) {
+ final ASTNode fileNode = element.getContainingFile().getNode();
if (DUMP_FORMATTING_AST) {
- ASTNode fileNode = element.getContainingFile().getNode();
System.out.println("AST tree for " + element.getContainingFile().getName() + ":");
printAST(fileNode, 0);
}
final PyBlockContext context = new PyBlockContext(settings, createSpacingBuilder(settings), mode);
- final PyBlock block = new PyBlock(null, element.getNode(), null, Indent.getNoneIndent(), null, context);
+ final PyBlock block = new PyBlock(null, fileNode, null, Indent.getNoneIndent(), null, context);
if (DUMP_FORMATTING_AST) {
FormattingModelDumper.dumpFormattingModel(block, 2, System.out);
}
diff --git a/python/src/com/jetbrains/python/inspections/PyCompatibilityInspection.java b/python/src/com/jetbrains/python/inspections/PyCompatibilityInspection.java
index c8a40a095134..0f69f4f72a56 100644
--- a/python/src/com/jetbrains/python/inspections/PyCompatibilityInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyCompatibilityInspection.java
@@ -200,9 +200,7 @@ public class PyCompatibilityInspection extends PyInspection {
}
for (int i = 0; i != myVersionsToProcess.size(); ++i) {
LanguageLevel languageLevel = myVersionsToProcess.get(i);
- PsiFile file = resolved.getContainingFile();
- VirtualFile virtualFile = file.getVirtualFile();
- if (virtualFile != null && ind.isInLibraryClasses(virtualFile)) {
+ if (PyBuiltinCache.getInstance(resolved).isBuiltin(resolved)) {
if (!"print".equals(name) && !myUsedImports.contains(name) && UnsupportedFeaturesUtil.BUILTINS.get(languageLevel).contains(name)) {
len = appendLanguageLevel(message, len, languageLevel);
}
diff --git a/python/src/com/jetbrains/python/inspections/PyStatementEffectInspection.java b/python/src/com/jetbrains/python/inspections/PyStatementEffectInspection.java
index 0cc7a4abd140..a521ed76d92f 100644
--- a/python/src/com/jetbrains/python/inspections/PyStatementEffectInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyStatementEffectInspection.java
@@ -72,9 +72,6 @@ public class PyStatementEffectInspection extends PyInspection {
final PyTryPart tryPart = PsiTreeUtil.getParentOfType(node, PyTryPart.class);
if (tryPart != null) {
final PyStatementList statementList = tryPart.getStatementList();
- if (statementList == null) {
- return;
- }
if (statementList.getStatements().length == 1 && statementList.getStatements()[0] == node) {
return;
}
diff --git a/python/src/com/jetbrains/python/inspections/quickfix/PyDefaultArgumentQuickFix.java b/python/src/com/jetbrains/python/inspections/quickfix/PyDefaultArgumentQuickFix.java
index 31723d3aab4e..db47f17f8ea8 100644
--- a/python/src/com/jetbrains/python/inspections/quickfix/PyDefaultArgumentQuickFix.java
+++ b/python/src/com/jetbrains/python/inspections/quickfix/PyDefaultArgumentQuickFix.java
@@ -61,29 +61,36 @@ public class PyDefaultArgumentQuickFix implements LocalQuickFix {
PyStatementList list = function.getStatementList();
PyParameterList paramList = function.getParameterList();
- StringBuilder str = new StringBuilder("def foo(");
+ final StringBuilder functionText = new StringBuilder("def foo(");
int size = paramList.getParameters().length;
for (int i = 0; i != size; ++i) {
PyParameter p = paramList.getParameters()[i];
if (p == param)
- str.append(defName).append("=None");
+ functionText.append(defName).append("=None");
else
- str.append(p.getText());
+ functionText.append(p.getText());
if (i != size-1)
- str.append(", ");
+ functionText.append(", ");
+ }
+ functionText.append("):\n\tif not ").append(defName).append(":\n\t\t").append(defName).append(" = ").append(defaultValue.getText());
+ final PyStatement[] statements = list.getStatements();
+ PyStatement firstStatement = statements.length > 0 ? statements[0] : null;
+ PyFunction newFunction = elementGenerator.createFromText(LanguageLevel.forElement(function), PyFunction.class,
+ functionText.toString());
+ if (firstStatement == null) {
+ function.replace(newFunction);
+ }
+ else {
+ final PyStatement ifStatement = newFunction.getStatementList().getStatements()[0];
+ PyStringLiteralExpression docString = function.getDocStringExpression();
+ if (docString != null)
+ list.addAfter(ifStatement, firstStatement);
+ else {
+ list.addBefore(ifStatement, firstStatement);
+ }
+ paramList.replace(elementGenerator.createFromText(LanguageLevel.forElement(defaultValue),
+ PyFunction.class, functionText.toString()).getParameterList());
}
- str.append("):\n\tpass");
- PyIfStatement ifStatement = elementGenerator.createFromText(LanguageLevel.forElement(function), PyIfStatement.class,
- "if not " + defName + ": " + defName + " = " + defaultValue.getText());
-
- PyStatement firstStatement = list.getStatements()[0];
- PyStringLiteralExpression docString = function.getDocStringExpression();
- if (docString != null)
- list.addAfter(ifStatement, firstStatement);
- else
- list.addBefore(ifStatement, firstStatement);
- paramList.replace(elementGenerator.createFromText(LanguageLevel.forElement(defaultValue),
- PyFunction.class, str.toString()).getParameterList());
}
}
}
diff --git a/python/src/com/jetbrains/python/inspections/quickfix/StatementEffectFunctionCallQuickFix.java b/python/src/com/jetbrains/python/inspections/quickfix/StatementEffectFunctionCallQuickFix.java
index 95daf466172e..43f4f0394015 100644
--- a/python/src/com/jetbrains/python/inspections/quickfix/StatementEffectFunctionCallQuickFix.java
+++ b/python/src/com/jetbrains/python/inspections/quickfix/StatementEffectFunctionCallQuickFix.java
@@ -18,14 +18,14 @@ package com.jetbrains.python.inspections.quickfix;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiComment;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiWhiteSpace;
+import com.intellij.psi.impl.source.tree.LeafPsiElement;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.PyNames;
-import com.jetbrains.python.psi.LanguageLevel;
-import com.jetbrains.python.psi.PyElementGenerator;
-import com.jetbrains.python.psi.PyExpression;
-import com.jetbrains.python.psi.PyReferenceExpression;
+import com.jetbrains.python.PyTokenTypes;
+import com.jetbrains.python.psi.*;
import org.jetbrains.annotations.NotNull;
/**
@@ -48,15 +48,17 @@ public class StatementEffectFunctionCallQuickFix implements LocalQuickFix {
PsiElement expression = descriptor.getPsiElement();
if (expression != null && expression.isWritable() && expression instanceof PyReferenceExpression) {
final String expressionText = expression.getText();
- if (PyNames.PRINT.equals(expressionText) || PyNames.EXEC.equals(expressionText))
- replacePrintExec(expression);
+ if (PyNames.PRINT.equals(expressionText))
+ replacePrint(expression);
+ else if (PyNames.EXEC.equals(expressionText))
+ replaceExec(expression);
else
expression.replace(PyElementGenerator.getInstance(project).createCallExpression(LanguageLevel.forElement(expression),
expressionText));
}
}
- private static void replacePrintExec(@NotNull final PsiElement expression) {
+ private static void replaceExec(@NotNull final PsiElement expression) {
final PyElementGenerator elementGenerator = PyElementGenerator.getInstance(expression.getProject());
final String expressionText = expression.getText();
final StringBuilder stringBuilder = new StringBuilder(expressionText + " (");
@@ -77,14 +79,88 @@ public class StatementEffectFunctionCallQuickFix implements LocalQuickFix {
RemoveUnnecessaryBackslashQuickFix.removeBackSlash(next);
if (whiteSpace != null) whiteSpace.delete();
+ if (next == null) {
+ stringBuilder.append(")");
+ expression.replace(elementGenerator.createFromText(LanguageLevel.forElement(expression), PyExpression.class,
+ stringBuilder.toString()));
+ return;
+ }
+ if (next instanceof PyExpressionStatement) {
+ final PyExpression expr = ((PyExpressionStatement)next).getExpression();
+ if (expr instanceof PyBinaryExpression) {
+ addInArguments(stringBuilder, (PyBinaryExpression)expr);
+ }
+ else if (expr instanceof PyTupleExpression) {
+ final PyExpression[] elements = ((PyTupleExpression)expr).getElements();
+ if (elements.length > 1) {
+ if (elements[0] instanceof PyBinaryExpression) {
+ addInArguments(stringBuilder, (PyBinaryExpression)elements[0]);
+ }
+ stringBuilder.append(", ");
+ stringBuilder.append(elements[1].getText());
+ }
+ }
+ else {
+ stringBuilder.append(next.getText());
+ }
+ }
+ else {
+ stringBuilder.append(next.getText());
+ }
+ next.delete();
+ stringBuilder.append(")");
+ expression.replace(elementGenerator.createFromText(LanguageLevel.forElement(expression), PyExpression.class,
+ stringBuilder.toString()));
+ }
+
+ private static void addInArguments(@NotNull final StringBuilder stringBuilder, @NotNull final PyBinaryExpression binaryExpression) {
+ final PsiElement operator = binaryExpression.getPsiOperator();
+ if (operator instanceof LeafPsiElement && ((LeafPsiElement)operator).getElementType() == PyTokenTypes.IN_KEYWORD) {
+ stringBuilder.append(binaryExpression.getLeftExpression().getText());
+ stringBuilder.append(", ");
+ final PyExpression rightExpression = binaryExpression.getRightExpression();
+ if (rightExpression != null)
+ stringBuilder.append(rightExpression.getText());
+ }
+ }
+
+ private static void replacePrint(@NotNull final PsiElement expression) {
+ final PyElementGenerator elementGenerator = PyElementGenerator.getInstance(expression.getProject());
+ final String expressionText = expression.getText();
+ final StringBuilder stringBuilder = new StringBuilder(expressionText + " (");
+
+ final PsiElement whiteSpace = expression.getContainingFile().findElementAt(expression.getTextOffset() + expression.getTextLength());
+ PsiElement next = null;
+ if (whiteSpace instanceof PsiWhiteSpace) {
+ final String whiteSpaceText = whiteSpace.getText();
+ if (!whiteSpaceText.contains("\n")) {
+ next = whiteSpace.getNextSibling();
+ while (next instanceof PsiWhiteSpace && whiteSpaceText.contains("\\")) {
+ next = next.getNextSibling();
+ }
+ }
+ }
+ else
+ next = whiteSpace;
+
+ RemoveUnnecessaryBackslashQuickFix.removeBackSlash(next);
+ if (whiteSpace != null) whiteSpace.delete();
+ String commentText = null;
if (next != null) {
- final String text = next.getText();
+ final PsiElement lastChild = next.getLastChild();
+ if (lastChild instanceof PsiComment) {
+ commentText = lastChild.getText();
+ }
+ final String text = next instanceof PyExpressionStatement ? ((PyExpressionStatement)next).getExpression().getText() : next.getText();
+
stringBuilder.append(text);
- if (text.endsWith(",") && PyNames.PRINT.equals(expressionText))
- stringBuilder.append(" end=' '");
+ if (text.endsWith(",")) stringBuilder.append(" end=' '");
next.delete();
}
stringBuilder.append(")");
+ if (commentText != null) {
+ stringBuilder.append(commentText);
+ }
expression.replace(elementGenerator.createFromText(LanguageLevel.forElement(expression), PyExpression.class,
stringBuilder.toString()));
}
diff --git a/python/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesInspection.java b/python/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesInspection.java
index 4fd58629c516..b7523caf90e7 100644
--- a/python/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesInspection.java
+++ b/python/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesInspection.java
@@ -755,7 +755,7 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
return false;
}
- private static void addCreateMemberFromUsageFixes(PyType type, PsiReference reference, String refText, List<LocalQuickFix> actions) {
+ private void addCreateMemberFromUsageFixes(PyType type, PsiReference reference, String refText, List<LocalQuickFix> actions) {
PsiElement element = reference.getElement();
if (type instanceof PyClassTypeImpl) {
PyClass cls = ((PyClassType)type).getPyClass();
@@ -771,6 +771,7 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
else if (type instanceof PyModuleType) {
PyFile file = ((PyModuleType)type).getModule();
actions.add(new AddFunctionQuickFix(refText, file.getName()));
+ addCreateClassFix(refText, element, actions);
}
}
diff --git a/python/src/com/jetbrains/python/module/PyContentEntriesEditor.java b/python/src/com/jetbrains/python/module/PyContentEntriesEditor.java
new file mode 100644
index 000000000000..8ea8b26c0b5f
--- /dev/null
+++ b/python/src/com/jetbrains/python/module/PyContentEntriesEditor.java
@@ -0,0 +1,367 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jetbrains.python.module;
+
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CustomShortcutSet;
+import com.intellij.openapi.actionSystem.Presentation;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ContentEntry;
+import com.intellij.openapi.roots.ContentFolder;
+import com.intellij.openapi.roots.ModifiableRootModel;
+import com.intellij.openapi.roots.impl.ContentEntryImpl;
+import com.intellij.openapi.roots.impl.ContentFolderBaseImpl;
+import com.intellij.openapi.roots.ui.configuration.*;
+import com.intellij.openapi.roots.ui.configuration.actions.ContentEntryEditingAction;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.vfs.VfsUtilCore;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.pointers.VirtualFilePointer;
+import com.intellij.openapi.vfs.pointers.VirtualFilePointerListener;
+import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager;
+import com.intellij.ui.JBColor;
+import com.intellij.util.EventDispatcher;
+import com.intellij.util.containers.MultiMap;
+import com.jetbrains.python.templateLanguages.TemplatesService;
+import icons.PythonIcons;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
+
+import javax.swing.*;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.tree.TreeCellRenderer;
+import java.awt.*;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.util.ArrayList;
+import java.util.List;
+
+public class PyContentEntriesEditor extends CommonContentEntriesEditor {
+ private static final Color TEMPLATES_COLOR = JBColor.MAGENTA;
+ private final MultiMap<ContentEntry, VirtualFilePointer> myTemplateRoots = new MultiMap<ContentEntry, VirtualFilePointer>();
+ private final Module myModule;
+ private Disposable myFilePointersDisposable;
+
+ private final VirtualFilePointerListener DUMMY_LISTENER = new VirtualFilePointerListener() {
+ @Override
+ public void beforeValidityChanged(@NotNull VirtualFilePointer[] pointers) {
+ }
+
+ @Override
+ public void validityChanged(@NotNull VirtualFilePointer[] pointers) {
+ }
+ };
+
+ public PyContentEntriesEditor(Module module, ModuleConfigurationState moduleConfigurationState,
+ JpsModuleSourceRootType<?>... rootTypes) {
+ super(module.getName(), moduleConfigurationState, rootTypes);
+ myModule = module;
+ reset();
+ }
+
+ @Override
+ protected ContentEntryTreeEditor createContentEntryTreeEditor(Project project) {
+ return new MyContentEntryTreeEditor(project, getEditHandlers());
+ }
+
+ @Override
+ protected List<ContentEntry> addContentEntries(VirtualFile[] files) {
+ List<ContentEntry> entries = super.addContentEntries(files);
+ addContentEntryPanels(entries.toArray(new ContentEntry[entries.size()]));
+ return entries;
+ }
+
+ @Override
+ public void reset() {
+ if (myFilePointersDisposable != null) {
+ Disposer.dispose(myFilePointersDisposable);
+ }
+ myTemplateRoots.clear();
+
+ myFilePointersDisposable = Disposer.newDisposable();
+ final TemplatesService instance = TemplatesService.getInstance(myModule);
+ if (instance != null) {
+ final List<VirtualFile> folders = instance.getTemplateFolders();
+ for (VirtualFile folder : folders) {
+ ContentEntry contentEntry = findContentEntryForFile(folder);
+ if (contentEntry != null) {
+ myTemplateRoots.putValue(contentEntry, VirtualFilePointerManager.getInstance().create(folder, myFilePointersDisposable,
+ DUMMY_LISTENER));
+ }
+ }
+ }
+
+ if (myRootTreeEditor != null) {
+ ContentEntryEditor editor = myRootTreeEditor.getContentEntryEditor();
+ if(editor!=null) editor.update();
+ myRootTreeEditor.update();
+ }
+ }
+
+ @Nullable
+ private ContentEntry findContentEntryForFile(VirtualFile virtualFile) {
+ for (ContentEntry contentEntry : getModel().getContentEntries()) {
+ final VirtualFile file = contentEntry.getFile();
+ if (file != null && VfsUtilCore.isAncestor(file, virtualFile, false)) {
+ return contentEntry;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void disposeUIResources() {
+ super.disposeUIResources();
+ if (myFilePointersDisposable != null) {
+ Disposer.dispose(myFilePointersDisposable);
+ }
+ }
+
+ @Override
+ public void apply() throws ConfigurationException {
+ super.apply();
+ List<VirtualFile> templateRoots = getCurrentState();
+ TemplatesService.getInstance(myModule).setTemplateFolders(templateRoots.toArray(new VirtualFile[templateRoots.size()]));
+ }
+
+ private List<VirtualFile> getCurrentState() {
+ List<VirtualFile> result = new ArrayList<VirtualFile>();
+ for (ContentEntry entry : myTemplateRoots.keySet()) {
+ for (VirtualFilePointer filePointer : myTemplateRoots.get(entry)) {
+ result.add(filePointer.getFile());
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public boolean isModified() {
+ if (super.isModified()) return true;
+ final TemplatesService templatesService = TemplatesService.getInstance(myModule);
+ if (templatesService != null) {
+ List<VirtualFile> original = templatesService.getTemplateFolders();
+ List<VirtualFile> current = getCurrentState();
+
+ if (!Comparing.haveEqualElements(original, current)) return true;
+
+ }
+ return false;
+ }
+
+ @Override
+ protected MyContentEntryEditor createContentEntryEditor(String contentEntryUrl) {
+ return new MyContentEntryEditor(contentEntryUrl, getEditHandlers());
+ }
+
+ protected class MyContentEntryEditor extends ContentEntryEditor {
+ private final EventDispatcher<ChangeListener> myEventDispatcher = EventDispatcher.create(ChangeListener.class);
+
+ public MyContentEntryEditor(String contentEntryUrl, List<ModuleSourceRootEditHandler<?>> handlers) {
+ super(contentEntryUrl, handlers);
+ }
+
+ @Override
+ protected ModifiableRootModel getModel() {
+ return PyContentEntriesEditor.this.getModel();
+ }
+
+ public void addListener(ChangeListener changeListener) {
+ myEventDispatcher.addListener(changeListener);
+ }
+
+ public void removeListener(ChangeListener changeListener) {
+ myEventDispatcher.removeListener(changeListener);
+ }
+
+ @Override
+ protected ContentRootPanel createContentRootPane() {
+ return new MyContentRootPanel();
+ }
+
+ @Override
+ public void deleteContentFolder(ContentEntry contentEntry, ContentFolder folder) {
+ if (folder instanceof TemplateRootFolder) {
+ final VirtualFile file = folder.getFile();
+ if (file != null) {
+ removeTemplateRoot(file);
+ }
+ }
+ else {
+ super.deleteContentFolder(contentEntry, folder);
+ }
+ }
+
+ public void addTemplateRoot(@NotNull final VirtualFile file) {
+ final VirtualFilePointer root = VirtualFilePointerManager.getInstance().create(file, myFilePointersDisposable, DUMMY_LISTENER);
+ myTemplateRoots.putValue(getContentEntry(), root);
+ myEventDispatcher.getMulticaster().stateChanged(new ChangeEvent(this));
+ update();
+ }
+
+ public void removeTemplateRoot(@NotNull final VirtualFile file) {
+ final VirtualFilePointer root = getTemplateRoot(file);
+ if (root != null) {
+ myTemplateRoots.remove(getContentEntry(), root);
+ myEventDispatcher.getMulticaster().stateChanged(new ChangeEvent(this));
+ update();
+ }
+ }
+
+ public boolean hasTemplateRoot(@NotNull final VirtualFile file) {
+ return getTemplateRoot(file) != null;
+ }
+
+ @Nullable
+ public VirtualFilePointer getTemplateRoot(@NotNull final VirtualFile file) {
+ for (VirtualFilePointer filePointer : myTemplateRoots.get(getContentEntry())) {
+ if (Comparing.equal(filePointer.getFile(), file)) {
+ return filePointer;
+ }
+ }
+ return null;
+ }
+
+ protected class MyContentRootPanel extends ContentRootPanel {
+ public MyContentRootPanel() {
+ super(MyContentEntryEditor.this, getEditHandlers());
+ }
+
+ @Override
+ @NotNull
+ protected ContentEntryImpl getContentEntry() {
+ //noinspection ConstantConditions
+ return (ContentEntryImpl)MyContentEntryEditor.this.getContentEntry();
+ }
+
+ @Override
+ protected void addFolderGroupComponents() {
+ super.addFolderGroupComponents();
+ if (!myTemplateRoots.get(getContentEntry()).isEmpty()) {
+ final List<TemplateRootFolder> folders = new ArrayList<TemplateRootFolder>(myTemplateRoots.size());
+ for (VirtualFilePointer root : myTemplateRoots.get(getContentEntry())) {
+ folders.add(new TemplateRootFolder(root, getContentEntry()));
+ }
+ final JComponent sourcesComponent = createFolderGroupComponent("Template Folders",
+ folders.toArray(new ContentFolder[folders.size()]),
+ TEMPLATES_COLOR, null);
+ this.add(sourcesComponent, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.HORIZONTAL, new Insets(0, 0, 10, 0), 0, 0));
+ }
+ }
+ }
+ }
+
+ private static class MyContentEntryTreeEditor extends ContentEntryTreeEditor {
+
+ private final ChangeListener myListener = new ChangeListener() {
+ @Override
+ public void stateChanged(ChangeEvent e) {
+ update();
+ }
+ };
+
+ public MyContentEntryTreeEditor(Project project, List<ModuleSourceRootEditHandler<?>> handlers) {
+ super(project, handlers);
+ }
+
+ @Override
+ public void setContentEntryEditor(ContentEntryEditor newEditor) {
+ PyContentEntriesEditor.MyContentEntryEditor existingEditor = getContentEntryEditor();
+ if (Comparing.equal(existingEditor, newEditor)) {
+ return;
+ }
+ if (existingEditor != null) {
+ existingEditor.removeListener(myListener);
+ }
+ if (newEditor != null) {
+ ((PyContentEntriesEditor.MyContentEntryEditor)newEditor).addListener(myListener);
+ }
+ super.setContentEntryEditor(newEditor);
+ }
+
+ @Override
+ public PyContentEntriesEditor.MyContentEntryEditor getContentEntryEditor() {
+ return (PyContentEntriesEditor.MyContentEntryEditor)super.getContentEntryEditor();
+ }
+
+ @Override
+ protected void createEditingActions() {
+ super.createEditingActions();
+
+ ContentEntryEditingAction a = new ContentEntryEditingAction(myTree) {
+ {
+ final Presentation templatePresentation = getTemplatePresentation();
+ templatePresentation.setText("Templates");
+ templatePresentation.setDescription("Template Folders");
+ templatePresentation.setIcon(PythonIcons.Python.TemplateRoot);
+ }
+
+ @Override
+ public boolean isSelected(AnActionEvent e) {
+ final VirtualFile[] selectedFiles = getSelectedFiles();
+ return selectedFiles.length != 0 && getContentEntryEditor().hasTemplateRoot(selectedFiles[0]);
+ }
+
+ @Override
+ public void setSelected(AnActionEvent e, boolean isSelected) {
+ final VirtualFile[] selectedFiles = getSelectedFiles();
+ assert selectedFiles.length != 0;
+
+ for (VirtualFile selectedFile : selectedFiles) {
+ boolean wasSelected = getContentEntryEditor().hasTemplateRoot(selectedFile);
+ if (isSelected) {
+ if (!wasSelected) {
+ getContentEntryEditor().addTemplateRoot(selectedFile);
+ }
+ }
+ else {
+ if (wasSelected) {
+ getContentEntryEditor().removeTemplateRoot(selectedFile);
+ }
+ }
+ }
+ }
+ };
+ myEditingActionsGroup.add(a);
+ a.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_R, InputEvent.ALT_MASK)), myTree);
+ }
+
+ @Override
+ protected TreeCellRenderer getContentEntryCellRenderer() {
+ return new ContentEntryTreeCellRenderer(this, getEditHandlers()) {
+ @Override
+ protected Icon updateIcon(final ContentEntry entry, final VirtualFile file, final Icon originalIcon) {
+ if (getContentEntryEditor().hasTemplateRoot(file)) {
+ return PythonIcons.Python.TemplateRoot;
+ }
+ return super.updateIcon(entry, file, originalIcon);
+ }
+ };
+ }
+ }
+ private static class TemplateRootFolder extends ContentFolderBaseImpl {
+ protected TemplateRootFolder(@NotNull VirtualFilePointer filePointer, @NotNull ContentEntryImpl contentEntry) {
+ super(filePointer, contentEntry);
+ }
+ }
+
+}
diff --git a/python/src/com/jetbrains/python/psi/impl/PyAnnotationImpl.java b/python/src/com/jetbrains/python/psi/impl/PyAnnotationImpl.java
index f3c806dac7c5..f8a4d482c2f2 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyAnnotationImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyAnnotationImpl.java
@@ -16,14 +16,16 @@
package com.jetbrains.python.psi.impl;
import com.intellij.lang.ASTNode;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiPolyVariantReference;
import com.jetbrains.python.PyElementTypes;
import com.jetbrains.python.psi.PyAnnotation;
-import com.jetbrains.python.psi.PyClass;
import com.jetbrains.python.psi.PyExpression;
-import com.jetbrains.python.psi.PyReferenceExpression;
import com.jetbrains.python.psi.stubs.PyAnnotationStub;
+import com.jetbrains.python.psi.types.PyClassLikeType;
+import com.jetbrains.python.psi.types.PyNoneType;
+import com.jetbrains.python.psi.types.PyType;
+import com.jetbrains.python.psi.types.TypeEvalContext;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
/**
* @author yole
@@ -37,19 +39,26 @@ public class PyAnnotationImpl extends PyBaseElementImpl<PyAnnotationStub> implem
super(stub, PyElementTypes.ANNOTATION);
}
+ @Nullable
@Override
public PyExpression getValue() {
return findChildByClass(PyExpression.class);
}
+ @Nullable
@Override
- public PyClass resolveToClass() {
- PyExpression expr = getValue();
- if (expr instanceof PyReferenceExpression) {
- final PsiPolyVariantReference reference = ((PyReferenceExpression)expr).getReference();
- final PsiElement result = reference.resolve();
- if (result instanceof PyClass) {
- return (PyClass) result;
+ public PyType getType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) {
+ final PyExpression value = getValue();
+ if (value != null) {
+ final PyType type = context.getType(value);
+ if (type instanceof PyClassLikeType) {
+ final PyClassLikeType classType = (PyClassLikeType)type;
+ if (classType.isDefinition()) {
+ return classType.toInstance();
+ }
+ }
+ else if (type instanceof PyNoneType) {
+ return type;
}
}
return null;
diff --git a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java
index 7538fbae2fd2..bb2104fc0c77 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java
@@ -20,7 +20,6 @@ import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.NotNullLazyValue;
-import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.search.LocalSearchScope;
@@ -187,6 +186,11 @@ public class PyClassImpl extends PyPresentableElementImpl<PyClassStub> implement
}
}
}
+ // Heuristic: unfold Foo[Bar] to Foo for subscription expressions for superclasses
+ else if (expression instanceof PySubscriptionExpression) {
+ final PySubscriptionExpression subscriptionExpr = (PySubscriptionExpression)expression;
+ return subscriptionExpr.getOperand();
+ }
return expression;
}
@@ -237,27 +241,7 @@ public class PyClassImpl extends PyPresentableElementImpl<PyClassStub> implement
@Nullable
public String getQualifiedName() {
- String name = getName();
- final PyClassStub stub = getStub();
- PsiElement ancestor = stub != null ? stub.getParentStub().getPsi() : getParent();
- while (!(ancestor instanceof PsiFile)) {
- if (ancestor == null) return name; // can this happen?
- if (ancestor instanceof PyClass) {
- name = ((PyClass)ancestor).getName() + "." + name;
- }
- ancestor = stub != null ? ((StubBasedPsiElement)ancestor).getStub().getParentStub().getPsi() : ancestor.getParent();
- }
-
- PsiFile psiFile = ((PsiFile)ancestor).getOriginalFile();
- final PyFile builtins = PyBuiltinCache.getInstance(this).getBuiltinsFile();
- if (!psiFile.equals(builtins)) {
- VirtualFile vFile = psiFile.getVirtualFile();
- if (vFile != null) {
- final String packageName = QualifiedNameFinder.findShortestImportableName(this, vFile);
- return packageName + "." + name;
- }
- }
- return name;
+ return QualifiedNameFinder.getQualifiedName(this);
}
@Override
diff --git a/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java
index 2531b37bf8b2..86f84abb7fb6 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java
@@ -184,11 +184,11 @@ public class PyFunctionImpl extends PyPresentableElementImpl<PyFunctionStub> imp
}
}
if (context.maySwitchToAST(this) && LanguageLevel.forElement(this).isAtLeast(LanguageLevel.PYTHON30)) {
- PyAnnotation anno = getAnnotation();
- if (anno != null) {
- PyClass pyClass = anno.resolveToClass();
- if (pyClass != null) {
- return new PyClassTypeImpl(pyClass, false);
+ final PyAnnotation annotation = getAnnotation();
+ if (annotation != null) {
+ final PyType type = context.getType(annotation);
+ if (type != null) {
+ return type;
}
}
}
@@ -571,7 +571,7 @@ public class PyFunctionImpl extends PyPresentableElementImpl<PyFunctionStub> imp
@Override
public PyAnnotation getAnnotation() {
- return findChildByClass(PyAnnotation.class);
+ return getStubOrPsiChild(PyElementTypes.ANNOTATION);
}
@NotNull
@@ -699,21 +699,6 @@ public class PyFunctionImpl extends PyPresentableElementImpl<PyFunctionStub> imp
@Nullable
@Override
public String getQualifiedName() {
- String name = getName();
- if (name == null) {
- return null;
- }
- PyClass containingClass = getContainingClass();
- if (containingClass != null) {
- return containingClass.getQualifiedName() + "." + name;
- }
- if (PsiTreeUtil.getStubOrPsiParent(this) instanceof PyFile) {
- VirtualFile virtualFile = getContainingFile().getVirtualFile();
- if (virtualFile != null) {
- final String packageName = QualifiedNameFinder.findShortestImportableName(this, virtualFile);
- return packageName + "." + name;
- }
- }
- return null;
+ return QualifiedNameFinder.getQualifiedName(this);
}
}
diff --git a/python/src/com/jetbrains/python/psi/impl/PyNamedParameterImpl.java b/python/src/com/jetbrains/python/psi/impl/PyNamedParameterImpl.java
index bf792fef0dae..cc9178c07f9e 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyNamedParameterImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyNamedParameterImpl.java
@@ -181,11 +181,11 @@ public class PyNamedParameterImpl extends PyPresentableElementImpl<PyNamedParame
PyParameterList parameterList = (PyParameterList)parent;
PyFunction func = parameterList.getContainingFunction();
if (func != null) {
- PyAnnotation anno = getAnnotation();
- if (anno != null) {
- final PyClass pyClass = anno.resolveToClass();
- if (pyClass != null) {
- return new PyClassTypeImpl(pyClass, false);
+ final PyAnnotation annotation = getAnnotation();
+ if (annotation != null) {
+ final PyType type = context.getType(annotation);
+ if (type != null) {
+ return type;
}
}
StructuredDocString docString = func.getStructuredDocString();
diff --git a/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java
index 545e8e86cba1..3805c8df525e 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java
@@ -43,6 +43,7 @@ import com.jetbrains.python.psi.impl.references.PyQualifiedReference;
import com.jetbrains.python.psi.impl.references.PyTargetReference;
import com.jetbrains.python.psi.impl.stubs.CustomTargetExpressionStub;
import com.jetbrains.python.psi.resolve.PyResolveContext;
+import com.jetbrains.python.psi.resolve.QualifiedNameFinder;
import com.jetbrains.python.psi.resolve.RatedResolveResult;
import com.jetbrains.python.psi.stubs.PyClassStub;
import com.jetbrains.python.psi.stubs.PyFunctionStub;
@@ -707,4 +708,10 @@ public class PyTargetExpressionImpl extends PyPresentableElementImpl<PyTargetExp
super.subtreeChanged();
myQualifiedName = null;
}
+
+ @Nullable
+ @Override
+ public String getQualifiedName() {
+ return QualifiedNameFinder.getQualifiedName(this);
+ }
}
diff --git a/python/src/com/jetbrains/python/psi/resolve/PyResolveUtil.java b/python/src/com/jetbrains/python/psi/resolve/PyResolveUtil.java
index 838a4dbcc75a..f207169df77f 100644
--- a/python/src/com/jetbrains/python/psi/resolve/PyResolveUtil.java
+++ b/python/src/com/jetbrains/python/psi/resolve/PyResolveUtil.java
@@ -101,7 +101,13 @@ public class PyResolveUtil {
@Nullable PsiElement roof) {
// Use real context here to enable correct completion and resolve in case of PyExpressionCodeFragment!!!
final PsiElement realContext = PyPsiUtils.getRealContext(element);
- final ScopeOwner originalOwner = ScopeUtil.getScopeOwner(realContext);
+ final ScopeOwner originalOwner;
+ if (realContext != element && realContext instanceof PyFile) {
+ originalOwner = (PyFile)realContext;
+ }
+ else {
+ originalOwner = ScopeUtil.getScopeOwner(realContext);
+ }
final PsiElement parent = element.getParent();
final boolean isGlobalOrNonlocal = parent instanceof PyGlobalStatement || parent instanceof PyNonlocalStatement;
ScopeOwner owner = originalOwner;
diff --git a/python/src/com/jetbrains/python/psi/resolve/QualifiedNameFinder.java b/python/src/com/jetbrains/python/psi/resolve/QualifiedNameFinder.java
index 97a15da105c3..1c081eff9356 100644
--- a/python/src/com/jetbrains/python/psi/resolve/QualifiedNameFinder.java
+++ b/python/src/com/jetbrains/python/psi/resolve/QualifiedNameFinder.java
@@ -24,10 +24,14 @@ import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.jetbrains.python.PyNames;
+import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
+import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
import com.jetbrains.python.psi.PyClass;
+import com.jetbrains.python.psi.PyElement;
import com.jetbrains.python.psi.PyFile;
import com.jetbrains.python.psi.PyFunction;
import com.intellij.psi.util.QualifiedName;
+import com.jetbrains.python.psi.impl.PyBuiltinCache;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -156,6 +160,36 @@ public class QualifiedNameFinder {
return qname;
}
+ @Nullable
+ public static String getQualifiedName(@NotNull PyElement element) {
+ final String name = element.getName();
+ if (name != null) {
+ final ScopeOwner owner = ScopeUtil.getScopeOwner(element);
+ final PyBuiltinCache builtinCache = PyBuiltinCache.getInstance(element);
+ if (owner instanceof PyClass) {
+ final String classQName = ((PyClass)owner).getQualifiedName();
+ if (classQName != null) {
+ return classQName + "." + name;
+ }
+ }
+ else if (owner instanceof PyFile) {
+ if (builtinCache.isBuiltin(element)) {
+ return name;
+ }
+ else {
+ final VirtualFile virtualFile = ((PyFile)owner).getVirtualFile();
+ if (virtualFile != null) {
+ final String fileQName = findShortestImportableName(element, virtualFile);
+ if (fileQName != null) {
+ return fileQName + "." + name;
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
/**
* Tries to find roots that contain given vfile, and among them the root that contains at the smallest depth.
* For equal depth source root is in preference to library.
diff --git a/python/src/com/jetbrains/python/psi/stubs/PyClassNameIndex.java b/python/src/com/jetbrains/python/psi/stubs/PyClassNameIndex.java
index 814f450df8d2..14e1546c7e30 100644
--- a/python/src/com/jetbrains/python/psi/stubs/PyClassNameIndex.java
+++ b/python/src/com/jetbrains/python/psi/stubs/PyClassNameIndex.java
@@ -57,7 +57,7 @@ public class PyClassNameIndex extends StringStubIndexExtension<PyClass> {
int pos = qName.lastIndexOf(".");
String shortName = pos > 0 ? qName.substring(pos+1) : qName;
for (PyClass pyClass : find(shortName, project, scope)) {
- if (pyClass.getQualifiedName().equals(qName)) {
+ if (qName.equals(pyClass.getQualifiedName())) {
return pyClass;
}
}
diff --git a/python/src/com/jetbrains/python/psi/types/PyFunctionType.java b/python/src/com/jetbrains/python/psi/types/PyFunctionType.java
index 4bdbae69d83d..fe3633449b74 100644
--- a/python/src/com/jetbrains/python/psi/types/PyFunctionType.java
+++ b/python/src/com/jetbrains/python/psi/types/PyFunctionType.java
@@ -108,10 +108,14 @@ public class PyFunctionType implements PyCallableType {
*/
@Nullable
private PyClassTypeImpl selectFakeType(@Nullable PyExpression location, @NotNull TypeEvalContext context) {
- if (location instanceof PyReferenceExpression && isBoundMethodReference(((PyReferenceExpression)location), context)) {
- return PyBuiltinCache.getInstance(getCallable()).getObjectType(PyNames.FAKE_METHOD);
+ final String fakeClassName;
+ if (location instanceof PyReferenceExpression && isBoundMethodReference((PyReferenceExpression)location, context)) {
+ fakeClassName = PyNames.FAKE_METHOD;
}
- return PyBuiltinCache.getInstance(getCallable()).getObjectType(PyNames.FAKE_FUNCTION);
+ else {
+ fakeClassName = PyNames.FAKE_FUNCTION;
+ }
+ return PyBuiltinCache.getInstance(getCallable()).getObjectType(fakeClassName);
}
private boolean isBoundMethodReference(@NotNull PyReferenceExpression location, @NotNull TypeEvalContext context) {
diff --git a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java
index 9881d6cc106c..2e7c58c8201c 100644
--- a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java
+++ b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java
@@ -428,41 +428,39 @@ public class PyTypeChecker {
public static AnalyzeCallResults analyzeCall(@NotNull PyBinaryExpression expr, @NotNull TypeEvalContext context) {
final PsiPolyVariantReference ref = expr.getReference(PyResolveContext.noImplicits().withTypeEvalContext(context));
final ResolveResult[] resolveResult;
- if (ref != null) {
- resolveResult = ref.multiResolve(false);
- AnalyzeCallResults firstResults = null;
- for (ResolveResult result : resolveResult) {
- final PsiElement resolved = result.getElement();
- if (resolved instanceof PyTypedElement) {
- final PyTypedElement typedElement = (PyTypedElement)resolved;
- final PyType type = context.getType(typedElement);
- if (!(type instanceof PyFunctionType)) {
- return null;
- }
- final Callable callable = ((PyFunctionType)type).getCallable();
- final boolean isRight = PyNames.isRightOperatorName(typedElement.getName());
- final PyExpression arg = isRight ? expr.getLeftExpression() : expr.getRightExpression();
- final PyExpression receiver = isRight ? expr.getRightExpression() : expr.getLeftExpression();
- final PyParameter[] parameters = callable.getParameterList().getParameters();
- if (parameters.length >= 2) {
- final PyNamedParameter param = parameters[1].getAsNamed();
- if (arg != null && param != null) {
- final Map<PyExpression, PyNamedParameter> arguments = new LinkedHashMap<PyExpression, PyNamedParameter>();
- arguments.put(arg, param);
- final AnalyzeCallResults results = new AnalyzeCallResults(callable, receiver, arguments);
- if (firstResults == null) {
- firstResults = results;
- }
- if (match(context.getType(param), context.getType(arg), context)) {
- return results;
- }
+ resolveResult = ref.multiResolve(false);
+ AnalyzeCallResults firstResults = null;
+ for (ResolveResult result : resolveResult) {
+ final PsiElement resolved = result.getElement();
+ if (resolved instanceof PyTypedElement) {
+ final PyTypedElement typedElement = (PyTypedElement)resolved;
+ final PyType type = context.getType(typedElement);
+ if (!(type instanceof PyFunctionType)) {
+ return null;
+ }
+ final Callable callable = ((PyFunctionType)type).getCallable();
+ final boolean isRight = PyNames.isRightOperatorName(typedElement.getName());
+ final PyExpression arg = isRight ? expr.getLeftExpression() : expr.getRightExpression();
+ final PyExpression receiver = isRight ? expr.getRightExpression() : expr.getLeftExpression();
+ final PyParameter[] parameters = callable.getParameterList().getParameters();
+ if (parameters.length >= 2) {
+ final PyNamedParameter param = parameters[1].getAsNamed();
+ if (arg != null && param != null) {
+ final Map<PyExpression, PyNamedParameter> arguments = new LinkedHashMap<PyExpression, PyNamedParameter>();
+ arguments.put(arg, param);
+ final AnalyzeCallResults results = new AnalyzeCallResults(callable, receiver, arguments);
+ if (firstResults == null) {
+ firstResults = results;
+ }
+ if (match(context.getType(param), context.getType(arg), context)) {
+ return results;
}
}
}
}
- if (firstResults != null) {
- return firstResults;
- }
+ }
+ if (firstResults != null) {
+ return firstResults;
}
return null;
}
@@ -471,22 +469,20 @@ public class PyTypeChecker {
public static AnalyzeCallResults analyzeCall(@NotNull PySubscriptionExpression expr, @NotNull TypeEvalContext context) {
final PsiReference ref = expr.getReference(PyResolveContext.noImplicits().withTypeEvalContext(context));
final PsiElement resolved;
- if (ref != null) {
- resolved = ref.resolve();
- if (resolved instanceof PyTypedElement) {
- final PyType type = context.getType((PyTypedElement)resolved);
- if (type instanceof PyFunctionType) {
- final Callable callable = ((PyFunctionType)type).getCallable();
- final PyParameter[] parameters = callable.getParameterList().getParameters();
- if (parameters.length == 2) {
- final PyNamedParameter param = parameters[1].getAsNamed();
- if (param != null) {
- final Map<PyExpression, PyNamedParameter> arguments = new LinkedHashMap<PyExpression, PyNamedParameter>();
- final PyExpression arg = expr.getIndexExpression();
- if (arg != null) {
- arguments.put(arg, param);
- return new AnalyzeCallResults(callable, expr.getOperand(), arguments);
- }
+ resolved = ref.resolve();
+ if (resolved instanceof PyTypedElement) {
+ final PyType type = context.getType((PyTypedElement)resolved);
+ if (type instanceof PyFunctionType) {
+ final Callable callable = ((PyFunctionType)type).getCallable();
+ final PyParameter[] parameters = callable.getParameterList().getParameters();
+ if (parameters.length == 2) {
+ final PyNamedParameter param = parameters[1].getAsNamed();
+ if (param != null) {
+ final Map<PyExpression, PyNamedParameter> arguments = new LinkedHashMap<PyExpression, PyNamedParameter>();
+ final PyExpression arg = expr.getIndexExpression();
+ if (arg != null) {
+ arguments.put(arg, param);
+ return new AnalyzeCallResults(callable, expr.getOperand(), arguments);
}
}
}
diff --git a/python/src/com/jetbrains/python/refactoring/PyReplaceExpressionUtil.java b/python/src/com/jetbrains/python/refactoring/PyReplaceExpressionUtil.java
index 2cebb3ec2720..4a8d2b9d8551 100644
--- a/python/src/com/jetbrains/python/refactoring/PyReplaceExpressionUtil.java
+++ b/python/src/com/jetbrains/python/refactoring/PyReplaceExpressionUtil.java
@@ -61,21 +61,26 @@ public class PyReplaceExpressionUtil implements PyElementTypes {
private PyReplaceExpressionUtil() {}
+ /**
+ * @param oldExpr old expression that will be substituted
+ * @param newExpr new expression to substitute with
+ * @return whether new expression should be wrapped in parenthesis to preserve original semantics
+ */
public static boolean isNeedParenthesis(@NotNull final PyElement oldExpr, @NotNull final PyElement newExpr) {
final PyElement parentExpr = (PyElement)oldExpr.getParent();
if (parentExpr instanceof PyArgumentList) {
return newExpr instanceof PyTupleExpression;
}
- if (!(parentExpr instanceof PyExpression)) {
+ if (parentExpr instanceof PyParenthesizedExpression || !(parentExpr instanceof PyExpression)) {
return false;
}
- int newPriority = getExpressionPriority(newExpr);
- int parentPriority = getExpressionPriority(parentExpr);
+ final int newPriority = getExpressionPriority(newExpr);
+ final int parentPriority = getExpressionPriority(parentExpr);
if (parentPriority > newPriority) {
return true;
} else if (parentPriority == newPriority && parentPriority != 0) {
if (parentExpr instanceof PyBinaryExpression) {
- PyBinaryExpression binaryExpression = (PyBinaryExpression)parentExpr;
+ final PyBinaryExpression binaryExpression = (PyBinaryExpression)parentExpr;
if (isNotAssociative(binaryExpression) && oldExpr.equals(binaryExpression.getRightExpression())) {
return true;
}
diff --git a/python/src/com/jetbrains/python/refactoring/inline/PyInlineLocalHandler.java b/python/src/com/jetbrains/python/refactoring/inline/PyInlineLocalHandler.java
index 575399c61ceb..4f2dc65a22d3 100644
--- a/python/src/com/jetbrains/python/refactoring/inline/PyInlineLocalHandler.java
+++ b/python/src/com/jetbrains/python/refactoring/inline/PyInlineLocalHandler.java
@@ -29,18 +29,19 @@ import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.wm.WindowManager;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.PsiReference;
-import com.intellij.psi.PsiWhiteSpace;
+import com.intellij.psi.*;
+import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.util.CommonRefactoringUtil;
import com.intellij.refactoring.util.RefactoringMessageDialog;
+import com.intellij.util.Function;
import com.intellij.util.Query;
+import com.intellij.util.containers.ContainerUtil;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.PyTokenTypes;
import com.jetbrains.python.PythonLanguage;
@@ -51,6 +52,7 @@ import com.jetbrains.python.psi.impl.PyAugAssignmentStatementImpl;
import com.jetbrains.python.psi.impl.PyPsiUtils;
import com.jetbrains.python.refactoring.PyDefUseUtil;
import com.jetbrains.python.refactoring.PyReplaceExpressionUtil;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
@@ -61,7 +63,7 @@ import java.util.List;
*/
public class PyInlineLocalHandler extends InlineActionHandler {
private static final Logger LOG = Logger.getInstance(PyInlineLocalHandler.class.getName());
-
+
private static final String REFACTORING_NAME = RefactoringBundle.message("inline.variable.title");
private static final Pair<PyStatement, Boolean> EMPTY_DEF_RESULT = Pair.create(null, false);
private static final String HELP_ID = "python.reference.inline";
@@ -111,21 +113,21 @@ public class PyInlineLocalHandler extends InlineActionHandler {
final PyStatement def = defPair.first;
if (def == null || getValue(def) == null){
final String key = defPair.second ? "variable.has.no.dominating.definition" : "variable.has.no.initializer";
- String message = RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message(key, localName));
+ final String message = RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message(key, localName));
CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HELP_ID);
return;
}
if (def instanceof PyAssignmentStatement && ((PyAssignmentStatement)def).getTargets().length > 1){
highlightManager.addOccurrenceHighlights(editor, new PsiElement[] {def}, writeAttributes, true, null);
- String message = RefactoringBundle.getCannotRefactorMessage(PyBundle.message("refactoring.inline.local.multiassignment", localName));
+ final String message = RefactoringBundle.getCannotRefactorMessage(PyBundle.message("refactoring.inline.local.multiassignment", localName));
CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HELP_ID);
return;
}
final PsiElement[] refsToInline = PyDefUseUtil.getPostRefs(containerBlock, local, getObject(def));
if (refsToInline.length == 0) {
- String message = RefactoringBundle.message("variable.is.never.used", localName);
+ final String message = RefactoringBundle.message("variable.is.never.used", localName);
CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HELP_ID);
return;
}
@@ -133,11 +135,10 @@ public class PyInlineLocalHandler extends InlineActionHandler {
final TextAttributes attributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES);
if (editor != null && !ApplicationManager.getApplication().isUnitTestMode()) {
highlightManager.addOccurrenceHighlights(editor, refsToInline, attributes, true, null);
- int occurrencesCount = refsToInline.length;
- String occurencesString = RefactoringBundle.message("occurrences.string", occurrencesCount);
- final String promptKey = "inline.local.variable.prompt";
- final String question = RefactoringBundle.message(promptKey, localName) + " " + occurencesString;
- RefactoringMessageDialog dialog = new RefactoringMessageDialog(REFACTORING_NAME, question, HELP_ID, "OptionPane.questionIcon", true, project);
+ final int occurrencesCount = refsToInline.length;
+ final String occurrencesString = RefactoringBundle.message("occurrences.string", occurrencesCount);
+ final String question = RefactoringBundle.message("inline.local.variable.prompt", localName) + " " + occurrencesString;
+ final RefactoringMessageDialog dialog = new RefactoringMessageDialog(REFACTORING_NAME, question, HELP_ID, "OptionPane.questionIcon", true, project);
dialog.show();
if (!dialog.isOK()){
WindowManager.getInstance().getStatusBar(project).setInfo(RefactoringBundle.message("press.escape.to.remove.the.highlighting"));
@@ -145,11 +146,11 @@ public class PyInlineLocalHandler extends InlineActionHandler {
}
}
- PsiFile workingFile = local.getContainingFile();
+ final PsiFile workingFile = local.getContainingFile();
for (PsiElement ref : refsToInline) {
final PsiFile otherFile = ref.getContainingFile();
if (!otherFile.equals(workingFile)) {
- String message = RefactoringBundle.message("variable.is.referenced.in.multiple.files", localName);
+ final String message = RefactoringBundle.message("variable.is.referenced.in.multiple.files", localName);
CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HELP_ID);
return;
}
@@ -170,9 +171,8 @@ public class PyInlineLocalHandler extends InlineActionHandler {
if (editor != null) {
highlightManager.addOccurrenceHighlights(editor, defs, writeAttributes, true, null);
highlightManager.addOccurrenceHighlights(editor, new PsiElement[]{ref}, attributes, true, null);
- String message =
- RefactoringBundle
- .getCannotRefactorMessage(RefactoringBundle.message("variable.is.accessed.for.writing.and.used.with.inlined", localName));
+ final String message = RefactoringBundle.getCannotRefactorMessage(
+ RefactoringBundle.message("variable.is.accessed.for.writing.and.used.with.inlined", localName));
CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HELP_ID);
}
WindowManager.getInstance().getStatusBar(project).setInfo(RefactoringBundle.message("press.escape.to.remove.the.highlighting"));
@@ -185,7 +185,7 @@ public class PyInlineLocalHandler extends InlineActionHandler {
public void run() {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
public void run() {
- PsiElement[] exprs = new PsiElement[refsToInline.length];
+ final PsiElement[] exprs = new PsiElement[refsToInline.length];
final PyExpression value = prepareValue(def, localName, project);
final PyExpression withParent = PyElementGenerator.getInstance(project).createExpressionFromText("(" + value.getText() + ")");
final PsiElement lastChild = def.getLastChild();
@@ -195,7 +195,7 @@ public class PyInlineLocalHandler extends InlineActionHandler {
}
for (int i = 0, refsToInlineLength = refsToInline.length; i < refsToInlineLength; i++) {
- PsiElement element = refsToInline[i];
+ final PsiElement element = refsToInline[i];
if (PyReplaceExpressionUtil.isNeedParenthesis((PyExpression)element, value)) {
exprs[i] = element.replace(withParent);
} else {
@@ -207,6 +207,16 @@ public class PyInlineLocalHandler extends InlineActionHandler {
PyPsiUtils.removeElements(next);
}
PyPsiUtils.removeElements(def);
+
+ final List<TextRange> ranges = ContainerUtil.mapNotNull(exprs, new Function<PsiElement, TextRange>() {
+ @Override
+ public TextRange fun(PsiElement element) {
+ final PyStatement parentalStatement = PsiTreeUtil.getParentOfType(element, PyStatement.class, false);
+ return parentalStatement != null ? parentalStatement.getTextRange() : null;
+ }
+ });
+ CodeStyleManager.getInstance(project).reformatText(workingFile, ranges);
+
if (editor != null && !ApplicationManager.getApplication().isUnitTestMode()) {
highlightManager.addOccurrenceHighlights(editor, exprs, attributes, true, null);
WindowManager.getInstance().getStatusBar(project)
@@ -262,7 +272,7 @@ public class PyInlineLocalHandler extends InlineActionHandler {
}
@Nullable
- private static PyExpression getValue(PyStatement def) {
+ private static PyExpression getValue(@Nullable PyStatement def) {
if (def == null) return null;
if (def instanceof PyAssignmentStatement) {
return ((PyAssignmentStatement)def).getAssignedValue();
@@ -271,7 +281,7 @@ public class PyInlineLocalHandler extends InlineActionHandler {
}
@Nullable
- private static PyExpression getObject(PyStatement def) {
+ private static PyExpression getObject(@Nullable PyStatement def) {
if (def == null) return null;
if (def instanceof PyAssignmentStatement) {
return ((PyAssignmentStatement)def).getTargets()[0];
@@ -279,12 +289,15 @@ public class PyInlineLocalHandler extends InlineActionHandler {
return ((PyAugAssignmentStatement)def).getTarget();
}
- private static PyExpression prepareValue(PyStatement def, String localName, Project project) {
+ @NotNull
+ private static PyExpression prepareValue(@NotNull PyStatement def, @NotNull String localName, @NotNull Project project) {
final PyExpression value = getValue(def);
assert value != null;
if (def instanceof PyAugAssignmentStatementImpl) {
final PyAugAssignmentStatementImpl expression = (PyAugAssignmentStatementImpl)def;
- String op = expression.getOperation().getText().replace('=', ' ');
+ final PsiElement operation = expression.getOperation();
+ assert operation != null;
+ final String op = operation.getText().replace('=', ' ');
return PyElementGenerator.getInstance(project).createExpressionFromText(localName + " " + op + value.getText() + ")");
}
return value;
diff --git a/python/src/com/jetbrains/python/refactoring/surround/surrounders/statements/PyWithIfElseSurrounder.java b/python/src/com/jetbrains/python/refactoring/surround/surrounders/statements/PyWithIfElseSurrounder.java
index 76c4f4932038..1e1b6d0db815 100644
--- a/python/src/com/jetbrains/python/refactoring/surround/surrounders/statements/PyWithIfElseSurrounder.java
+++ b/python/src/com/jetbrains/python/refactoring/surround/surrounders/statements/PyWithIfElseSurrounder.java
@@ -44,7 +44,6 @@ public class PyWithIfElseSurrounder extends PyStatementSurrounder {
PyElementGenerator.getInstance(project).createFromText(LanguageLevel.getDefault(), PyIfStatement.class, "if True:\n pass\nelse: pass\n");
final PsiElement parent = elements[0].getParent();
final PyStatementList statementList = ifStatement.getIfPart().getStatementList();
- assert statementList != null;
statementList.addRange(elements[0], elements[elements.length - 1]);
statementList.deleteChildRange(statementList.getFirstChild(), statementList.getFirstChild());
diff --git a/python/src/com/jetbrains/python/refactoring/surround/surrounders/statements/PyWithIfSurrounder.java b/python/src/com/jetbrains/python/refactoring/surround/surrounders/statements/PyWithIfSurrounder.java
index 5ccca3de55e6..ac93e60af828 100644
--- a/python/src/com/jetbrains/python/refactoring/surround/surrounders/statements/PyWithIfSurrounder.java
+++ b/python/src/com/jetbrains/python/refactoring/surround/surrounders/statements/PyWithIfSurrounder.java
@@ -22,10 +22,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.util.IncorrectOperationException;
-import com.jetbrains.python.psi.LanguageLevel;
-import com.jetbrains.python.psi.PyElementGenerator;
-import com.jetbrains.python.psi.PyIfStatement;
-import com.jetbrains.python.psi.PyStatementList;
+import com.jetbrains.python.psi.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -40,7 +37,6 @@ public class PyWithIfSurrounder extends PyStatementSurrounder {
PyIfStatement ifStatement = PyElementGenerator.getInstance(project).createFromText(LanguageLevel.getDefault(), PyIfStatement.class, "if True:\n ");
final PsiElement parent = elements[0].getParent();
final PyStatementList statementList = ifStatement.getIfPart().getStatementList();
- assert statementList != null;
statementList.addRange(elements[0], elements[elements.length - 1]);
ifStatement = (PyIfStatement) parent.addBefore(ifStatement, elements[0]);
parent.deleteChildRange(elements[0], elements[elements.length - 1]);
@@ -49,7 +45,8 @@ public class PyWithIfSurrounder extends PyStatementSurrounder {
if (ifStatement == null) {
return null;
}
- return ifStatement.getIfPart().getCondition().getTextRange();
+ final PyExpression condition = ifStatement.getIfPart().getCondition();
+ return condition != null ? condition.getTextRange() : null;
}
public String getTemplateDescription() {
diff --git a/python/src/com/jetbrains/python/refactoring/surround/surrounders/statements/PyWithTryExceptSurrounder.java b/python/src/com/jetbrains/python/refactoring/surround/surrounders/statements/PyWithTryExceptSurrounder.java
index 25a9f26308d3..7466def257f4 100644
--- a/python/src/com/jetbrains/python/refactoring/surround/surrounders/statements/PyWithTryExceptSurrounder.java
+++ b/python/src/com/jetbrains/python/refactoring/surround/surrounders/statements/PyWithTryExceptSurrounder.java
@@ -44,7 +44,6 @@ public class PyWithTryExceptSurrounder extends PyStatementSurrounder {
createFromText(LanguageLevel.getDefault(), PyTryExceptStatement.class, getTemplate());
final PsiElement parent = elements[0].getParent();
final PyStatementList statementList = tryStatement.getTryPart().getStatementList();
- assert statementList != null;
statementList.addRange(elements[0], elements[elements.length - 1]);
statementList.getFirstChild().delete();
tryStatement = (PyTryExceptStatement)parent.addBefore(tryStatement, elements[0]);
@@ -71,7 +70,6 @@ public class PyWithTryExceptSurrounder extends PyStatementSurrounder {
protected TextRange getResultRange(PyTryExceptStatement tryStatement) {
final PyExceptPart part = tryStatement.getExceptParts()[0];
final PyStatementList list = part.getStatementList();
- assert list != null;
return list.getTextRange();
}
diff --git a/python/src/com/jetbrains/python/refactoring/surround/surrounders/statements/PyWithTryFinallySurrounder.java b/python/src/com/jetbrains/python/refactoring/surround/surrounders/statements/PyWithTryFinallySurrounder.java
index d457e32232c2..532fad5c5114 100644
--- a/python/src/com/jetbrains/python/refactoring/surround/surrounders/statements/PyWithTryFinallySurrounder.java
+++ b/python/src/com/jetbrains/python/refactoring/surround/surrounders/statements/PyWithTryFinallySurrounder.java
@@ -42,7 +42,6 @@ public class PyWithTryFinallySurrounder extends PyWithTryExceptSurrounder {
final PyFinallyPart finallyPart = tryStatement.getFinallyPart();
assert finallyPart != null;
final PyStatementList statementList = finallyPart.getStatementList();
- assert statementList != null;
return statementList.getTextRange();
}
}
diff --git a/python/src/com/jetbrains/python/refactoring/surround/surrounders/statements/PyWithWhileSurrounder.java b/python/src/com/jetbrains/python/refactoring/surround/surrounders/statements/PyWithWhileSurrounder.java
index 4ce663900065..a564d4ca3d3f 100644
--- a/python/src/com/jetbrains/python/refactoring/surround/surrounders/statements/PyWithWhileSurrounder.java
+++ b/python/src/com/jetbrains/python/refactoring/surround/surrounders/statements/PyWithWhileSurrounder.java
@@ -41,7 +41,6 @@ public class PyWithWhileSurrounder extends PyStatementSurrounder{
PyElementGenerator.getInstance(project).createFromText(LanguageLevel.getDefault(), PyWhileStatement.class, "while True:\n ");
final PsiElement parent = elements[0].getParent();
final PyStatementList statementList = whileStatement.getWhilePart().getStatementList();
- assert statementList != null;
statementList.addRange(elements[0], elements[elements.length - 1]);
whileStatement = (PyWhileStatement) parent.addBefore(whileStatement, elements[0]);
parent.deleteChildRange(elements[0], elements[elements.length - 1]);
diff --git a/python/src/com/jetbrains/python/run/AbstractPythonRunConfiguration.java b/python/src/com/jetbrains/python/run/AbstractPythonRunConfiguration.java
index 339f91ea7e3a..0927d2e37a3d 100644
--- a/python/src/com/jetbrains/python/run/AbstractPythonRunConfiguration.java
+++ b/python/src/com/jetbrains/python/run/AbstractPythonRunConfiguration.java
@@ -37,10 +37,10 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.util.PathMappingSettings;
import com.intellij.util.PlatformUtils;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.PythonModuleTypeBase;
-import com.intellij.util.PathMappingSettings;
import com.jetbrains.python.psi.PyClass;
import com.jetbrains.python.psi.PyFunction;
import com.jetbrains.python.sdk.PythonEnvUtil;
@@ -64,6 +64,7 @@ public abstract class AbstractPythonRunConfiguration<T extends AbstractRunConfig
private boolean myUseModuleSdk;
private boolean myAddContentRoots = true;
private boolean myAddSourceRoots = true;
+
protected PathMappingSettings myMappingSettings;
public AbstractPythonRunConfiguration(Project project, final ConfigurationFactory factory) {
diff --git a/python/src/com/jetbrains/python/run/PythonCommandLineState.java b/python/src/com/jetbrains/python/run/PythonCommandLineState.java
index 220939efc274..b1c768f0b012 100644
--- a/python/src/com/jetbrains/python/run/PythonCommandLineState.java
+++ b/python/src/com/jetbrains/python/run/PythonCommandLineState.java
@@ -141,7 +141,8 @@ public abstract class PythonCommandLineState extends CommandLineState {
protected void addTracebackFilter(Project project, ConsoleView consoleView, ProcessHandler processHandler) {
if (PySdkUtil.isRemote(myConfig.getSdk())) {
assert processHandler instanceof RemoteProcessHandlerBase;
- consoleView.addMessageFilter(new PyRemoteTracebackFilter(project, myConfig.getWorkingDirectory(), (RemoteProcessHandlerBase) processHandler));
+ consoleView
+ .addMessageFilter(new PyRemoteTracebackFilter(project, myConfig.getWorkingDirectory(), (RemoteProcessHandlerBase)processHandler));
}
else {
consoleView.addMessageFilter(new PythonTracebackFilter(project, myConfig.getWorkingDirectory()));
@@ -174,7 +175,8 @@ public abstract class PythonCommandLineState extends CommandLineState {
GeneralCommandLine commandLine = generateCommandLine(patchers);
// Extend command line
- PythonRunConfigurationExtensionsManager.getInstance().patchCommandLine(myConfig, getRunnerSettings(), commandLine, getEnvironment().getRunner().getRunnerId());
+ PythonRunConfigurationExtensionsManager.getInstance()
+ .patchCommandLine(myConfig, getRunnerSettings(), commandLine, getEnvironment().getRunner().getRunnerId());
Sdk sdk = PythonSdkType.findSdkByPath(myConfig.getInterpreterPath());
final ProcessHandler processHandler;
if (PySdkUtil.isRemote(sdk)) {
diff --git a/python/src/com/jetbrains/python/run/PythonRunConfiguration.java b/python/src/com/jetbrains/python/run/PythonRunConfiguration.java
index 118c27beb548..5efc8d465bc1 100644
--- a/python/src/com/jetbrains/python/run/PythonRunConfiguration.java
+++ b/python/src/com/jetbrains/python/run/PythonRunConfiguration.java
@@ -47,8 +47,10 @@ public class PythonRunConfiguration extends AbstractPythonRunConfiguration
public static final String SCRIPT_NAME = "SCRIPT_NAME";
public static final String PARAMETERS = "PARAMETERS";
public static final String MULTIPROCESS = "MULTIPROCESS";
+ public static final String SHOW_COMMAND_LINE = "SHOW_COMMAND_LINE";
private String myScriptName;
private String myScriptParameters;
+ private boolean myShowCommandLineAfterwards = false;
protected PythonRunConfiguration(Project project, ConfigurationFactory configurationFactory) {
super(project, configurationFactory);
@@ -98,17 +100,27 @@ public class PythonRunConfiguration extends AbstractPythonRunConfiguration
myScriptParameters = scriptParameters;
}
+ public boolean showCommandLineAfterwards() {
+ return myShowCommandLineAfterwards;
+ }
+
+ public void setShowCommandLineAfterwards(boolean showCommandLineAfterwards) {
+ myShowCommandLineAfterwards = showCommandLineAfterwards;
+ }
+
public void readExternal(Element element) throws InvalidDataException {
PathMacroManager.getInstance(getProject()).expandPaths(element);
super.readExternal(element);
myScriptName = JDOMExternalizerUtil.readField(element, SCRIPT_NAME);
myScriptParameters = JDOMExternalizerUtil.readField(element, PARAMETERS);
+ myShowCommandLineAfterwards = Boolean.parseBoolean(JDOMExternalizerUtil.readField(element, SHOW_COMMAND_LINE, "false"));
}
public void writeExternal(Element element) throws WriteExternalException {
super.writeExternal(element);
JDOMExternalizerUtil.writeField(element, SCRIPT_NAME, myScriptName);
JDOMExternalizerUtil.writeField(element, PARAMETERS, myScriptParameters);
+ JDOMExternalizerUtil.writeField(element, SHOW_COMMAND_LINE, Boolean.toString(myShowCommandLineAfterwards));
PathMacroManager.getInstance(getProject()).collapsePathsRecursively(element);
}
@@ -120,6 +132,7 @@ public class PythonRunConfiguration extends AbstractPythonRunConfiguration
AbstractPythonRunConfiguration.copyParams(source.getBaseParams(), target.getBaseParams());
target.setScriptName(source.getScriptName());
target.setScriptParameters(source.getScriptParameters());
+ target.setShowCommandLineAfterwards(source.showCommandLineAfterwards());
}
@Override
diff --git a/python/src/com/jetbrains/python/run/PythonRunConfigurationForm.form b/python/src/com/jetbrains/python/run/PythonRunConfigurationForm.form
index 1ba245143902..33e45b9c04ee 100644
--- a/python/src/com/jetbrains/python/run/PythonRunConfigurationForm.form
+++ b/python/src/com/jetbrains/python/run/PythonRunConfigurationForm.form
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.jetbrains.python.run.PythonRunConfigurationForm">
- <grid id="27dc6" binding="myRootPanel" layout-manager="GridLayoutManager" row-count="5" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="27dc6" binding="myRootPanel" layout-manager="GridLayoutManager" row-count="6" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="507" height="400"/>
@@ -44,7 +44,7 @@
</component>
<vspacer id="f8c96">
<constraints>
- <grid row="4" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+ <grid row="5" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<grid id="9b4b8" binding="myCommonOptionsPlaceholder" layout-manager="BorderLayout" hgap="0" vgap="0">
@@ -63,6 +63,15 @@
<border type="none"/>
<children/>
</grid>
+ <component id="99b13" class="com.intellij.ui.components.JBCheckBox" binding="myShowCommandLineCheckbox">
+ <constraints>
+ <grid row="4" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <selected value="true"/>
+ <text value="Show command line afterwards"/>
+ </properties>
+ </component>
</children>
</grid>
</form>
diff --git a/python/src/com/jetbrains/python/run/PythonRunConfigurationForm.java b/python/src/com/jetbrains/python/run/PythonRunConfigurationForm.java
index da041f961f80..cad905fd9618 100644
--- a/python/src/com/jetbrains/python/run/PythonRunConfigurationForm.java
+++ b/python/src/com/jetbrains/python/run/PythonRunConfigurationForm.java
@@ -25,6 +25,7 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.PanelWithAnchor;
import com.intellij.ui.RawCommandLineEditor;
+import com.intellij.ui.components.JBCheckBox;
import com.intellij.ui.components.JBLabel;
import com.jetbrains.python.debugger.PyDebuggerOptionsProvider;
import org.jetbrains.annotations.NotNull;
@@ -44,6 +45,7 @@ public class PythonRunConfigurationForm implements PythonRunConfigurationParams,
private final AbstractPyCommonOptionsForm myCommonOptionsForm;
private JComponent anchor;
private final Project myProject;
+ private JBCheckBox myShowCommandLineCheckbox;
public PythonRunConfigurationForm(PythonRunConfiguration configuration) {
myCommonOptionsForm = PyCommonOptionsFormFactory.getInstance().createForm(configuration.getCommonOptionsFormData());
@@ -105,6 +107,16 @@ public class PythonRunConfigurationForm implements PythonRunConfigurationParams,
}
@Override
+ public boolean showCommandLineAfterwards() {
+ return myShowCommandLineCheckbox.isSelected();
+ }
+
+ @Override
+ public void setShowCommandLineAfterwards(boolean showCommandLineAfterwards) {
+ myShowCommandLineCheckbox.setSelected(showCommandLineAfterwards);
+ }
+
+ @Override
public JComponent getAnchor() {
return anchor;
}
diff --git a/python/src/com/jetbrains/python/run/PythonScriptCommandLineState.java b/python/src/com/jetbrains/python/run/PythonScriptCommandLineState.java
index 81d2daaee3d0..cd92fdb34638 100644
--- a/python/src/com/jetbrains/python/run/PythonScriptCommandLineState.java
+++ b/python/src/com/jetbrains/python/run/PythonScriptCommandLineState.java
@@ -15,11 +15,37 @@
*/
package com.jetbrains.python.run;
+import com.google.common.collect.Lists;
+import com.intellij.execution.*;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.configurations.ParametersList;
import com.intellij.execution.configurations.ParamsGroup;
+import com.intellij.execution.executors.DefaultDebugExecutor;
+import com.intellij.execution.process.CommandLineArgumentsProvider;
+import com.intellij.execution.process.OSProcessHandler;
+import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.runners.ExecutionEnvironment;
+import com.intellij.execution.ui.RunContentDescriptor;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.progress.Task;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.ui.UIUtil;
+import com.jetbrains.python.PythonHelpersLocator;
+import com.jetbrains.python.console.PyConsoleType;
+import com.jetbrains.python.console.PydevConsoleRunner;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
/**
* @author yole
@@ -32,6 +58,34 @@ public class PythonScriptCommandLineState extends PythonCommandLineState {
myConfig = runConfiguration;
}
+ @NotNull
+ @Override
+ public ExecutionResult execute(Executor executor, final CommandLinePatcher... patchers) throws ExecutionException {
+ if (myConfig.showCommandLineAfterwards()) {
+ if (executor.getId() == DefaultDebugExecutor.EXECUTOR_ID) {
+ return super.execute(executor, ArrayUtil.append(patchers, new CommandLinePatcher() {
+ @Override
+ public void patchCommandLine(GeneralCommandLine commandLine) {
+ commandLine.getParametersList().getParamsGroup(PythonCommandLineState.GROUP_DEBUGGER).addParameterAt(1, "--cmd-line");
+ }
+ }));
+ }
+
+ PydevConsoleRunner runner =
+ new PythonScriptWithConsoleRunner(myConfig.getProject(), myConfig.getSdk(), PyConsoleType.PYTHON, myConfig.getWorkingDirectory(),
+ myConfig.getEnvs(), patchers);
+
+ runner.runSync();
+
+ List<AnAction> actions = Lists.newArrayList(createActions(runner.getConsoleView(), runner.getProcessHandler()));
+
+ return new DefaultExecutionResult(runner.getConsoleView(), runner.getProcessHandler(), actions.toArray(new AnAction[actions.size()]));
+ }
+ else {
+ return super.execute(executor, patchers);
+ }
+ }
+
@Override
protected void buildCommandLineParameters(GeneralCommandLine commandLine) {
ParametersList parametersList = commandLine.getParametersList();
@@ -53,4 +107,68 @@ public class PythonScriptCommandLineState extends PythonCommandLineState {
}
}
+ /**
+ * @author traff
+ */
+ public class PythonScriptWithConsoleRunner extends PydevConsoleRunner {
+
+ private CommandLinePatcher[] myPatchers;
+
+ public PythonScriptWithConsoleRunner(@NotNull Project project,
+ @NotNull Sdk sdk,
+ @NotNull PyConsoleType consoleType,
+ @Nullable String workingDir,
+ Map<String, String> environmentVariables,
+ CommandLinePatcher[] patchers,
+ String... statementsToExecute) {
+ super(project, sdk, consoleType, workingDir, environmentVariables, statementsToExecute);
+ myPatchers = patchers;
+ }
+
+ @Override
+ protected void createContentDescriptorAndActions() {
+ AnAction a = createConsoleExecAction(myConsoleExecuteActionHandler);
+ registerActionShortcuts(Lists.newArrayList(a), getConsoleView().getConsole().getConsoleEditor().getComponent());
+ }
+
+ @Override
+ protected CommandLineArgumentsProvider createCommandLineArgumentsProvider(final Sdk sdk,
+ final Map<String, String> environmentVariables,
+ int[] ports) {
+ final ArrayList<String> args = new ArrayList<String>();
+ args.add(sdk.getHomePath());
+ final String versionString = sdk.getVersionString();
+ if (versionString == null || !versionString.toLowerCase().contains("jython")) {
+ args.add("-u");
+ }
+ args.add(FileUtil.toSystemDependentName(PythonHelpersLocator.getHelperPath("pydev/pydev_run_in_console.py")));
+ for (int port : ports) {
+ args.add(String.valueOf(port));
+ }
+
+ try {
+ GeneralCommandLine cmd = generateCommandLine(myPatchers);
+ args.addAll(cmd.getParametersList().getList());
+ }
+ catch (Exception e) {
+ //pass
+ }
+ return new CommandLineArgumentsProvider() {
+ @Override
+ public String[] getArguments() {
+ return ArrayUtil.toStringArray(args);
+ }
+
+ @Override
+ public boolean passParentEnvs() {
+ return false;
+ }
+
+ @Override
+ public Map<String, String> getAdditionalEnvs() {
+ return addDefaultEnvironments(sdk, environmentVariables);
+ }
+ };
+ }
+ }
}
diff --git a/python/src/com/jetbrains/python/sdk/PySdkListCellRenderer.java b/python/src/com/jetbrains/python/sdk/PySdkListCellRenderer.java
index 1a42621dde3d..e165e59656f4 100644
--- a/python/src/com/jetbrains/python/sdk/PySdkListCellRenderer.java
+++ b/python/src/com/jetbrains/python/sdk/PySdkListCellRenderer.java
@@ -20,6 +20,7 @@ import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.SdkModificator;
import com.intellij.openapi.projectRoots.SdkType;
import com.intellij.openapi.util.IconLoader;
+import com.intellij.openapi.util.io.FileUtil;
import com.intellij.ui.LayeredIcon;
import com.intellij.ui.ListCellRendererWrapper;
import com.jetbrains.python.sdk.flavors.PythonSdkFlavor;
@@ -113,7 +114,7 @@ public class PySdkListCellRenderer extends ListCellRendererWrapper<Object> {
}
}
else if (new File(name).exists()) {
- name = "..." + File.separator + new File(name).getParentFile().getParentFile().getName();
+ name = FileUtil.getLocationRelativeToUserHome(name);
}
return name;
}
diff --git a/python/src/com/jetbrains/python/sdk/flavors/WinPythonSdkFlavor.java b/python/src/com/jetbrains/python/sdk/flavors/WinPythonSdkFlavor.java
index 8e75e634755b..9d22af8c03bf 100644
--- a/python/src/com/jetbrains/python/sdk/flavors/WinPythonSdkFlavor.java
+++ b/python/src/com/jetbrains/python/sdk/flavors/WinPythonSdkFlavor.java
@@ -15,7 +15,9 @@
*/
package com.jetbrains.python.sdk.flavors;
+import com.google.common.collect.ImmutableMap;
import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.io.WindowsRegistryUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
@@ -23,15 +25,17 @@ import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
import com.jetbrains.python.PythonHelpersLocator;
import java.io.File;
-import java.util.Collection;
-import java.util.Set;
-import java.util.TreeSet;
+import java.util.*;
/**
* @author yole
*/
public class WinPythonSdkFlavor extends CPythonSdkFlavor {
public static WinPythonSdkFlavor INSTANCE = new WinPythonSdkFlavor();
+ private static Map<String, String> ourRegistryMap =
+ ImmutableMap.of("HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore", "python.exe",
+ "HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Python\\PythonCore", "python.exe",
+ "HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython", "ipy.exe");
private WinPythonSdkFlavor() {
}
@@ -48,6 +52,7 @@ public class WinPythonSdkFlavor extends CPythonSdkFlavor {
for (String name : exe_names) {
findInstallations(candidates, name, "C:\\", "C:\\Program Files\\");
findInPath(candidates, name);
+ findInRegistry(candidates);
}
}
@@ -59,6 +64,7 @@ public class WinPythonSdkFlavor extends CPythonSdkFlavor {
public static void findInPath(Collection<String> candidates, String exeName) {
final String path = System.getenv("PATH");
+ if (path == null) return;
for (String pathEntry : StringUtil.split(path, ";")) {
if (pathEntry.startsWith("\"") && pathEntry.endsWith("\"")) {
if (pathEntry.length() < 2) continue;
@@ -71,6 +77,25 @@ public class WinPythonSdkFlavor extends CPythonSdkFlavor {
}
}
+ public static void findInRegistry(Collection<String> candidates) {
+ for (Map.Entry<String, String> entry : ourRegistryMap.entrySet()) {
+ final String prefix = entry.getKey();
+ final String exePath = entry.getValue();
+ List<String> strings = WindowsRegistryUtil.readRegistryBranch(prefix);
+ for (String string : strings) {
+ final String path =
+ WindowsRegistryUtil.readRegistryDefault(prefix + "\\" + string +
+ "\\InstallPath");
+ if (path != null) {
+ File f = new File(path, exePath);
+ if (f.exists()) {
+ candidates.add(FileUtil.toSystemDependentName(f.getPath()));
+ }
+ }
+ }
+ }
+ }
+
private static void findSubdirInstallations(Collection<String> candidates, String rootDir, String dir_prefix, String exe_name) {
VirtualFile rootVDir = LocalFileSystem.getInstance().findFileByPath(rootDir);
if (rootVDir != null) {
diff --git a/python/src/com/jetbrains/python/validation/CompatibilityVisitor.java b/python/src/com/jetbrains/python/validation/CompatibilityVisitor.java
index f48af7ff0e73..9be15944f37e 100644
--- a/python/src/com/jetbrains/python/validation/CompatibilityVisitor.java
+++ b/python/src/com/jetbrains/python/validation/CompatibilityVisitor.java
@@ -295,7 +295,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
}
}
commonRegisterProblem(message, " not support this syntax. Raise with no arguments can only be used in an except block",
- len, node, null);
+ len, node, null, false);
// raise 1, 2, 3
len = 0;
message = new StringBuilder(myCommonMessage);
diff --git a/python/testData/dotNet/whole_namespace.py b/python/testData/dotNet/whole_namespace.py
index b07fa0e7c1e3..163f6dfb225a 100644
--- a/python/testData/dotNet/whole_namespace.py
+++ b/python/testData/dotNet/whole_namespace.py
@@ -2,5 +2,5 @@ import clr
clr.AddReferenceByPartialName("SingleNameSpace")
-<caret>ingleNameSpace
+import <caret>SingleNameSpace
print SingleNameSpace.MyClass \ No newline at end of file
diff --git a/python/testData/formatter/reformatOfSingleElementPossible.py b/python/testData/formatter/reformatOfSingleElementPossible.py
new file mode 100644
index 000000000000..d97d8ab38f38
--- /dev/null
+++ b/python/testData/formatter/reformatOfSingleElementPossible.py
@@ -0,0 +1,2 @@
+x=[1,2,3]
+y='spam<caret>'*2 \ No newline at end of file
diff --git a/python/testData/formatter/reformatOfSingleElementPossible_after.py b/python/testData/formatter/reformatOfSingleElementPossible_after.py
new file mode 100644
index 000000000000..2528c032e2f1
--- /dev/null
+++ b/python/testData/formatter/reformatOfSingleElementPossible_after.py
@@ -0,0 +1,2 @@
+x=[1,2,3]
+y = 'spam' * 2 \ No newline at end of file
diff --git a/python/testData/highlighting/unsupportedFeaturesInPython3.py b/python/testData/highlighting/unsupportedFeaturesInPython3.py
index fce5f970f8ef..5a4f399b3f62 100644
--- a/python/testData/highlighting/unsupportedFeaturesInPython3.py
+++ b/python/testData/highlighting/unsupportedFeaturesInPython3.py
@@ -18,7 +18,7 @@ try:
<error descr="Python version 3.0 does not have module __builtin__">import __builtin__</error>
-<error descr="Python version 3.0 does not support this syntax. Raise with no arguments can only be used in an except block">raise</error>
+<warning descr="Python version 3.0 does not support this syntax. Raise with no arguments can only be used in an except block">raise</warning>
try:
pass
diff --git a/python/testData/inspections/DefaultArgumentEmptyList.py b/python/testData/inspections/DefaultArgumentEmptyList.py
new file mode 100644
index 000000000000..55748eb449d5
--- /dev/null
+++ b/python/testData/inspections/DefaultArgumentEmptyList.py
@@ -0,0 +1 @@
+def foo(args=<warning descr="Default argument value is mutable">[<caret>]</warning>):<EOLError descr="Indent expected"></EOLError> \ No newline at end of file
diff --git a/python/testData/inspections/DefaultArgumentEmptyList_after.py b/python/testData/inspections/DefaultArgumentEmptyList_after.py
new file mode 100644
index 000000000000..2de1bb88ef92
--- /dev/null
+++ b/python/testData/inspections/DefaultArgumentEmptyList_after.py
@@ -0,0 +1,3 @@
+def foo(args=None):
+ if not args:
+ args = [] \ No newline at end of file
diff --git a/python/testData/inspections/DefaultArgument_after.py b/python/testData/inspections/DefaultArgument_after.py
index e2036d24bf53..8007f9411df1 100644
--- a/python/testData/inspections/DefaultArgument_after.py
+++ b/python/testData/inspections/DefaultArgument_after.py
@@ -1,3 +1,4 @@
def foo(args=None):
- if not args: args = []
+ if not args:
+ args = []
pass \ No newline at end of file
diff --git a/python/testData/inspections/ReplacePrintComment.py b/python/testData/inspections/ReplacePrintComment.py
new file mode 100644
index 000000000000..1cf3778b69b1
--- /dev/null
+++ b/python/testData/inspections/ReplacePrintComment.py
@@ -0,0 +1 @@
+<warning descr="Statement seems to have no effect and can be replaced with function call to have effect">print</warning><error descr="End of statement expected"> </error><warning descr="Statement seems to have no effect">'%s %s %s %s' % bar</warning> # <- doesn't work either \ No newline at end of file
diff --git a/python/testData/inspections/ReplacePrintComment_after.py b/python/testData/inspections/ReplacePrintComment_after.py
new file mode 100644
index 000000000000..416deb8fd16e
--- /dev/null
+++ b/python/testData/inspections/ReplacePrintComment_after.py
@@ -0,0 +1 @@
+print('%s %s %s %s' % bar) # <- doesn't work either
diff --git a/python/testData/inspections/ReplacePrintEnd.py b/python/testData/inspections/ReplacePrintEnd.py
new file mode 100644
index 000000000000..afc37fbe2840
--- /dev/null
+++ b/python/testData/inspections/ReplacePrintEnd.py
@@ -0,0 +1 @@
+<warning descr="Statement seems to have no effect and can be replaced with function call to have effect">print</warning><error descr="End of statement expected"> </error><warning descr="Statement seems to have no effect">var,</warning> \ No newline at end of file
diff --git a/python/testData/inspections/ReplacePrintEnd_after.py b/python/testData/inspections/ReplacePrintEnd_after.py
new file mode 100644
index 000000000000..bae6b0c068a7
--- /dev/null
+++ b/python/testData/inspections/ReplacePrintEnd_after.py
@@ -0,0 +1 @@
+print(var, end=' ')
diff --git a/python/testData/intentions/afterDocStubKeywordOnly.py b/python/testData/intentions/afterDocStubKeywordOnly.py
index c65f5e99a856..161b9c14c960 100644
--- a/python/testData/intentions/afterDocStubKeywordOnly.py
+++ b/python/testData/intentions/afterDocStubKeywordOnly.py
@@ -1,4 +1,4 @@
-def f(my, *, param, **args):
+def foo(my, *, param, **args):
"""
:param my:
diff --git a/python/testData/intentions/afterImportToImportFrom.py b/python/testData/intentions/afterImportToImportFrom.py
new file mode 100644
index 000000000000..45b576a58c94
--- /dev/null
+++ b/python/testData/intentions/afterImportToImportFrom.py
@@ -0,0 +1,9 @@
+from __builtin__ import staticmethod, divmod
+
+quotient, rem = divmod(42, 3)
+
+// PY-11074
+class MyClass(object):
+ @staticmethod
+ def method():
+ pass \ No newline at end of file
diff --git a/python/testData/intentions/beforeDocStubKeywordOnly.py b/python/testData/intentions/beforeDocStubKeywordOnly.py
index b87a414f3a74..d0534c4dc01c 100644
--- a/python/testData/intentions/beforeDocStubKeywordOnly.py
+++ b/python/testData/intentions/beforeDocStubKeywordOnly.py
@@ -1,2 +1,2 @@
-def f(my, <caret>*, param, **args):
+def f<caret>oo(my, *, param, **args):
pass \ No newline at end of file
diff --git a/python/testData/intentions/beforeImportToImportFrom.py b/python/testData/intentions/beforeImportToImportFrom.py
new file mode 100644
index 000000000000..88b5894a01e4
--- /dev/null
+++ b/python/testData/intentions/beforeImportToImportFrom.py
@@ -0,0 +1,9 @@
+import __builtin<caret>__ as b
+
+quotient, rem = b.divmod(42, 3)
+
+// PY-11074
+class MyClass(object):
+ @b.staticmethod
+ def method():
+ pass \ No newline at end of file
diff --git a/python/testData/refactoring/inlinelocal/py5832.after.py b/python/testData/refactoring/inlinelocal/py5832.after.py
index 6b78080fbe57..bde7ba338a65 100644
--- a/python/testData/refactoring/inlinelocal/py5832.after.py
+++ b/python/testData/refactoring/inlinelocal/py5832.after.py
@@ -1,3 +1,5 @@
def foo(arg):
print arg
+
+
foo(('a', 'b')) \ No newline at end of file
diff --git a/python/testData/refactoring/inlinelocal/referenceInParenthesis.after.py b/python/testData/refactoring/inlinelocal/referenceInParenthesis.after.py
new file mode 100644
index 000000000000..67bea27b020e
--- /dev/null
+++ b/python/testData/refactoring/inlinelocal/referenceInParenthesis.after.py
@@ -0,0 +1,3 @@
+print ('spam!' * 42)
+('spam!' * 42)
+hex('spam!' * 42) \ No newline at end of file
diff --git a/python/testData/refactoring/inlinelocal/referenceInParenthesis.before.py b/python/testData/refactoring/inlinelocal/referenceInParenthesis.before.py
new file mode 100644
index 000000000000..da3059f478cd
--- /dev/null
+++ b/python/testData/refactoring/inlinelocal/referenceInParenthesis.before.py
@@ -0,0 +1,5 @@
+x<caret> = 'spam!' * 42
+
+print (x)
+(x)
+hex(x) \ No newline at end of file
diff --git a/python/testData/refactoring/inlinelocal/resultExceedsRightMargin.after.py b/python/testData/refactoring/inlinelocal/resultExceedsRightMargin.after.py
new file mode 100644
index 000000000000..acc61d6ec5ae
--- /dev/null
+++ b/python/testData/refactoring/inlinelocal/resultExceedsRightMargin.after.py
@@ -0,0 +1,3 @@
+result = '123456789|123456789|123456789|123456789|123456789|' + \
+ '123456789|123456789|123456789|123456789|123456789|' + \
+ '123456789|123456789|123456789|123456789|123456789|' \ No newline at end of file
diff --git a/python/testData/refactoring/inlinelocal/resultExceedsRightMargin.before.py b/python/testData/refactoring/inlinelocal/resultExceedsRightMargin.before.py
new file mode 100644
index 000000000000..8910b0d40270
--- /dev/null
+++ b/python/testData/refactoring/inlinelocal/resultExceedsRightMargin.before.py
@@ -0,0 +1,3 @@
+s = '123456789|123456789|123456789|123456789|123456789|'
+
+result = s + s + s \ No newline at end of file
diff --git a/python/testData/typing/typing.py b/python/testData/typing/typing.py
new file mode 100644
index 000000000000..1fbd5fc8081b
--- /dev/null
+++ b/python/testData/typing/typing.py
@@ -0,0 +1,582 @@
+"""Static type checking helpers"""
+
+from abc import ABCMeta, abstractmethod, abstractproperty
+import inspect
+import sys
+import re
+
+
+__all__ = [
+ # Type system related
+ 'AbstractGeneric',
+ 'AbstractGenericMeta',
+ 'Any',
+ 'AnyStr',
+ 'Dict',
+ 'Function',
+ 'Generic',
+ 'GenericMeta',
+ 'IO',
+ 'List',
+ 'Match',
+ 'Pattern',
+ 'Protocol',
+ 'Set',
+ 'Tuple',
+ 'Undefined',
+ 'Union',
+ 'cast',
+ 'forwardref',
+ 'overload',
+ 'typevar',
+ # Protocols and abstract base classes
+ 'Container',
+ 'Iterable',
+ 'Iterator',
+ 'Sequence',
+ 'Sized',
+ 'AbstractSet',
+ 'Mapping',
+ 'BinaryIO',
+ 'TextIO',
+]
+
+
+def builtinclass(cls):
+ """Mark a class as a built-in/extension class for type checking."""
+ return cls
+
+
+def ducktype(type):
+ """Return a duck type declaration decorator.
+
+ The decorator only affects type checking.
+ """
+ def decorator(cls):
+ return cls
+ return decorator
+
+
+def disjointclass(type):
+ """Return a disjoint class declaration decorator.
+
+ The decorator only affects type checking.
+ """
+ def decorator(cls):
+ return cls
+ return decorator
+
+
+class GenericMeta(type):
+ """Metaclass for generic classes that support indexing by types."""
+
+ def __getitem__(self, args):
+ # Just ignore args; they are for compile-time checks only.
+ return self
+
+
+class Generic(metaclass=GenericMeta):
+ """Base class for generic classes."""
+
+
+class AbstractGenericMeta(ABCMeta):
+ """Metaclass for abstract generic classes that support type indexing.
+
+ This is used for both protocols and ordinary abstract classes.
+ """
+
+ def __new__(mcls, name, bases, namespace):
+ cls = super().__new__(mcls, name, bases, namespace)
+ # 'Protocol' must be an explicit base class in order for a class to
+ # be a protocol.
+ cls._is_protocol = name == 'Protocol' or Protocol in bases
+ return cls
+
+ def __getitem__(self, args):
+ # Just ignore args; they are for compile-time checks only.
+ return self
+
+
+class Protocol(metaclass=AbstractGenericMeta):
+ """Base class for protocol classes."""
+
+ @classmethod
+ def __subclasshook__(cls, c):
+ if not cls._is_protocol:
+ # No structural checks since this isn't a protocol.
+ return NotImplemented
+
+ if cls is Protocol:
+ # Every class is a subclass of the empty protocol.
+ return True
+
+ # Find all attributes defined in the protocol.
+ attrs = cls._get_protocol_attrs()
+
+ for attr in attrs:
+ if not any(attr in d.__dict__ for d in c.__mro__):
+ return NotImplemented
+ return True
+
+ @classmethod
+ def _get_protocol_attrs(cls):
+ # Get all Protocol base classes.
+ protocol_bases = []
+ for c in cls.__mro__:
+ if getattr(c, '_is_protocol', False) and c.__name__ != 'Protocol':
+ protocol_bases.append(c)
+
+ # Get attributes included in protocol.
+ attrs = set()
+ for base in protocol_bases:
+ for attr in base.__dict__.keys():
+ # Include attributes not defined in any non-protocol bases.
+ for c in cls.__mro__:
+ if (c is not base and attr in c.__dict__ and
+ not getattr(c, '_is_protocol', False)):
+ break
+ else:
+ if (not attr.startswith('_abc_') and
+ attr != '__abstractmethods__' and
+ attr != '_is_protocol' and
+ attr != '__dict__' and
+ attr != '_get_protocol_attrs' and
+ attr != '__module__'):
+ attrs.add(attr)
+
+ return attrs
+
+
+class AbstractGeneric(metaclass=AbstractGenericMeta):
+ """Base class for abstract generic classes."""
+
+
+class TypeAlias:
+ """Class for defining generic aliases for library types."""
+
+ def __init__(self, target_type):
+ self.target_type = target_type
+
+ def __getitem__(self, typeargs):
+ return self.target_type
+
+
+Traceback = object() # TODO proper type object
+
+
+# Define aliases for built-in types that support indexing.
+List = TypeAlias(list)
+Dict = TypeAlias(dict)
+Set = TypeAlias(set)
+Tuple = TypeAlias(tuple)
+Function = TypeAlias(callable)
+Pattern = TypeAlias(type(re.compile('')))
+Match = TypeAlias(type(re.match('', '')))
+
+def union(x): return x
+
+Union = TypeAlias(union)
+
+class typevar:
+ def __init__(self, name, *, values=None):
+ self.name = name
+ self.values = values
+
+
+# Predefined type variables.
+AnyStr = typevar('AnyStr', values=(str, bytes))
+
+
+class forwardref:
+ def __init__(self, name):
+ self.name = name
+
+
+def Any(x):
+ """The Any type; can also be used to cast a value to type Any."""
+ return x
+
+def cast(type, object):
+ """Cast a value to a type.
+
+ This only affects static checking; simply return object at runtime.
+ """
+ return object
+
+
+def overload(func):
+ """Function decorator for defining overloaded functions."""
+ frame = sys._getframe(1)
+ locals = frame.f_locals
+ # See if there is a previous overload variant available. Also verify
+ # that the existing function really is overloaded: otherwise, replace
+ # the definition. The latter is actually important if we want to reload
+ # a library module such as genericpath with a custom one that uses
+ # overloading in the implementation.
+ if func.__name__ in locals and hasattr(locals[func.__name__], 'dispatch'):
+ orig_func = locals[func.__name__]
+
+ def wrapper(*args, **kwargs):
+ ret, ok = orig_func.dispatch(*args, **kwargs)
+ if ok:
+ return ret
+ return func(*args, **kwargs)
+ wrapper.isoverload = True
+ wrapper.dispatch = make_dispatcher(func, orig_func.dispatch)
+ wrapper.next = orig_func
+ wrapper.__name__ = func.__name__
+ if hasattr(func, '__isabstractmethod__'):
+ # Note that we can't reliably check that abstractmethod is
+ # used consistently across overload variants, so we let a
+ # static checker do it.
+ wrapper.__isabstractmethod__ = func.__isabstractmethod__
+ return wrapper
+ else:
+ # Return the initial overload variant.
+ func.isoverload = True
+ func.dispatch = make_dispatcher(func)
+ func.next = None
+ return func
+
+
+def is_erased_type(t):
+ return t is Any or isinstance(t, typevar)
+
+
+def make_dispatcher(func, previous=None):
+ """Create argument dispatcher for an overloaded function.
+
+ Also handle chaining of multiple overload variants.
+ """
+ (args, varargs, varkw, defaults,
+ kwonlyargs, kwonlydefaults, annotations) = inspect.getfullargspec(func)
+
+ argtypes = []
+ for arg in args:
+ ann = annotations.get(arg)
+ if isinstance(ann, forwardref):
+ ann = ann.name
+ if is_erased_type(ann):
+ ann = None
+ elif isinstance(ann, str):
+ # The annotation is a string => evaluate it lazily when the
+ # overloaded function is first called.
+ frame = sys._getframe(2)
+ t = [None]
+ ann_str = ann
+ def check(x):
+ if not t[0]:
+ # Evaluate string in the context of the overload caller.
+ t[0] = eval(ann_str, frame.f_globals, frame.f_locals)
+ if is_erased_type(t[0]):
+ # Anything goes.
+ t[0] = object
+ if isinstance(t[0], type):
+ return isinstance(x, t[0])
+ else:
+ return t[0](x)
+ ann = check
+ argtypes.append(ann)
+
+ maxargs = len(argtypes)
+ minargs = maxargs
+ if defaults:
+ minargs = len(argtypes) - len(defaults)
+
+ def dispatch(*args, **kwargs):
+ if previous:
+ ret, ok = previous(*args, **kwargs)
+ if ok:
+ return ret, ok
+
+ nargs = len(args)
+ if nargs < minargs or nargs > maxargs:
+ # Invalid argument count.
+ return None, False
+
+ for i in range(nargs):
+ argtype = argtypes[i]
+ if argtype:
+ if isinstance(argtype, type):
+ if not isinstance(args[i], argtype):
+ break
+ else:
+ if not argtype(args[i]):
+ break
+ else:
+ return func(*args, **kwargs), True
+ return None, False
+ return dispatch
+
+
+class Undefined:
+ """Class that represents an undefined value with a specified type.
+
+ At runtime the name Undefined is bound to an instance of this
+ class. The intent is that any operation on an Undefined object
+ raises an exception, including use in a boolean context. Some
+ operations cannot be disallowed: Undefined can be used as an
+ operand of 'is', and it can be assigned to variables and stored in
+ containers.
+
+ 'Undefined' makes it possible to declare the static type of a
+ variable even if there is no useful default value to initialize it
+ with:
+
+ from typing import Undefined
+ x = Undefined(int)
+ y = Undefined # type: int
+
+ The latter form can be used if efficiency is of utmost importance,
+ since it saves a call operation and potentially additional
+ operations needed to evaluate a type expression. Undefined(x)
+ just evaluates to Undefined, ignoring the argument value.
+ """
+
+ def __repr__(self):
+ return '<typing.Undefined>'
+
+ def __setattr__(self, attr, value):
+ raise AttributeError("'Undefined' object has no attribute '%s'" % attr)
+
+ def __eq__(self, other):
+ raise TypeError("'Undefined' object cannot be compared")
+
+ def __call__(self, type):
+ return self
+
+ def __bool__(self):
+ raise TypeError("'Undefined' object is not valid as a boolean")
+
+
+Undefined = Undefined()
+
+
+# Abstract classes
+
+
+T = typevar('T')
+KT = typevar('KT')
+VT = typevar('VT')
+
+
+class SupportsInt(Protocol):
+ @abstractmethod
+ def __int__(self) -> int: pass
+
+
+class SupportsFloat(Protocol):
+ @abstractmethod
+ def __float__(self) -> float: pass
+
+
+class SupportsAbs(Protocol[T]):
+ @abstractmethod
+ def __abs__(self) -> T: pass
+
+
+class SupportsRound(Protocol[T]):
+ @abstractmethod
+ def __round__(self, ndigits: int = 0) -> T: pass
+
+
+class Reversible(Protocol[T]):
+ @abstractmethod
+ def __reversed__(self) -> 'Iterator[T]': pass
+
+
+class Sized(Protocol):
+ @abstractmethod
+ def __len__(self) -> int: pass
+
+
+class Container(Protocol[T]):
+ @abstractmethod
+ def __contains__(self, x) -> bool: pass
+
+
+class Iterable(Protocol[T]):
+ @abstractmethod
+ def __iter__(self) -> 'Iterator[T]': pass
+
+
+class Iterator(Iterable[T], Protocol[T]):
+ @abstractmethod
+ def __next__(self) -> T: pass
+
+
+class Sequence(Sized, Iterable[T], Container[T], AbstractGeneric[T]):
+ @abstractmethod
+ @overload
+ def __getitem__(self, i: int) -> T: pass
+
+ @abstractmethod
+ @overload
+ def __getitem__(self, s: slice) -> 'Sequence[T]': pass
+
+ @abstractmethod
+ def __reversed__(self, s: slice) -> Iterator[T]: pass
+
+ @abstractmethod
+ def index(self, x) -> int: pass
+
+ @abstractmethod
+ def count(self, x) -> int: pass
+
+
+for t in list, tuple, str, bytes, range:
+ Sequence.register(t)
+
+
+class AbstractSet(Sized, Iterable[T], AbstractGeneric[T]):
+ @abstractmethod
+ def __contains__(self, x: object) -> bool: pass
+ @abstractmethod
+ def __and__(self, s: 'AbstractSet[T]') -> 'AbstractSet[T]': pass
+ @abstractmethod
+ def __or__(self, s: 'AbstractSet[T]') -> 'AbstractSet[T]': pass
+ @abstractmethod
+ def __sub__(self, s: 'AbstractSet[T]') -> 'AbstractSet[T]': pass
+ @abstractmethod
+ def __xor__(self, s: 'AbstractSet[T]') -> 'AbstractSet[T]': pass
+ @abstractmethod
+ def isdisjoint(self, s: 'AbstractSet[T]') -> bool: pass
+
+
+for t in set, frozenset, type({}.keys()), type({}.items()):
+ AbstractSet.register(t)
+
+
+class Mapping(Sized, Iterable[KT], AbstractGeneric[KT, VT]):
+ @abstractmethod
+ def __getitem__(self, k: KT) -> VT: pass
+ @abstractmethod
+ def __setitem__(self, k: KT, v: VT) -> None: pass
+ @abstractmethod
+ def __delitem__(self, v: KT) -> None: pass
+ @abstractmethod
+ def __contains__(self, o: object) -> bool: pass
+
+ @abstractmethod
+ def clear(self) -> None: pass
+ @abstractmethod
+ def copy(self) -> 'Mapping[KT, VT]': pass
+ @overload
+ @abstractmethod
+ def get(self, k: KT) -> VT: pass
+ @overload
+ @abstractmethod
+ def get(self, k: KT, default: VT) -> VT: pass
+ @overload
+ @abstractmethod
+ def pop(self, k: KT) -> VT: pass
+ @overload
+ @abstractmethod
+ def pop(self, k: KT, default: VT) -> VT: pass
+ @abstractmethod
+ def popitem(self) -> Tuple[KT, VT]: pass
+ @overload
+ @abstractmethod
+ def setdefault(self, k: KT) -> VT: pass
+ @overload
+ @abstractmethod
+ def setdefault(self, k: KT, default: VT) -> VT: pass
+
+ @overload
+ @abstractmethod
+ def update(self, m: 'Mapping[KT, VT]') -> None: pass
+ @overload
+ @abstractmethod
+ def update(self, m: Iterable[Tuple[KT, VT]]) -> None: pass
+
+ @abstractmethod
+ def keys(self) -> AbstractSet[KT]: pass
+ @abstractmethod
+ def values(self) -> AbstractSet[VT]: pass
+ @abstractmethod
+ def items(self) -> AbstractSet[Tuple[KT, VT]]: pass
+
+
+# TODO Consider more types: os.environ, etc. However, these add dependencies.
+Mapping.register(dict)
+
+
+# Note that the BinaryIO and TextIO classes must be in sync with typing module
+# stubs.
+
+
+class IO(AbstractGeneric[AnyStr]):
+ @abstractproperty
+ def mode(self) -> str: pass
+ @abstractproperty
+ def name(self) -> str: pass
+ @abstractmethod
+ def close(self) -> None: pass
+ @abstractmethod
+ def closed(self) -> bool: pass
+ @abstractmethod
+ def fileno(self) -> int: pass
+ @abstractmethod
+ def flush(self) -> None: pass
+ @abstractmethod
+ def isatty(self) -> bool: pass
+ @abstractmethod
+ def read(self, n: int = -1) -> AnyStr: pass
+ @abstractmethod
+ def readable(self) -> bool: pass
+ @abstractmethod
+ def readline(self, limit: int = -1) -> AnyStr: pass
+ @abstractmethod
+ def readlines(self, hint: int = -1) -> List[AnyStr]: pass
+ @abstractmethod
+ def seek(self, offset: int, whence: int = 0) -> int: pass
+ @abstractmethod
+ def seekable(self) -> bool: pass
+ @abstractmethod
+ def tell(self) -> int: pass
+ @abstractmethod
+ def truncate(self, size: int = None) -> int: pass
+ @abstractmethod
+ def writable(self) -> bool: pass
+ @abstractmethod
+ def write(self, s: AnyStr) -> int: pass
+ @abstractmethod
+ def writelines(self, lines: List[AnyStr]) -> None: pass
+
+ @abstractmethod
+ def __enter__(self) -> 'IO[AnyStr]': pass
+ @abstractmethod
+ def __exit__(self, type, value, traceback) -> None: pass
+
+
+class BinaryIO(IO[bytes]):
+ @overload
+ @abstractmethod
+ def write(self, s: bytes) -> int: pass
+ @overload
+ @abstractmethod
+ def write(self, s: bytearray) -> int: pass
+
+ @abstractmethod
+ def __enter__(self) -> 'BinaryIO': pass
+
+
+class TextIO(IO[str]):
+ @abstractproperty
+ def buffer(self) -> BinaryIO: pass
+ @abstractproperty
+ def encoding(self) -> str: pass
+ @abstractproperty
+ def errors(self) -> str: pass
+ @abstractproperty
+ def line_buffering(self) -> bool: pass
+ @abstractproperty
+ def newlines(self) -> Any: pass
+ @abstractmethod
+ def __enter__(self) -> 'TextIO': pass
+
+
+# TODO Register IO/TextIO/BinaryIO as the base class of file-like types.
+
+
+del t
diff --git a/python/testSrc/com/jetbrains/python/PyFillParagraphTest.java b/python/testSrc/com/jetbrains/python/PyFillParagraphTest.java
index 0a26253aec56..287c65f9e8a1 100644
--- a/python/testSrc/com/jetbrains/python/PyFillParagraphTest.java
+++ b/python/testSrc/com/jetbrains/python/PyFillParagraphTest.java
@@ -22,6 +22,7 @@ import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
+import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.jetbrains.python.fixtures.PyTestCase;
/**
@@ -62,7 +63,8 @@ public class PyFillParagraphTest extends PyTestCase {
}
public void testEnter() {
- final CodeStyleSettings settings = CodeStyleSettingsManager.getInstance(myFixture.getProject()).getCurrentSettings();
+ final CommonCodeStyleSettings settings =
+ CodeStyleSettingsManager.getInstance(myFixture.getProject()).getCurrentSettings().getCommonSettings(PythonLanguage.getInstance());
int oldValue = settings.RIGHT_MARGIN;
settings.RIGHT_MARGIN = 80;
try {
diff --git a/python/testSrc/com/jetbrains/python/PyFormatterTest.java b/python/testSrc/com/jetbrains/python/PyFormatterTest.java
index 36805442a1ea..35a97e03efae 100644
--- a/python/testSrc/com/jetbrains/python/PyFormatterTest.java
+++ b/python/testSrc/com/jetbrains/python/PyFormatterTest.java
@@ -21,10 +21,12 @@ import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
+import com.intellij.psi.util.PsiTreeUtil;
import com.jetbrains.python.fixtures.PyTestCase;
import com.jetbrains.python.formatter.PyCodeStyleSettings;
import com.jetbrains.python.psi.LanguageLevel;
import com.jetbrains.python.psi.PyElementGenerator;
+import com.jetbrains.python.psi.PyStatement;
import com.jetbrains.python.psi.impl.PythonLanguageLevelPusher;
/**
@@ -273,19 +275,19 @@ public class PyFormatterTest extends PyTestCase {
}
public void testWrapDefinitionWithLongLine() { // IDEA-92081
- settings().RIGHT_MARGIN = 30;
+ settings().setRightMargin(PythonLanguage.getInstance(), 30);
settings().WRAP_LONG_LINES = true;
doTest();
}
public void testWrapAssignment() { // PY-8572
- settings().RIGHT_MARGIN = 120;
+ settings().setRightMargin(PythonLanguage.getInstance(), 120);
settings().WRAP_LONG_LINES = false;
doTest();
}
public void testIndentInSlice() { // PY-8572
- settings().RIGHT_MARGIN = 120;
+ settings().setRightMargin(PythonLanguage.getInstance(), 120);
settings().WRAP_LONG_LINES = false;
doTest();
}
@@ -352,7 +354,7 @@ public class PyFormatterTest extends PyTestCase {
}
public void testWrapInBinaryExpression() { // PY-9032
- settings().RIGHT_MARGIN = 80;
+ settings().setRightMargin(PythonLanguage.getInstance(), 80);
doTest(true);
}
@@ -370,7 +372,7 @@ public class PyFormatterTest extends PyTestCase {
}
public void testWrapImports() { // PY-9163
- settings().RIGHT_MARGIN = 80;
+ settings().setRightMargin(PythonLanguage.getInstance(), 80);
doTest();
}
@@ -424,6 +426,26 @@ public class PyFormatterTest extends PyTestCase {
myFixture.checkResultByFile("formatter/" + getTestName(true) + "_after.py");
}
+ /**
+ * This test merely checks that call to {@link com.intellij.psi.codeStyle.CodeStyleManager#reformat(com.intellij.psi.PsiElement)}
+ * is possible for Python sources.
+ */
+ public void testReformatOfSingleElementPossible() {
+ myFixture.configureByFile("formatter/" + getTestName(true) + ".py");
+ WriteCommandAction.runWriteCommandAction(myFixture.getProject(), new Runnable() {
+ @Override
+ public void run() {
+ final PsiElement elementAtCaret = myFixture.getFile().findElementAt(myFixture.getCaretOffset());
+ assertNotNull(elementAtCaret);
+ final PyStatement statement = PsiTreeUtil.getParentOfType(elementAtCaret, PyStatement.class, false);
+ assertNotNull(statement);
+ final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(myFixture.getProject());
+ codeStyleManager.reformat(statement);
+ }
+ });
+ myFixture.checkResultByFile("formatter/" + getTestName(true) + "_after.py");
+ }
+
private CodeStyleSettings settings() {
return CodeStyleSettingsManager.getInstance().getSettings(myFixture.getProject());
}
diff --git a/python/testSrc/com/jetbrains/python/PyQuickFixTest.java b/python/testSrc/com/jetbrains/python/PyQuickFixTest.java
index c36372d9ba64..e49b0eaee6c8 100644
--- a/python/testSrc/com/jetbrains/python/PyQuickFixTest.java
+++ b/python/testSrc/com/jetbrains/python/PyQuickFixTest.java
@@ -251,6 +251,23 @@ public class PyQuickFixTest extends PyTestCase {
PyBundle.message("QFIX.statement.effect.introduce.variable"), true, true);
}
+ public void testReplacePrintEnd() {
+ runWithLanguageLevel(LanguageLevel.PYTHON34, new Runnable() {
+ @Override
+ public void run() {
+ doInspectionTest("ReplacePrintEnd.py", PyStatementEffectInspection.class, PyBundle.message("QFIX.statement.effect"), true, true);
+ }});
+ }
+
+ public void testReplacePrintComment() {
+ runWithLanguageLevel(LanguageLevel.PYTHON34, new Runnable() {
+ @Override
+ public void run() {
+ doInspectionTest("ReplacePrintComment.py", PyStatementEffectInspection.class, PyBundle.message("QFIX.statement.effect"), true,
+ true);
+ }});
+ }
+
public void testUnresolvedWith() { // PY-2083
setLanguageLevel(LanguageLevel.PYTHON25);
doInspectionTest("UnresolvedWith.py", PyUnresolvedReferencesInspection.class,
@@ -296,6 +313,11 @@ public class PyQuickFixTest extends PyTestCase {
PyBundle.message("QFIX.default.argument"), true, true);
}
+ public void testDefaultArgumentEmptyList() {
+ doInspectionTest("DefaultArgumentEmptyList.py", PyDefaultArgumentInspection.class,
+ PyBundle.message("QFIX.default.argument"), true, true);
+ }
+
public void testPyArgumentEqualDefault() { //PY-3125
doInspectionTest("ArgumentEqualDefault.py", PyArgumentEqualDefaultInspection.class,
PyBundle.message("QFIX.remove.argument.equal.default"), true, true);
diff --git a/python/testSrc/com/jetbrains/python/PyTypeTest.java b/python/testSrc/com/jetbrains/python/PyTypeTest.java
index b0e41bcffddc..b6ed1090edad 100644
--- a/python/testSrc/com/jetbrains/python/PyTypeTest.java
+++ b/python/testSrc/com/jetbrains/python/PyTypeTest.java
@@ -835,6 +835,37 @@ public class PyTypeTest extends PyTestCase {
"expr = (1,) + (True, 'spam') + ()");
}
+ public void testConstructorUnification() {
+ doTest("C[int]",
+ "class C(object):\n" +
+ " def __init__(self, x):\n" +
+ " '''\n" +
+ " :type x: T\n" +
+ " :rtype: C[T]\n" +
+ " '''\n" +
+ " pass\n" +
+ "\n" +
+ "expr = C(10)\n");
+ }
+
+ public void testGenericClassMethodUnification() {
+ doTest("int",
+ "class C(object):\n" +
+ " def __init__(self, x):\n" +
+ " '''\n" +
+ " :type x: T\n" +
+ " :rtype: C[T]\n" +
+ " '''\n" +
+ " pass\n" +
+ " def foo(self):\n" +
+ " '''\n" +
+ " :rtype: T\n" +
+ " '''\n" +
+ " pass\n" +
+ "\n" +
+ "expr = C(10).foo()\n");
+ }
+
private static TypeEvalContext getTypeEvalContext(@NotNull PyExpression element) {
return TypeEvalContext.userInitiated(element.getContainingFile()).withTracing();
}
diff --git a/python/testSrc/com/jetbrains/python/PyTypingTest.java b/python/testSrc/com/jetbrains/python/PyTypingTest.java
new file mode 100644
index 000000000000..9513795cb5b7
--- /dev/null
+++ b/python/testSrc/com/jetbrains/python/PyTypingTest.java
@@ -0,0 +1,267 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jetbrains.python;
+
+import com.intellij.testFramework.LightProjectDescriptor;
+import com.jetbrains.python.documentation.PythonDocumentationProvider;
+import com.jetbrains.python.fixtures.PyTestCase;
+import com.jetbrains.python.psi.LanguageLevel;
+import com.jetbrains.python.psi.PyExpression;
+import com.jetbrains.python.psi.types.PyType;
+import com.jetbrains.python.psi.types.TypeEvalContext;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Tests for a type system based on mypy's typing module.
+ *
+ * @author vlan
+ */
+public class PyTypingTest extends PyTestCase {
+ @Nullable
+ @Override
+ protected LightProjectDescriptor getProjectDescriptor() {
+ return ourPy3Descriptor;
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ setLanguageLevel(LanguageLevel.PYTHON32);
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ setLanguageLevel(null);
+ super.tearDown();
+ }
+
+ public void testClassType() {
+ doTest("Foo",
+ "class Foo:" +
+ " pass\n" +
+ "\n" +
+ "def f(expr: Foo):\n" +
+ " pass\n");
+ }
+
+ public void testClassReturnType() {
+ doTest("Foo",
+ "class Foo:" +
+ " pass\n" +
+ "\n" +
+ "def f() -> Foo:\n" +
+ " pass\n" +
+ "\n" +
+ "expr = f()\n");
+
+ }
+
+ public void testNoneType() {
+ doTest("None",
+ "def f(expr: None):\n" +
+ " pass\n");
+ }
+
+ public void testNoneReturnType() {
+ doTest("None",
+ "def f() -> None:\n" +
+ " return 0\n" +
+ "expr = f()\n");
+ }
+
+ public void testUnionType() {
+ doTest("int | str",
+ "from typing import Union\n" +
+ "\n" +
+ "def f(expr: Union[int, str]):\n" +
+ " pass\n");
+ }
+
+ public void testBuiltinList() {
+ doTest("list",
+ "from typing import List\n" +
+ "\n" +
+ "def f(expr: List):\n" +
+ " pass\n");
+ }
+
+ public void testBuiltinListWithParameter() {
+ doTest("list[int]",
+ "from typing import List\n" +
+ "\n" +
+ "def f(expr: List[int]):\n" +
+ " pass\n");
+ }
+
+ public void testBuiltinDictWithParameters() {
+ doTest("dict[str, int]",
+ "from typing import Dict\n" +
+ "\n" +
+ "def f(expr: Dict[str, int]):\n" +
+ " pass\n");
+ }
+
+ public void testBuiltinTuple() {
+ doTest("tuple",
+ "from typing import Tuple\n" +
+ "\n" +
+ "def f(expr: Tuple):\n" +
+ " pass\n");
+ }
+
+ public void testBuiltinTupleWithParameters() {
+ doTest("(int, str)",
+ "from typing import Tuple\n" +
+ "\n" +
+ "def f(expr: Tuple[int, str]):\n" +
+ " pass\n");
+ }
+
+ public void testAnyType() {
+ doTest("unknown",
+ "from typing import Any\n" +
+ "\n" +
+ "def f(expr: Any):\n" +
+ " pass\n");
+ }
+
+ public void testGenericType() {
+ doTest("A",
+ "from typing import typevar\n" +
+ "\n" +
+ "T = typevar('A')\n" +
+ "\n" +
+ "def f(expr: T):\n" +
+ " pass\n");
+ }
+
+ public void testGenericBoundedType() {
+ doTest("T <= int | str",
+ "from typing import typevar\n" +
+ "\n" +
+ "T = typevar('T', values=(int, str))\n" +
+ "\n" +
+ "def f(expr: T):\n" +
+ " pass\n");
+ }
+
+ public void testParameterizedClass() {
+ doTest("C[int]",
+ "from typing import Generic, typevar\n" +
+ "\n" +
+ "T = typevar('T')\n" +
+ "\n" +
+ "class C(Generic[T]):\n" +
+ " def __init__(self, x: T):\n" +
+ " pass\n" +
+ "\n" +
+ "expr = C(10)\n");
+ }
+
+ public void testParameterizedClassMethod() {
+ doTest("int",
+ "from typing import Generic, typevar\n" +
+ "\n" +
+ "T = typevar('T')\n" +
+ "\n" +
+ "class C(Generic[T]):\n" +
+ " def __init__(self, x: T):\n" +
+ " pass\n" +
+ " def foo(self) -> T:\n" +
+ " pass\n" +
+ "\n" +
+ "expr = C(10).foo()\n");
+ }
+
+ public void testParameterizedClassInheritance() {
+ doTest("int",
+ "from typing import Generic, typevar\n" +
+ "\n" +
+ "T = typevar('T')\n" +
+ "\n" +
+ "class B(Generic[T]):\n" +
+ " def foo(self) -> T:\n" +
+ " pass\n" +
+ "class C(B[T]):\n" +
+ " def __init__(self, x: T):\n" +
+ " pass\n" +
+ "\n" +
+ "expr = C(10).foo()\n");
+ }
+
+ public void testAnyStrUnification() {
+ doTest("bytes",
+ "from typing import AnyStr\n" +
+ "\n" +
+ "def foo(x: AnyStr) -> AnyStr:\n" +
+ " pass\n" +
+ "\n" +
+ "expr = foo(b'bar')\n");
+ }
+
+ public void testAnyStrForUnknown() {
+ doTest("str | bytes",
+ "from typing import AnyStr\n" +
+ "\n" +
+ "def foo(x: AnyStr) -> AnyStr:\n" +
+ " pass\n" +
+ "\n" +
+ "def bar(x):\n" +
+ " expr = foo(x)\n");
+ }
+
+ public void testFunctionType() {
+ doTest("(int, str) -> str",
+ "from typing import Function\n" +
+ "\n" +
+ "def foo(expr: Function[[int, str], str]):\n" +
+ " pass\n");
+ }
+
+ public void testTypeInStringLiteral() {
+ doTest("C",
+ "class C:\n" +
+ " def foo(self, expr: 'C'):\n" +
+ " pass\n");
+ }
+
+ public void testQualifiedTypeInStringLiteral() {
+ doTest("str",
+ "import typing\n" +
+ "\n" +
+ "def foo(x: 'typing.AnyStr') -> typing.AnyStr:\n" +
+ " pass\n" +
+ "\n" +
+ "expr = foo('bar')\n");
+ }
+
+ private void doTest(@NotNull String expectedType, @NotNull String text) {
+ myFixture.copyDirectoryToProject("typing", "");
+ myFixture.configureByText(PythonFileType.INSTANCE, text);
+ final PyExpression expr = myFixture.findElementByText("expr", PyExpression.class);
+ final TypeEvalContext codeAnalysis = TypeEvalContext.codeAnalysis(expr.getContainingFile());
+ final TypeEvalContext userInitiated = TypeEvalContext.userInitiated(expr.getContainingFile()).withTracing();
+ assertType(expectedType, expr, codeAnalysis, "code analysis");
+ assertType(expectedType, expr, userInitiated, "user initiated");
+ }
+
+ private static void assertType(String expectedType, PyExpression expr, TypeEvalContext context, String contextName) {
+ final PyType actual = context.getType(expr);
+ final String actualType = PythonDocumentationProvider.getTypeName(actual, context);
+ assertEquals("Failed in " + contextName + " context", expectedType, actualType);
+ }
+}
diff --git a/python/testSrc/com/jetbrains/python/PyWrapTest.java b/python/testSrc/com/jetbrains/python/PyWrapTest.java
index 05c21b8af21a..4146391ea5d8 100644
--- a/python/testSrc/com/jetbrains/python/PyWrapTest.java
+++ b/python/testSrc/com/jetbrains/python/PyWrapTest.java
@@ -17,6 +17,7 @@ package com.jetbrains.python;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
+import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.jetbrains.python.fixtures.PyTestCase;
/**
@@ -30,17 +31,19 @@ public class PyWrapTest extends PyTestCase {
protected void setUp() throws Exception {
super.setUp();
final CodeStyleSettings settings = CodeStyleSettingsManager.getInstance(myFixture.getProject()).getCurrentSettings();
+ final CommonCodeStyleSettings pythonSettings = settings.getCommonSettings(PythonLanguage.getInstance());
myOldWrap = settings.WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN;
- myOldMargin = settings.RIGHT_MARGIN;
+ myOldMargin = pythonSettings.RIGHT_MARGIN;
settings.WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN = true;
- settings.RIGHT_MARGIN = 80;
+ pythonSettings.RIGHT_MARGIN = 80;
}
@Override
protected void tearDown() throws Exception {
final CodeStyleSettings settings = CodeStyleSettingsManager.getInstance(myFixture.getProject()).getCurrentSettings();
+ final CommonCodeStyleSettings pythonSettings = settings.getCommonSettings(PythonLanguage.getInstance());
settings.WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN = myOldWrap;
- settings.RIGHT_MARGIN = myOldMargin;
+ pythonSettings.RIGHT_MARGIN = myOldMargin;
super.tearDown();
}
@@ -71,9 +74,10 @@ public class PyWrapTest extends PyTestCase {
public void testWrapRightMargin() {
final CodeStyleSettings settings = CodeStyleSettingsManager.getInstance(myFixture.getProject()).getCurrentSettings();
- int oldValue = settings.RIGHT_MARGIN;
+ final CommonCodeStyleSettings pythonSettings = settings.getCommonSettings(PythonLanguage.getInstance());
+ int oldValue = pythonSettings.RIGHT_MARGIN;
boolean oldMarginValue = settings.WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN;
- settings.RIGHT_MARGIN = 100;
+ pythonSettings.RIGHT_MARGIN = 100;
settings.WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN = true;
try {
final String testName = "wrap/" + getTestName(true);
@@ -84,7 +88,7 @@ public class PyWrapTest extends PyTestCase {
myFixture.checkResultByFile(testName + ".after.py");
}
finally {
- settings.RIGHT_MARGIN = oldValue;
+ pythonSettings.RIGHT_MARGIN = oldValue;
settings.WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN = oldMarginValue;
}
}
diff --git a/python/testSrc/com/jetbrains/python/fixtures/PyTestCase.java b/python/testSrc/com/jetbrains/python/fixtures/PyTestCase.java
index 99da2a43aea1..8a237b7dfb01 100644
--- a/python/testSrc/com/jetbrains/python/fixtures/PyTestCase.java
+++ b/python/testSrc/com/jetbrains/python/fixtures/PyTestCase.java
@@ -111,6 +111,7 @@ public abstract class PyTestCase extends UsefulTestCase {
final PythonLanguageLevelPusher levelPusher = Extensions.findExtension(FilePropertyPusher.EP_NAME, PythonLanguageLevelPusher.class);
levelPusher.flushLanguageLevelCache();
super.tearDown();
+ clearFields(this);
}
@Nullable
diff --git a/python/testSrc/com/jetbrains/python/intentions/PyIntentionTest.java b/python/testSrc/com/jetbrains/python/intentions/PyIntentionTest.java
index 2891d819cf43..058da63e4d01 100644
--- a/python/testSrc/com/jetbrains/python/intentions/PyIntentionTest.java
+++ b/python/testSrc/com/jetbrains/python/intentions/PyIntentionTest.java
@@ -259,6 +259,11 @@ public class PyIntentionTest extends PyTestCase {
doTest("Convert to 'import sys'");
}
+ // PY-11074
+ public void testImportToImportFrom() {
+ doTest("Convert to 'from __builtin__ import ...'");
+ }
+
public void testTypeInDocstring() {
doDocReferenceTest();
}
diff --git a/python/testSrc/com/jetbrains/python/refactoring/PyInlineLocalTest.java b/python/testSrc/com/jetbrains/python/refactoring/PyInlineLocalTest.java
index 4f02da1038ff..9a764b94169d 100644
--- a/python/testSrc/com/jetbrains/python/refactoring/PyInlineLocalTest.java
+++ b/python/testSrc/com/jetbrains/python/refactoring/PyInlineLocalTest.java
@@ -18,6 +18,9 @@ package com.jetbrains.python.refactoring;
import com.intellij.codeInsight.TargetElementUtilBase;
import com.intellij.openapi.util.Comparing;
import com.intellij.psi.PsiElement;
+import com.intellij.psi.codeStyle.CodeStyleSettings;
+import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
+import com.jetbrains.python.PythonLanguage;
import com.jetbrains.python.fixtures.PyTestCase;
import com.jetbrains.python.refactoring.inline.PyInlineLocalHandler;
@@ -81,7 +84,21 @@ public class PyInlineLocalTest extends PyTestCase {
doTest();
}
+ // PY-12401
public void testComment() {
doTest();
}
+
+ // PY-13114
+ public void testReferenceInParenthesis() {
+ doTest();
+ }
+
+ // PY-12409
+ public void testResultExceedsRightMargin() {
+ final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(myFixture.getProject());
+ settings.WRAP_LONG_LINES = true;
+ settings.setRightMargin(PythonLanguage.getInstance(), 80);
+ doTest();
+ }
}
diff --git a/resources-en/src/messages/DebuggerBundle.properties b/resources-en/src/messages/DebuggerBundle.properties
index c9802d35cb44..ac623acc1fbe 100644
--- a/resources-en/src/messages/DebuggerBundle.properties
+++ b/resources-en/src/messages/DebuggerBundle.properties
@@ -438,4 +438,4 @@ action.kill.process.text=Kill Process
action.kill.process.description=Forcibly terminate debugged application
evaluation.error.unknown.method.return.type=Cannot resolve method return type: {0}
rule.name.group.by.class=Group by class
-rule.name.group.by.package=Group by package
+rule.name.group.by.package=Group by package \ No newline at end of file
diff --git a/resources-en/src/postfixTemplates/AssertStatementPostfixTemplate/description.html b/resources-en/src/postfixTemplates/AssertStatementPostfixTemplate/description.html
index 2a472356ab71..68f6b1e8a47c 100644
--- a/resources-en/src/postfixTemplates/AssertStatementPostfixTemplate/description.html
+++ b/resources-en/src/postfixTemplates/AssertStatementPostfixTemplate/description.html
@@ -1,5 +1,7 @@
<html>
<body>
+<font face="verdana" size="-1">
Creates assertion from boolean expression.
-</body>
+</font>
+<body>
</html>
diff --git a/resources-en/src/postfixTemplates/CastExpressionPostfixTemplate/description.html b/resources-en/src/postfixTemplates/CastExpressionPostfixTemplate/description.html
index 7d20d583eb16..5ec1847e6545 100644
--- a/resources-en/src/postfixTemplates/CastExpressionPostfixTemplate/description.html
+++ b/resources-en/src/postfixTemplates/CastExpressionPostfixTemplate/description.html
@@ -1,5 +1,7 @@
<html>
<body>
+<font face="verdana" size="-1">
Surrounds expression with cast.
+</font>
</body>
</html>
diff --git a/resources-en/src/postfixTemplates/ElseStatementPostfixTemplate/description.html b/resources-en/src/postfixTemplates/ElseStatementPostfixTemplate/description.html
index 862ad3ab3c55..ca9bc6cd72bf 100644
--- a/resources-en/src/postfixTemplates/ElseStatementPostfixTemplate/description.html
+++ b/resources-en/src/postfixTemplates/ElseStatementPostfixTemplate/description.html
@@ -1,5 +1,7 @@
<html>
<body>
+<font face="verdana" size="-1">
Checks boolean expression to be 'false'.
+</font>
</body>
</html>
diff --git a/resources-en/src/postfixTemplates/ForAscendingPostfixTemplate/description.html b/resources-en/src/postfixTemplates/ForAscendingPostfixTemplate/description.html
index 6b6212f51fbd..c68655d964c6 100644
--- a/resources-en/src/postfixTemplates/ForAscendingPostfixTemplate/description.html
+++ b/resources-en/src/postfixTemplates/ForAscendingPostfixTemplate/description.html
@@ -1,5 +1,7 @@
<html>
<body>
+<font face="verdana" size="-1">
Iterates with index over collection.
+</font>
</body>
</html>
diff --git a/resources-en/src/postfixTemplates/ForDescendingPostfixTemplate/description.html b/resources-en/src/postfixTemplates/ForDescendingPostfixTemplate/description.html
index 22f6cbccd39d..9663c6c93ec2 100644
--- a/resources-en/src/postfixTemplates/ForDescendingPostfixTemplate/description.html
+++ b/resources-en/src/postfixTemplates/ForDescendingPostfixTemplate/description.html
@@ -1,5 +1,7 @@
<html>
<body>
+<font face="verdana" size="-1">
Iterates with index in reverse order.
+</font>
</body>
</html>
diff --git a/resources-en/src/postfixTemplates/ForeachPostfixTemplate/description.html b/resources-en/src/postfixTemplates/ForeachPostfixTemplate/description.html
index fc31a3ae8341..c911d040d419 100644
--- a/resources-en/src/postfixTemplates/ForeachPostfixTemplate/description.html
+++ b/resources-en/src/postfixTemplates/ForeachPostfixTemplate/description.html
@@ -1,5 +1,7 @@
<html>
<body>
+<font face="verdana" size="-1">
Iterates over enumerable collection.
+</font>
</body>
</html>
diff --git a/resources-en/src/postfixTemplates/FormatPostfixTemplate/description.html b/resources-en/src/postfixTemplates/FormatPostfixTemplate/description.html
index c62959a48280..2d76496c51be 100644
--- a/resources-en/src/postfixTemplates/FormatPostfixTemplate/description.html
+++ b/resources-en/src/postfixTemplates/FormatPostfixTemplate/description.html
@@ -1,5 +1,7 @@
<html>
<body>
+<font face="verdana" size="-1">
Creates String.format call.
+</font>
</body>
</html>
diff --git a/resources-en/src/postfixTemplates/IfStatementPostfixTemplate/description.html b/resources-en/src/postfixTemplates/IfStatementPostfixTemplate/description.html
index 28234e198291..e7d1cf104833 100644
--- a/resources-en/src/postfixTemplates/IfStatementPostfixTemplate/description.html
+++ b/resources-en/src/postfixTemplates/IfStatementPostfixTemplate/description.html
@@ -1,5 +1,7 @@
<html>
<body>
+<font face="verdana" size="-1">
Checks boolean expression to be 'true'.
+</font>
</body>
</html>
diff --git a/resources-en/src/postfixTemplates/InstanceofExpressionPostfixTemplate/description.html b/resources-en/src/postfixTemplates/InstanceofExpressionPostfixTemplate/description.html
index 249f7daac259..f682f5be8eaf 100644
--- a/resources-en/src/postfixTemplates/InstanceofExpressionPostfixTemplate/description.html
+++ b/resources-en/src/postfixTemplates/InstanceofExpressionPostfixTemplate/description.html
@@ -1,5 +1,7 @@
<html>
<body>
+<font face="verdana" size="-1">
Surrounds expression with instanceof.
+</font>
</body>
</html>
diff --git a/resources-en/src/postfixTemplates/IntroduceFieldPostfixTemplate/description.html b/resources-en/src/postfixTemplates/IntroduceFieldPostfixTemplate/description.html
index 4f20d5109618..f659ac01784c 100644
--- a/resources-en/src/postfixTemplates/IntroduceFieldPostfixTemplate/description.html
+++ b/resources-en/src/postfixTemplates/IntroduceFieldPostfixTemplate/description.html
@@ -1,5 +1,7 @@
<html>
<body>
+<font face="verdana" size="-1">
Introduces field for expression.
+</font>
</body>
</html>
diff --git a/resources-en/src/postfixTemplates/IntroduceVariablePostfixTemplate/description.html b/resources-en/src/postfixTemplates/IntroduceVariablePostfixTemplate/description.html
index 2024a122609d..d780db76efe1 100644
--- a/resources-en/src/postfixTemplates/IntroduceVariablePostfixTemplate/description.html
+++ b/resources-en/src/postfixTemplates/IntroduceVariablePostfixTemplate/description.html
@@ -1,5 +1,7 @@
<html>
<body>
+<font face="verdana" size="-1">
Introduces variable for expression.
+</font>
</body>
</html>
diff --git a/resources-en/src/postfixTemplates/IsNullCheckPostfixTemplate/description.html b/resources-en/src/postfixTemplates/IsNullCheckPostfixTemplate/description.html
index eb854ae563ad..9b485cefdfa9 100644
--- a/resources-en/src/postfixTemplates/IsNullCheckPostfixTemplate/description.html
+++ b/resources-en/src/postfixTemplates/IsNullCheckPostfixTemplate/description.html
@@ -1,5 +1,7 @@
<html>
<body>
+<font face="verdana" size="-1">
Checks expression to be null.
+</font>
</body>
</html>
diff --git a/resources-en/src/postfixTemplates/NotExpressionPostfixTemplate/description.html b/resources-en/src/postfixTemplates/NotExpressionPostfixTemplate/description.html
index 533a7601fe8f..6e7c6ebaa6d0 100644
--- a/resources-en/src/postfixTemplates/NotExpressionPostfixTemplate/description.html
+++ b/resources-en/src/postfixTemplates/NotExpressionPostfixTemplate/description.html
@@ -1,5 +1,7 @@
<html>
<body>
+<font face="verdana" size="-1">
Negates boolean expression.
+</font>
</body>
</html>
diff --git a/resources-en/src/postfixTemplates/NotNullCheckPostfixTemplate/description.html b/resources-en/src/postfixTemplates/NotNullCheckPostfixTemplate/description.html
index 65a10f3669bd..55b6f9a6df20 100644
--- a/resources-en/src/postfixTemplates/NotNullCheckPostfixTemplate/description.html
+++ b/resources-en/src/postfixTemplates/NotNullCheckPostfixTemplate/description.html
@@ -1,5 +1,7 @@
<html>
<body>
+<font face="verdana" size="-1">
Checks expression to be not-null.
+</font>
</body>
</html>
diff --git a/resources-en/src/postfixTemplates/ParenthesizedExpressionPostfixTemplate/description.html b/resources-en/src/postfixTemplates/ParenthesizedExpressionPostfixTemplate/description.html
index f3effd96dd97..20f92fed4bb8 100644
--- a/resources-en/src/postfixTemplates/ParenthesizedExpressionPostfixTemplate/description.html
+++ b/resources-en/src/postfixTemplates/ParenthesizedExpressionPostfixTemplate/description.html
@@ -1,5 +1,7 @@
<html>
<body>
+<font face="verdana" size="-1">
Parenthesizes expression.
+</font>
</body>
</html>
diff --git a/resources-en/src/postfixTemplates/ReturnStatementPostfixTemplate/description.html b/resources-en/src/postfixTemplates/ReturnStatementPostfixTemplate/description.html
index 4efea2894c04..7cb0f59688b9 100644
--- a/resources-en/src/postfixTemplates/ReturnStatementPostfixTemplate/description.html
+++ b/resources-en/src/postfixTemplates/ReturnStatementPostfixTemplate/description.html
@@ -1,5 +1,7 @@
<html>
<body>
+<font face="verdana" size="-1">
Returns value from containing method.
+</font>
</body>
</html>
diff --git a/resources-en/src/postfixTemplates/SoutPostfixTemplate/description.html b/resources-en/src/postfixTemplates/SoutPostfixTemplate/description.html
index 02dacc2cb7a9..4890d4bdff38 100644
--- a/resources-en/src/postfixTemplates/SoutPostfixTemplate/description.html
+++ b/resources-en/src/postfixTemplates/SoutPostfixTemplate/description.html
@@ -1,5 +1,7 @@
<html>
<body>
+<font face="verdana" size="-1">
Creates System.out.println call.
+</font>
</body>
</html>
diff --git a/resources-en/src/postfixTemplates/SwitchStatementPostfixTemplate/description.html b/resources-en/src/postfixTemplates/SwitchStatementPostfixTemplate/description.html
index e1e63da8325c..f7fa1a6989a7 100644
--- a/resources-en/src/postfixTemplates/SwitchStatementPostfixTemplate/description.html
+++ b/resources-en/src/postfixTemplates/SwitchStatementPostfixTemplate/description.html
@@ -1,5 +1,7 @@
<html>
<body>
+<font face="verdana" size="-1">
Produces switch over integral/enum/string values.
+</font>
</body>
</html>
diff --git a/resources-en/src/postfixTemplates/SynchronizedStatementPostfixTemplate/description.html b/resources-en/src/postfixTemplates/SynchronizedStatementPostfixTemplate/description.html
index 1589a80dcd4d..df16c96f9e54 100644
--- a/resources-en/src/postfixTemplates/SynchronizedStatementPostfixTemplate/description.html
+++ b/resources-en/src/postfixTemplates/SynchronizedStatementPostfixTemplate/description.html
@@ -1,5 +1,7 @@
<html>
<body>
+<font face="verdana" size="-1">
Produces synchronization statement.
+</font>
</body>
</html>
diff --git a/resources-en/src/postfixTemplates/ThrowExceptionPostfixTemplate/description.html b/resources-en/src/postfixTemplates/ThrowExceptionPostfixTemplate/description.html
index d81b2d78ae7d..a714eecd3bb1 100644
--- a/resources-en/src/postfixTemplates/ThrowExceptionPostfixTemplate/description.html
+++ b/resources-en/src/postfixTemplates/ThrowExceptionPostfixTemplate/description.html
@@ -1,5 +1,7 @@
<html>
<body>
+<font face="verdana" size="-1">
Throws expression of 'Throwable' type.
+</font>
</body>
</html>
diff --git a/resources-en/src/postfixTemplates/TryStatementPostfixTemplate/description.html b/resources-en/src/postfixTemplates/TryStatementPostfixTemplate/description.html
index 582e5dd9681f..38df0e522cae 100644
--- a/resources-en/src/postfixTemplates/TryStatementPostfixTemplate/description.html
+++ b/resources-en/src/postfixTemplates/TryStatementPostfixTemplate/description.html
@@ -1,5 +1,7 @@
<html>
<body>
+<font face="verdana" size="-1">
Insert statement in try-catch block.
+</font>
</body>
</html>
diff --git a/resources-en/src/postfixTemplates/TryWithResourcesPostfixTemplate/description.html b/resources-en/src/postfixTemplates/TryWithResourcesPostfixTemplate/description.html
index 77c0e6368ef2..0786540252b5 100644
--- a/resources-en/src/postfixTemplates/TryWithResourcesPostfixTemplate/description.html
+++ b/resources-en/src/postfixTemplates/TryWithResourcesPostfixTemplate/description.html
@@ -1,5 +1,7 @@
<html>
<body>
+<font face="verdana" size="-1">
Insert statement in try-with-resources block (java 7 or higher requires).
+</font>
</body>
</html>
diff --git a/resources-en/src/postfixTemplates/WhileStatementPostfixTemplate/description.html b/resources-en/src/postfixTemplates/WhileStatementPostfixTemplate/description.html
index daf90248cd28..5c1699e18f70 100644
--- a/resources-en/src/postfixTemplates/WhileStatementPostfixTemplate/description.html
+++ b/resources-en/src/postfixTemplates/WhileStatementPostfixTemplate/description.html
@@ -1,5 +1,7 @@
<html>
<body>
+<font face="verdana" size="-1">
Iterating while boolean statement is 'true'.
+</font>
</body>
</html>
diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml
index 20536b2a6a61..ec30ca2614dc 100644
--- a/resources/src/META-INF/IdeaPlugin.xml
+++ b/resources/src/META-INF/IdeaPlugin.xml
@@ -26,10 +26,6 @@
<component>
<implementation-class>com.intellij.util.xml.impl.JavaDomApplicationComponent</implementation-class>
</component>
- <component>
- <interface-class>com.intellij.codeInspection.bytecodeAnalysis.BytecodeAnalysisConverter</interface-class>
- <implementation-class>com.intellij.codeInspection.bytecodeAnalysis.BytecodeAnalysisConverterImpl</implementation-class>
- </component>
</application-components>
<project-components>
@@ -50,6 +46,8 @@
<extensionPoints>
<extensionPoint name="codeInsight.changeVariableTypeQuickFixProvider"
interface="com.intellij.codeInsight.quickfix.ChangeVariableTypeQuickFixProvider"/>
+ <extensionPoint name="codeInsight.implementedAtRuntime"
+ interface="com.intellij.codeInspection.inheritance.ImplementedAtRuntimeCondition"/>
<extensionPoint name="conversion.rule"
interface="com.intellij.refactoring.typeMigration.rules.TypeConversionRule"/>
@@ -1345,8 +1343,6 @@
<elementDescriptionProvider implementation="com.intellij.ide.util.JavaDeleteTypeDescriptionProvider"/>
- <!-- <fileTypeIndentOptionsProvider implementation="com.intellij.application.options.JavaIndentOptionsProvider"/>-->
-
<referenceImporter implementation="com.intellij.codeInsight.daemon.impl.JavaReferenceImporter"/>
<elementLookupRenderer implementation="com.intellij.codeInsight.lookup.impl.JavaElementLookupRenderer"/>
diff --git a/resources/src/idea/JavaActions.xml b/resources/src/idea/JavaActions.xml
index bcfa7f37dda1..81a791f42208 100644
--- a/resources/src/idea/JavaActions.xml
+++ b/resources/src/idea/JavaActions.xml
@@ -162,9 +162,6 @@
<action id="Debugger.ViewText" class="com.intellij.debugger.actions.ViewTextAction">
<add-to-group group-id="XDebugger.ValueGroup" anchor="last"/>
</action>
- <action id="Debugger.ShowReferring" internal="true" class="com.intellij.debugger.actions.ShowReferringObjectsAction">
- <add-to-group group-id="XDebugger.ValueGroup" anchor="last"/>
- </action>
<action id="Debugger.CopyValue" class="com.intellij.debugger.actions.CopyValueAction"/>
<action id="Debugger.CompareValueWithClipboard" class="com.intellij.debugger.actions.CompareValueWithClipboardAction"/>
<action id="Debugger.CustomizeThreadsView" class="com.intellij.debugger.actions.CustomizeThreadsViewAction">
diff --git a/resources/src/idea/RichPlatformActions.xml b/resources/src/idea/RichPlatformActions.xml
index 562f7c4177c7..324f2fe29c6e 100644
--- a/resources/src/idea/RichPlatformActions.xml
+++ b/resources/src/idea/RichPlatformActions.xml
@@ -50,17 +50,10 @@
<action id="NewModule" class="com.intellij.openapi.roots.ui.configuration.actions.NewModuleAction"/>
<action id="ImportProject" class="com.intellij.ide.actions.ImportProjectAction" text="Import Project..."/>
<action id="ImportModule" class="com.intellij.ide.actions.ImportModuleAction" text="Import Module..."/>
- <action id="OpenProject" class="com.intellij.ide.actions.OpenProjectAction"/>
-
+ <action id="NewElement" class="com.intellij.ide.actions.NewElementAction"/>
<add-to-group group-id="FileOpenGroup" anchor="first"/>
</group>
- <action id="NewElement" class="com.intellij.ide.actions.NewElementAction">
- <add-to-group group-id="OpenProjectGroup" anchor="before" relative-to-action="OpenFile"/>
- </action>
- <group>
- <add-to-group group-id="ExportImportGroup" anchor="first"/>
- </group>
<action id="SaveAsNewFormat" class="com.intellij.ide.actions.SaveAsDirectoryBasedFormatAction" text="Save as Directory-Based Format...">
<add-to-group group-id="ExportImportGroup" anchor="last"/>
</action>
@@ -362,11 +355,9 @@
<!-- ****************************************************************** -->
<group id="WelcomeScreen.QuickStart.IDEA">
- <action id="WelcomeScreen.CreateNewProject" class="com.intellij.ide.actions.NewProjectAction"
- icon="AllIcons.General.CreateNewProject"/>
+ <action id="WelcomeScreen.CreateNewProject" class="com.intellij.ide.actions.NewProjectAction" icon="AllIcons.General.CreateNewProject"/>
<action id="WelcomeScreen.ImportProject" class="com.intellij.ide.actions.ImportProjectAction" icon="AllIcons.General.ImportProject"/>
- <action id="WelcomeScreen.OpenProject" class="com.intellij.ide.actions.OpenFileAction"
- icon="AllIcons.General.OpenProject"/>
+ <action id="WelcomeScreen.OpenProject" class="com.intellij.ide.actions.OpenFileAction" icon="AllIcons.General.OpenProject"/>
<add-to-group group-id="WelcomeScreen.QuickStart" anchor="first"/>
</group>
diff --git a/resources/src/idea/RichPlatformPlugin.xml b/resources/src/idea/RichPlatformPlugin.xml
index 2b1794d236a3..444336338b1a 100644
--- a/resources/src/idea/RichPlatformPlugin.xml
+++ b/resources/src/idea/RichPlatformPlugin.xml
@@ -239,10 +239,10 @@
<!-- Errors -->
<!-- Show full error options configurable only in full IDEA - platform supports only default IDE profile for now -->
- <projectConfigurable groupId="editor" displayName="Inspections" provider="com.intellij.profile.codeInspection.ui.ProjectInspectionToolsConfigurableProvider"/>
+ <projectConfigurable groupId="editor" groupWeight="160" displayName="Inspections" provider="com.intellij.profile.codeInspection.ui.ProjectInspectionToolsConfigurableProvider"/>
<!-- Compiler -->
- <projectConfigurable groupId="build" instance="com.intellij.compiler.options.CompilerConfigurable" id="project.propCompiler" order="after project"
+ <projectConfigurable groupId="build" groupWeight="130" instance="com.intellij.compiler.options.CompilerConfigurable" id="project.propCompiler" order="after project"
key="compiler.configurable.display.name" bundle="messages.CompilerBundle" childrenEPName="com.intellij.compilerSettingsFactory">
<configurable instance="com.intellij.openapi.compiler.options.ExcludedEntriesConfigurable" id="reference.projectsettings.compiler.excludes"
displayName="Excludes"/>
@@ -312,6 +312,8 @@
implementationClass="com.intellij.openapi.roots.ui.configuration.libraryEditor.JavadocOrderRootTypeUIFactory"/>
<OrderRootTypeUI key="ANNOTATIONS"
implementationClass="com.intellij.openapi.roots.ui.configuration.libraryEditor.AnnotationsOrderRootTypeUIFactory"/>
+ <OrderRootTypeUI key="NATIVE"
+ implementationClass="com.intellij.openapi.roots.ui.configuration.libraryEditor.NativeLibraryOrderRootTypeUIFactory"/>
<OrderRootTypeUI key="CLASSES"
implementationClass="com.intellij.openapi.roots.ui.configuration.libraryEditor.ClassesOrderRootTypeUIFactory"/>
<OrderRootTypeUI key="SOURCES"
@@ -332,6 +334,7 @@
<moduleExtension implementation="com.intellij.openapi.roots.impl.JavaModuleExternalPathsImpl"/>
<orderRootType implementation="com.intellij.openapi.roots.AnnotationOrderRootType"/>
+ <orderRootType implementation="com.intellij.openapi.roots.NativeLibraryOrderRootType"/>
<orderRootType implementation="com.intellij.openapi.roots.JavadocOrderRootType"/>
diff --git a/spellchecker/src/com/intellij/spellchecker/jetbrains.dic b/spellchecker/src/com/intellij/spellchecker/jetbrains.dic
index 45610cdbdf1c..7e6817c5984c 100644
--- a/spellchecker/src/com/intellij/spellchecker/jetbrains.dic
+++ b/spellchecker/src/com/intellij/spellchecker/jetbrains.dic
@@ -302,6 +302,7 @@ namespaces
nchar
nclob
ndbcluster
+nmtoken
noarchivelog
noaudit
nocache
@@ -538,6 +539,8 @@ taglib
teamcity
temptable
throwable
+thymeleaf
+thymes
timestamp
tinyblob
tinyint
diff --git a/spellchecker/src/com/intellij/spellchecker/tokenizer/SpellcheckingStrategy.java b/spellchecker/src/com/intellij/spellchecker/tokenizer/SpellcheckingStrategy.java
index 6d28563e062c..17044a102559 100644
--- a/spellchecker/src/com/intellij/spellchecker/tokenizer/SpellcheckingStrategy.java
+++ b/spellchecker/src/com/intellij/spellchecker/tokenizer/SpellcheckingStrategy.java
@@ -49,6 +49,9 @@ public class SpellcheckingStrategy {
@NotNull
public Tokenizer getTokenizer(PsiElement element) {
+ if (element instanceof PsiLanguageInjectionHost && InjectedLanguageUtil.hasInjections((PsiLanguageInjectionHost)element)) {
+ return EMPTY_TOKENIZER;
+ }
if (element instanceof PsiNameIdentifierOwner) return new PsiIdentifierOwnerTokenizer();
if (element instanceof PsiComment) {
if (SuppressionUtil.isSuppressionComment(element)) {
diff --git a/tools/launcher-generator/.idea/codeStyleSettings.xml b/tools/launcher-generator/.idea/codeStyleSettings.xml
index 203f145b61f7..fcffa69814c6 100644
--- a/tools/launcher-generator/.idea/codeStyleSettings.xml
+++ b/tools/launcher-generator/.idea/codeStyleSettings.xml
@@ -25,206 +25,6 @@
<option name="CONTINUATION_INDENT_SIZE" value="4" />
<option name="TAB_SIZE" value="2" />
</indentOptions>
- <arrangement>
- <groups>
- <group>
- <type>GETTERS_AND_SETTERS</type>
- <order>KEEP</order>
- </group>
- </groups>
- <rules>
- <rule>
- <match>
- <AND>
- <TYPE>FIELD</TYPE>
- <MODIFIER>PUBLIC</MODIFIER>
- <MODIFIER>STATIC</MODIFIER>
- <MODIFIER>FINAL</MODIFIER>
- </AND>
- </match>
- </rule>
- <rule>
- <match>
- <AND>
- <TYPE>FIELD</TYPE>
- <MODIFIER>PROTECTED</MODIFIER>
- <MODIFIER>STATIC</MODIFIER>
- <MODIFIER>FINAL</MODIFIER>
- </AND>
- </match>
- </rule>
- <rule>
- <match>
- <AND>
- <TYPE>FIELD</TYPE>
- <MODIFIER>PACKAGE_PRIVATE</MODIFIER>
- <MODIFIER>STATIC</MODIFIER>
- <MODIFIER>FINAL</MODIFIER>
- </AND>
- </match>
- </rule>
- <rule>
- <match>
- <AND>
- <TYPE>FIELD</TYPE>
- <MODIFIER>PRIVATE</MODIFIER>
- <MODIFIER>STATIC</MODIFIER>
- <MODIFIER>FINAL</MODIFIER>
- </AND>
- </match>
- </rule>
- <rule>
- <match>
- <AND>
- <TYPE>FIELD</TYPE>
- <MODIFIER>PUBLIC</MODIFIER>
- <MODIFIER>STATIC</MODIFIER>
- </AND>
- </match>
- </rule>
- <rule>
- <match>
- <AND>
- <TYPE>FIELD</TYPE>
- <MODIFIER>PROTECTED</MODIFIER>
- <MODIFIER>STATIC</MODIFIER>
- </AND>
- </match>
- </rule>
- <rule>
- <match>
- <AND>
- <TYPE>FIELD</TYPE>
- <MODIFIER>PACKAGE_PRIVATE</MODIFIER>
- <MODIFIER>STATIC</MODIFIER>
- </AND>
- </match>
- </rule>
- <rule>
- <match>
- <AND>
- <TYPE>FIELD</TYPE>
- <MODIFIER>PRIVATE</MODIFIER>
- <MODIFIER>STATIC</MODIFIER>
- </AND>
- </match>
- </rule>
- <rule>
- <match>
- <AND>
- <TYPE>FIELD</TYPE>
- <MODIFIER>PUBLIC</MODIFIER>
- <MODIFIER>FINAL</MODIFIER>
- </AND>
- </match>
- </rule>
- <rule>
- <match>
- <AND>
- <TYPE>FIELD</TYPE>
- <MODIFIER>PROTECTED</MODIFIER>
- <MODIFIER>FINAL</MODIFIER>
- </AND>
- </match>
- </rule>
- <rule>
- <match>
- <AND>
- <TYPE>FIELD</TYPE>
- <MODIFIER>PACKAGE_PRIVATE</MODIFIER>
- <MODIFIER>FINAL</MODIFIER>
- </AND>
- </match>
- </rule>
- <rule>
- <match>
- <AND>
- <TYPE>FIELD</TYPE>
- <MODIFIER>PRIVATE</MODIFIER>
- <MODIFIER>FINAL</MODIFIER>
- </AND>
- </match>
- </rule>
- <rule>
- <match>
- <AND>
- <TYPE>FIELD</TYPE>
- <MODIFIER>PUBLIC</MODIFIER>
- </AND>
- </match>
- </rule>
- <rule>
- <match>
- <AND>
- <TYPE>FIELD</TYPE>
- <MODIFIER>PROTECTED</MODIFIER>
- </AND>
- </match>
- </rule>
- <rule>
- <match>
- <AND>
- <TYPE>FIELD</TYPE>
- <MODIFIER>PACKAGE_PRIVATE</MODIFIER>
- </AND>
- </match>
- </rule>
- <rule>
- <match>
- <AND>
- <TYPE>FIELD</TYPE>
- <MODIFIER>PRIVATE</MODIFIER>
- </AND>
- </match>
- </rule>
- <rule>
- <match>
- <TYPE>FIELD</TYPE>
- </match>
- </rule>
- <rule>
- <match>
- <TYPE>CONSTRUCTOR</TYPE>
- </match>
- </rule>
- <rule>
- <match>
- <AND>
- <TYPE>METHOD</TYPE>
- <MODIFIER>STATIC</MODIFIER>
- </AND>
- </match>
- </rule>
- <rule>
- <match>
- <TYPE>METHOD</TYPE>
- </match>
- </rule>
- <rule>
- <match>
- <TYPE>ENUM</TYPE>
- </match>
- </rule>
- <rule>
- <match>
- <TYPE>INTERFACE</TYPE>
- </match>
- </rule>
- <rule>
- <match>
- <AND>
- <TYPE>CLASS</TYPE>
- <MODIFIER>STATIC</MODIFIER>
- </AND>
- </match>
- </rule>
- <rule>
- <match>
- <TYPE>CLASS</TYPE>
- </match>
- </rule>
- </rules>
- </arrangement>
</codeStyleSettings>
</value>
</option>
diff --git a/tools/launcher-generator/.idea/copyright/profiles_settings.xml b/tools/launcher-generator/.idea/copyright/profiles_settings.xml
index ad23b0748861..d282fc12f62f 100644
--- a/tools/launcher-generator/.idea/copyright/profiles_settings.xml
+++ b/tools/launcher-generator/.idea/copyright/profiles_settings.xml
@@ -1,5 +1,3 @@
<component name="CopyrightManager">
- <settings default="apache 2 productiveme">
- <module2copyright />
- </settings>
+ <settings default="apache 2 productiveme" />
</component> \ No newline at end of file
diff --git a/tools/launcher-generator/.idea/libraries/guava.xml b/tools/launcher-generator/.idea/libraries/guava.xml
index 3383a0eb8540..d0bf7efad7c6 100644
--- a/tools/launcher-generator/.idea/libraries/guava.xml
+++ b/tools/launcher-generator/.idea/libraries/guava.xml
@@ -1,7 +1,7 @@
<component name="libraryTable">
<library name="guava">
<CLASSES>
- <root url="jar://$PROJECT_DIR$/../../lib/guava-14.0.1.jar!/" />
+ <root url="jar://$PROJECT_DIR$/../../lib/guava-17.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
diff --git a/xml/dom-impl/src/com/intellij/util/xml/highlighting/DomElementAnnotationsManagerImpl.java b/xml/dom-impl/src/com/intellij/util/xml/highlighting/DomElementAnnotationsManagerImpl.java
index aec3931e6a45..9acad44ae743 100644
--- a/xml/dom-impl/src/com/intellij/util/xml/highlighting/DomElementAnnotationsManagerImpl.java
+++ b/xml/dom-impl/src/com/intellij/util/xml/highlighting/DomElementAnnotationsManagerImpl.java
@@ -112,7 +112,7 @@ public class DomElementAnnotationsManagerImpl extends DomElementAnnotationsManag
myProject = project;
final ProfileChangeAdapter profileChangeAdapter = new ProfileChangeAdapter() {
@Override
- public void profileActivated(@NotNull Profile oldProfile, Profile profile) {
+ public void profileActivated(Profile oldProfile, Profile profile) {
dropAnnotationsCache();
}
diff --git a/xml/dom-tests/tests/com/intellij/util/xml/DomFileDescriptionTest.java b/xml/dom-tests/tests/com/intellij/util/xml/DomFileDescriptionTest.java
index 7d76e0e2c9c2..0025c58ff063 100644
--- a/xml/dom-tests/tests/com/intellij/util/xml/DomFileDescriptionTest.java
+++ b/xml/dom-tests/tests/com/intellij/util/xml/DomFileDescriptionTest.java
@@ -1,8 +1,17 @@
/*
- * Copyright (c) 2000-2006 JetBrains s.r.o. All Rights Reserved.
- */
-/*
- * Copyright (c) 2000-2006 JetBrains s.r.o. All Rights Reserved.
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package com.intellij.util.xml;
@@ -33,7 +42,7 @@ public class DomFileDescriptionTest extends DomHardCoreTestCase {
myFooElementFile = new WriteCommandAction<XmlFile>(getProject()) {
@Override
- protected void run(Result<XmlFile> result) throws Throwable {
+ protected void run(@NotNull Result<XmlFile> result) throws Throwable {
result.setResult((XmlFile)createFile("a.xml", "<a/>"));
}
}.execute().getResultObject();
@@ -42,7 +51,7 @@ public class DomFileDescriptionTest extends DomHardCoreTestCase {
myBarElementFile = new WriteCommandAction<XmlFile>(getProject()) {
@Override
- protected void run(Result<XmlFile> result) throws Throwable {
+ protected void run(@NotNull Result<XmlFile> result) throws Throwable {
result.setResult((XmlFile)createFile("b.xml", "<b/>"));
}
}.execute().getResultObject();
@@ -63,6 +72,14 @@ public class DomFileDescriptionTest extends DomHardCoreTestCase {
assertResultsAndClear();
}
+ @Override
+ public void tearDown() throws Exception {
+ myFooElementFile = null;
+ myBarElementFile = null;
+
+ super.tearDown();
+ }
+
public void testNoInitialDomnessInB() throws Throwable {
assertFalse(getDomManager().isDomFile(myBarElementFile));
assertNull(getDomManager().getFileElement(myBarElementFile));
@@ -70,7 +87,7 @@ public class DomFileDescriptionTest extends DomHardCoreTestCase {
public void testIsDomValue() throws Throwable {
final XmlFile file = (XmlFile)createFile("a.xml", "<b>42</b>");
- getDomManager().registerFileDescription(new DomFileDescription(MyElement.class, "b") {
+ getDomManager().registerFileDescription(new DomFileDescription<MyElement>(MyElement.class, "b") {
@Override
public boolean isMyFile(@NotNull final XmlFile file, final Module module) {
@@ -84,7 +101,7 @@ public class DomFileDescriptionTest extends DomHardCoreTestCase {
new WriteCommandAction(getProject()) {
@Override
- protected void run(Result result) throws Throwable {
+ protected void run(@NotNull Result result) throws Throwable {
file.getDocument().getRootTag().getValue().setText("239");
}
}.execute();
@@ -97,7 +114,7 @@ public class DomFileDescriptionTest extends DomHardCoreTestCase {
new WriteCommandAction(getProject()) {
@Override
- protected void run(Result result) throws Throwable {
+ protected void run(@NotNull Result result) throws Throwable {
file.getDocument().getRootTag().getValue().setText("57121");
}
}.execute();
@@ -110,7 +127,7 @@ public class DomFileDescriptionTest extends DomHardCoreTestCase {
public void testCopyFileDescriptionFromOriginalFile() throws Throwable {
final XmlFile file = (XmlFile)createFile("a.xml", "<b>42</b>");
- getDomManager().registerFileDescription(new MockDomFileDescription(MyElement.class, "b", file), getTestRootDisposable());
+ getDomManager().registerFileDescription(new MockDomFileDescription<MyElement>(MyElement.class, "b", file), getTestRootDisposable());
file.setName("b.xml");
assertTrue(getDomManager().isDomFile(file));
final XmlFile copy = (XmlFile)file.copy();
@@ -121,9 +138,9 @@ public class DomFileDescriptionTest extends DomHardCoreTestCase {
public void testDependantFileDescriptionCauseStackOverflow() throws Throwable {
final XmlFile interestingFile = (XmlFile)createFile("a.xml", "<b>42</b>");
- getDomManager().registerFileDescription(new MockDomFileDescription(MyElement.class, "b", (XmlFile)null), getTestRootDisposable());
+ getDomManager().registerFileDescription(new MockDomFileDescription<MyElement>(MyElement.class, "b", (XmlFile)null), getTestRootDisposable());
for (int i = 0; i < 239; i++) {
- getDomManager().registerFileDescription(new MockDomFileDescription(AbstractElement.class, "b", (XmlFile)null) {
+ getDomManager().registerFileDescription(new MockDomFileDescription<AbstractElement>(AbstractElement.class, "b", (XmlFile)null) {
@Override
@NotNull
public Set getDependencyItems(final XmlFile file) {
@@ -137,7 +154,7 @@ public class DomFileDescriptionTest extends DomHardCoreTestCase {
}
public void testCheckNamespace() throws Throwable {
- getDomManager().registerFileDescription(new DomFileDescription(NamespacedElement.class, "xxx", "bar"){
+ getDomManager().registerFileDescription(new DomFileDescription<NamespacedElement>(NamespacedElement.class, "xxx", "bar"){
@Override
protected void initializeFileDescription() {
@@ -150,17 +167,16 @@ public class DomFileDescriptionTest extends DomHardCoreTestCase {
new WriteCommandAction(getProject()) {
@Override
- protected void run(Result result) throws Throwable {
+ protected void run(@NotNull Result result) throws Throwable {
((XmlFile)file).getDocument().getRootTag().setAttribute("xmlns", "bar");
}
}.execute();
assertTrue(getDomManager().isDomFile(file));
-
}
public void testCheckDtdPublicId() throws Throwable {
- getDomManager().registerFileDescription(new DomFileDescription(NamespacedElement.class, "xxx", "bar"){
+ getDomManager().registerFileDescription(new DomFileDescription<NamespacedElement>(NamespacedElement.class, "xxx", "bar"){
@Override
protected void initializeFileDescription() {
@@ -173,7 +189,7 @@ public class DomFileDescriptionTest extends DomHardCoreTestCase {
new WriteCommandAction(getProject()) {
@Override
- protected void run(Result result) throws Throwable {
+ protected void run(@NotNull Result result) throws Throwable {
final Document document = getDocument(file);
document.insertString(0, "<!DOCTYPE xxx PUBLIC \"bar\" \"http://java.sun.com/dtd/ejb-jar_2_0.dtd\">\n");
commitDocument(document);
@@ -184,7 +200,7 @@ public class DomFileDescriptionTest extends DomHardCoreTestCase {
}
public void testChangeCustomDomness() throws Throwable {
- getDomManager().registerFileDescription(new DomFileDescription(MyElement.class, "xxx"){
+ getDomManager().registerFileDescription(new DomFileDescription<MyElement>(MyElement.class, "xxx"){
@Override
public boolean isMyFile(@NotNull final XmlFile file, @Nullable final Module module) {
return file.getText().contains("foo");
@@ -194,7 +210,7 @@ public class DomFileDescriptionTest extends DomHardCoreTestCase {
final MyElement boy = getDomManager().getFileElement(file, MyElement.class).getRootElement().getBoys().get(0);
new WriteCommandAction(getProject()) {
@Override
- protected void run(Result result) throws Throwable {
+ protected void run(@NotNull Result result) throws Throwable {
file.getDocument().getRootTag().setAttribute("zzz", "bar");
}
}.execute();
@@ -228,5 +244,4 @@ public class DomFileDescriptionTest extends DomHardCoreTestCase {
}
-
}
diff --git a/xml/dom-tests/tests/com/intellij/util/xml/DomHighlightingLiteTest.java b/xml/dom-tests/tests/com/intellij/util/xml/DomHighlightingLiteTest.java
index e96d2e40a325..1106a7ae2b4d 100644
--- a/xml/dom-tests/tests/com/intellij/util/xml/DomHighlightingLiteTest.java
+++ b/xml/dom-tests/tests/com/intellij/util/xml/DomHighlightingLiteTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -76,9 +76,10 @@ public class DomHighlightingLiteTest extends DomTestCase {
@Override
public XmlTag getXmlTag() {
- return file.getDocument().getRootTag();
+ return file.getRootTag();
}
+ @NotNull
@Override
public Type getDomElementType() {
return DomElement.class;
@@ -109,6 +110,7 @@ public class DomHighlightingLiteTest extends DomTestCase {
return rootElement;
}
+ @NotNull
@Override
public Class getRootElementClass() {
return DomElement.class;
@@ -121,6 +123,15 @@ public class DomHighlightingLiteTest extends DomTestCase {
};
}
+ @Override
+ public void tearDown() throws Exception {
+ myAnnotationsManager = null;
+ myElement = null;
+ myInspectionProfile = null;
+
+ super.tearDown();
+ }
+
public void testEmptyProblemDescriptorInTheBeginning() throws Throwable {
assertEmptyHolder(myAnnotationsManager.getProblemHolder(myElement));
}
@@ -171,7 +182,7 @@ public class DomHighlightingLiteTest extends DomTestCase {
}
public void testMockAnnotatingDomInspection() throws Throwable {
- myElement.setFileDescription(new DomFileDescription(DomElement.class, "a"));
+ myElement.setFileDescription(new DomFileDescription<DomElement>(DomElement.class, "a"));
assertInstanceOf(myAnnotationsManager.getMockInspection(myElement), MockAnnotatingDomInspection.class);
}
@@ -216,14 +227,14 @@ public class DomHighlightingLiteTest extends DomTestCase {
assertEquals(DomHighlightStatus.INSPECTIONS_FINISHED, myAnnotationsManager.getHighlightStatus(myElement));
}
public void testHighlightStatus_MockAnnotatingDomInspection() throws Throwable {
- myElement.setFileDescription(new DomFileDescription(DomElement.class, "a"));
+ myElement.setFileDescription(new DomFileDescription<DomElement>(DomElement.class, "a"));
myAnnotationsManager.appendProblems(myElement, createHolder(), MockAnnotatingDomInspection.class);
assertEquals(DomHighlightStatus.INSPECTIONS_FINISHED, myAnnotationsManager.getHighlightStatus(myElement));
}
public void testHighlightStatus_OtherInspections() throws Throwable {
- myElement.setFileDescription(new DomFileDescription(DomElement.class, "a"));
+ myElement.setFileDescription(new DomFileDescription<DomElement>(DomElement.class, "a"));
final MyDomElementsInspection inspection = new MyDomElementsInspection() {
@Override
@@ -248,7 +259,7 @@ public class DomHighlightingLiteTest extends DomTestCase {
}
public void testHighlightStatus_OtherInspections2() throws Throwable {
- myElement.setFileDescription(new DomFileDescription(DomElement.class, "a"));
+ myElement.setFileDescription(new DomFileDescription<DomElement>(DomElement.class, "a"));
final MyDomElementsInspection inspection = new MyDomElementsInspection() {
@Override
@@ -276,7 +287,7 @@ public class DomHighlightingLiteTest extends DomTestCase {
new MyBasicDomElementsInspection().checkDomElement(element.getId(), createHolder(), DomHighlightingHelperImpl.INSTANCE);
}
- private class MyDomElementsInspection extends DomElementsInspection {
+ private static class MyDomElementsInspection extends DomElementsInspection<DomElement> {
public MyDomElementsInspection() {
super(DomElement.class);
}
@@ -300,7 +311,7 @@ public class DomHighlightingLiteTest extends DomTestCase {
}
}
- private class MyBasicDomElementsInspection extends BasicDomElementsInspection {
+ private static class MyBasicDomElementsInspection extends BasicDomElementsInspection<DomElement> {
public MyBasicDomElementsInspection() {
super(DomElement.class);
}
@@ -330,7 +341,7 @@ public class DomHighlightingLiteTest extends DomTestCase {
}
- private static class MyNonHighlightingDomFileDescription extends DomFileDescription {
+ private static class MyNonHighlightingDomFileDescription extends DomFileDescription<DomElement> {
public MyNonHighlightingDomFileDescription() {
super(DomElement.class, "a");
}
diff --git a/xml/dom-tests/tests/com/intellij/util/xml/MockDomElement.java b/xml/dom-tests/tests/com/intellij/util/xml/MockDomElement.java
index d861ead47908..0172b6e00113 100644
--- a/xml/dom-tests/tests/com/intellij/util/xml/MockDomElement.java
+++ b/xml/dom-tests/tests/com/intellij/util/xml/MockDomElement.java
@@ -1,5 +1,17 @@
/*
- * Copyright (c) 2000-2006 JetBrains s.r.o. All Rights Reserved.
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package com.intellij.util.xml;
@@ -8,8 +20,8 @@ import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.xml.XmlElement;
import com.intellij.psi.xml.XmlTag;
-import com.intellij.util.xml.reflect.DomGenericInfo;
import com.intellij.util.xml.reflect.AbstractDomChildrenDescription;
+import com.intellij.util.xml.reflect.DomGenericInfo;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -20,7 +32,7 @@ import java.lang.reflect.Type;
/**
* @author peter
*/
-public class MockDomElement extends UserDataHolderBase implements DomElement{
+public class MockDomElement extends UserDataHolderBase implements DomElement {
@Override
@Nullable
public XmlTag getXmlTag() {
@@ -112,6 +124,7 @@ public class MockDomElement extends UserDataHolderBase implements DomElement{
throw new UnsupportedOperationException("Method getManager is not yet implemented in " + getClass().getName());
}
+ @NotNull
@Override
public Type getDomElementType() {
throw new UnsupportedOperationException("Method getDomElementType is not yet implemented in " + getClass().getName());
@@ -123,6 +136,7 @@ public class MockDomElement extends UserDataHolderBase implements DomElement{
throw new UnsupportedOperationException("Method getChildDescription is not yet implemented in " + getClass().getName());
}
+ @NotNull
@Override
public DomNameStrategy getNameStrategy() {
throw new UnsupportedOperationException("Method getNameStrategy is not yet implemented in " + getClass().getName());
diff --git a/xml/dom-tests/tests/com/intellij/util/xml/MockDomFileElement.java b/xml/dom-tests/tests/com/intellij/util/xml/MockDomFileElement.java
index b2bbb5f30577..ec16169e73ab 100644
--- a/xml/dom-tests/tests/com/intellij/util/xml/MockDomFileElement.java
+++ b/xml/dom-tests/tests/com/intellij/util/xml/MockDomFileElement.java
@@ -1,5 +1,17 @@
/*
- * Copyright (c) 2000-2006 JetBrains s.r.o. All Rights Reserved.
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package com.intellij.util.xml;
@@ -9,8 +21,8 @@ import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.xml.XmlElement;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
-import com.intellij.util.xml.reflect.DomGenericInfo;
import com.intellij.util.xml.reflect.AbstractDomChildrenDescription;
+import com.intellij.util.xml.reflect.DomGenericInfo;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -21,11 +33,11 @@ import java.lang.reflect.Type;
/**
* @author peter
*/
-public class MockDomFileElement extends UserDataHolderBase implements DomFileElement<DomElement>{
+public class MockDomFileElement extends UserDataHolderBase implements DomFileElement<DomElement> {
private long myModCount = 0;
- private DomFileDescription myFileDescription;
+ private DomFileDescription<DomElement> myFileDescription;
- public void setFileDescription(final DomFileDescription fileDescription) {
+ public void setFileDescription(final DomFileDescription<DomElement> fileDescription) {
myFileDescription = fileDescription;
}
@@ -52,14 +64,15 @@ public class MockDomFileElement extends UserDataHolderBase implements DomFileEle
throw new UnsupportedOperationException("Method getRootElement is not yet implemented in " + getClass().getName());
}
+ @NotNull
@Override
- public Class getRootElementClass() {
+ public Class<DomElement> getRootElementClass() {
throw new UnsupportedOperationException("Method getRootElementType is not yet implemented in " + getClass().getName());
}
@Override
@NotNull
- public DomFileDescription getFileDescription() {
+ public DomFileDescription<DomElement> getFileDescription() {
return myFileDescription;
}
@@ -153,6 +166,7 @@ public class MockDomFileElement extends UserDataHolderBase implements DomFileEle
throw new UnsupportedOperationException("Method getManager is not yet implemented in " + getClass().getName());
}
+ @NotNull
@Override
public Type getDomElementType() {
throw new UnsupportedOperationException("Method getDomElementType is not yet implemented in " + getClass().getName());
@@ -164,6 +178,7 @@ public class MockDomFileElement extends UserDataHolderBase implements DomFileEle
throw new UnsupportedOperationException("Method getChildDescription is not yet implemented in " + getClass().getName());
}
+ @NotNull
@Override
public DomNameStrategy getNameStrategy() {
throw new UnsupportedOperationException("Method getNameStrategy is not yet implemented in " + getClass().getName());
diff --git a/xml/dom-tests/tests/com/intellij/util/xml/MockGenericAttributeValue.java b/xml/dom-tests/tests/com/intellij/util/xml/MockGenericAttributeValue.java
index 15b7a0468d30..22f18218ad85 100644
--- a/xml/dom-tests/tests/com/intellij/util/xml/MockGenericAttributeValue.java
+++ b/xml/dom-tests/tests/com/intellij/util/xml/MockGenericAttributeValue.java
@@ -1,5 +1,17 @@
/*
- * Copyright (c) 2000-2007 JetBrains s.r.o. All Rights Reserved.
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package com.intellij.util.xml;
@@ -23,7 +35,7 @@ public class MockGenericAttributeValue extends MockDomElement implements Generic
@Override
@NotNull
- public Converter getConverter() {
+ public Converter<Object> getConverter() {
throw new UnsupportedOperationException("Method getConverter is not yet implemented in " + getClass().getName());
}
diff --git a/xml/dom-tests/tests/com/intellij/util/xml/ProxyTest.java b/xml/dom-tests/tests/com/intellij/util/xml/ProxyTest.java
index 3db1009c15de..c44d9e74eb45 100644
--- a/xml/dom-tests/tests/com/intellij/util/xml/ProxyTest.java
+++ b/xml/dom-tests/tests/com/intellij/util/xml/ProxyTest.java
@@ -107,6 +107,8 @@ public class ProxyTest extends TestCase {
public abstract String getBar();
+ @Override
+ public abstract String foo();
}
public void testAddInterfaces() throws Throwable {
diff --git a/xml/dom-tests/tests/com/intellij/util/xml/impl/IncrementalUpdateEventsTest.java b/xml/dom-tests/tests/com/intellij/util/xml/impl/IncrementalUpdateEventsTest.java
index 5568b312844c..66a3adaa2ee5 100644
--- a/xml/dom-tests/tests/com/intellij/util/xml/impl/IncrementalUpdateEventsTest.java
+++ b/xml/dom-tests/tests/com/intellij/util/xml/impl/IncrementalUpdateEventsTest.java
@@ -17,7 +17,6 @@ package com.intellij.util.xml.impl;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.psi.xml.XmlTag;
-import com.intellij.util.IncorrectOperationException;
import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.SubTag;
import com.intellij.util.xml.events.DomEvent;
@@ -36,7 +35,7 @@ public class IncrementalUpdateEventsTest extends DomTestCase {
myElement = createElement("<a><child/><child/><child-element/><child-element/></a>");
}
- public void testRemove0() throws IncorrectOperationException {
+ public void testRemove0() {
deleteTag(0);
putExpected(new DomEvent(myElement, false));
assertResultsAndClear();
@@ -54,13 +53,13 @@ public class IncrementalUpdateEventsTest extends DomTestCase {
assertResultsAndClear();
}
- public void testRemove1() throws IncorrectOperationException {
+ public void testRemove1() {
deleteTag(1);
putExpected(new DomEvent(myElement, false));
assertResultsAndClear();
}
- public void testRemove2() throws IncorrectOperationException {
+ public void testRemove2() {
deleteTag(2);
putExpected(new DomEvent(myElement, false));
assertResultsAndClear();
@@ -70,37 +69,37 @@ public class IncrementalUpdateEventsTest extends DomTestCase {
assertResultsAndClear();
}
- public void testRemove3() throws IncorrectOperationException {
+ public void testRemove3() {
deleteTag(3);
putExpected(new DomEvent(myElement, false));
assertResultsAndClear();
}
- public void testAdd0() throws Throwable {
+ public void testAdd0() {
addChildTag(0);
putExpected(new DomEvent(myElement, false));
assertResultsAndClear();
}
- public void testAdd1() throws Throwable {
+ public void testAdd1() {
addChildTag(1);
putExpected(new DomEvent(myElement, false));
assertResultsAndClear();
}
- public void testAdd2() throws Throwable {
+ public void testAdd2() {
addChildElementTag(2);
putExpected(new DomEvent(myElement, false));
assertResultsAndClear();
}
- public void testAdd3() throws Throwable {
+ public void testAdd3() {
addChildElementTag(3);
putExpected(new DomEvent(myElement, false));
assertResultsAndClear();
}
- public void testAdd4() throws Throwable {
+ public void testAdd4() {
final XmlTag tag = myElement.getXmlTag();
tag.addAfter(createTag("<child-element/>"), tag.getSubTags()[3]);
putExpected(new DomEvent(myElement, false));
@@ -111,18 +110,18 @@ public class IncrementalUpdateEventsTest extends DomTestCase {
return myElement.getChildElements().get(index);
}
- private void addChildTag(int index) throws IncorrectOperationException {
+ private void addChildTag(int index) {
final XmlTag tag = myElement.getXmlTag();
tag.addBefore(createTag("<child/>"), tag.getSubTags()[index]);
}
- private void addChildElementTag(int index) throws IncorrectOperationException {
+ private void addChildElementTag(int index) {
final XmlTag tag = myElement.getXmlTag();
tag.addBefore(createTag("<child-element/>"), tag.getSubTags()[index]);
}
- private void deleteTag(final int index) throws IncorrectOperationException {
+ private void deleteTag(final int index) {
WriteCommandAction.runWriteCommandAction(null, new Runnable() {
@Override
public void run() {
@@ -131,7 +130,7 @@ public class IncrementalUpdateEventsTest extends DomTestCase {
});
}
- private MyElement createElement(final String xml) throws IncorrectOperationException {
+ private MyElement createElement(final String xml) {
return createElement(xml, MyElement.class);
}
@@ -143,6 +142,4 @@ public class IncrementalUpdateEventsTest extends DomTestCase {
List<MyElement> getChildElements();
}
-
-
}
diff --git a/xml/impl/src/com/intellij/codeInsight/editorActions/HtmlCopyPastePreProcessor.java b/xml/impl/src/com/intellij/codeInsight/editorActions/HtmlCopyPastePreProcessor.java
new file mode 100644
index 000000000000..9e081ebebf6a
--- /dev/null
+++ b/xml/impl/src/com/intellij/codeInsight/editorActions/HtmlCopyPastePreProcessor.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.editorActions;
+
+import com.intellij.lang.html.HTMLLanguage;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.CaretStateTransferableData;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.RawText;
+import com.intellij.openapi.ide.CopyPasteManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.PsiFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.text.BadLocationException;
+import javax.swing.text.DefaultStyledDocument;
+import javax.swing.text.html.HTMLEditorKit;
+import javax.swing.text.rtf.RTFEditorKit;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+
+/**
+ * @author Dennis.Ushakov
+ */
+public class HtmlCopyPastePreProcessor implements CopyPastePreProcessor {
+ private static final Logger LOG = Logger.getInstance(HtmlCopyPastePreProcessor.class);
+
+ private static final DataFlavor ourHtmlDataFlavor = buildDataFlavor("text/html;class=java.lang.String");
+ private static final DataFlavor ourRtfDataFlavor = buildDataFlavor("text/rtf;class=java.io.InputStream");
+
+ private static DataFlavor buildDataFlavor(final String flavor) {
+ try {
+ return new DataFlavor(flavor);
+ }
+ catch (ClassNotFoundException e) {
+ return null;
+ }
+ }
+
+ @Nullable
+ @Override
+ public String preprocessOnCopy(PsiFile file, int[] startOffsets, int[] endOffsets, String text) {
+ return null;
+ }
+
+ @NotNull
+ @Override
+ public String preprocessOnPaste(Project project, PsiFile file, Editor editor, String text, RawText rawText) {
+ if (file.getLanguage() != HTMLLanguage.INSTANCE) return text;
+
+ CopyPasteManager manager = CopyPasteManager.getInstance();
+ if (manager.areDataFlavorsAvailable(ourHtmlDataFlavor, ourRtfDataFlavor)) {
+ Transferable content = manager.getContents();
+ if (content != null && !content.isDataFlavorSupported(CaretStateTransferableData.FLAVOR)) {
+ try {
+ final String data = content.isDataFlavorSupported(ourHtmlDataFlavor) ? (String)content.getTransferData(ourHtmlDataFlavor) :
+ convertFromRtfStream((InputStream)content.getTransferData(ourRtfDataFlavor));
+ if (!StringUtil.isEmpty(data)) return data;
+ }
+ catch (UnsupportedFlavorException e) {
+ LOG.error(e);
+ }
+ catch (IOException e) {
+ LOG.error(e);
+ }
+ }
+ }
+ return text;
+ }
+
+ private static String convertFromRtfStream(InputStream stream) {
+ final DefaultStyledDocument document = new DefaultStyledDocument();
+ try {
+ new RTFEditorKit().read(stream, document, 0);
+ final StringWriter writer = new StringWriter();
+ new HTMLEditorKit().write(writer, document, 0, document.getLength());
+ return writer.toString();
+ }
+ catch (IOException e) {
+ LOG.error(e);
+ }
+ catch (BadLocationException e) {
+ LOG.error(e);
+ }
+ return null;
+ }
+}
diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/generators/XmlZenCodingGenerator.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/generators/XmlZenCodingGenerator.java
index b0165652173e..0ecbaafd8b89 100644
--- a/xml/impl/src/com/intellij/codeInsight/template/emmet/generators/XmlZenCodingGenerator.java
+++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/generators/XmlZenCodingGenerator.java
@@ -101,18 +101,17 @@ public abstract class XmlZenCodingGenerator extends ZenCodingGenerator {
while (prevVisibleLeaf != null) {
TextRange textRange = prevVisibleLeaf.getTextRange();
final int endOffset = textRange.getEndOffset();
- if (endOffset > currentOffset) {
- continue;
+ if (endOffset <= currentOffset) {
+ if (endOffset <= startOffset) {
+ break;
+ }
+ IElementType prevType = prevVisibleLeaf.getNode().getElementType();
+ if (prevType == XmlTokenType.XML_TAG_END || prevType == XmlTokenType.XML_EMPTY_ELEMENT_END) {
+ startOffset = endOffset;
+ break;
+ }
}
- if (endOffset <= startOffset) {
- break;
- }
- IElementType prevType = prevVisibleLeaf.getNode().getElementType();
- if (prevType == XmlTokenType.XML_TAG_END || prevType == XmlTokenType.XML_EMPTY_ELEMENT_END) {
- startOffset = endOffset;
- break;
- }
- prevVisibleLeaf = PsiTreeUtil.prevVisibleLeaf(prevVisibleLeaf);
+ prevVisibleLeaf = PsiTreeUtil.prevVisibleLeaf(prevVisibleLeaf);
}
if (startOffset < 0 || currentOffset > documentText.length() || currentOffset < startOffset) {
diff --git a/xml/impl/src/com/intellij/ide/browsers/BrowserLauncherImpl.java b/xml/impl/src/com/intellij/ide/browsers/BrowserLauncherImpl.java
index 4f7f4efa5085..65da7b30722c 100644
--- a/xml/impl/src/com/intellij/ide/browsers/BrowserLauncherImpl.java
+++ b/xml/impl/src/com/intellij/ide/browsers/BrowserLauncherImpl.java
@@ -24,6 +24,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.AppUIUtil;
import com.intellij.util.ArrayUtil;
@@ -38,7 +39,7 @@ final class BrowserLauncherImpl extends BrowserLauncherAppless {
@Override
protected void browseUsingNotSystemDefaultBrowserPolicy(@NotNull URI uri, @NotNull GeneralSettings settings, @Nullable Project project) {
WebBrowserManager browserManager = WebBrowserManager.getInstance();
- if (browserManager.getDefaultBrowserPolicy() == DefaultBrowserPolicy.FIRST) {
+ if (browserManager.getDefaultBrowserPolicy() == DefaultBrowserPolicy.FIRST || (SystemInfo.isMac && "open".equals(settings.getBrowserPath()))) {
WebBrowser browser = browserManager.getFirstActiveBrowser();
if (browser != null) {
browseUsingPath(uri.toString(), null, browser, project, ArrayUtil.EMPTY_STRING_ARRAY);
@@ -50,7 +51,11 @@ final class BrowserLauncherImpl extends BrowserLauncherAppless {
}
@Override
- protected void doShowError(@Nullable final String error, @Nullable final WebBrowser browser, @Nullable final Project project, final String title, @Nullable final Runnable launchTask) {
+ protected void showError(@Nullable final String error,
+ @Nullable final WebBrowser browser,
+ @Nullable final Project project,
+ final String title,
+ @Nullable final Runnable launchTask) {
AppUIUtil.invokeOnEdt(new Runnable() {
@Override
public void run() {
@@ -85,7 +90,7 @@ final class BrowserLauncherImpl extends BrowserLauncherAppless {
public void run() {
try {
if (process.waitFor() == 1) {
- doShowError(ExecUtil.readFirstLine(process.getErrorStream(), null), browser, project, null, launchTask);
+ showError(ExecUtil.readFirstLine(process.getErrorStream(), null), browser, project, null, launchTask);
}
}
catch (InterruptedException ignored) {
diff --git a/xml/impl/src/com/intellij/ide/browsers/BrowserStarter.java b/xml/impl/src/com/intellij/ide/browsers/BrowserStarter.java
index 8e3f014ea5af..ca6726926d6f 100644
--- a/xml/impl/src/com/intellij/ide/browsers/BrowserStarter.java
+++ b/xml/impl/src/com/intellij/ide/browsers/BrowserStarter.java
@@ -21,12 +21,12 @@ public class BrowserStarter {
private static final Logger LOG = Logger.getInstance(BrowserStarter.class);
private final StartBrowserSettings mySettings;
- private final RunConfiguration myNodeRunConfiguration;
+ private final RunConfiguration myRunConfiguration;
private final ProcessHandler myServerProcessHandler;
public BrowserStarter(@NotNull RunConfiguration runConfiguration, @NotNull StartBrowserSettings settings, @NotNull ProcessHandler serverProcessHandler) {
mySettings = settings;
- myNodeRunConfiguration = runConfiguration;
+ myRunConfiguration = runConfiguration;
myServerProcessHandler = serverProcessHandler;
}
@@ -102,7 +102,7 @@ public class BrowserStarter {
private void openPageNow() {
if (!isProcessTerminated()) {
- JavaScriptDebuggerStarter.Util.startDebugOrLaunchBrowser(myNodeRunConfiguration, mySettings);
+ JavaScriptDebuggerStarter.Util.startDebugOrLaunchBrowser(myRunConfiguration, mySettings);
}
}
diff --git a/xml/impl/src/com/intellij/ide/browsers/JavaScriptDebuggerStarter.java b/xml/impl/src/com/intellij/ide/browsers/JavaScriptDebuggerStarter.java
index cbc8cb111557..71dbb0c0dd71 100644
--- a/xml/impl/src/com/intellij/ide/browsers/JavaScriptDebuggerStarter.java
+++ b/xml/impl/src/com/intellij/ide/browsers/JavaScriptDebuggerStarter.java
@@ -12,8 +12,7 @@ import org.jetbrains.annotations.Nullable;
public interface JavaScriptDebuggerStarter<RC extends RunConfiguration, U> {
boolean isApplicable(@NotNull RunConfiguration runConfiguration);
- // todo we must pass browser family, otherwise result could be unexpected (by default Chrome will be used, but user can prefer Firefox)
- void start(@NotNull String url, @NotNull RC runConfiguration, @NotNull U userData);
+ void start(@NotNull String url, @NotNull RC runConfiguration, @NotNull U userData, @Nullable WebBrowser browser);
final class Util {
static final ExtensionPointName<JavaScriptDebuggerStarter> EP_NAME = ExtensionPointName.create("org.jetbrains.javaScriptDebuggerStarter");
@@ -31,11 +30,15 @@ public interface JavaScriptDebuggerStarter<RC extends RunConfiguration, U> {
}
public static <RC extends RunConfiguration> boolean start(@NotNull RC runConfiguration, @NotNull String url) {
+ return start(runConfiguration, url, null);
+ }
+
+ public static <RC extends RunConfiguration> boolean start(@NotNull RC runConfiguration, @NotNull String url, @Nullable WebBrowser browser) {
JavaScriptDebuggerStarter<RC, Object> starter = get(runConfiguration);
if (starter == null) {
return false;
}
- starter.start(url, runConfiguration, NULL_OBJECT);
+ starter.start(url, runConfiguration, NULL_OBJECT, browser);
return true;
}
@@ -49,9 +52,13 @@ public interface JavaScriptDebuggerStarter<RC extends RunConfiguration, U> {
@NotNull String url,
@Nullable WebBrowser browser,
boolean startDebugger) {
- if (!startDebugger || !start(runConfiguration, url)) {
+ if (!startDebugger || !start(runConfiguration, url, browser)) {
BrowserLauncher.getInstance().browse(url, browser, runConfiguration.getProject());
}
}
+
+ public static boolean hasStarters() {
+ return EP_NAME.getExtensions().length > 0;
+ }
}
}
diff --git a/xml/impl/src/com/intellij/ide/browsers/OpenUrlHyperlinkInfo.java b/xml/impl/src/com/intellij/ide/browsers/OpenUrlHyperlinkInfo.java
index e6bd32729b13..b634fd2fc8b1 100644
--- a/xml/impl/src/com/intellij/ide/browsers/OpenUrlHyperlinkInfo.java
+++ b/xml/impl/src/com/intellij/ide/browsers/OpenUrlHyperlinkInfo.java
@@ -40,15 +40,15 @@ public final class OpenUrlHyperlinkInfo implements HyperlinkWithPopupMenuInfo {
this(url, Conditions.<WebBrowser>alwaysTrue(), null);
}
- public OpenUrlHyperlinkInfo(@NotNull String url, @Nullable WebBrowser browser) {
- this(url, null, browser);
+ public OpenUrlHyperlinkInfo(@NotNull String url, @Nullable final WebBrowser browser) {
+ this(url, browser == null ? Conditions.<WebBrowser>alwaysTrue() : Conditions.is(browser));
}
public OpenUrlHyperlinkInfo(@NotNull String url, @NotNull Condition<WebBrowser> browserCondition) {
this(url, browserCondition, null);
}
- private OpenUrlHyperlinkInfo(@NotNull String url, @Nullable Condition<WebBrowser> browserCondition, @Nullable WebBrowser browser) {
+ private OpenUrlHyperlinkInfo(@NotNull String url, @NotNull Condition<WebBrowser> browserCondition, @Nullable WebBrowser browser) {
this.url = url;
this.browserCondition = browserCondition;
this.browser = browser;
@@ -58,7 +58,7 @@ public final class OpenUrlHyperlinkInfo implements HyperlinkWithPopupMenuInfo {
public ActionGroup getPopupMenuGroup(@NotNull MouseEvent event) {
DefaultActionGroup group = new DefaultActionGroup();
for (final WebBrowser browser : WebBrowserManager.getInstance().getActiveBrowsers()) {
- if (browserCondition == null ? (this.browser == null || browser.equals(this.browser)) : browserCondition.value(browser)) {
+ if (browserCondition.value(browser)) {
group.add(new AnAction("Open in " + browser.getName(), "Open URL in " + browser.getName(), browser.getIcon()) {
@Override
public void actionPerformed(AnActionEvent e) {
diff --git a/xml/impl/src/com/intellij/ide/browsers/StartBrowserPanel.java b/xml/impl/src/com/intellij/ide/browsers/StartBrowserPanel.java
index 603746bb3c60..a0faad5a0eb5 100644
--- a/xml/impl/src/com/intellij/ide/browsers/StartBrowserPanel.java
+++ b/xml/impl/src/com/intellij/ide/browsers/StartBrowserPanel.java
@@ -59,7 +59,7 @@ public class StartBrowserPanel {
private JPanel myRoot;
public StartBrowserPanel() {
- myStartJavaScriptDebuggerCheckBox.setVisible(JavaScriptDebuggerStarter.Util.EP_NAME.getExtensions().length > 0);
+ myStartJavaScriptDebuggerCheckBox.setVisible(JavaScriptDebuggerStarter.Util.hasStarters());
myRoot.addAncestorListener(new AncestorListenerAdapter() {
@Override
public void ancestorAdded(AncestorEvent event) {
diff --git a/xml/impl/src/com/intellij/lang/xml/XmlEnclosingTagUnwrapper.java b/xml/impl/src/com/intellij/lang/xml/XmlEnclosingTagUnwrapper.java
index b40ca4b64f60..480174b40cc0 100644
--- a/xml/impl/src/com/intellij/lang/xml/XmlEnclosingTagUnwrapper.java
+++ b/xml/impl/src/com/intellij/lang/xml/XmlEnclosingTagUnwrapper.java
@@ -16,18 +16,18 @@
package com.intellij.lang.xml;
import com.intellij.codeInsight.unwrap.Unwrapper;
+import com.intellij.lang.ASTNode;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.xml.XmlChildRole;
import com.intellij.psi.xml.XmlTag;
-import com.intellij.xml.XmlBundle;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.util.TextRange;
import com.intellij.util.IncorrectOperationException;
-import com.intellij.lang.ASTNode;
+import com.intellij.xml.XmlBundle;
-import java.util.Set;
-import java.util.List;
import java.util.Collections;
+import java.util.List;
+import java.util.Set;
public class XmlEnclosingTagUnwrapper implements Unwrapper {
@Override
@@ -45,8 +45,21 @@ public class XmlEnclosingTagUnwrapper implements Unwrapper {
}
@Override
- public PsiElement collectAffectedElements(PsiElement e, List<PsiElement> toExtract) {
- return e;
+ public PsiElement collectAffectedElements(PsiElement element, List<PsiElement> toExtract) {
+ final TextRange range = element.getTextRange();
+ final ASTNode startTagNameEnd = XmlChildRole.START_TAG_END_FINDER.findChild(element.getNode());
+ final ASTNode endTagNameStart = XmlChildRole.CLOSING_TAG_START_FINDER.findChild(element.getNode());
+
+ int start = startTagNameEnd != null ? startTagNameEnd.getTextRange().getEndOffset() : range.getStartOffset();
+ int end = endTagNameStart != null ? endTagNameStart.getTextRange().getStartOffset() : range.getEndOffset();
+
+ for (PsiElement child : element.getChildren()) {
+ final TextRange childRange = child.getTextRange();
+ if (childRange.getStartOffset() >= start && childRange.getEndOffset() <= end) {
+ toExtract.add(child);
+ }
+ }
+ return element;
}
@Override
diff --git a/xml/impl/src/com/intellij/xml/util/documentation/html5.html b/xml/impl/src/com/intellij/xml/util/documentation/html5.html
index 97adbfb5c932..3c40f5d544a8 100644
--- a/xml/impl/src/com/intellij/xml/util/documentation/html5.html
+++ b/xml/impl/src/com/intellij/xml/util/documentation/html5.html
@@ -118,7 +118,6 @@
.element dd, .element dl { margin-top: 0em; margin-bottom: 0.25em;}
dt { margin-top: 0.75em; margin-bottom: 0.5em; clear: left; }
.element dt { margin-top: 0.5em; margin-bottom: 0.5em; }
- adding tag omission & allowed ARIA role, state and property info to element definitions in HTML5.1 http://www.w3.org/html/wg/drafts/html/master/semantics.html#the-html-element … feedabck welcome!
dt + dt { margin-top: 0; }
dd dt { margin-top: 0.25em; margin-bottom: 0; }
dd p { margin-top: 0; }
@@ -179,8 +178,9 @@
h1, h2, h3, h4, h5, h6 { page-break-after: avoid; }
h1 + h2, hr + h2.no-toc { page-break-before: auto; }
- p > span:not([title=""]):not([class="XXX"]):not([class="impl"]):not([class="note"]),
- li > span:not([title=""]):not([class="XXX"]):not([class="impl"]):not([class="note"]) { border-bottom: solid #9999CC; }
+ p > span:not([title=""]):not([class="XXX"]):not([class="impl"]):not([class="note"]):not([class="t2"]):not([id]):not([lang]),
+ li > span:not([title=""]):not([class="XXX"]):not([class="impl"]):not([class="note"]):not([class="t2"]):not([id]):not([lang])
+ { border-bottom: solid #9999CC; }
div.head { margin: 0 0 1em; padding: 1em 0 0 0; }
div.head p { margin: 0; }
@@ -339,7 +339,7 @@
Nightly
</h1>
<p class="no-num no-toc subline">A vocabulary and associated APIs for HTML and XHTML</p>
- <p class="no-num no-toc subline">Editor's Draft 16 January 2014</p>
+ <p class="no-num no-toc subline">Editor's Draft 23 August 2014</p>
</header></div>
@@ -361,6 +361,7 @@
<h3 class="no-num" id="elements-1">Elements</h3>
<p><i>This section is non-normative.</i></p>
+
<!-- XXX this index doesn't list the palpable elements -->
<table><caption>List of elements</caption>
@@ -379,13 +380,13 @@
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
<td><a href="dom.html#transparent">transparent</a>*</td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-hyperlink-href"><a href="links.html#href-3">href</a></code>;
- <code data-anolis-xref="attr-hyperlink-target"><a href="links.html#target-4">target</a></code>;
- <code data-anolis-xref="attr-hyperlink-download"><a href="links.html#download-1">download</a></code>;
+ <code data-anolis-xref="attr-hyperlink-href"><a href="links.html#attr-hyperlink-href">href</a></code>;
+ <code data-anolis-xref="attr-hyperlink-target"><a href="links.html#attr-hyperlink-target">target</a></code>;
+ <code data-anolis-xref="attr-hyperlink-download"><a href="links.html#attr-hyperlink-download">download</a></code>;
<!--PING-->
- <code data-anolis-xref="attr-hyperlink-rel"><a href="links.html#rel-3">rel</a></code>;
- <code data-anolis-xref="attr-hyperlink-hreflang"><a href="links.html#hreflang-3">hreflang</a></code>;
- <code data-anolis-xref="attr-hyperlink-type"><a href="links.html#type-14">type</a></code></td>
+ <code data-anolis-xref="attr-hyperlink-rel"><a href="links.html#attr-hyperlink-rel">rel</a></code>;
+ <code data-anolis-xref="attr-hyperlink-hreflang"><a href="links.html#attr-hyperlink-hreflang">hreflang</a></code>;
+ <code data-anolis-xref="attr-hyperlink-type"><a href="links.html#attr-hyperlink-type">type</a></code></td>
<td><code><a href="text-level-semantics.html#htmlanchorelement">HTMLAnchorElement</a></code></td>
<tr><th><code><a href="text-level-semantics.html#the-abbr-element">abbr</a></code></th>
<td>Abbreviation</td>
@@ -402,24 +403,24 @@
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a>*</td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a></td>
<td><code><a href="dom.html#htmlelement">HTMLElement</a></code></td>
- <tr><th><code><a href="embedded-content-0.html#the-area-element">area</a></code></th>
+ <tr><th><code><a href="embedded-content.html#the-area-element">area</a></code></th>
<td>Hyperlink or dead area on an image map</td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a>;
<a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a>*</td>
<td>empty</td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-area-alt"><a href="embedded-content-0.html#alt-2">alt</a></code>;
- <code data-anolis-xref="attr-area-coords"><a href="embedded-content-0.html#coords">coords</a></code>;
- <code data-anolis-xref="attr-area-shape"><a href="embedded-content-0.html#shape">shape</a></code>;
- <code data-anolis-xref="attr-hyperlink-href"><a href="links.html#href-3">href</a></code>;
- <code data-anolis-xref="attr-hyperlink-target"><a href="links.html#target-4">target</a></code>;
- <code data-anolis-xref="attr-hyperlink-download"><a href="links.html#download-1">download</a></code>;
+ <code data-anolis-xref="attr-area-alt"><a href="embedded-content.html#attr-area-alt">alt</a></code>;
+ <code data-anolis-xref="attr-area-coords"><a href="embedded-content.html#attr-area-coords">coords</a></code>;
+ <code data-anolis-xref="attr-area-shape"><a href="embedded-content.html#attr-area-shape">shape</a></code>;
+ <code data-anolis-xref="attr-hyperlink-href"><a href="links.html#attr-hyperlink-href">href</a></code>;
+ <code data-anolis-xref="attr-hyperlink-target"><a href="links.html#attr-hyperlink-target">target</a></code>;
+ <code data-anolis-xref="attr-hyperlink-download"><a href="links.html#attr-hyperlink-download">download</a></code>;
<!--PING-->
- <code data-anolis-xref="attr-hyperlink-rel"><a href="links.html#rel-3">rel</a></code>;
- <code data-anolis-xref="attr-hyperlink-hreflang"><a href="links.html#hreflang-3">hreflang</a></code>;
- <code data-anolis-xref="attr-hyperlink-type"><a href="links.html#type-14">type</a></code></td>
- <td><code><a href="embedded-content-0.html#htmlareaelement">HTMLAreaElement</a></code></td>
+ <code data-anolis-xref="attr-hyperlink-rel"><a href="links.html#attr-hyperlink-rel">rel</a></code>;
+ <code data-anolis-xref="attr-hyperlink-hreflang"><a href="links.html#attr-hyperlink-hreflang">hreflang</a></code>;
+ <code data-anolis-xref="attr-hyperlink-type"><a href="links.html#attr-hyperlink-type">type</a></code></td>
+ <td><code><a href="embedded-content.html#htmlareaelement">HTMLAreaElement</a></code></td>
<tr><th><code><a href="sections.html#the-article-element">article</a></code></th>
<td>Self-contained syndicatable or reusable composition</td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a>;
@@ -436,25 +437,25 @@
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a></td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a></td>
<td><code><a href="dom.html#htmlelement">HTMLElement</a></code></td>
- <tr><th><code><a href="embedded-content-0.html#the-audio-element">audio</a></code></th>
+ <tr><th><code><a href="embedded-content.html#the-audio-element">audio</a></code></th>
<td>Audio player</td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a>;
<a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a>;
- <a data-anolis-xref="Embedded content" href="dom.html#embedded-content-2">embedded</a>;
+ <a data-anolis-xref="Embedded content" href="dom.html#embedded-content-category">embedded</a>;
<a data-anolis-xref="Interactive content" href="dom.html#interactive-content-0">interactive</a></td>
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
- <td><code><a href="embedded-content-0.html#the-source-element">source</a></code>*;
+ <td><code><a href="embedded-content.html#the-source-element">source</a></code>*;
<a href="dom.html#transparent">transparent</a>*</td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-media-src"><a href="embedded-content-0.html#src-9">src</a></code>;
- <code data-anolis-xref="attr-media-crossorigin"><a href="embedded-content-0.html#crossorigin-3">crossorigin</a></code>;
- <code data-anolis-xref="attr-media-preload"><a href="embedded-content-0.html#preload">preload</a></code>;
- <code data-anolis-xref="attr-media-autoplay"><a href="embedded-content-0.html#autoplay">autoplay</a></code>;
- <code data-anolis-xref="attr-media-mediagroup"><a href="embedded-content-0.html#mediagroup">mediagroup</a></code>;
- <code data-anolis-xref="attr-media-loop"><a href="embedded-content-0.html#loop">loop</a></code>;
- <code data-anolis-xref="attr-media-muted"><a href="embedded-content-0.html#muted-1">muted</a></code>;
- <code data-anolis-xref="attr-media-controls"><a href="embedded-content-0.html#controls">controls</a></code></td>
- <td><code><a href="embedded-content-0.html#htmlaudioelement">HTMLAudioElement</a></code></td>
+ <code data-anolis-xref="attr-media-src"><a href="embedded-content.html#attr-media-src">src</a></code>;
+ <code data-anolis-xref="attr-media-crossorigin"><a href="embedded-content.html#attr-media-crossorigin">crossorigin</a></code>;
+ <code data-anolis-xref="attr-media-preload"><a href="embedded-content.html#attr-media-preload">preload</a></code>;
+ <code data-anolis-xref="attr-media-autoplay"><a href="embedded-content.html#attr-media-autoplay">autoplay</a></code>;
+ <code data-anolis-xref="attr-media-mediagroup"><a href="embedded-content.html#attr-media-mediagroup">mediagroup</a></code>;
+ <code data-anolis-xref="attr-media-loop"><a href="embedded-content.html#attr-media-loop">loop</a></code>;
+ <code data-anolis-xref="attr-media-muted"><a href="embedded-content.html#attr-media-muted">muted</a></code>;
+ <code data-anolis-xref="attr-media-controls"><a href="embedded-content.html#attr-media-controls">controls</a></code></td>
+ <td><code><a href="embedded-content.html#htmlaudioelement">HTMLAudioElement</a></code></td>
<tr><th><code><a href="text-level-semantics.html#the-b-element">b</a></code></th>
<td>Keywords</td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a>;
@@ -464,14 +465,14 @@
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a></td>
<td><code><a href="dom.html#htmlelement">HTMLElement</a></code></td>
<tr><th><code><a href="document-metadata.html#the-base-element">base</a></code></th>
- <td>Base URL and default target <a href="browsers.html#browsing-context">browsing context</a> for <a data-anolis-xref="attr-hyperlink-target" href="links.html#target-4">hyperlinks</a> and <a data-anolis-xref="attr-fs-target" href="forms.html#target-5">forms</a></td>
+ <td>Base URL and default target <a href="browsers.html#browsing-context">browsing context</a> for <a data-anolis-xref="attr-hyperlink-target" href="links.html#attr-hyperlink-target">hyperlinks</a> and <a data-anolis-xref="attr-fs-target" href="forms.html#attr-fs-target">forms</a></td>
<td><a data-anolis-xref="Metadata content" href="dom.html#metadata-content-0">metadata</a></td>
<td><code><a href="document-metadata.html#the-head-element">head</a></code>;
<code><a href="scripting-1.html#the-template-element">template</a></code></td>
<td>empty</td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-base-href"><a href="document-metadata.html#href">href</a></code>;
- <code data-anolis-xref="attr-base-target"><a href="document-metadata.html#target-0">target</a></code></td>
+ <code data-anolis-xref="attr-base-href"><a href="document-metadata.html#attr-base-href">href</a></code>;
+ <code data-anolis-xref="attr-base-target"><a href="document-metadata.html#attr-base-target">target</a></code></td>
<td><code><a href="document-metadata.html#htmlbaseelement">HTMLBaseElement</a></code></td>
<tr><th><code><a href="text-level-semantics.html#the-bdi-element">bdi</a></code></th>
<td>Text directionality isolation</td>
@@ -492,30 +493,31 @@
<tr><th><code><a href="grouping-content.html#the-blockquote-element">blockquote</a></code></th>
<td>A section quoted from another source</td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a>;
- <a data-anolis-xref="Sectioning root" href="sections.html#sectioning-roots">sectioning root</a></td>
+ <a data-anolis-xref="Sectioning root" href="sections.html#sectioning-root">sectioning root</a></td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a></td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a></td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-blockquote-cite"><a href="grouping-content.html#cite">cite</a></code></td>
+ <code data-anolis-xref="attr-blockquote-cite"><a href="grouping-content.html#attr-blockquote-cite">cite</a></code></td>
<td><code><a href="grouping-content.html#htmlquoteelement">HTMLQuoteElement</a></code></td>
<tr><th><code><a href="sections.html#the-body-element">body</a></code></th>
<td>Document body</td>
- <td><a data-anolis-xref="Sectioning root" href="sections.html#sectioning-roots">sectioning root</a></td>
+ <td><a data-anolis-xref="Sectioning root" href="sections.html#sectioning-root">sectioning root</a></td>
<td><code><a href="semantics.html#the-html-element">html</a></code></td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a></td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="handler-window-onafterprint"><a href="webappapis.html#onafterprint">onafterprint</a></code>;
- <code data-anolis-xref="handler-window-onbeforeprint"><a href="webappapis.html#onbeforeprint">onbeforeprint</a></code>;
- <code data-anolis-xref="handler-window-onbeforeunload"><a href="webappapis.html#onbeforeunload">onbeforeunload</a></code>;
- <code data-anolis-xref="handler-window-onhashchange"><a href="webappapis.html#onhashchange">onhashchange</a></code>;
- <code data-anolis-xref="handler-window-onmessage"><a href="webappapis.html#onmessage">onmessage</a></code>;
- <code data-anolis-xref="handler-window-onoffline"><a href="webappapis.html#onoffline">onoffline</a></code>;
- <code data-anolis-xref="handler-window-ononline"><a href="webappapis.html#ononline">ononline</a></code>;
- <code data-anolis-xref="handler-window-onpagehide"><a href="webappapis.html#onpagehide">onpagehide</a></code>;
- <code data-anolis-xref="handler-window-onpageshow"><a href="webappapis.html#onpageshow">onpageshow</a></code>;
- <code data-anolis-xref="handler-window-onpopstate"><a href="webappapis.html#onpopstate">onpopstate</a></code>;
- <code data-anolis-xref="handler-window-onstorage"><a href="webappapis.html#onstorage">onstorage</a></code>;
- <code data-anolis-xref="handler-window-onunload"><a href="webappapis.html#onunload">onunload</a></code></td>
+ <code data-anolis-xref="handler-window-onafterprint"><a href="webappapis.html#handler-window-onafterprint">onafterprint</a></code>;
+ <code data-anolis-xref="handler-window-onbeforeprint"><a href="webappapis.html#handler-window-onbeforeprint">onbeforeprint</a></code>;
+ <code data-anolis-xref="handler-window-onbeforeunload"><a href="webappapis.html#handler-window-onbeforeunload">onbeforeunload</a></code>;
+ <code data-anolis-xref="handler-window-onhashchange"><a href="webappapis.html#handler-window-onhashchange">onhashchange</a></code>;
+ <code data-anolis-xref="handler-window-onlanguagechange"><a href="webappapis.html#handler-window-onlanguagechange">onlanguagechange</a></code>;
+ <code data-anolis-xref="handler-window-onmessage"><a href="webappapis.html#handler-window-onmessage">onmessage</a></code>;
+ <code data-anolis-xref="handler-window-onoffline"><a href="webappapis.html#handler-window-onoffline">onoffline</a></code>;
+ <code data-anolis-xref="handler-window-ononline"><a href="webappapis.html#handler-window-ononline">ononline</a></code>;
+ <code data-anolis-xref="handler-window-onpagehide"><a href="webappapis.html#handler-window-onpagehide">onpagehide</a></code>;
+ <code data-anolis-xref="handler-window-onpageshow"><a href="webappapis.html#handler-window-onpageshow">onpageshow</a></code>;
+ <code data-anolis-xref="handler-window-onpopstate"><a href="webappapis.html#handler-window-onpopstate">onpopstate</a></code>;
+ <code data-anolis-xref="handler-window-onstorage"><a href="webappapis.html#handler-window-onstorage">onstorage</a></code>;
+ <code data-anolis-xref="handler-window-onunload"><a href="webappapis.html#handler-window-onunload">onunload</a></code></td>
<td><code><a href="sections.html#htmlbodyelement">HTMLBodyElement</a></code></td>
<tr><th><code><a href="text-level-semantics.html#the-br-element">br</a></code></th>
<td>Line break, e.g. in poem or postal address</td>
@@ -530,37 +532,37 @@
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a>;
<a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a>;
<a data-anolis-xref="Interactive content" href="dom.html#interactive-content-0">interactive</a>;
- <a data-anolis-xref="category-listed" href="forms.html#listed-elements">listed</a>;
- <a data-anolis-xref="category-label" href="forms.html#labelable-elements">labelable</a>;
- <a data-anolis-xref="category-submit" href="forms.html#submittable-elements">submittable</a>;
- <a data-anolis-xref="category-form-attr" href="forms.html#reassociateable-elements">reassociateable</a>;
- <a data-anolis-xref="Form-associated element" href="forms.html#form-associated-elements">form-associated</a></td>
+ <a data-anolis-xref="category-listed" href="forms.html#category-listed">listed</a>;
+ <a data-anolis-xref="category-label" href="forms.html#category-label">labelable</a>;
+ <a data-anolis-xref="category-submit" href="forms.html#category-submit">submittable</a>;
+ <a data-anolis-xref="category-form-attr" href="forms.html#category-form-attr">reassociateable</a>;
+ <a data-anolis-xref="Form-associated element" href="forms.html#form-associated-element">form-associated</a></td>
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a>*</td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-fe-autofocus"><a href="forms.html#autofocus">autofocus</a></code>;
- <code data-anolis-xref="attr-fe-disabled"><a href="forms.html#disabled-12">disabled</a></code>;
- <code data-anolis-xref="attr-fae-form"><a href="forms.html#form-1">form</a></code>;
- <code data-anolis-xref="attr-fs-formaction"><a href="forms.html#formaction">formaction</a></code>;
- <code data-anolis-xref="attr-fs-formenctype"><a href="forms.html#formenctype">formenctype</a></code>;
- <code data-anolis-xref="attr-fs-formmethod"><a href="forms.html#formmethod">formmethod</a></code>;
- <code data-anolis-xref="attr-fs-formnovalidate"><a href="forms.html#formnovalidate">formnovalidate</a></code>;
- <code data-anolis-xref="attr-fs-formtarget"><a href="forms.html#formtarget">formtarget</a></code>;
- <code data-anolis-xref="attr-button-menu"><a href="forms.html#menu-1">menu</a></code>;
- <code data-anolis-xref="attr-fe-name"><a href="forms.html#name-11">name</a></code>;
- <code data-anolis-xref="attr-button-type"><a href="forms.html#type-17">type</a></code>;
- <code data-anolis-xref="attr-button-value"><a href="forms.html#value-9">value</a></code></td>
+ <code data-anolis-xref="attr-fe-autofocus"><a href="forms.html#attr-fe-autofocus">autofocus</a></code>;
+ <code data-anolis-xref="attr-fe-disabled"><a href="forms.html#attr-fe-disabled">disabled</a></code>;
+ <code data-anolis-xref="attr-fae-form"><a href="forms.html#attr-fae-form">form</a></code>;
+ <code data-anolis-xref="attr-fs-formaction"><a href="forms.html#attr-fs-formaction">formaction</a></code>;
+ <code data-anolis-xref="attr-fs-formenctype"><a href="forms.html#attr-fs-formenctype">formenctype</a></code>;
+ <code data-anolis-xref="attr-fs-formmethod"><a href="forms.html#attr-fs-formmethod">formmethod</a></code>;
+ <code data-anolis-xref="attr-fs-formnovalidate"><a href="forms.html#attr-fs-formnovalidate">formnovalidate</a></code>;
+ <code data-anolis-xref="attr-fs-formtarget"><a href="forms.html#attr-fs-formtarget">formtarget</a></code>;
+ <code data-anolis-xref="attr-button-menu"><a href="forms.html#attr-button-menu">menu</a></code>;
+ <code data-anolis-xref="attr-fe-name"><a href="forms.html#attr-fe-name">name</a></code>;
+ <code data-anolis-xref="attr-button-type"><a href="forms.html#attr-button-type">type</a></code>;
+ <code data-anolis-xref="attr-button-value"><a href="forms.html#attr-button-value">value</a></code></td>
<td><code><a href="forms.html#htmlbuttonelement">HTMLButtonElement</a></code></td>
<tr><th><code><a href="scripting-1.html#the-canvas-element">canvas</a></code></th>
<td>Scriptable bitmap canvas</td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a>;
<a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a>;
- <a data-anolis-xref="Embedded content" href="dom.html#embedded-content-2">embedded</a></td>
+ <a data-anolis-xref="Embedded content" href="dom.html#embedded-content-category">embedded</a></td>
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
<td><a href="dom.html#transparent">transparent</a></td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-canvas-width"><a href="scripting-1.html#width-3">width</a></code>;
- <code data-anolis-xref="attr-canvas-height"><a href="scripting-1.html#height-3">height</a></code></td>
+ <code data-anolis-xref="attr-canvas-width"><a href="scripting-1.html#attr-canvas-width">width</a></code>;
+ <code data-anolis-xref="attr-canvas-height"><a href="scripting-1.html#attr-canvas-height">height</a></code></td>
<td><code><a href="scripting-1.html#htmlcanvaselement">HTMLCanvasElement</a></code></td>
<tr><th><code><a href="tabular-data.html#the-caption-element">caption</a></code></th>
<td>Table caption</td>
@@ -593,7 +595,7 @@
<code><a href="scripting-1.html#the-template-element">template</a></code></td>
<td>empty</td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-col-span"><a href="tabular-data.html#span-1">span</a></code></td>
+ <code data-anolis-xref="attr-col-span"><a href="tabular-data.html#attr-col-span">span</a></code></td>
<td><code><a href="tabular-data.html#htmltablecolelement">HTMLTableColElement</a></code></td>
<tr><th><code><a href="tabular-data.html#the-colgroup-element">colgroup</a></code></th>
<td>Group of columns in a table</td>
@@ -601,9 +603,9 @@
<td><code><a href="tabular-data.html#the-table-element">table</a></code>;
<code><a href="scripting-1.html#the-template-element">template</a></code></td>
<td><code><a href="tabular-data.html#the-col-element">col</a></code>*;
- <a href="dom.html#script-supporting-elements-0">script-supporting elements</a>*</td>
+ <code><a href="scripting-1.html#the-template-element">template</a></code>*</td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-colgroup-span"><a href="tabular-data.html#span">span</a></code></td>
+ <code data-anolis-xref="attr-colgroup-span"><a href="tabular-data.html#attr-colgroup-span">span</a></code></td>
<td><code><a href="tabular-data.html#htmltablecolelement">HTMLTableColElement</a></code></td>
<tr><th><code><a href="text-level-semantics.html#the-data-element">data</a></code></th>
<td>Machine-readable equivalent</td>
@@ -612,10 +614,10 @@
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-data-value"><a href="text-level-semantics.html#value-2">value</a></code></td>
+ <code data-anolis-xref="attr-data-value"><a href="text-level-semantics.html#attr-data-value">value</a></code></td>
<td><code><a href="text-level-semantics.html#htmldataelement">HTMLDataElement</a></code></td>
<tr><th><code><a href="forms.html#the-datalist-element">datalist</a></code></th>
- <td>Container for options for <a data-anolis-xref="attr-input-list" href="forms.html#list">combo box control</a></td>
+ <td>Container for options for <a data-anolis-xref="attr-input-list" href="forms.html#attr-input-list">combo box control</a></td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a>;
<a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
@@ -638,19 +640,19 @@
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
<td><a href="dom.html#transparent">transparent</a></td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-mod-cite"><a href="edits.html#cite-2">cite</a></code>;
- <code data-anolis-xref="attr-mod-datetime"><a href="edits.html#datetime-1">datetime</a></code></td>
+ <code data-anolis-xref="attr-mod-cite"><a href="edits.html#attr-mod-cite">cite</a></code>;
+ <code data-anolis-xref="attr-mod-datetime"><a href="edits.html#attr-mod-datetime">datetime</a></code></td>
<td><code><a href="edits.html#htmlmodelement">HTMLModElement</a></code></td>
<tr><th><code><a href="interactive-elements.html#the-details-element">details</a></code></th>
<td>Disclosure control for hiding details</td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a>;
- <a data-anolis-xref="Sectioning root" href="sections.html#sectioning-roots">sectioning root</a>;
+ <a data-anolis-xref="Sectioning root" href="sections.html#sectioning-root">sectioning root</a>;
<a data-anolis-xref="Interactive content" href="dom.html#interactive-content-0">interactive</a></td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a></td>
<td><code><a href="interactive-elements.html#the-summary-element">summary</a></code>*;
<a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a></td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-details-open"><a href="interactive-elements.html#open">open</a></code></td>
+ <code data-anolis-xref="attr-details-open"><a href="interactive-elements.html#attr-details-open">open</a></code></td>
<td><code><a href="interactive-elements.html#htmldetailselement">HTMLDetailsElement</a></code></td>
<tr><th><code><a href="text-level-semantics.html#the-dfn-element">dfn</a></code></th>
<td>Defining instance</td>
@@ -663,11 +665,11 @@
<tr><th><code><a href="interactive-elements.html#the-dialog-element">dialog</a></code></th>
<td>Dialog box or window</td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a>;
- <a data-anolis-xref="Sectioning root" href="sections.html#sectioning-roots">sectioning root</a></td>
+ <a data-anolis-xref="Sectioning root" href="sections.html#sectioning-root">sectioning root</a></td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a></td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a></td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-dialog-open"><a href="interactive-elements.html#open-1">open</a></code></td>
+ <code data-anolis-xref="attr-dialog-open"><a href="interactive-elements.html#attr-dialog-open">open</a></code></td>
<td><code><a href="interactive-elements.html#htmldialogelement">HTMLDialogElement</a></code></td>
<tr><th><code><a href="grouping-content.html#the-div-element">div</a></code></th>
<td>Generic flow container</td>
@@ -701,35 +703,35 @@
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a></td>
<td><code><a href="dom.html#htmlelement">HTMLElement</a></code></td>
- <tr><th><code><a href="embedded-content-0.html#the-embed-element">embed</a></code></th>
+ <tr><th><code><a href="embedded-content.html#the-embed-element">embed</a></code></th>
<td><a href="infrastructure.html#plugin">Plugin</a></td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a>;
<a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a>;
- <a data-anolis-xref="Embedded content" href="dom.html#embedded-content-2">embedded</a>;
+ <a data-anolis-xref="Embedded content" href="dom.html#embedded-content-category">embedded</a>;
<a data-anolis-xref="Interactive content" href="dom.html#interactive-content-0">interactive</a></td>
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
<td>empty</td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-embed-src"><a href="embedded-content-0.html#src-3">src</a></code>;
- <code data-anolis-xref="attr-embed-type"><a href="embedded-content-0.html#type-7">type</a></code>;
- <code data-anolis-xref="attr-dim-width"><a href="embedded-content-0.html#width-0">width</a></code>;
- <code data-anolis-xref="attr-dim-height"><a href="embedded-content-0.html#height-0">height</a></code>;
+ <code data-anolis-xref="attr-embed-src"><a href="embedded-content.html#attr-embed-src">src</a></code>;
+ <code data-anolis-xref="attr-embed-type"><a href="embedded-content.html#attr-embed-type">type</a></code>;
+ <code data-anolis-xref="attr-dim-width"><a href="embedded-content.html#attr-dim-width">width</a></code>;
+ <code data-anolis-xref="attr-dim-height"><a href="embedded-content.html#attr-dim-height">height</a></code>;
any*</td>
- <td><code><a href="embedded-content-0.html#htmlembedelement">HTMLEmbedElement</a></code></td>
+ <td><code><a href="embedded-content.html#htmlembedelement">HTMLEmbedElement</a></code></td>
<tr><th><code><a href="forms.html#the-fieldset-element">fieldset</a></code></th>
<td>Group of form controls</td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a>;
- <a data-anolis-xref="Sectioning root" href="sections.html#sectioning-roots">sectioning root</a>;
- <a data-anolis-xref="category-listed" href="forms.html#listed-elements">listed</a>;
- <a data-anolis-xref="category-form-attr" href="forms.html#reassociateable-elements">reassociateable</a>;
- <a data-anolis-xref="Form-associated element" href="forms.html#form-associated-elements">form-associated</a></td>
+ <a data-anolis-xref="Sectioning root" href="sections.html#sectioning-root">sectioning root</a>;
+ <a data-anolis-xref="category-listed" href="forms.html#category-listed">listed</a>;
+ <a data-anolis-xref="category-form-attr" href="forms.html#category-form-attr">reassociateable</a>;
+ <a data-anolis-xref="Form-associated element" href="forms.html#form-associated-element">form-associated</a></td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a></td>
<td><code><a href="forms.html#the-legend-element">legend</a></code>*;
<a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a></td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-fieldset-disabled"><a href="forms.html#disabled-10">disabled</a></code>;
- <code data-anolis-xref="attr-fae-form"><a href="forms.html#form-1">form</a></code>;
- <code data-anolis-xref="attr-fe-name"><a href="forms.html#name-11">name</a></code></td>
+ <code data-anolis-xref="attr-fieldset-disabled"><a href="forms.html#attr-fieldset-disabled">disabled</a></code>;
+ <code data-anolis-xref="attr-fae-form"><a href="forms.html#attr-fae-form">form</a></code>;
+ <code data-anolis-xref="attr-fe-name"><a href="forms.html#attr-fe-name">name</a></code></td>
<td><code><a href="forms.html#htmlfieldsetelement">HTMLFieldSetElement</a></code></td>
<tr><th><code><a href="grouping-content.html#the-figcaption-element">figcaption</a></code></th>
<td>Caption for <code><a href="grouping-content.html#the-figure-element">figure</a></code></td>
@@ -742,7 +744,7 @@
<tr><th><code><a href="grouping-content.html#the-figure-element">figure</a></code></th>
<td>Figure with optional caption</td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a>;
- <a data-anolis-xref="Sectioning root" href="sections.html#sectioning-roots">sectioning root</a></td>
+ <a data-anolis-xref="Sectioning root" href="sections.html#sectioning-root">sectioning root</a></td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a></td>
<td><code><a href="grouping-content.html#the-figcaption-element">figcaption</a></code>*;
<a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a></td>
@@ -761,14 +763,14 @@
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a></td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a>*</td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-form-accept-charset"><a href="forms.html#accept-charset">accept-charset</a></code>;
- <code data-anolis-xref="attr-fs-action"><a href="forms.html#action">action</a></code>;
- <code data-anolis-xref="attr-form-autocomplete"><a href="forms.html#autocomplete">autocomplete</a></code>;
- <code data-anolis-xref="attr-fs-enctype"><a href="forms.html#enctype">enctype</a></code>;
- <code data-anolis-xref="attr-fs-method"><a href="forms.html#method">method</a></code>;
- <code data-anolis-xref="attr-form-name"><a href="forms.html#name-9">name</a></code>;
- <code data-anolis-xref="attr-fs-novalidate"><a href="forms.html#novalidate">novalidate</a></code>;
- <code data-anolis-xref="attr-fs-target"><a href="forms.html#target-5">target</a></code></td>
+ <code data-anolis-xref="attr-form-accept-charset"><a href="forms.html#attr-form-accept-charset">accept-charset</a></code>;
+ <code data-anolis-xref="attr-fs-action"><a href="forms.html#attr-fs-action">action</a></code>;
+ <code data-anolis-xref="attr-form-autocomplete"><a href="forms.html#attr-form-autocomplete">autocomplete</a></code>;
+ <code data-anolis-xref="attr-fs-enctype"><a href="forms.html#attr-fs-enctype">enctype</a></code>;
+ <code data-anolis-xref="attr-fs-method"><a href="forms.html#attr-fs-method">method</a></code>;
+ <code data-anolis-xref="attr-form-name"><a href="forms.html#attr-form-name">name</a></code>;
+ <code data-anolis-xref="attr-fs-novalidate"><a href="forms.html#attr-fs-novalidate">novalidate</a></code>;
+ <code data-anolis-xref="attr-fs-target"><a href="forms.html#attr-fs-target">target</a></code></td>
<td><code><a href="forms.html#htmlformelement">HTMLFormElement</a></code></td>
<tr><th><code><a href="sections.html#the-h1,-h2,-h3,-h4,-h5,-and-h6-elements">h1</a></code>, <code><a href="sections.html#the-h1,-h2,-h3,-h4,-h5,-and-h6-elements">h2</a></code>, <code><a href="sections.html#the-h1,-h2,-h3,-h4,-h5,-and-h6-elements">h3</a></code>, <code><a href="sections.html#the-h1,-h2,-h3,-h4,-h5,-and-h6-elements">h4</a></code>, <code><a href="sections.html#the-h1,-h2,-h3,-h4,-h5,-and-h6-elements">h5</a></code>, <code><a href="sections.html#the-h1,-h2,-h3,-h4,-h5,-and-h6-elements">h6</a></code></th>
<td>Section heading</td>
@@ -808,7 +810,7 @@
<td><code><a href="document-metadata.html#the-head-element">head</a></code>*;
<code><a href="sections.html#the-body-element">body</a></code>*</td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-html-manifest"><a href="semantics.html#manifest">manifest</a></code></td>
+ <code data-anolis-xref="attr-html-manifest"><a href="semantics.html#attr-html-manifest">manifest</a></code></td>
<td><code><a href="semantics.html#htmlhtmlelement">HTMLHtmlElement</a></code></td>
<tr><th><code><a href="text-level-semantics.html#the-i-element">i</a></code></th>
<td>Alternate voice</td>
@@ -818,88 +820,89 @@
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a></td>
<td><code><a href="dom.html#htmlelement">HTMLElement</a></code></td>
- <tr><th><code><a href="embedded-content-0.html#the-iframe-element">iframe</a></code></th>
- <td><a href="browsers.html#nested-browsing-contexts-0">Nested browsing context</a></td>
+ <tr><th><code><a href="embedded-content.html#the-iframe-element">iframe</a></code></th>
+ <td><a href="browsers.html#nested-browsing-context">Nested browsing context</a></td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a>;
<a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a>;
- <a data-anolis-xref="Embedded content" href="dom.html#embedded-content-2">embedded</a>;
+ <a data-anolis-xref="Embedded content" href="dom.html#embedded-content-category">embedded</a>;
<a data-anolis-xref="Interactive content" href="dom.html#interactive-content-0">interactive</a></td>
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
<td>text*</td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-iframe-src"><a href="embedded-content-0.html#src-1">src</a></code>;
- <code data-anolis-xref="attr-iframe-srcdoc"><a href="embedded-content-0.html#srcdoc">srcdoc</a></code>;
- <code data-anolis-xref="attr-iframe-name"><a href="embedded-content-0.html#name-1">name</a></code>;
- <code data-anolis-xref="attr-iframe-sandbox"><a href="embedded-content-0.html#sandbox">a/a></code>;
- <code data-anolis-xref="attr-iframe-seamless"><a href="embedded-content-0.html#seamless">seamless</a></code>;
- <code data-anolis-xref="attr-iframe-allowfullscreen"><a href="embedded-content-0.html#allowfullscreen">allowfullscreen</a></code>;
- <code data-anolis-xref="attr-dim-width"><a href="embedded-content-0.html#width-0">width</a></code>;
- <code data-anolis-xref="attr-dim-height"><a href="embedded-content-0.html#height-0">height</a></code></td>
- <td><code><a href="embedded-content-0.html#htmliframeelement">HTMLIFrameElement</a></code></td>
- <tr><th><code><a href="embedded-content-0.html#the-img-element">img</a></code></th>
+ <code data-anolis-xref="attr-iframe-src"><a href="embedded-content.html#attr-iframe-src">src</a></code>;
+ <code data-anolis-xref="attr-iframe-srcdoc"><a href="embedded-content.html#attr-iframe-srcdoc">srcdoc</a></code>;
+ <code data-anolis-xref="attr-iframe-name"><a href="embedded-content.html#attr-iframe-name">name</a></code>;
+ <code data-anolis-xref="attr-iframe-sandbox"><a href="embedded-content.html#attr-iframe-sandbox">sandbox</a></code>;
+ <code data-anolis-xref="attr-iframe-seamless"><a href="embedded-content.html#attr-iframe-seamless">seamless</a></code>;
+ <code data-anolis-xref="attr-iframe-allowfullscreen"><a href="embedded-content.html#attr-iframe-allowfullscreen">allowfullscreen</a></code>;
+ <code data-anolis-xref="attr-dim-width"><a href="embedded-content.html#attr-dim-width">width</a></code>;
+ <code data-anolis-xref="attr-dim-height"><a href="embedded-content.html#attr-dim-height">height</a></code></td>
+ <td><code><a href="embedded-content.html#htmliframeelement">HTMLIFrameElement</a></code></td>
+ <tr><th><code><a href="embedded-content.html#the-img-element">img</a></code></th>
<td>Image</td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a>;
<a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a>;
- <a data-anolis-xref="Embedded content" href="dom.html#embedded-content-2">embedded</a>;
+ <a data-anolis-xref="Embedded content" href="dom.html#embedded-content-category">embedded</a>;
<a data-anolis-xref="Interactive content" href="dom.html#interactive-content-0">interactive</a>*;
- <a data-anolis-xref="Form-associated element" href="forms.html#form-associated-elements">form-associated</a></td>
+ <a data-anolis-xref="Form-associated element" href="forms.html#form-associated-element">form-associated</a></td>
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
<td>empty</td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-img-alt"><a href="embedded-content-0.html#alt-0">alt</a></code>;
- <code data-anolis-xref="attr-img-src"><a href="embedded-content-0.html#src">src</a></code>;
- <code data-anolis-xref="attr-img-crossorigin"><a href="embedded-content-0.html#crossorigin-1">crossorigin</a></code>;
- <code data-anolis-xref="attr-hyperlink-usemap"><a href="embedded-content-0.html#usemap-1">usemap</a></code>;
- <code data-anolis-xref="attr-img-ismap"><a href="embedded-content-0.html#ismap">ismap</a></code>;
- <code data-anolis-xref="attr-dim-width"><a href="embedded-content-0.html#width-0">width</a></code>;
- <code data-anolis-xref="attr-dim-height"><a href="embedded-content-0.html#height-0">height</a></code></td>
- <td><code><a href="embedded-content-0.html#htmlimageelement">HTMLImageElement</a></code></td>
+ <code data-anolis-xref="attr-img-alt"><a href="embedded-content.html#attr-img-alt">alt</a></code>;
+ <code data-anolis-xref="attr-img-src"><a href="embedded-content.html#attr-img-src">src</a></code>;
+ <code data-anolis-xref="attr-img-srcset"><a href="embedded-content.html#attr-img-srcset">srcset</a></code>;
+ <code data-anolis-xref="attr-img-crossorigin"><a href="embedded-content.html#attr-img-crossorigin">crossorigin</a></code>;
+ <code data-anolis-xref="attr-hyperlink-usemap"><a href="embedded-content.html#attr-hyperlink-usemap">usemap</a></code>;
+ <code data-anolis-xref="attr-img-ismap"><a href="embedded-content.html#attr-img-ismap">ismap</a></code>;
+ <code data-anolis-xref="attr-dim-width"><a href="embedded-content.html#attr-dim-width">width</a></code>;
+ <code data-anolis-xref="attr-dim-height"><a href="embedded-content.html#attr-dim-height">height</a></code></td>
+ <td><code><a href="embedded-content.html#htmlimageelement">HTMLImageElement</a></code></td>
<tr><th><code><a href="forms.html#the-input-element">input</a></code></th>
<td>Form control</td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a>;
<a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a>;
<a data-anolis-xref="Interactive content" href="dom.html#interactive-content-0">interactive</a>*;
- <a data-anolis-xref="category-listed" href="forms.html#listed-elements">listed</a>;
- <a data-anolis-xref="category-label" href="forms.html#labelable-elements">labelable</a>;
- <a data-anolis-xref="category-submit" href="forms.html#submittable-elements">submittable</a>;
- <a data-anolis-xref="category-reset" href="forms.html#resettable-elements">resettable</a>;
- <a data-anolis-xref="category-form-attr" href="forms.html#reassociateable-elements">reassociateable</a>;
- <a data-anolis-xref="Form-associated element" href="forms.html#form-associated-elements">form-associated</a></td>
+ <a data-anolis-xref="category-listed" href="forms.html#category-listed">listed</a>;
+ <a data-anolis-xref="category-label" href="forms.html#category-label">labelable</a>;
+ <a data-anolis-xref="category-submit" href="forms.html#category-submit">submittable</a>;
+ <a data-anolis-xref="category-reset" href="forms.html#category-reset">resettable</a>;
+ <a data-anolis-xref="category-form-attr" href="forms.html#category-form-attr">reassociateable</a>;
+ <a data-anolis-xref="Form-associated element" href="forms.html#form-associated-element">form-associated</a></td>
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
<td>empty</td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-input-accept"><a href="forms.html#accept-0">accept</a></code>;
- <code data-anolis-xref="attr-input-alt"><a href="forms.html#alt-5">alt</a></code>;
- <code data-anolis-xref="attr-fe-autocomplete"><a href="forms.html#autocomplete-1">autocomplete</a></code>;
- <code data-anolis-xref="attr-fe-autofocus"><a href="forms.html#autofocus">autofocus</a></code>;
- <code data-anolis-xref="attr-input-checked"><a href="forms.html#checked">checked</a></code>;
- <code data-anolis-xref="attr-fe-dirname"><a href="forms.html#dirname-1">dirname</a></code>;
- <code data-anolis-xref="attr-fe-disabled"><a href="forms.html#disabled-12">disabled</a></code>;
- <code data-anolis-xref="attr-fae-form"><a href="forms.html#form-1">form</a></code>;
- <code data-anolis-xref="attr-fs-formaction"><a href="forms.html#formaction">formaction</a></code>;
- <code data-anolis-xref="attr-fs-formenctype"><a href="forms.html#formenctype">formenctype</a></code>;
- <code data-anolis-xref="attr-fs-formmethod"><a href="forms.html#formmethod">formmethod</a></code>;
- <code data-anolis-xref="attr-fs-formnovalidate"><a href="forms.html#formnovalidate">formnovalidate</a></code>;
- <code data-anolis-xref="attr-fs-formtarget"><a href="forms.html#formtarget">formtarget</a></code>;
- <code data-anolis-xref="attr-dim-height"><a href="embedded-content-0.html#height-0">height</a></code>;
- <code data-anolis-xref="attr-fe-inputmode"><a href="forms.html#inputmode-1">inputmode</a></code>;
- <code data-anolis-xref="attr-input-list"><a href="forms.html#list">list</a></code>;
- <code data-anolis-xref="attr-input-max"><a href="forms.html#max-0">max</a></code>;
- <code data-anolis-xref="attr-input-maxlength"><a href="forms.html#maxlength-0">maxlength</a></code>;
- <code data-anolis-xref="attr-input-min"><a href="forms.html#min-0">min</a></code>;
- <code data-anolis-xref="attr-input-minlength"><a href="forms.html#minlength-0">minlength</a></code>;
- <code data-anolis-xref="attr-input-multiple"><a href="forms.html#multiple-0">multiple</a></code>;
- <code data-anolis-xref="attr-fe-name"><a href="forms.html#name-11">name</a></code>;
- <code data-anolis-xref="attr-input-pattern"><a href="forms.html#pattern-0">pattern</a></code>;
- <code data-anolis-xref="attr-input-placeholder"><a href="forms.html#placeholder-0">placeholder</a></code>;
- <code data-anolis-xref="attr-input-readonly"><a href="forms.html#readonly-0">readonly</a></code>;
- <code data-anolis-xref="attr-input-required"><a href="forms.html#required-0">required</a></code>;
- <code data-anolis-xref="attr-input-size"><a href="forms.html#size-1">size</a></code>;
- <code data-anolis-xref="attr-input-src"><a href="forms.html#src-12">src</a></code>;
- <code data-anolis-xref="attr-input-step"><a href="forms.html#step-0">step</a></code>;
- <code data-anolis-xref="attr-input-type"><a href="forms.html#type-15">type</a></code>;
- <code data-anolis-xref="attr-input-value"><a href="forms.html#value-6">value</a></code>;
- <code data-anolis-xref="attr-dim-width"><a href="embedded-content-0.html#width-0">width</a></code></td>
+ <code data-anolis-xref="attr-input-accept"><a href="forms.html#attr-input-accept">accept</a></code>;
+ <code data-anolis-xref="attr-input-alt"><a href="forms.html#attr-input-alt">alt</a></code>;
+ <code data-anolis-xref="attr-fe-autocomplete"><a href="forms.html#attr-fe-autocomplete">autocomplete</a></code>;
+ <code data-anolis-xref="attr-fe-autofocus"><a href="forms.html#attr-fe-autofocus">autofocus</a></code>;
+ <code data-anolis-xref="attr-input-checked"><a href="forms.html#attr-input-checked">checked</a></code>;
+ <code data-anolis-xref="attr-fe-dirname"><a href="forms.html#attr-fe-dirname">dirname</a></code>;
+ <code data-anolis-xref="attr-fe-disabled"><a href="forms.html#attr-fe-disabled">disabled</a></code>;
+ <code data-anolis-xref="attr-fae-form"><a href="forms.html#attr-fae-form">form</a></code>;
+ <code data-anolis-xref="attr-fs-formaction"><a href="forms.html#attr-fs-formaction">formaction</a></code>;
+ <code data-anolis-xref="attr-fs-formenctype"><a href="forms.html#attr-fs-formenctype">formenctype</a></code>;
+ <code data-anolis-xref="attr-fs-formmethod"><a href="forms.html#attr-fs-formmethod">formmethod</a></code>;
+ <code data-anolis-xref="attr-fs-formnovalidate"><a href="forms.html#attr-fs-formnovalidate">formnovalidate</a></code>;
+ <code data-anolis-xref="attr-fs-formtarget"><a href="forms.html#attr-fs-formtarget">formtarget</a></code>;
+ <code data-anolis-xref="attr-dim-height"><a href="embedded-content.html#attr-dim-height">height</a></code>;
+ <code data-anolis-xref="attr-fe-inputmode"><a href="forms.html#attr-fe-inputmode">inputmode</a></code>;
+ <code data-anolis-xref="attr-input-list"><a href="forms.html#attr-input-list">list</a></code>;
+ <code data-anolis-xref="attr-input-max"><a href="forms.html#attr-input-max">max</a></code>;
+ <code data-anolis-xref="attr-input-maxlength"><a href="forms.html#attr-input-maxlength">maxlength</a></code>;
+ <code data-anolis-xref="attr-input-min"><a href="forms.html#attr-input-min">min</a></code>;
+ <code data-anolis-xref="attr-input-minlength"><a href="forms.html#attr-input-minlength">minlength</a></code>;
+ <code data-anolis-xref="attr-input-multiple"><a href="forms.html#attr-input-multiple">multiple</a></code>;
+ <code data-anolis-xref="attr-fe-name"><a href="forms.html#attr-fe-name">name</a></code>;
+ <code data-anolis-xref="attr-input-pattern"><a href="forms.html#attr-input-pattern">pattern</a></code>;
+ <code data-anolis-xref="attr-input-placeholder"><a href="forms.html#attr-input-placeholder">placeholder</a></code>;
+ <code data-anolis-xref="attr-input-readonly"><a href="forms.html#attr-input-readonly">readonly</a></code>;
+ <code data-anolis-xref="attr-input-required"><a href="forms.html#attr-input-required">required</a></code>;
+ <code data-anolis-xref="attr-input-size"><a href="forms.html#attr-input-size">size</a></code>;
+ <code data-anolis-xref="attr-input-src"><a href="forms.html#attr-input-src">src</a></code>;
+ <code data-anolis-xref="attr-input-step"><a href="forms.html#attr-input-step">step</a></code>;
+ <code data-anolis-xref="attr-input-type"><a href="forms.html#attr-input-type">type</a></code>;
+ <code data-anolis-xref="attr-input-value"><a href="forms.html#attr-input-value">value</a></code>;
+ <code data-anolis-xref="attr-dim-width"><a href="embedded-content.html#attr-dim-width">width</a></code></td>
<td><code><a href="forms.html#htmlinputelement">HTMLInputElement</a></code></td>
<tr><th><code><a href="edits.html#the-ins-element">ins</a></code></th>
<td>An addition to the document</td>
@@ -908,8 +911,8 @@
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
<td><a href="dom.html#transparent">transparent</a></td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-mod-cite"><a href="edits.html#cite-2">cite</a></code>;
- <code data-anolis-xref="attr-mod-datetime"><a href="edits.html#datetime-1">datetime</a></code></td>
+ <code data-anolis-xref="attr-mod-cite"><a href="edits.html#attr-mod-cite">cite</a></code>;
+ <code data-anolis-xref="attr-mod-datetime"><a href="edits.html#attr-mod-datetime">datetime</a></code></td>
<td><code><a href="edits.html#htmlmodelement">HTMLModElement</a></code></td>
<tr><th><code><a href="text-level-semantics.html#the-kbd-element">kbd</a></code></th>
<td>User input</td>
@@ -924,34 +927,34 @@
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a>;
<a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a>;
<a data-anolis-xref="Interactive content" href="dom.html#interactive-content-0">interactive</a>;
- <a data-anolis-xref="category-listed" href="forms.html#listed-elements">listed</a>;
- <a data-anolis-xref="category-label" href="forms.html#labelable-elements">labelable</a>;
- <a data-anolis-xref="category-submit" href="forms.html#submittable-elements">submittable</a>;
- <a data-anolis-xref="category-reset" href="forms.html#resettable-elements">resettable</a>;
- <a data-anolis-xref="category-form-attr" href="forms.html#reassociateable-elements">reassociateable</a>;
- <a data-anolis-xref="Form-associated element" href="forms.html#form-associated-elements">form-associated</a></td>
+ <a data-anolis-xref="category-listed" href="forms.html#category-listed">listed</a>;
+ <a data-anolis-xref="category-label" href="forms.html#category-label">labelable</a>;
+ <a data-anolis-xref="category-submit" href="forms.html#category-submit">submittable</a>;
+ <a data-anolis-xref="category-reset" href="forms.html#category-reset">resettable</a>;
+ <a data-anolis-xref="category-form-attr" href="forms.html#category-form-attr">reassociateable</a>;
+ <a data-anolis-xref="Form-associated element" href="forms.html#form-associated-element">form-associated</a></td>
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
<td>empty</td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-fe-autofocus"><a href="forms.html#autofocus">autofocus</a></code>;
- <code data-anolis-xref="attr-keygen-challenge"><a href="forms.html#challenge">challenge</a></code>;
- <code data-anolis-xref="attr-fe-disabled"><a href="forms.html#disabled-12">disabled</a></code>;
- <code data-anolis-xref="attr-fae-form"><a href="forms.html#form-1">form</a></code>;
- <code data-anolis-xref="attr-keygen-keytype"><a href="forms.html#keytype">keytype</a></code>;
- <code data-anolis-xref="attr-fe-name"><a href="forms.html#name-11">name</a></code></td>
+ <code data-anolis-xref="attr-fe-autofocus"><a href="forms.html#attr-fe-autofocus">autofocus</a></code>;
+ <code data-anolis-xref="attr-keygen-challenge"><a href="forms.html#attr-keygen-challenge">challenge</a></code>;
+ <code data-anolis-xref="attr-fe-disabled"><a href="forms.html#attr-fe-disabled">disabled</a></code>;
+ <code data-anolis-xref="attr-fae-form"><a href="forms.html#attr-fae-form">form</a></code>;
+ <code data-anolis-xref="attr-keygen-keytype"><a href="forms.html#attr-keygen-keytype">keytype</a></code>;
+ <code data-anolis-xref="attr-fe-name"><a href="forms.html#attr-fe-name">name</a></code></td>
<td><code><a href="forms.html#htmlkeygenelement">HTMLKeygenElement</a></code></td>
<tr><th><code><a href="forms.html#the-label-element">label</a></code></th>
<td>Caption for a form control</td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a>;
<a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a>;
<a data-anolis-xref="Interactive content" href="dom.html#interactive-content-0">interactive</a>;
- <a data-anolis-xref="category-form-attr" href="forms.html#reassociateable-elements">reassociateable</a>;
- <a data-anolis-xref="Form-associated element" href="forms.html#form-associated-elements">form-associated</a></td>
+ <a data-anolis-xref="category-form-attr" href="forms.html#category-form-attr">reassociateable</a>;
+ <a data-anolis-xref="Form-associated element" href="forms.html#form-associated-element">form-associated</a></td>
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a>*</td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-fae-form"><a href="forms.html#form-1">form</a></code>;
- <code data-anolis-xref="attr-label-for"><a href="forms.html#for">for</a></code></td>
+ <code data-anolis-xref="attr-fae-form"><a href="forms.html#attr-fae-form">form</a></code>;
+ <code data-anolis-xref="attr-label-for"><a href="forms.html#attr-label-for">for</a></code></td>
<td><code><a href="forms.html#htmllabelelement">HTMLLabelElement</a></code></td>
<tr><th><code><a href="forms.html#the-legend-element">legend</a></code></th>
<td>Caption for <code><a href="forms.html#the-fieldset-element">fieldset</a></code></td>
@@ -970,7 +973,7 @@
<code><a href="scripting-1.html#the-template-element">template</a></code></td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a></td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-li-value"><a href="grouping-content.html#value-0">value</a></code>*</td>
+ <code data-anolis-xref="attr-li-value"><a href="grouping-content.html#attr-li-value">value</a></code>*</td>
<td><code><a href="grouping-content.html#htmllielement">HTMLLIElement</a></code></td>
<tr><th><code><a href="document-metadata.html#the-link-element">link</a></code></th>
<td>Link metadata</td>
@@ -983,13 +986,13 @@
<a data-anolis-xref="phrasing content" href="dom.html#phrasing-content-1">phrasing</a>*</td>
<td>empty</td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-link-href"><a href="document-metadata.html#href-1">href</a></code>;
- <code data-anolis-xref="attr-link-crossorigin"><a href="document-metadata.html#crossorigin">crossorigin</a></code>;
- <code data-anolis-xref="attr-link-rel"><a href="document-metadata.html#rel">rel</a></code>;
- <code data-anolis-xref="attr-link-media"><a href="document-metadata.html#media">media</a></code>;
- <code data-anolis-xref="attr-link-hreflang"><a href="document-metadata.html#hreflang">hreflang</a></code>;
- <code data-anolis-xref="attr-link-type"><a href="document-metadata.html#type-0">type</a></code>;
- <code data-anolis-xref="attr-link-sizes"><a href="links.html#sizes-0">sizes</a></code></td>
+ <code data-anolis-xref="attr-link-href"><a href="document-metadata.html#attr-link-href">href</a></code>;
+ <code data-anolis-xref="attr-link-crossorigin"><a href="document-metadata.html#attr-link-crossorigin">crossorigin</a></code>;
+ <code data-anolis-xref="attr-link-rel"><a href="document-metadata.html#attr-link-rel">rel</a></code>;
+ <code data-anolis-xref="attr-link-media"><a href="document-metadata.html#attr-link-media">media</a></code>;
+ <code data-anolis-xref="attr-link-hreflang"><a href="document-metadata.html#attr-link-hreflang">hreflang</a></code>;
+ <code data-anolis-xref="attr-link-type"><a href="document-metadata.html#attr-link-type">type</a></code>;
+ <code data-anolis-xref="attr-link-sizes"><a href="links.html#attr-link-sizes">sizes</a></code></td>
<td><code><a href="document-metadata.html#htmllinkelement">HTMLLinkElement</a></code></td>
</tr><!-- main is main content of doc not body SF--><tr><th><code><a href="grouping-content.html#the-main-element">main</a></code></th>
<td>Main content of a document
@@ -998,16 +1001,16 @@
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a>*
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>
<td><code><a href="dom.html#htmlelement">HTMLElement</a></code>
- <tr><th><code><a href="embedded-content-0.html#the-map-element">map</a></code></th>
- <td><a href="embedded-content-0.html#image-map">Image map</a></td>
+ <tr><th><code><a href="embedded-content.html#the-map-element">map</a></code></th>
+ <td><a href="embedded-content.html#image-map">Image map</a></td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a>;
<a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a>*</td>
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
<td><a href="dom.html#transparent">transparent</a>;
- <code><a href="embedded-content-0.html#the-area-element">area</a></code>*</td>
+ <code><a href="embedded-content.html#the-area-element">area</a></code>*</td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-map-name"><a href="embedded-content-0.html#name-7">name</a></code></td>
- <td><code><a href="embedded-content-0.html#htmlmapelement">HTMLMapElement</a></code></td>
+ <code data-anolis-xref="attr-map-name"><a href="embedded-content.html#attr-map-name">name</a></code></td>
+ <td><code><a href="embedded-content.html#htmlmapelement">HTMLMapElement</a></code></td>
<tr><th><code><a href="text-level-semantics.html#the-mark-element">mark</a></code></th>
<td>Highlight</td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a>;
@@ -1028,24 +1031,24 @@
<code><a href="interactive-elements.html#the-menu-element">menu</a></code>*;
<a href="dom.html#script-supporting-elements-0">script-supporting elements</a>*</td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-menu-type"><a href="interactive-elements.html#type-24">type</a></code>;
- <code data-anolis-xref="attr-menu-label"><a href="interactive-elements.html#label-7">label</a></code></td>
+ <code data-anolis-xref="attr-menu-type"><a href="interactive-elements.html#attr-menu-type">type</a></code>;
+ <code data-anolis-xref="attr-menu-label"><a href="interactive-elements.html#attr-menu-label">label</a></code></td>
<td><code><a href="interactive-elements.html#htmlmenuelement">HTMLMenuElement</a></code></td>
<tr><th><code><a href="interactive-elements.html#the-menuitem-element">menuitem</a></code></th>
<td>Menu command</td>
<td>none</td>
- <td><code><a href="interactive-elements.html#the-menu-element">menu</a></code>;
+ <td><code><a href="interactive-elements.html#the-menu-element">menu</a></code>;
<code><a href="scripting-1.html#the-template-element">template</a></code></td>
<td>empty</td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-menuitem-type"><a href="interactive-elements.html#type-26">type</a></code>;
- <code data-anolis-xref="attr-menuitem-label"><a href="interactive-elements.html#label-9">label</a></code>;
- <code data-anolis-xref="attr-menuitem-icon"><a href="interactive-elements.html#icon">icon</a></code>;
- <code data-anolis-xref="attr-menuitem-disabled"><a href="interactive-elements.html#disabled-15">disabled</a></code>;
- <code data-anolis-xref="attr-menuitem-checked"><a href="interactive-elements.html#checked-1">checked</a></code>;
- <code data-anolis-xref="attr-menuitem-radiogroup"><a href="interactive-elements.html#radiogroup">radiogroup</a></code>;
- <code data-anolis-xref="attr-menuitem-default"><a href="interactive-elements.html#default-4">default</a></code>;
- <code data-anolis-xref="attr-menuitem-command"><a href="interactive-elements.html#command-1">command</a></code></td>
+ <code data-anolis-xref="attr-menuitem-type"><a href="interactive-elements.html#attr-menuitem-type">type</a></code>;
+ <code data-anolis-xref="attr-menuitem-label"><a href="interactive-elements.html#attr-menuitem-label">label</a></code>;
+ <code data-anolis-xref="attr-menuitem-icon"><a href="interactive-elements.html#attr-menuitem-icon">icon</a></code>;
+ <code data-anolis-xref="attr-menuitem-disabled"><a href="interactive-elements.html#attr-menuitem-disabled">disabled</a></code>;
+ <code data-anolis-xref="attr-menuitem-checked"><a href="interactive-elements.html#attr-menuitem-checked">checked</a></code>;
+ <code data-anolis-xref="attr-menuitem-radiogroup"><a href="interactive-elements.html#attr-menuitem-radiogroup">radiogroup</a></code>;
+ <code data-anolis-xref="attr-menuitem-default"><a href="interactive-elements.html#attr-menuitem-default">default</a></code>;
+ <code data-anolis-xref="attr-menuitem-command"><a href="interactive-elements.html#attr-menuitem-command">command</a></code></td>
<td><code><a href="interactive-elements.html#htmlmenuitemelement">HTMLMenuItemElement</a></code></td>
<tr><th><code><a href="document-metadata.html#the-meta-element">meta</a></code></th>
<td>Text metadata</td>
@@ -1058,25 +1061,25 @@
<a data-anolis-xref="phrasing content" href="dom.html#phrasing-content-1">phrasing</a>*</td>
<td>empty</td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-meta-name"><a href="document-metadata.html#name">name</a></code>;
- <code data-anolis-xref="attr-meta-http-equiv"><a href="document-metadata.html#http-equiv">http-equiv</a></code>;
- <code data-anolis-xref="attr-meta-content"><a href="document-metadata.html#content">content</a></code>;
- <code data-anolis-xref="attr-meta-charset"><a href="document-metadata.html#charset-0">charset</a></code></td>
+ <code data-anolis-xref="attr-meta-name"><a href="document-metadata.html#attr-meta-name">name</a></code>;
+ <code data-anolis-xref="attr-meta-http-equiv"><a href="document-metadata.html#attr-meta-http-equiv">http-equiv</a></code>;
+ <code data-anolis-xref="attr-meta-content"><a href="document-metadata.html#attr-meta-content">content</a></code>;
+ <code data-anolis-xref="attr-meta-charset"><a href="document-metadata.html#attr-meta-charset">charset</a></code></td>
<td><code><a href="document-metadata.html#htmlmetaelement">HTMLMetaElement</a></code></td>
<tr><th><code><a href="forms.html#the-meter-element">meter</a></code></th>
<td>Gauge</td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a>;
<a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a>;
- <a data-anolis-xref="category-label" href="forms.html#labelable-elements">labelable</a></td>
+ <a data-anolis-xref="category-label" href="forms.html#category-label">labelable</a></td>
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a>*</td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-meter-value"><a href="forms.html#value-19">value</a></code>;
- <code data-anolis-xref="attr-meter-min"><a href="forms.html#min-1">min</a></code>;
- <code data-anolis-xref="attr-meter-max"><a href="forms.html#max-3">max</a></code>;
- <code data-anolis-xref="attr-meter-low"><a href="forms.html#low">low</a></code>;
- <code data-anolis-xref="attr-meter-high"><a href="forms.html#high">high</a></code>;
- <code data-anolis-xref="attr-meter-optimum"><a href="forms.html#optimum">optimum</a></code></td>
+ <code data-anolis-xref="attr-meter-value"><a href="forms.html#attr-meter-value">value</a></code>;
+ <code data-anolis-xref="attr-meter-min"><a href="forms.html#attr-meter-min">min</a></code>;
+ <code data-anolis-xref="attr-meter-max"><a href="forms.html#attr-meter-max">max</a></code>;
+ <code data-anolis-xref="attr-meter-low"><a href="forms.html#attr-meter-low">low</a></code>;
+ <code data-anolis-xref="attr-meter-high"><a href="forms.html#attr-meter-high">high</a></code>;
+ <code data-anolis-xref="attr-meter-optimum"><a href="forms.html#attr-meter-optimum">optimum</a></code></td>
<td><code><a href="forms.html#htmlmeterelement">HTMLMeterElement</a></code></td>
<tr><th><code><a href="sections.html#the-nav-element">nav</a></code></th>
<td>Section with navigational links</td>
@@ -1097,29 +1100,29 @@
<td>varies*</td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a></td>
<td><code><a href="dom.html#htmlelement">HTMLElement</a></code></td>
- <tr><th><code><a href="embedded-content-0.html#the-object-element">object</a></code></th>
- <td>Image, <a href="browsers.html#nested-browsing-contexts-0">nested browsing context</a>, or <a href="infrastructure.html#plugin">plugin</a></td>
+ <tr><th><code><a href="embedded-content.html#the-object-element">object</a></code></th>
+ <td>Image, <a href="browsers.html#nested-browsing-context">nested browsing context</a>, or <a href="infrastructure.html#plugin">plugin</a></td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a>;
<a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a>;
- <a data-anolis-xref="Embedded content" href="dom.html#embedded-content-2">embedded</a>;
+ <a data-anolis-xref="Embedded content" href="dom.html#embedded-content-category">embedded</a>;
<a data-anolis-xref="Interactive content" href="dom.html#interactive-content-0">interactive</a>*;
- <a data-anolis-xref="category-listed" href="forms.html#listed-elements">listed</a>;
- <a data-anolis-xref="category-submit" href="forms.html#submittable-elements">submittable</a>;
- <a data-anolis-xref="category-form-attr" href="forms.html#reassociateable-elements">reassociateable</a>;
- <a data-anolis-xref="Form-associated element" href="forms.html#form-associated-elements">form-associated</a></td>
+ <a data-anolis-xref="category-listed" href="forms.html#category-listed">listed</a>;
+ <a data-anolis-xref="category-submit" href="forms.html#category-submit">submittable</a>;
+ <a data-anolis-xref="category-form-attr" href="forms.html#category-form-attr">reassociateable</a>;
+ <a data-anolis-xref="Form-associated element" href="forms.html#form-associated-element">form-associated</a></td>
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
- <td><code><a href="embedded-content-0.html#the-param-element">param</a></code>*;
+ <td><code><a href="embedded-content.html#the-param-element">param</a></code>*;
<a href="dom.html#transparent">transparent</a></td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-object-data"><a href="embedded-content-0.html#data-1">data</a></code>;
- <code data-anolis-xref="attr-object-type"><a href="embedded-content-0.html#type-9">type</a></code>;
- <code data-anolis-xref="attr-object-typemustmatch"><a href="embedded-content-0.html#typemustmatch">typemustmatch</a></code>;
- <code data-anolis-xref="attr-object-name"><a href="embedded-content-0.html#name-3">name</a></code>;
- <code data-anolis-xref="attr-hyperlink-usemap"><a href="embedded-content-0.html#usemap-1">usemap</a></code>;
- <code data-anolis-xref="attr-fae-form"><a href="forms.html#form-1">form</a></code>;
- <code data-anolis-xref="attr-dim-width"><a href="embedded-content-0.html#width-0">width</a></code>;
- <code data-anolis-xref="attr-dim-height"><a href="embedded-content-0.html#height-0">height</a></code></td>
- <td><code><a href="embedded-content-0.html#htmlobjectelement">HTMLObjectElement</a></code></td>
+ <code data-anolis-xref="attr-object-data"><a href="embedded-content.html#attr-object-data">data</a></code>;
+ <code data-anolis-xref="attr-object-type"><a href="embedded-content.html#attr-object-type">type</a></code>;
+ <code data-anolis-xref="attr-object-typemustmatch"><a href="embedded-content.html#attr-object-typemustmatch">typemustmatch</a></code>;
+ <code data-anolis-xref="attr-object-name"><a href="embedded-content.html#attr-object-name">name</a></code>;
+ <code data-anolis-xref="attr-hyperlink-usemap"><a href="embedded-content.html#attr-hyperlink-usemap">usemap</a></code>;
+ <code data-anolis-xref="attr-fae-form"><a href="forms.html#attr-fae-form">form</a></code>;
+ <code data-anolis-xref="attr-dim-width"><a href="embedded-content.html#attr-dim-width">width</a></code>;
+ <code data-anolis-xref="attr-dim-height"><a href="embedded-content.html#attr-dim-height">height</a></code></td>
+ <td><code><a href="embedded-content.html#htmlobjectelement">HTMLObjectElement</a></code></td>
<tr><th><code><a href="grouping-content.html#the-ol-element">ol</a></code></th>
<td>Ordered list</td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a></td>
@@ -1127,9 +1130,9 @@
<td><code><a href="grouping-content.html#the-li-element">li</a></code>;
<a href="dom.html#script-supporting-elements-0">script-supporting elements</a></td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-ol-reversed"><a href="grouping-content.html#reversed">reversed</a></code>;
- <code data-anolis-xref="attr-ol-start"><a href="grouping-content.html#start-0">start</a></code>;
- <code data-anolis-xref="attr-ol-type"><a href="grouping-content.html#type-4">type</a></code></td>
+ <code data-anolis-xref="attr-ol-reversed"><a href="grouping-content.html#attr-ol-reversed">reversed</a></code>;
+ <code data-anolis-xref="attr-ol-start"><a href="grouping-content.html#attr-ol-start">start</a></code>;
+ <code data-anolis-xref="attr-ol-type"><a href="grouping-content.html#attr-ol-type">type</a></code></td>
<td><code><a href="grouping-content.html#htmlolistelement">HTMLOListElement</a></code></td>
<tr><th><code><a href="forms.html#the-optgroup-element">optgroup</a></code></th>
<td>Group of options in a list box</td>
@@ -1139,8 +1142,8 @@
<td><code><a href="forms.html#the-option-element">option</a></code>;
<a href="dom.html#script-supporting-elements-0">script-supporting elements</a></td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-optgroup-disabled"><a href="forms.html#disabled-5">disabled</a></code>;
- <code data-anolis-xref="attr-optgroup-label"><a href="forms.html#label-2">label</a></code></td>
+ <code data-anolis-xref="attr-optgroup-disabled"><a href="forms.html#attr-optgroup-disabled">disabled</a></code>;
+ <code data-anolis-xref="attr-optgroup-label"><a href="forms.html#attr-optgroup-label">label</a></code></td>
<td><code><a href="forms.html#htmloptgroupelement">HTMLOptGroupElement</a></code></td>
<tr><th><code><a href="forms.html#the-option-element">option</a></code></th>
<td>Option in a list box or combo box control</td>
@@ -1149,28 +1152,28 @@
<code><a href="forms.html#the-datalist-element">datalist</a></code>;
<code><a href="forms.html#the-optgroup-element">optgroup</a></code>;
<code><a href="scripting-1.html#the-template-element">template</a></code></td>
- <td><a data-anolis-xref="text content" href="dom.html#text-1">text</a>*</td>
+ <td><a data-anolis-xref="text content" href="dom.html#text-content">text</a>*</td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-option-disabled"><a href="forms.html#disabled-7">disabled</a></code>;
- <code data-anolis-xref="attr-option-label"><a href="forms.html#label-4">label</a></code>;
- <code data-anolis-xref="attr-option-selected"><a href="forms.html#selected">selected</a></code>;
- <code data-anolis-xref="attr-option-value"><a href="forms.html#value-12">value</a></code></td>
+ <code data-anolis-xref="attr-option-disabled"><a href="forms.html#attr-option-disabled">disabled</a></code>;
+ <code data-anolis-xref="attr-option-label"><a href="forms.html#attr-option-label">label</a></code>;
+ <code data-anolis-xref="attr-option-selected"><a href="forms.html#attr-option-selected">selected</a></code>;
+ <code data-anolis-xref="attr-option-value"><a href="forms.html#attr-option-value">value</a></code></td>
<td><code><a href="forms.html#htmloptionelement">HTMLOptionElement</a></code></td>
<tr><th><code><a href="forms.html#the-output-element">output</a></code></th>
<td>Calculated output value</td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a>;
<a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a>;
- <a data-anolis-xref="category-listed" href="forms.html#listed-elements">listed</a>;
- <a data-anolis-xref="category-label" href="forms.html#labelable-elements">labelable</a>;
- <a data-anolis-xref="category-reset" href="forms.html#resettable-elements">resettable</a>;
- <a data-anolis-xref="category-form-attr" href="forms.html#reassociateable-elements">reassociateable</a>;
- <a data-anolis-xref="Form-associated element" href="forms.html#form-associated-elements">form-associated</a></td>
+ <a data-anolis-xref="category-listed" href="forms.html#category-listed">listed</a>;
+ <a data-anolis-xref="category-label" href="forms.html#category-label">labelable</a>;
+ <a data-anolis-xref="category-reset" href="forms.html#category-reset">resettable</a>;
+ <a data-anolis-xref="category-form-attr" href="forms.html#category-form-attr">reassociateable</a>;
+ <a data-anolis-xref="Form-associated element" href="forms.html#form-associated-element">form-associated</a></td>
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-output-for"><a href="forms.html#for-0">for</a></code>;
- <code data-anolis-xref="attr-fae-form"><a href="forms.html#form-1">form</a></code>;
- <code data-anolis-xref="attr-fe-name"><a href="forms.html#name-11">name</a></code></td>
+ <code data-anolis-xref="attr-output-for"><a href="forms.html#attr-output-for">for</a></code>;
+ <code data-anolis-xref="attr-fae-form"><a href="forms.html#attr-fae-form">form</a></code>;
+ <code data-anolis-xref="attr-fe-name"><a href="forms.html#attr-fe-name">name</a></code></td>
<td><code><a href="forms.html#htmloutputelement">HTMLOutputElement</a></code></td>
<tr><th><code><a href="grouping-content.html#the-p-element">p</a></code></th>
<td>Paragraph</td>
@@ -1179,16 +1182,16 @@
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a></td>
<td><code><a href="grouping-content.html#htmlparagraphelement">HTMLParagraphElement</a></code></td>
- <tr><th><code><a href="embedded-content-0.html#the-param-element">param</a></code></th>
- <td>Parameter for <code><a href="embedded-content-0.html#the-object-element">object</a></code></td>
+ <tr><th><code><a href="embedded-content.html#the-param-element">param</a></code></th>
+ <td>Parameter for <code><a href="embedded-content.html#the-object-element">object</a></code></td>
<td>none</td>
- <td><code><a href="embedded-content-0.html#the-object-element">object</a></code>;
+ <td><code><a href="embedded-content.html#the-object-element">object</a></code>;
<code><a href="scripting-1.html#the-template-element">template</a></code></td>
<td>empty</td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-param-name"><a href="embedded-content-0.html#name-5">name</a></code>;
- <code data-anolis-xref="attr-param-value"><a href="embedded-content-0.html#value-4">value</a></code></td>
- <td><code><a href="embedded-content-0.html#htmlparamelement">HTMLParamElement</a></code></td>
+ <code data-anolis-xref="attr-param-name"><a href="embedded-content.html#attr-param-name">name</a></code>;
+ <code data-anolis-xref="attr-param-value"><a href="embedded-content.html#attr-param-value">value</a></code></td>
+ <td><code><a href="embedded-content.html#htmlparamelement">HTMLParamElement</a></code></td>
<tr><th><code><a href="grouping-content.html#the-pre-element">pre</a></code></th>
<td>Block of preformatted text</td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a></td>
@@ -1200,12 +1203,12 @@
<td>Progress bar</td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a>;
<a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a>;
- <a data-anolis-xref="category-label" href="forms.html#labelable-elements">labelable</a></td>
+ <a data-anolis-xref="category-label" href="forms.html#category-label">labelable</a></td>
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a>*</td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-progress-value"><a href="forms.html#value-17">value</a></code>;
- <code data-anolis-xref="attr-progress-max"><a href="forms.html#max-1">max</a></code></td>
+ <code data-anolis-xref="attr-progress-value"><a href="forms.html#attr-progress-value">value</a></code>;
+ <code data-anolis-xref="attr-progress-max"><a href="forms.html#attr-progress-max">max</a></code></td>
<td><code><a href="forms.html#htmlprogresselement">HTMLProgressElement</a></code></td>
<tr><th><code><a href="text-level-semantics.html#the-q-element">q</a></code></th>
<td>Quotation</td>
@@ -1214,7 +1217,7 @@
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-q-cite"><a href="text-level-semantics.html#cite-1">cite</a></code></td>
+ <code data-anolis-xref="attr-q-cite"><a href="text-level-semantics.html#attr-q-cite">cite</a></code></td>
<td><code><a href="grouping-content.html#htmlquoteelement">HTMLQuoteElement</a></code></td>
</tr><!-- FORK --><tr><th><code><a href="text-level-semantics.html#the-rb-element">rb</a></code></th>
<td>Ruby base</td>
@@ -1228,6 +1231,7 @@
<td>Parenthesis for ruby annotation text</td>
<td>none</td>
<td><code><a href="text-level-semantics.html#the-ruby-element">ruby</a></code>;
+ <code><a href="text-level-semantics.html#the-rtc-element">rtc</a></code>;
<code><a href="scripting-1.html#the-template-element">template</a></code></td>
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a></td>
@@ -1293,12 +1297,12 @@
<a data-anolis-xref="Script-supporting elements" href="dom.html#script-supporting-elements-0">script-supporting</a></td>
<td>script, data, or script documentation*</td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-script-src"><a href="scripting-1.html#src-13">src</a></code>;
- <code data-anolis-xref="attr-script-type"><a href="scripting-1.html#type-29">type</a></code>;
- <code data-anolis-xref="attr-script-charset"><a href="scripting-1.html#charset-1">charset</a></code>;
- <code data-anolis-xref="attr-script-async"><a href="scripting-1.html#async">async</a></code>;
- <code data-anolis-xref="attr-script-defer"><a href="scripting-1.html#defer">defer</a></code>;
- <code data-anolis-xref="attr-script-crossorigin"><a href="scripting-1.html#crossorigin-5">crossorigin</a></code></td>
+ <code data-anolis-xref="attr-script-src"><a href="scripting-1.html#attr-script-src">src</a></code>;
+ <code data-anolis-xref="attr-script-type"><a href="scripting-1.html#attr-script-type">type</a></code>;
+ <code data-anolis-xref="attr-script-charset"><a href="scripting-1.html#attr-script-charset">charset</a></code>;
+ <code data-anolis-xref="attr-script-async"><a href="scripting-1.html#attr-script-async">async</a></code>;
+ <code data-anolis-xref="attr-script-defer"><a href="scripting-1.html#attr-script-defer">defer</a></code>;
+ <code data-anolis-xref="attr-script-crossorigin"><a href="scripting-1.html#attr-script-crossorigin">crossorigin</a></code></td>
<td><code><a href="scripting-1.html#htmlscriptelement">HTMLScriptElement</a></code></td>
<tr><th><code><a href="sections.html#the-section-element">section</a></code></th>
<td>Generic document or application section</td>
@@ -1313,22 +1317,25 @@
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a>;
<a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a>;
<a data-anolis-xref="Interactive content" href="dom.html#interactive-content-0">interactive</a>;
- <a data-anolis-xref="category-listed" href="forms.html#listed-elements">listed</a>;
- <a data-anolis-xref="category-label" href="forms.html#labelable-elements">labelable</a>;
- <a data-anolis-xref="category-submit" href="forms.html#submittable-elements">submittable</a>;
- <a data-anolis-xref="category-reset" href="forms.html#resettable-elements">resettable</a>;
- <a data-anolis-xref="category-form-attr" href="forms.html#reassociateable-elements">reassociateable</a>;
- <a data-anolis-xref="Form-associated element" href="forms.html#form-associated-elements">form-associated</a></td>
- <td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
- <td><code><a href="forms.html#the-option-element">option</a></code>, <code><a href="forms.html#the-optgroup-element">optgroup</a></code></td>
+ <a data-anolis-xref="category-listed" href="forms.html#category-listed">listed</a>;
+ <a data-anolis-xref="category-label" href="forms.html#category-label">labelable</a>;
+ <a data-anolis-xref="category-submit" href="forms.html#category-submit">submittable</a>;
+ <a data-anolis-xref="category-reset" href="forms.html#category-reset">resettable</a>;
+ <a data-anolis-xref="category-form-attr" href="forms.html#category-form-attr">reassociateable</a>;
+ <a data-anolis-xref="Form-associated element" href="forms.html#form-associated-element">form-associated</a></td>
+ <td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
+ <td><code><a href="forms.html#the-option-element">option</a></code>;
+ <code><a href="forms.html#the-optgroup-element">optgroup</a></code>;
+ <a href="dom.html#script-supporting-elements-0">script-supporting elements</a></td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-fe-autofocus"><a href="forms.html#autofocus">autofocus</a></code>;
- <code data-anolis-xref="attr-fe-disabled"><a href="forms.html#disabled-12">disabled</a></code>;
- <code data-anolis-xref="attr-fae-form"><a href="forms.html#form-1">form</a></code>;
- <code data-anolis-xref="attr-select-multiple"><a href="forms.html#multiple-1">multiple</a></code>;
- <code data-anolis-xref="attr-fe-name"><a href="forms.html#name-11">name</a></code>;
- <code data-anolis-xref="attr-select-required"><a href="forms.html#required-2">required</a></code>;
- <code data-anolis-xref="attr-select-size"><a href="forms.html#size-2">size</a></code></td>
+ <code data-anolis-xref="attr-fe-autocomplete"><a href="forms.html#attr-fe-autocomplete">autocomplete</a></code>;
+ <code data-anolis-xref="attr-fe-autofocus"><a href="forms.html#attr-fe-autofocus">autofocus</a></code>;
+ <code data-anolis-xref="attr-fe-disabled"><a href="forms.html#attr-fe-disabled">disabled</a></code>;
+ <code data-anolis-xref="attr-fae-form"><a href="forms.html#attr-fae-form">form</a></code>;
+ <code data-anolis-xref="attr-select-multiple"><a href="forms.html#attr-select-multiple">multiple</a></code>;
+ <code data-anolis-xref="attr-fe-name"><a href="forms.html#attr-fe-name">name</a></code>;
+ <code data-anolis-xref="attr-select-required"><a href="forms.html#attr-select-required">required</a></code>;
+ <code data-anolis-xref="attr-select-size"><a href="forms.html#attr-select-size">size</a></code></td>
<td><code><a href="forms.html#htmlselectelement">HTMLSelectElement</a></code></td>
<tr><th><code><a href="text-level-semantics.html#the-small-element">small</a></code></th>
<td>Side comment</td>
@@ -1338,18 +1345,17 @@
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a></td>
<td><code><a href="dom.html#htmlelement">HTMLElement</a></code></td>
- <tr><th><code><a href="embedded-content-0.html#the-source-element">source</a></code></th>
- <td>Media source for <code><a href="embedded-content-0.html#the-video-element">video</a></code> or <code><a href="embedded-content-0.html#the-audio-element">audio</a></code></td>
+ <tr><th><code><a href="embedded-content.html#the-source-element">source</a></code></th>
+ <td>Media source for <code><a href="embedded-content.html#the-video-element">video</a></code> or <code><a href="embedded-content.html#the-audio-element">audio</a></code></td>
<td>none</td>
- <td><code><a href="embedded-content-0.html#the-video-element">video</a></code>;
- <code><a href="embedded-content-0.html#the-audio-element">audio</a></code>;
+ <td><code><a href="embedded-content.html#the-video-element">video</a></code>;
+ <code><a href="embedded-content.html#the-audio-element">audio</a></code>;
<code><a href="scripting-1.html#the-template-element">template</a></code></td>
<td>empty</td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-source-src"><a href="embedded-content-0.html#src-5">src</a></code>;
- <code data-anolis-xref="attr-source-type"><a href="embedded-content-0.html#type-11">type</a></code>;
- <code data-anolis-xref="attr-source-media"><a href="embedded-content-0.html#media-3">media</a></code></td>
- <td><code><a href="embedded-content-0.html#htmlsourceelement">HTMLSourceElement</a></code></td>
+ <code data-anolis-xref="attr-source-src"><a href="embedded-content.html#attr-source-src">src</a></code>;
+ <code data-anolis-xref="attr-source-type"><a href="embedded-content.html#attr-source-type">type</a></code></td>
+ <td><code><a href="embedded-content.html#htmlsourceelement">HTMLSourceElement</a></code></td>
<tr><th><code><a href="text-level-semantics.html#the-span-element">span</a></code></th>
<td>Generic phrasing container</td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a>;
@@ -1369,15 +1375,15 @@
<tr><th><code><a href="document-metadata.html#the-style-element">style</a></code></th>
<td>Embedded styling information</td>
<td><a data-anolis-xref="Metadata content" href="dom.html#metadata-content-0">metadata</a>;
- <a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a></td>
+ <a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a>*</td>
<td><code><a href="document-metadata.html#the-head-element">head</a></code>;
<code><a href="scripting-1.html#the-noscript-element">noscript</a></code>*;
<a data-anolis-xref="flow content" href="dom.html#flow-content-1">flow</a>*</td>
<td>varies*</td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-style-media"><a href="document-metadata.html#media-1">media</a></code>;
- <code data-anolis-xref="attr-style-type"><a href="document-metadata.html#type-2">type</a></code>;
- <code data-anolis-xref="attr-style-scoped"><a href="document-metadata.html#scoped">scoped</a></code></td>
+ <code data-anolis-xref="attr-style-media"><a href="document-metadata.html#attr-style-media">media</a></code>;
+ <code data-anolis-xref="attr-style-type"><a href="document-metadata.html#attr-style-type">type</a></code>;
+ <code data-anolis-xref="attr-style-scoped"><a href="document-metadata.html#attr-style-scoped">scoped</a></code></td>
<td><code><a href="document-metadata.html#htmlstyleelement">HTMLStyleElement</a></code></td>
<tr><th><code><a href="text-level-semantics.html#the-sub-and-sup-elements">sub</a></code></th>
<td>Subscript</td>
@@ -1415,8 +1421,8 @@
<a href="dom.html#script-supporting-elements-0">script-supporting elements</a></td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
<!--FORK:table border not in WHATWG spec-->
- <code data-anolis-xref="attr-table-border"><a href="tabular-data.html#border">border</a></code>
- <code data-anolis-xref="attr-table-sortable"><a href="tabular-data.html#sortable-0">sortable</a></code></td>
+ <code data-anolis-xref="attr-table-border"><a href="tabular-data.html#attr-table-border">border</a></code>
+ <code data-anolis-xref="attr-table-sortable"><a href="tabular-data.html#attr-table-sortable">sortable</a></code></td>
<td><code><a href="tabular-data.html#htmltableelement">HTMLTableElement</a></code></td>
<tr><th><code><a href="tabular-data.html#the-tbody-element">tbody</a></code></th>
<td>Group of rows in a table</td>
@@ -1429,14 +1435,14 @@
<td><code><a href="tabular-data.html#htmltablesectionelement">HTMLTableSectionElement</a></code></td>
<tr><th><code><a href="tabular-data.html#the-td-element">td</a></code></th>
<td>Table cell</td>
- <td><a data-anolis-xref="Sectioning root" href="sections.html#sectioning-roots">sectioning root</a></td>
+ <td><a data-anolis-xref="Sectioning root" href="sections.html#sectioning-root">sectioning root</a></td>
<td><code><a href="tabular-data.html#the-tr-element">tr</a></code>;
<code><a href="scripting-1.html#the-template-element">template</a></code></td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a></td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-tdth-colspan"><a href="tabular-data.html#colspan">colspan</a></code>;
- <code data-anolis-xref="attr-tdth-rowspan"><a href="tabular-data.html#rowspan">rowspan</a></code>;
- <code data-anolis-xref="attr-tdth-headers"><a href="tabular-data.html#headers">headers</a></code></td>
+ <code data-anolis-xref="attr-tdth-colspan"><a href="tabular-data.html#attr-tdth-colspan">colspan</a></code>;
+ <code data-anolis-xref="attr-tdth-rowspan"><a href="tabular-data.html#attr-tdth-rowspan">rowspan</a></code>;
+ <code data-anolis-xref="attr-tdth-headers"><a href="tabular-data.html#attr-tdth-headers">headers</a></code></td>
<td><code><a href="tabular-data.html#htmltabledatacellelement">HTMLTableDataCellElement</a></code></td>
<tr><th><code><a href="scripting-1.html#the-template-element">template</a></code></th>
<td>Template</td>
@@ -1456,29 +1462,29 @@
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a>;
<a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a>;
<a data-anolis-xref="Interactive content" href="dom.html#interactive-content-0">interactive</a>;
- <a data-anolis-xref="category-listed" href="forms.html#listed-elements">listed</a>;
- <a data-anolis-xref="category-label" href="forms.html#labelable-elements">labelable</a>;
- <a data-anolis-xref="category-submit" href="forms.html#submittable-elements">submittable</a>;
- <a data-anolis-xref="category-reset" href="forms.html#resettable-elements">resettable</a>;
- <a data-anolis-xref="category-form-attr" href="forms.html#reassociateable-elements">reassociateable</a>;
- <a data-anolis-xref="Form-associated element" href="forms.html#form-associated-elements">form-associated</a></td>
- <td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
- <td><a data-anolis-xref="text content" href="dom.html#text-1">text</a></td>
+ <a data-anolis-xref="category-listed" href="forms.html#category-listed">listed</a>;
+ <a data-anolis-xref="category-label" href="forms.html#category-label">labelable</a>;
+ <a data-anolis-xref="category-submit" href="forms.html#category-submit">submittable</a>;
+ <a data-anolis-xref="category-reset" href="forms.html#category-reset">resettable</a>;
+ <a data-anolis-xref="category-form-attr" href="forms.html#category-form-attr">reassociateable</a>;
+ <a data-anolis-xref="Form-associated element" href="forms.html#form-associated-element">form-associated</a></td>
+ <td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
+ <td><a data-anolis-xref="text content" href="dom.html#text-content">text</a></td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-fe-autofocus"><a href="forms.html#autofocus">autofocus</a></code>;
- <code data-anolis-xref="attr-textarea-cols"><a href="forms.html#cols">cols</a></code>;
- <code data-anolis-xref="attr-fe-dirname"><a href="forms.html#dirname-1">dirname</a></code>;
- <code data-anolis-xref="attr-fe-disabled"><a href="forms.html#disabled-12">disabled</a></code>;
- <code data-anolis-xref="attr-fae-form"><a href="forms.html#form-1">form</a></code>;
- <code data-anolis-xref="attr-fe-inputmode"><a href="forms.html#inputmode-1">inputmode</a></code>;
- <code data-anolis-xref="attr-textarea-maxlength"><a href="forms.html#maxlength-1">maxlength</a></code>;
- <code data-anolis-xref="attr-textarea-minlength"><a href="forms.html#minlength-1">minlength</a></code>;
- <code data-anolis-xref="attr-fe-name"><a href="forms.html#name-11">name</a></code>;
- <code data-anolis-xref="attr-textarea-placeholder"><a href="forms.html#placeholder-1">placeholder</a></code>;
- <code data-anolis-xref="attr-textarea-readonly"><a href="forms.html#readonly-1">readonly</a></code>;
- <code data-anolis-xref="attr-textarea-required"><a href="forms.html#required-4">required</a></code>;
- <code data-anolis-xref="attr-textarea-rows"><a href="forms.html#rows-1">rows</a></code>;
- <code data-anolis-xref="attr-textarea-wrap"><a href="forms.html#wrap">wrap</a></code></td>
+ <code data-anolis-xref="attr-fe-autofocus"><a href="forms.html#attr-fe-autofocus">autofocus</a></code>;
+ <code data-anolis-xref="attr-textarea-cols"><a href="forms.html#attr-textarea-cols">cols</a></code>;
+ <code data-anolis-xref="attr-fe-dirname"><a href="forms.html#attr-fe-dirname">dirname</a></code>;
+ <code data-anolis-xref="attr-fe-disabled"><a href="forms.html#attr-fe-disabled">disabled</a></code>;
+ <code data-anolis-xref="attr-fae-form"><a href="forms.html#attr-fae-form">form</a></code>;
+ <code data-anolis-xref="attr-fe-inputmode"><a href="forms.html#attr-fe-inputmode">inputmode</a></code>;
+ <code data-anolis-xref="attr-textarea-maxlength"><a href="forms.html#attr-textarea-maxlength">maxlength</a></code>;
+ <code data-anolis-xref="attr-textarea-minlength"><a href="forms.html#attr-textarea-minlength">minlength</a></code>;
+ <code data-anolis-xref="attr-fe-name"><a href="forms.html#attr-fe-name">name</a></code>;
+ <code data-anolis-xref="attr-textarea-placeholder"><a href="forms.html#attr-textarea-placeholder">placeholder</a></code>;
+ <code data-anolis-xref="attr-textarea-readonly"><a href="forms.html#attr-textarea-readonly">readonly</a></code>;
+ <code data-anolis-xref="attr-textarea-required"><a href="forms.html#attr-textarea-required">required</a></code>;
+ <code data-anolis-xref="attr-textarea-rows"><a href="forms.html#attr-textarea-rows">rows</a></code>;
+ <code data-anolis-xref="attr-textarea-wrap"><a href="forms.html#attr-textarea-wrap">wrap</a></code></td>
<td><code><a href="forms.html#htmltextareaelement">HTMLTextAreaElement</a></code></td>
<tr><th><code><a href="tabular-data.html#the-tfoot-element">tfoot</a></code></th>
<td>Group of footer rows in a table</td>
@@ -1491,17 +1497,17 @@
<td><code><a href="tabular-data.html#htmltablesectionelement">HTMLTableSectionElement</a></code></td>
<tr><th><code><a href="tabular-data.html#the-th-element">th</a></code></th>
<td>Table header cell</td>
- <td>none</td>
+ <td><a data-anolis-xref="Interactive content" href="dom.html#interactive-content-0">interactive</a>*</td>
<td><code><a href="tabular-data.html#the-tr-element">tr</a></code>;
<code><a href="scripting-1.html#the-template-element">template</a></code></td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a>*</td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-tdth-colspan"><a href="tabular-data.html#colspan">colspan</a></code>;
- <code data-anolis-xref="attr-tdth-rowspan"><a href="tabular-data.html#rowspan">rowspan</a></code>;
- <code data-anolis-xref="attr-tdth-headers"><a href="tabular-data.html#headers">headers</a></code>;
- <code data-anolis-xref="attr-th-scope"><a href="tabular-data.html#scope-0">scope</a></code>;
- <code data-anolis-xref="attr-th-sorted"><a href="tabular-data.html#sorted-0">sorted</a></code>;
- <code data-anolis-xref="attr-th-abbr"><a href="tabular-data.html#abbr">abbr</a></code></td>
+ <code data-anolis-xref="attr-tdth-colspan"><a href="tabular-data.html#attr-tdth-colspan">colspan</a></code>;
+ <code data-anolis-xref="attr-tdth-rowspan"><a href="tabular-data.html#attr-tdth-rowspan">rowspan</a></code>;
+ <code data-anolis-xref="attr-tdth-headers"><a href="tabular-data.html#attr-tdth-headers">headers</a></code>;
+ <code data-anolis-xref="attr-th-scope"><a href="tabular-data.html#attr-th-scope">scope</a></code>;
+ <code data-anolis-xref="attr-th-sorted"><a href="tabular-data.html#attr-th-sorted">sorted</a></code>;
+ <code data-anolis-xref="attr-th-abbr"><a href="tabular-data.html#attr-th-abbr">abbr</a></code></td>
<td><code><a href="tabular-data.html#htmltableheadercellelement">HTMLTableHeaderCellElement</a></code></td>
<tr><th><code><a href="tabular-data.html#the-thead-element">thead</a></code></th>
<td>Group of heading rows in a table</td>
@@ -1519,14 +1525,14 @@
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-time-datetime"><a href="text-level-semantics.html#datetime">datetime</a></code></td>
+ <code data-anolis-xref="attr-time-datetime"><a href="text-level-semantics.html#attr-time-datetime">datetime</a></code></td>
<td><code><a href="text-level-semantics.html#htmltimeelement">HTMLTimeElement</a></code></td>
<tr><th><code><a href="document-metadata.html#the-title-element">title</a></code></th>
<td>Document title</td>
<td><a data-anolis-xref="Metadata content" href="dom.html#metadata-content-0">metadata</a></td>
<td><code><a href="document-metadata.html#the-head-element">head</a></code>;
<code><a href="scripting-1.html#the-template-element">template</a></code></td>
- <td><a data-anolis-xref="text content" href="dom.html#text-1">text</a>*</td>
+ <td><a data-anolis-xref="text content" href="dom.html#text-content">text</a>*</td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a></td>
<td><code><a href="document-metadata.html#htmltitleelement">HTMLTitleElement</a></code></td>
<tr><th><code><a href="tabular-data.html#the-tr-element">tr</a></code></th>
@@ -1542,20 +1548,20 @@
<a href="dom.html#script-supporting-elements-0">script-supporting elements</a></td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a></td>
<td><code><a href="tabular-data.html#htmltablerowelement">HTMLTableRowElement</a></code></td>
- <tr><th><code><a href="embedded-content-0.html#the-track-element">track</a></code></th>
+ <tr><th><code><a href="embedded-content.html#the-track-element">track</a></code></th>
<td>Timed text track</td>
<td>none</td>
- <td><code><a href="embedded-content-0.html#the-audio-element">audio</a></code>;
- <code><a href="embedded-content-0.html#the-video-element">video</a></code>;
+ <td><code><a href="embedded-content.html#the-audio-element">audio</a></code>;
+ <code><a href="embedded-content.html#the-video-element">video</a></code>;
<code><a href="scripting-1.html#the-template-element">template</a></code></td>
<td>empty</td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-track-default"><a href="embedded-content-0.html#default">default</a></code>;
- <code data-anolis-xref="attr-track-kind"><a href="embedded-content-0.html#kind">kind</a></code>;
- <code data-anolis-xref="attr-track-label"><a href="embedded-content-0.html#label">label</a></code>;
- <code data-anolis-xref="attr-track-src"><a href="embedded-content-0.html#src-7">src</a></code>;
- <code data-anolis-xref="attr-track-srclang"><a href="embedded-content-0.html#srclang">srclang</a></code></td>
- <td><code><a href="embedded-content-0.html#htmltrackelement">HTMLTrackElement</a></code></td>
+ <code data-anolis-xref="attr-track-default"><a href="embedded-content.html#attr-track-default">default</a></code>;
+ <code data-anolis-xref="attr-track-kind"><a href="embedded-content.html#attr-track-kind">kind</a></code>;
+ <code data-anolis-xref="attr-track-label"><a href="embedded-content.html#attr-track-label">label</a></code>;
+ <code data-anolis-xref="attr-track-src"><a href="embedded-content.html#attr-track-src">src</a></code>;
+ <code data-anolis-xref="attr-track-srclang"><a href="embedded-content.html#attr-track-srclang">srclang</a></code></td>
+ <td><code><a href="embedded-content.html#htmltrackelement">HTMLTrackElement</a></code></td>
<tr><th><code><a href="text-level-semantics.html#the-u-element">u</a></code></th>
<td>Keywords</td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a>;
@@ -1580,28 +1586,28 @@
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a></td>
<td><code><a href="dom.html#htmlelement">HTMLElement</a></code></td>
- <tr><th><code><a href="embedded-content-0.html#the-video-element">video</a></code></th>
+ <tr><th><code><a href="embedded-content.html#the-video-element">video</a></code></th>
<td>Video player</td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a>;
<a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a>;
- <a data-anolis-xref="Embedded content" href="dom.html#embedded-content-2">embedded</a>;
+ <a data-anolis-xref="Embedded content" href="dom.html#embedded-content-category">embedded</a>;
<a data-anolis-xref="Interactive content" href="dom.html#interactive-content-0">interactive</a></td>
<td><a data-anolis-xref="Phrasing content" href="dom.html#phrasing-content-1">phrasing</a></td>
- <td><code><a href="embedded-content-0.html#the-source-element">source</a></code>*;
+ <td><code><a href="embedded-content.html#the-source-element">source</a></code>*;
<a href="dom.html#transparent">transparent</a>*</td>
<td><a data-anolis-xref="global attributes" href="dom.html#global-attributes">globals</a>;
- <code data-anolis-xref="attr-media-src"><a href="embedded-content-0.html#src-9">src</a></code>;
- <code data-anolis-xref="attr-media-crossorigin"><a href="embedded-content-0.html#crossorigin-3">crossorigin</a></code>;
- <code data-anolis-xref="attr-video-poster"><a href="embedded-content-0.html#poster">poster</a></code>;
- <code data-anolis-xref="attr-media-preload"><a href="embedded-content-0.html#preload">preload</a></code>;
- <code data-anolis-xref="attr-media-autoplay"><a href="embedded-content-0.html#autoplay">autoplay</a></code>;
- <code data-anolis-xref="attr-media-mediagroup"><a href="embedded-content-0.html#mediagroup">mediagroup</a></code>;
- <code data-anolis-xref="attr-media-loop"><a href="embedded-content-0.html#loop">loop</a></code>;
- <code data-anolis-xref="attr-media-muted"><a href="embedded-content-0.html#muted-1">muted</a></code>;
- <code data-anolis-xref="attr-media-controls"><a href="embedded-content-0.html#controls">controls</a></code>;
- <code data-anolis-xref="attr-dim-width"><a href="embedded-content-0.html#width-0">width</a></code>;
- <code data-anolis-xref="attr-dim-height"><a href="embedded-content-0.html#height-0">height</a></code></td>
- <td><code><a href="embedded-content-0.html#htmlvideoelement">HTMLVideoElement</a></code></td>
+ <code data-anolis-xref="attr-media-src"><a href="embedded-content.html#attr-media-src">src</a></code>;
+ <code data-anolis-xref="attr-media-crossorigin"><a href="embedded-content.html#attr-media-crossorigin">crossorigin</a></code>;
+ <code data-anolis-xref="attr-video-poster"><a href="embedded-content.html#attr-video-poster">poster</a></code>;
+ <code data-anolis-xref="attr-media-preload"><a href="embedded-content.html#attr-media-preload">preload</a></code>;
+ <code data-anolis-xref="attr-media-autoplay"><a href="embedded-content.html#attr-media-autoplay">autoplay</a></code>;
+ <code data-anolis-xref="attr-media-mediagroup"><a href="embedded-content.html#attr-media-mediagroup">mediagroup</a></code>;
+ <code data-anolis-xref="attr-media-loop"><a href="embedded-content.html#attr-media-loop">loop</a></code>;
+ <code data-anolis-xref="attr-media-muted"><a href="embedded-content.html#attr-media-muted">muted</a></code>;
+ <code data-anolis-xref="attr-media-controls"><a href="embedded-content.html#attr-media-controls">controls</a></code>;
+ <code data-anolis-xref="attr-dim-width"><a href="embedded-content.html#attr-dim-width">width</a></code>;
+ <code data-anolis-xref="attr-dim-height"><a href="embedded-content.html#attr-dim-height">height</a></code></td>
+ <td><code><a href="embedded-content.html#htmlvideoelement">HTMLVideoElement</a></code></td>
<tr><th><code><a href="text-level-semantics.html#the-wbr-element">wbr</a></code></th>
<td>Line breaking opportunity</td>
<td><a data-anolis-xref="Flow content" href="dom.html#flow-content-1">flow</a>;
@@ -1613,18 +1619,19 @@
</table><p class="tablenote"><small>An asterisk (*) in a cell indicates that the actual rules are more
complicated than indicated in the table above.</small></p>
- <p>† Categories in the "Parents" column refer to parents that list the given categories in
- their content model, not to elements that themselves are in those categories. For example, the
- <code><a href="text-level-semantics.html#the-a-element">a</a></code> element's "Parents" column says "phrasing", so any element whose content model
- contains the "phrasing" category could be a parent of an <code><a href="text-level-semantics.html#the-a-element">a</a></code> element. Since the "flow"
- category includes all the "phrasing" elements, that means the <code><a href="tabular-data.html#the-th-element">th</a></code> element could be a
- parent to an <code><a href="text-level-semantics.html#the-a-element">a</a></code> element.</p>
+ <p class="tablenote"><small>† Categories in the "Parents" column refer to parents that list
+ the given categories in their content model, not to elements that themselves are in those
+ categories. For example, the <code><a href="text-level-semantics.html#the-a-element">a</a></code> element's "Parents" column says "phrasing", so any
+ element whose content model contains the "phrasing" category could be a parent of an
+ <code><a href="text-level-semantics.html#the-a-element">a</a></code> element. Since the "flow" category includes all the "phrasing" elements, that means
+ the <code><a href="tabular-data.html#the-th-element">th</a></code> element could be a parent to an <code><a href="text-level-semantics.html#the-a-element">a</a></code> element.</small></p>
<h3 class="no-num" id="element-content-categories">Element content categories</h3>
<p><i>This section is non-normative.</i></p>
+
<!-- when updating this also check the category-list <ul>s -->
<table><caption>List of element content categories</caption>
@@ -1651,7 +1658,7 @@
<code><a href="sections.html#the-address-element">address</a></code>;
<code><a href="sections.html#the-article-element">article</a></code>;
<code><a href="sections.html#the-aside-element">aside</a></code>;
- <code><a href="embedded-content-0.html#the-audio-element">audio</a></code>;
+ <code><a href="embedded-content.html#the-audio-element">audio</a></code>;
<code><a href="text-level-semantics.html#the-b-element">b</a></code>;
<code><a href="text-level-semantics.html#the-bdi-element">bdi</a></code>;
<code><a href="text-level-semantics.html#the-bdo-element">bdo</a></code>;
@@ -1670,7 +1677,7 @@
<code><a href="grouping-content.html#the-div-element">div</a></code>;
<code><a href="grouping-content.html#the-dl-element">dl</a></code>;
<code><a href="text-level-semantics.html#the-em-element">em</a></code>;
- <code><a href="embedded-content-0.html#the-embed-element">embed</a></code>;
+ <code><a href="embedded-content.html#the-embed-element">embed</a></code>;
<code><a href="forms.html#the-fieldset-element">fieldset</a></code>;
<code><a href="grouping-content.html#the-figure-element">figure</a></code>;
<code><a href="sections.html#the-footer-element">footer</a></code>;
@@ -1685,22 +1692,22 @@
<!--FORK START/END HGROUP removed-->
<code><a href="grouping-content.html#the-hr-element">hr</a></code>;
<code><a href="text-level-semantics.html#the-i-element">i</a></code>;
- <code><a href="embedded-content-0.html#the-iframe-element">iframe</a></code>;
- <code><a href="embedded-content-0.html#the-img-element">img</a></code>;
+ <code><a href="embedded-content.html#the-iframe-element">iframe</a></code>;
+ <code><a href="embedded-content.html#the-img-element">img</a></code>;
<code><a href="forms.html#the-input-element">input</a></code>;
<code><a href="edits.html#the-ins-element">ins</a></code>;
<code><a href="text-level-semantics.html#the-kbd-element">kbd</a></code>;
<code><a href="forms.html#the-keygen-element">keygen</a></code>;
<code><a href="forms.html#the-label-element">label</a></code>;
<code><a href="grouping-content.html#the-main-element">main</a></code>;
- <code><a href="embedded-content-0.html#the-map-element">map</a></code>;
+ <code><a href="embedded-content.html#the-map-element">map</a></code>;
<code><a href="text-level-semantics.html#the-mark-element">mark</a></code>;
- <code><a href="embedded-content-0.html#math">math</a></code>;
+ <code><a href="embedded-content.html#math">math</a></code>;
<code><a href="interactive-elements.html#the-menu-element">menu</a></code>;
<code><a href="forms.html#the-meter-element">meter</a></code>;
<code><a href="sections.html#the-nav-element">nav</a></code>;
<code><a href="scripting-1.html#the-noscript-element">noscript</a></code>;
- <code><a href="embedded-content-0.html#the-object-element">object</a></code>;
+ <code><a href="embedded-content.html#the-object-element">object</a></code>;
<code><a href="grouping-content.html#the-ol-element">ol</a></code>;
<code><a href="forms.html#the-output-element">output</a></code>;
<code><a href="grouping-content.html#the-p-element">p</a></code>;
@@ -1718,7 +1725,7 @@
<code><a href="text-level-semantics.html#the-strong-element">strong</a></code>;
<code><a href="text-level-semantics.html#the-sub-and-sup-elements">sub</a></code>;
<code><a href="text-level-semantics.html#the-sub-and-sup-elements">sup</a></code>;
- <code><a href="embedded-content-0.html#svg-0">svg</a></code>;
+ <code><a href="embedded-content.html#svg-0">svg</a></code>;
<code><a href="tabular-data.html#the-table-element">table</a></code>;
<code><a href="scripting-1.html#the-template-element">template</a></code>;
<code><a href="forms.html#the-textarea-element">textarea</a></code>;
@@ -1726,14 +1733,14 @@
<code><a href="text-level-semantics.html#the-u-element">u</a></code>;
<code><a href="grouping-content.html#the-ul-element">ul</a></code>;
<code><a href="text-level-semantics.html#the-var-element">var</a></code>;
- <code><a href="embedded-content-0.html#the-video-element">video</a></code>;
+ <code><a href="embedded-content.html#the-video-element">video</a></code>;
<code><a href="text-level-semantics.html#the-wbr-element">wbr</a></code>;
- <a data-anolis-xref="text content" href="dom.html#text-1">Text</a>
+ <a data-anolis-xref="text content" href="dom.html#text-content">Text</a>
<td>
- <code><a href="embedded-content-0.html#the-area-element">area</a></code> (if it is a descendant of a <code><a href="embedded-content-0.html#the-map-element">map</a></code> element);
+ <code><a href="embedded-content.html#the-area-element">area</a></code> (if it is a descendant of a <code><a href="embedded-content.html#the-map-element">map</a></code> element);
<code><a href="document-metadata.html#the-link-element">link</a></code> (if the <code data-anolis-xref="attr-itemprop">itemprop</code> attribute is present);
<code><a href="document-metadata.html#the-meta-element">meta</a></code> (if the <code data-anolis-xref="attr-itemprop">itemprop</code> attribute is present);
- <code><a href="document-metadata.html#the-style-element">style</a></code> (if the <code data-anolis-xref="attr-style-scoped"><a href="document-metadata.html#scoped">scoped</a></code> attribute is present)
+ <code><a href="document-metadata.html#the-style-element">style</a></code> (if the <code data-anolis-xref="attr-style-scoped"><a href="document-metadata.html#attr-style-scoped">scoped</a></code> attribute is present)
<tr><td> <a href="dom.html#sectioning-content-0">Sectioning content</a>
<td>
@@ -1760,7 +1767,7 @@
<td>
<code><a href="text-level-semantics.html#the-a-element">a</a></code>;
<code><a href="text-level-semantics.html#the-abbr-element">abbr</a></code>;
- <code><a href="embedded-content-0.html#the-audio-element">audio</a></code>;
+ <code><a href="embedded-content.html#the-audio-element">audio</a></code>;
<code><a href="text-level-semantics.html#the-b-element">b</a></code>;
<code><a href="text-level-semantics.html#the-bdi-element">bdi</a></code>;
<code><a href="text-level-semantics.html#the-bdo-element">bdo</a></code>;
@@ -1774,21 +1781,21 @@
<code><a href="edits.html#the-del-element">del</a></code>;
<code><a href="text-level-semantics.html#the-dfn-element">dfn</a></code>;
<code><a href="text-level-semantics.html#the-em-element">em</a></code>;
- <code><a href="embedded-content-0.html#the-embed-element">embed</a></code>;
+ <code><a href="embedded-content.html#the-embed-element">embed</a></code>;
<code><a href="text-level-semantics.html#the-i-element">i</a></code>;
- <code><a href="embedded-content-0.html#the-iframe-element">iframe</a></code>;
- <code><a href="embedded-content-0.html#the-img-element">img</a></code>;
+ <code><a href="embedded-content.html#the-iframe-element">iframe</a></code>;
+ <code><a href="embedded-content.html#the-img-element">img</a></code>;
<code><a href="forms.html#the-input-element">input</a></code>;
<code><a href="edits.html#the-ins-element">ins</a></code>;
<code><a href="text-level-semantics.html#the-kbd-element">kbd</a></code>;
<code><a href="forms.html#the-keygen-element">keygen</a></code>;
<code><a href="forms.html#the-label-element">label</a></code>;
- <code><a href="embedded-content-0.html#the-map-element">map</a></code>;
+ <code><a href="embedded-content.html#the-map-element">map</a></code>;
<code><a href="text-level-semantics.html#the-mark-element">mark</a></code>;
- <code><a href="embedded-content-0.html#math">math</a></code>;
+ <code><a href="embedded-content.html#math">math</a></code>;
<code><a href="forms.html#the-meter-element">meter</a></code>;
<code><a href="scripting-1.html#the-noscript-element">noscript</a></code>;
- <code><a href="embedded-content-0.html#the-object-element">object</a></code>;
+ <code><a href="embedded-content.html#the-object-element">object</a></code>;
<code><a href="forms.html#the-output-element">output</a></code>;
<code><a href="forms.html#the-progress-element">progress</a></code>;
<code><a href="text-level-semantics.html#the-q-element">q</a></code>;
@@ -1802,53 +1809,54 @@
<code><a href="text-level-semantics.html#the-strong-element">strong</a></code>;
<code><a href="text-level-semantics.html#the-sub-and-sup-elements">sub</a></code>;
<code><a href="text-level-semantics.html#the-sub-and-sup-elements">sup</a></code>;
- <code><a href="embedded-content-0.html#svg-0">svg</a></code>;
+ <code><a href="embedded-content.html#svg-0">svg</a></code>;
<code><a href="scripting-1.html#the-template-element">template</a></code>;
<code><a href="forms.html#the-textarea-element">textarea</a></code>;
<code><a href="text-level-semantics.html#the-time-element">time</a></code>;
<code><a href="text-level-semantics.html#the-u-element">u</a></code>;
<code><a href="text-level-semantics.html#the-var-element">var</a></code>;
- <code><a href="embedded-content-0.html#the-video-element">video</a></code>;
+ <code><a href="embedded-content.html#the-video-element">video</a></code>;
<code><a href="text-level-semantics.html#the-wbr-element">wbr</a></code>;
- <a data-anolis-xref="text content" href="dom.html#text-1">Text</a>
+ <a data-anolis-xref="text content" href="dom.html#text-content">Text</a>
<td>
- <code><a href="embedded-content-0.html#the-area-element">area</a></code> (if it is a descendant of a <code><a href="embedded-content-0.html#the-map-element">map</a></code> element);
+ <code><a href="embedded-content.html#the-area-element">area</a></code> (if it is a descendant of a <code><a href="embedded-content.html#the-map-element">map</a></code> element);
<code><a href="document-metadata.html#the-link-element">link</a></code> (if the <code data-anolis-xref="attr-itemprop">itemprop</code> attribute is present);
<code><a href="document-metadata.html#the-meta-element">meta</a></code> (if the <code data-anolis-xref="attr-itemprop">itemprop</code> attribute is present)
- <tr><td> <a href="dom.html#embedded-content-2">Embedded content</a>
+ <tr><td> <a href="dom.html#embedded-content-category">Embedded content</a>
<td>
- <code><a href="embedded-content-0.html#the-audio-element">audio</a></code>
- <code><a href="scripting-1.html#the-canvas-element">canvas</a></code>
- <code><a href="embedded-content-0.html#the-embed-element">embed</a></code>
- <code><a href="embedded-content-0.html#the-iframe-element">iframe</a></code>
- <code><a href="embedded-content-0.html#the-img-element">img</a></code>
- <code><a href="embedded-content-0.html#math">math</a></code>
- <code><a href="embedded-content-0.html#the-object-element">object</a></code>
- <code><a href="embedded-content-0.html#svg-0">svg</a></code>
- <code><a href="embedded-content-0.html#the-video-element">video</a></code>
+ <code><a href="embedded-content.html#the-audio-element">audio</a></code>;
+ <code><a href="scripting-1.html#the-canvas-element">canvas</a></code>;
+ <code><a href="embedded-content.html#the-embed-element">embed</a></code>;
+ <code><a href="embedded-content.html#the-iframe-element">iframe</a></code>;
+ <code><a href="embedded-content.html#the-img-element">img</a></code>;
+ <code><a href="embedded-content.html#math">math</a></code>;
+ <code><a href="embedded-content.html#the-object-element">object</a></code>;
+ <code><a href="embedded-content.html#svg-0">svg</a></code>;
+ <code><a href="embedded-content.html#the-video-element">video</a></code>
<td>
—
- <tr><td> <a href="dom.html#interactive-content-0">Interactive content</a>
+ <tr><td> <a href="dom.html#interactive-content-0">Interactive content</a>*
<td>
<code><a href="text-level-semantics.html#the-a-element">a</a></code>;
<code><a href="forms.html#the-button-element">button</a></code>;
<code><a href="interactive-elements.html#the-details-element">details</a></code>;
- <code><a href="embedded-content-0.html#the-embed-element">embed</a></code>;
- <code><a href="embedded-content-0.html#the-iframe-element">iframe</a></code>;
+ <code><a href="embedded-content.html#the-embed-element">embed</a></code>;
+ <code><a href="embedded-content.html#the-iframe-element">iframe</a></code>;
<code><a href="forms.html#the-keygen-element">keygen</a></code>;
<code><a href="forms.html#the-label-element">label</a></code>;
<code><a href="forms.html#the-select-element">select</a></code>;
- <code><a href="forms.html#the-textarea-element">textarea</a></code>;
+ <code><a href="forms.html#the-textarea-element">textarea</a></code>
<td>
- <code><a href="embedded-content-0.html#the-audio-element">audio</a></code> (if the <code data-anolis-xref="attr-media-controls"><a href="embedded-content-0.html#controls">controls</a></code> attribute is present);
- <code><a href="embedded-content-0.html#the-img-element">img</a></code> (if the <code data-anolis-xref="attr-hyperlink-usemap"><a href="embedded-content-0.html#usemap-1">usemap</a></code> attribute is present);
- <code><a href="forms.html#the-input-element">input</a></code> (if the <code data-anolis-xref="attr-input-type"><a href="forms.html#type-15">type</a></code> attribute is <em>not</em> in the <a data-anolis-xref="attr-input-type-hidden" href="forms.html#hidden-state-(type=hidden)">Hidden</a> state);
- <code><a href="embedded-content-0.html#the-object-element">object</a></code> (if the <code data-anolis-xref="attr-hyperlink-usemap"><a href="embedded-content-0.html#usemap-1">usemap</a></code> attribute is present)<!-- see also comment in <object> section -->;
- <code><a href="embedded-content-0.html#the-video-element">video</a></code> (if the <code data-anolis-xref="attr-media-controls"><a href="embedded-content-0.html#controls">controls</a></code> attribute is present)
-
- <tr><td> <a data-anolis-xref="sectioning root" href="sections.html#sectioning-roots">Sectioning roots</a>
+ <code><a href="embedded-content.html#the-audio-element">audio</a></code> (if the <code data-anolis-xref="attr-media-controls"><a href="embedded-content.html#attr-media-controls">controls</a></code> attribute is present);
+ <code><a href="embedded-content.html#the-img-element">img</a></code> (if the <code data-anolis-xref="attr-hyperlink-usemap"><a href="embedded-content.html#attr-hyperlink-usemap">usemap</a></code> attribute is present);
+ <code><a href="forms.html#the-input-element">input</a></code> (if the <code data-anolis-xref="attr-input-type"><a href="forms.html#attr-input-type">type</a></code> attribute is <em>not</em> in the <a data-anolis-xref="attr-input-type-hidden" href="forms.html#hidden-state-(type=hidden)">Hidden</a> state);
+ <code><a href="embedded-content.html#the-object-element">object</a></code> (if the <code data-anolis-xref="attr-hyperlink-usemap"><a href="embedded-content.html#attr-hyperlink-usemap">usemap</a></code> attribute is present)<!-- see also comment in <object> section -->;
+ <code><a href="tabular-data.html#the-th-element">th</a></code> (for <a data-anolis-xref="sorting interface th element" href="tabular-data.html#sorting-interface-th-element">sorting interface <code>th</code> elements</a>)
+ <code><a href="embedded-content.html#the-video-element">video</a></code> (if the <code data-anolis-xref="attr-media-controls"><a href="embedded-content.html#attr-media-controls">controls</a></code> attribute is present)
+
+ <tr><td> <a data-anolis-xref="sectioning root" href="sections.html#sectioning-root">Sectioning roots</a>
<td>
<code><a href="grouping-content.html#the-blockquote-element">blockquote</a></code>;
<code><a href="sections.html#the-body-element">body</a></code>;
@@ -1860,46 +1868,46 @@
<td>
—
- <tr><td> <a data-anolis-xref="form-associated element" href="forms.html#form-associated-elements">Form-associated elements</a>
+ <tr><td> <a data-anolis-xref="form-associated element" href="forms.html#form-associated-element">Form-associated elements</a>
<td>
<code><a href="forms.html#the-button-element">button</a></code>;
<code><a href="forms.html#the-fieldset-element">fieldset</a></code>;
<code><a href="forms.html#the-input-element">input</a></code>;
<code><a href="forms.html#the-keygen-element">keygen</a></code>;
<code><a href="forms.html#the-label-element">label</a></code>;
- <code><a href="embedded-content-0.html#the-object-element">object</a></code>;
+ <code><a href="embedded-content.html#the-object-element">object</a></code>;
<code><a href="forms.html#the-output-element">output</a></code>;
<code><a href="forms.html#the-select-element">select</a></code>;
<code><a href="forms.html#the-textarea-element">textarea</a></code>;
- <code><a href="embedded-content-0.html#the-img-element">img</a></code>
+ <code><a href="embedded-content.html#the-img-element">img</a></code>
<td>
—
- <tr><td> <a data-anolis-xref="category-listed" href="forms.html#listed-elements">Listed elements</a>
+ <tr><td> <a data-anolis-xref="category-listed" href="forms.html#category-listed">Listed elements</a>
<td>
<code><a href="forms.html#the-button-element">button</a></code>;
<code><a href="forms.html#the-fieldset-element">fieldset</a></code>;
<code><a href="forms.html#the-input-element">input</a></code>;
<code><a href="forms.html#the-keygen-element">keygen</a></code>;
- <code><a href="embedded-content-0.html#the-object-element">object</a></code>;
+ <code><a href="embedded-content.html#the-object-element">object</a></code>;
<code><a href="forms.html#the-output-element">output</a></code>;
<code><a href="forms.html#the-select-element">select</a></code>;
<code><a href="forms.html#the-textarea-element">textarea</a></code>
<td>
—
- <tr><td> <a data-anolis-xref="category-submit" href="forms.html#submittable-elements">Submittable elements</a>
+ <tr><td> <a data-anolis-xref="category-submit" href="forms.html#category-submit">Submittable elements</a>
<td>
<code><a href="forms.html#the-button-element">button</a></code>;
<code><a href="forms.html#the-input-element">input</a></code>;
<code><a href="forms.html#the-keygen-element">keygen</a></code>;
- <code><a href="embedded-content-0.html#the-object-element">object</a></code>;
+ <code><a href="embedded-content.html#the-object-element">object</a></code>;
<code><a href="forms.html#the-select-element">select</a></code>;
<code><a href="forms.html#the-textarea-element">textarea</a></code>
<td>
—
- <tr><td> <a data-anolis-xref="category-reset" href="forms.html#resettable-elements">Resettable elements</a>
+ <tr><td> <a data-anolis-xref="category-reset" href="forms.html#category-reset">Resettable elements</a>
<td>
<code><a href="forms.html#the-input-element">input</a></code>;
<code><a href="forms.html#the-keygen-element">keygen</a></code>;
@@ -1909,7 +1917,7 @@
<td>
—
- <tr><td> <a data-anolis-xref="category-label" href="forms.html#labelable-elements">Labelable elements</a>
+ <tr><td> <a data-anolis-xref="category-label" href="forms.html#category-label">Labelable elements</a>
<td>
<code><a href="forms.html#the-button-element">button</a></code>;
<code><a href="forms.html#the-input-element">input</a></code>;
@@ -1922,14 +1930,14 @@
<td>
—
- <tr><td> <a data-anolis-xref="category-form-attr" href="forms.html#reassociateable-elements">Reassociateable elements</a>
+ <tr><td> <a data-anolis-xref="category-form-attr" href="forms.html#category-form-attr">Reassociateable elements</a>
<td>
<code><a href="forms.html#the-button-element">button</a></code>;
<code><a href="forms.html#the-fieldset-element">fieldset</a></code>;
<code><a href="forms.html#the-input-element">input</a></code>;
<code><a href="forms.html#the-keygen-element">keygen</a></code>;
<code><a href="forms.html#the-label-element">label</a></code>;
- <code><a href="embedded-content-0.html#the-object-element">object</a></code>;
+ <code><a href="embedded-content.html#the-object-element">object</a></code>;
<code><a href="forms.html#the-output-element">output</a></code>;
<code><a href="forms.html#the-select-element">select</a></code>;
<code><a href="forms.html#the-textarea-element">textarea</a></code>
@@ -1956,7 +1964,7 @@
<code><a href="text-level-semantics.html#the-dfn-element">dfn</a></code>;
<code><a href="grouping-content.html#the-div-element">div</a></code>;
<code><a href="text-level-semantics.html#the-em-element">em</a></code>;
- <code><a href="embedded-content-0.html#the-embed-element">embed</a></code>;
+ <code><a href="embedded-content.html#the-embed-element">embed</a></code>;
<code><a href="forms.html#the-fieldset-element">fieldset</a></code>;
<code><a href="grouping-content.html#the-figure-element">figure</a></code>;
<code><a href="sections.html#the-footer-element">footer</a></code>;
@@ -1970,19 +1978,19 @@
<code><a href="sections.html#the-header-element">header</a></code>;
<!--FORK START/END hgroup removed-->
<code><a href="text-level-semantics.html#the-i-element">i</a></code>;
- <code><a href="embedded-content-0.html#the-iframe-element">iframe</a></code>;
- <code><a href="embedded-content-0.html#the-img-element">img</a></code>;
+ <code><a href="embedded-content.html#the-iframe-element">iframe</a></code>;
+ <code><a href="embedded-content.html#the-img-element">img</a></code>;
<code><a href="edits.html#the-ins-element">ins</a></code>;
<code><a href="text-level-semantics.html#the-kbd-element">kbd</a></code>;
<code><a href="forms.html#the-keygen-element">keygen</a></code>;
<code><a href="forms.html#the-label-element">label</a></code>;
<code><a href="grouping-content.html#the-main-element">main</a></code>;
- <code><a href="embedded-content-0.html#the-map-element">map</a></code>;
+ <code><a href="embedded-content.html#the-map-element">map</a></code>;
<code><a href="text-level-semantics.html#the-mark-element">mark</a></code>;
- <code><a href="embedded-content-0.html#math">math</a></code>;
+ <code><a href="embedded-content.html#math">math</a></code>;
<code><a href="forms.html#the-meter-element">meter</a></code>;
<code><a href="sections.html#the-nav-element">nav</a></code>;
- <code><a href="embedded-content-0.html#the-object-element">object</a></code>;
+ <code><a href="embedded-content.html#the-object-element">object</a></code>;
<code><a href="forms.html#the-output-element">output</a></code>;
<code><a href="grouping-content.html#the-p-element">p</a></code>;
<code><a href="grouping-content.html#the-pre-element">pre</a></code>;
@@ -1998,21 +2006,21 @@
<code><a href="text-level-semantics.html#the-strong-element">strong</a></code>;
<code><a href="text-level-semantics.html#the-sub-and-sup-elements">sub</a></code>;
<code><a href="text-level-semantics.html#the-sub-and-sup-elements">sup</a></code>;
- <code><a href="embedded-content-0.html#svg-0">svg</a></code>;
+ <code><a href="embedded-content.html#svg-0">svg</a></code>;
<code><a href="tabular-data.html#the-table-element">table</a></code>;
<code><a href="forms.html#the-textarea-element">textarea</a></code>;
<code><a href="text-level-semantics.html#the-time-element">time</a></code>;
<code><a href="text-level-semantics.html#the-u-element">u</a></code>;
<code><a href="text-level-semantics.html#the-var-element">var</a></code>;
- <code><a href="embedded-content-0.html#the-video-element">video</a></code>
+ <code><a href="embedded-content.html#the-video-element">video</a></code>
<td>
- <code><a href="embedded-content-0.html#the-audio-element">audio</a></code> (if the <code data-anolis-xref="attr-media-controls"><a href="embedded-content-0.html#controls">controls</a></code> attribute is present);
+ <code><a href="embedded-content.html#the-audio-element">audio</a></code> (if the <code data-anolis-xref="attr-media-controls"><a href="embedded-content.html#attr-media-controls">controls</a></code> attribute is present);
<code><a href="grouping-content.html#the-dl-element">dl</a></code> (if the element's children include at least one name-value group);
- <code><a href="forms.html#the-input-element">input</a></code> (if the <code data-anolis-xref="attr-input-type"><a href="forms.html#type-15">type</a></code> attribute is <em>not</em> in the <a data-anolis-xref="attr-input-type-hidden" href="forms.html#hidden-state-(type=hidden)">Hidden</a> state);
- <code><a href="interactive-elements.html#the-menu-element">menu</a></code> (if the <code data-anolis-xref="attr-menu-type"><a href="interactive-elements.html#type-24">type</a></code> attribute is in the <a data-anolis-xref="toolbar state" href="interactive-elements.html#toolbar">toolbar</a> state);
+ <code><a href="forms.html#the-input-element">input</a></code> (if the <code data-anolis-xref="attr-input-type"><a href="forms.html#attr-input-type">type</a></code> attribute is <em>not</em> in the <a data-anolis-xref="attr-input-type-hidden" href="forms.html#hidden-state-(type=hidden)">Hidden</a> state);
+ <code><a href="interactive-elements.html#the-menu-element">menu</a></code> (if the <code data-anolis-xref="attr-menu-type"><a href="interactive-elements.html#attr-menu-type">type</a></code> attribute is in the <a data-anolis-xref="toolbar state" href="interactive-elements.html#toolbar-state">toolbar</a> state);
<code><a href="grouping-content.html#the-ol-element">ol</a></code> (if the element's children include at least one <code><a href="grouping-content.html#the-li-element">li</a></code> element);
<code><a href="grouping-content.html#the-ul-element">ul</a></code> (if the element's children include at least one <code><a href="grouping-content.html#the-li-element">li</a></code> element);
- <a data-anolis-xref="text content" href="dom.html#text-1">Text</a> that is not <a href="dom.html#inter-element-whitespace">inter-element whitespace</a>
+ <a data-anolis-xref="text content" href="dom.html#text-content">Text</a> that is not <a href="dom.html#inter-element-whitespace">inter-element whitespace</a>
<tr><td> <a href="dom.html#script-supporting-elements-0">Script-supporting elements</a>
<td>
@@ -2021,97 +2029,103 @@
<td>
—
- </table><h3 class="no-num" id="attributes-1">Attributes</h3>
+ </table><p class="tablenote"><small>* The <code data-anolis-xref="attr-tabindex"><a href="editing.html#attr-tabindex">tabindex</a></code> attribute can also
+ make any element into <a href="dom.html#interactive-content-0">interactive content</a>.</small></p>
+
+
+
+ <h3 class="no-num" id="attributes-1">Attributes</h3>
<p><i>This section is non-normative.</i></p>
+
<table><caption>List of attributes (excluding event handler content attributes)</caption>
<thead><tr><th> Attribute
<th> Element(s)
<th> Description
<th> Value
<tbody><tr><th> <code data-anolis-xref="">abbr</code>
- <td> <code data-anolis-xref="attr-th-abbr"><a href="tabular-data.html#abbr">th</a></code>
+ <td> <code data-anolis-xref="attr-th-abbr"><a href="tabular-data.html#attr-th-abbr">th</a></code>
<td> Alternative label to use for the header cell when referencing the cell in other contexts
<td> <a href="dom.html#attribute-text">Text</a>*
<tr><th> <code data-anolis-xref="">accept</code>
- <td> <code data-anolis-xref="attr-input-accept"><a href="forms.html#accept-0">input</a></code>
+ <td> <code data-anolis-xref="attr-input-accept"><a href="forms.html#attr-input-accept">input</a></code>
<td> Hint for expected file type in <a data-anolis-xref="attr-input-type-file" href="forms.html#file-upload-state-(type=file)">file upload controls</a>
<td> <a href="infrastructure.html#set-of-comma-separated-tokens">Set of comma-separated tokens</a>* consisting of <a data-anolis-xref="valid MIME type" href="infrastructure.html#valid-mime-type">valid MIME types with no parameters</a> or <code data-anolis-xref="">audio/*</code>, <code data-anolis-xref="">video/*</code>, or <code data-anolis-xref="">image/*</code>
<tr><th> <code data-anolis-xref="">accept-charset</code>
- <td> <code data-anolis-xref="attr-form-accept-charset"><a href="forms.html#accept-charset">form</a></code>
+ <td> <code data-anolis-xref="attr-form-accept-charset"><a href="forms.html#attr-form-accept-charset">form</a></code>
<td> Character encodings to use for <a href="forms.html#form-submission-0">form submission</a>
- <td> <a href="infrastructure.html#ordered-set-of-unique-space-separated-tokens">Ordered set of unique space-separated tokens</a>, <a href="infrastructure.html#ascii-case-insensitive">ASCII case-insensitive</a>, consisting of <a data-anolis-xref="encoding label" href="infrastructure.html#encoding-labels">labels</a> of <a data-anolis-xref="ASCII-compatible character encoding" href="infrastructure.html#ascii-compatible-character-encoding">ASCII-compatible character encodings</a>*
+ <td> <a href="infrastructure.html#ordered-set-of-unique-space-separated-tokens">Ordered set of unique space-separated tokens</a>, <a href="infrastructure.html#ascii-case-insensitive">ASCII case-insensitive</a>, consisting of <a data-anolis-xref="encoding label" href="infrastructure.html#encoding-label">labels</a> of <a data-anolis-xref="ASCII-compatible character encoding" href="infrastructure.html#ascii-compatible-character-encoding">ASCII-compatible character encodings</a>*
<tr><th> <code data-anolis-xref="">accesskey</code>
<td> <a data-anolis-xref="attr-accesskey" href="editing.html#the-accesskey-attribute">HTML elements</a>
<td> Keyboard shortcut to activate or focus element
<td> <a href="infrastructure.html#ordered-set-of-unique-space-separated-tokens">Ordered set of unique space-separated tokens</a>, <a href="infrastructure.html#case-sensitive">case-sensitive</a>, consisting of one Unicode code point in length
<tr><th> <code data-anolis-xref="">action</code>
- <td> <code data-anolis-xref="attr-fs-action"><a href="forms.html#action">form</a></code>
+ <td> <code data-anolis-xref="attr-fs-action"><a href="forms.html#attr-fs-action">form</a></code>
<td> <a href="infrastructure.html#url">URL</a> to use for <a href="forms.html#form-submission-0">form submission</a>
<td> <a href="infrastructure.html#valid-non-empty-url-potentially-surrounded-by-spaces">Valid non-empty URL potentially surrounded by spaces</a>
<tr><th> <code data-anolis-xref="">allowfullscreen</code>
- <td> <code data-anolis-xref="attr-iframe-allowfullscreen"><a href="embedded-content-0.html#allowfullscreen">iframe</a></code>
- <td> Whether to allow the <code><a href="embedded-content-0.html#the-iframe-element">iframe</a></code>'s contents to use <code data-anolis-xref="dom-element-requestFullscreen"><a href="infrastructure.html#requestfullscreen()">requestFullscreen()</a></code>
- <td> <a href="infrastructure.html#boolean-attributes-0">Boolean attribute</a>
+ <td> <code data-anolis-xref="attr-iframe-allowfullscreen"><a href="embedded-content.html#attr-iframe-allowfullscreen">iframe</a></code>
+ <td> Whether to allow the <code><a href="embedded-content.html#the-iframe-element">iframe</a></code>'s contents to use <code data-anolis-xref="dom-element-requestFullscreen"><a href="infrastructure.html#dom-element-requestfullscreen">requestFullscreen()</a></code>
+ <td> <a href="infrastructure.html#boolean-attribute">Boolean attribute</a>
<tr><th> <code data-anolis-xref="">alt</code>
- <td> <code data-anolis-xref="attr-area-alt"><a href="embedded-content-0.html#alt-2">area</a></code>;
- <code data-anolis-xref="attr-img-alt"><a href="embedded-content-0.html#alt-0">img</a></code>;
- <code data-anolis-xref="attr-input-alt"><a href="forms.html#alt-5">input</a></code>
+ <td> <code data-anolis-xref="attr-area-alt"><a href="embedded-content.html#attr-area-alt">area</a></code>;
+ <code data-anolis-xref="attr-img-alt"><a href="embedded-content.html#attr-img-alt">img</a></code>;
+ <code data-anolis-xref="attr-input-alt"><a href="forms.html#attr-input-alt">input</a></code>
<td> Replacement text for use when images are not available
<td> <a href="dom.html#attribute-text">Text</a>*
<tr><th> <code data-anolis-xref="">async</code>
- <td> <code data-anolis-xref="attr-script-async"><a href="scripting-1.html#async">script</a></code>
+ <td> <code data-anolis-xref="attr-script-async"><a href="scripting-1.html#attr-script-async">script</a></code>
<td> Execute script asynchronously
- <td> <a href="infrastructure.html#boolean-attributes-0">Boolean attribute</a>
+ <td> <a href="infrastructure.html#boolean-attribute">Boolean attribute</a>
<tr><th> <code data-anolis-xref="">autocomplete</code>
- <td> <code data-anolis-xref="attr-form-autocomplete"><a href="forms.html#autocomplete">form</a></code>
+ <td> <code data-anolis-xref="attr-form-autocomplete"><a href="forms.html#attr-form-autocomplete">form</a></code>
<td> Default setting for autofill feature for controls in the form
<td> "<code data-anolis-xref="">on</code>"; "<code data-anolis-xref="">off</code>"
<tr><th> <code data-anolis-xref="">autocomplete</code>
- <td> <code data-anolis-xref="attr-fe-autocomplete"><a href="forms.html#autocomplete-1">input</a></code>;
- <code data-anolis-xref="attr-fe-autocomplete"><a href="forms.html#autocomplete-1">select</a></code>;
- <code data-anolis-xref="attr-fe-autocomplete"><a href="forms.html#autocomplete-1">textarea</a></code>
+ <td> <code data-anolis-xref="attr-fe-autocomplete"><a href="forms.html#attr-fe-autocomplete">input</a></code>;
+ <code data-anolis-xref="attr-fe-autocomplete"><a href="forms.html#attr-fe-autocomplete">select</a></code>;
+ <code data-anolis-xref="attr-fe-autocomplete"><a href="forms.html#attr-fe-autocomplete">textarea</a></code>
<td> Hint for form autofill feature
- <td> <a data-anolis-xref="autofill field" href="forms.html#autofill-fields">Autofill field</a> name and related tokens*
+ <td> <a data-anolis-xref="autofill field" href="forms.html#autofill-field">Autofill field</a> name and related tokens*
<tr><th> <code data-anolis-xref="">autofocus</code>
- <td> <code data-anolis-xref="attr-fe-autofocus"><a href="forms.html#autofocus">button</a></code>;
- <code data-anolis-xref="attr-fe-autofocus"><a href="forms.html#autofocus">input</a></code>;
- <code data-anolis-xref="attr-fe-autofocus"><a href="forms.html#autofocus">keygen</a></code>;
- <code data-anolis-xref="attr-fe-autofocus"><a href="forms.html#autofocus">select</a></code>;
- <code data-anolis-xref="attr-fe-autofocus"><a href="forms.html#autofocus">textarea</a></code>
+ <td> <code data-anolis-xref="attr-fe-autofocus"><a href="forms.html#attr-fe-autofocus">button</a></code>;
+ <code data-anolis-xref="attr-fe-autofocus"><a href="forms.html#attr-fe-autofocus">input</a></code>;
+ <code data-anolis-xref="attr-fe-autofocus"><a href="forms.html#attr-fe-autofocus">keygen</a></code>;
+ <code data-anolis-xref="attr-fe-autofocus"><a href="forms.html#attr-fe-autofocus">select</a></code>;
+ <code data-anolis-xref="attr-fe-autofocus"><a href="forms.html#attr-fe-autofocus">textarea</a></code>
<td> Automatically focus the form control when the page is loaded
- <td> <a href="infrastructure.html#boolean-attributes-0">Boolean attribute</a>
+ <td> <a href="infrastructure.html#boolean-attribute">Boolean attribute</a>
<tr><th> <code data-anolis-xref="">autoplay</code>
- <td> <code data-anolis-xref="attr-media-autoplay"><a href="embedded-content-0.html#autoplay">audio</a></code>;
- <code data-anolis-xref="attr-media-autoplay"><a href="embedded-content-0.html#autoplay">video</a></code>
- <td> Hint that the <a href="embedded-content-0.html#media-resource">media resource</a> can be started automatically when the page is loaded
- <td> <a href="infrastructure.html#boolean-attributes-0">Boolean attribute</a>
+ <td> <code data-anolis-xref="attr-media-autoplay"><a href="embedded-content.html#attr-media-autoplay">audio</a></code>;
+ <code data-anolis-xref="attr-media-autoplay"><a href="embedded-content.html#attr-media-autoplay">video</a></code>
+ <td> Hint that the <a href="embedded-content.html#media-resource">media resource</a> can be started automatically when the page is loaded
+ <td> <a href="infrastructure.html#boolean-attribute">Boolean attribute</a>
<tr><th> <code data-anolis-xref="">border</code>
- <td> <code data-anolis-xref="attr-table-border"><a href="tabular-data.html#border">table</a></code>
+ <td> <code data-anolis-xref="attr-table-border"><a href="tabular-data.html#attr-table-border">table</a></code>
<td> Explicit indication that the <code><a href="tabular-data.html#the-table-element">table</a></code> element is not being used for layout purposes
<td> The empty string, or "<code data-anolis-xref="">1</code>"
<tr><th> <code data-anolis-xref="">challenge</code>
- <td> <code data-anolis-xref="attr-keygen-challenge"><a href="forms.html#challenge">keygen</a></code>
+ <td> <code data-anolis-xref="attr-keygen-challenge"><a href="forms.html#attr-keygen-challenge">keygen</a></code>
<td> String to package with the generated and signed public key
<td> <a href="dom.html#attribute-text">Text</a>
<tr><th> <code data-anolis-xref="">charset</code>
- <td> <code data-anolis-xref="attr-meta-charset"><a href="document-metadata.html#charset-0">meta</a></code>
+ <td> <code data-anolis-xref="attr-meta-charset"><a href="document-metadata.html#attr-meta-charset">meta</a></code>
<td> <a href="document-metadata.html#character-encoding-declaration">Character encoding declaration</a>
- <td> <a href="infrastructure.html#encoding-labels">Encoding label</a>*
+ <td> <a href="infrastructure.html#encoding-label">Encoding label</a>*
<tr><th> <code data-anolis-xref="">charset</code>
- <td> <code data-anolis-xref="attr-script-charset"><a href="scripting-1.html#charset-1">script</a></code>
+ <td> <code data-anolis-xref="attr-script-charset"><a href="scripting-1.html#attr-script-charset">script</a></code>
<td> Character encoding of the external script resource
- <td> <a href="infrastructure.html#encoding-labels">Encoding label</a>*
+ <td> <a href="infrastructure.html#encoding-label">Encoding label</a>*
<tr><th> <code data-anolis-xref="">checked</code>
- <td> <code data-anolis-xref="attr-menuitem-checked"><a href="interactive-elements.html#checked-1">menuitem</a></code>;
- <code data-anolis-xref="attr-input-checked"><a href="forms.html#checked">input</a></code>
+ <td> <code data-anolis-xref="attr-menuitem-checked"><a href="interactive-elements.html#attr-menuitem-checked">menuitem</a></code>;
+ <code data-anolis-xref="attr-input-checked"><a href="forms.html#attr-input-checked">input</a></code>
<td> Whether the command or control is checked
- <td> <a href="infrastructure.html#boolean-attributes-0">Boolean attribute</a>
+ <td> <a href="infrastructure.html#boolean-attribute">Boolean attribute</a>
<tr><th> <code data-anolis-xref="">cite</code>
- <td> <code data-anolis-xref="attr-blockquote-cite"><a href="grouping-content.html#cite">blockquote</a></code>;
- <code data-anolis-xref="attr-mod-cite"><a href="edits.html#cite-2">del</a></code>;
- <code data-anolis-xref="attr-mod-cite"><a href="edits.html#cite-2">ins</a></code>;
- <code data-anolis-xref="attr-q-cite"><a href="text-level-semantics.html#cite-1">q</a></code>
+ <td> <code data-anolis-xref="attr-blockquote-cite"><a href="grouping-content.html#attr-blockquote-cite">blockquote</a></code>;
+ <code data-anolis-xref="attr-mod-cite"><a href="edits.html#attr-mod-cite">del</a></code>;
+ <code data-anolis-xref="attr-mod-cite"><a href="edits.html#attr-mod-cite">ins</a></code>;
+ <code data-anolis-xref="attr-q-cite"><a href="text-level-semantics.html#attr-q-cite">q</a></code>
<td> Link to the source of the quotation or more information about the edit
<td> <a href="infrastructure.html#valid-url-potentially-surrounded-by-spaces">Valid URL potentially surrounded by spaces</a>
<tr><th> <code data-anolis-xref="">class</code>
@@ -2119,109 +2133,109 @@
<td> Classes to which the element belongs
<td> <a href="infrastructure.html#set-of-space-separated-tokens">Set of space-separated tokens</a>
<tr><th> <code data-anolis-xref="">cols</code>
- <td> <code data-anolis-xref="attr-textarea-cols"><a href="forms.html#cols">textarea</a></code>
+ <td> <code data-anolis-xref="attr-textarea-cols"><a href="forms.html#attr-textarea-cols">textarea</a></code>
<td> Maximum number of characters per line
<td> <a href="infrastructure.html#valid-non-negative-integer">Valid non-negative integer</a> greater than zero
<tr><th> <code data-anolis-xref="">colspan</code>
- <td> <code data-anolis-xref="attr-tdth-colspan"><a href="tabular-data.html#colspan">td</a></code>;
- <code data-anolis-xref="attr-tdth-colspan"><a href="tabular-data.html#colspan">th</a></code>
+ <td> <code data-anolis-xref="attr-tdth-colspan"><a href="tabular-data.html#attr-tdth-colspan">td</a></code>;
+ <code data-anolis-xref="attr-tdth-colspan"><a href="tabular-data.html#attr-tdth-colspan">th</a></code>
<td> Number of columns that the cell is to span
<td> <a href="infrastructure.html#valid-non-negative-integer">Valid non-negative integer</a> greater than zero
<tr><th> <code data-anolis-xref="">command</code>
- <td> <code data-anolis-xref="attr-menuitem-command"><a href="interactive-elements.html#command-1">menuitem</a></code>
+ <td> <code data-anolis-xref="attr-menuitem-command"><a href="interactive-elements.html#attr-menuitem-command">menuitem</a></code>
<td> Command definition
- <td> <a data-anolis-xref="concept-id" href="infrastructure.html#unique-identifier-(id)">ID</a>*
+ <td> <a data-anolis-xref="concept-id" href="infrastructure.html#concept-id">ID</a>*
<tr><th> <code data-anolis-xref="">content</code>
- <td> <code data-anolis-xref="attr-meta-content"><a href="document-metadata.html#content">meta</a></code>
+ <td> <code data-anolis-xref="attr-meta-content"><a href="document-metadata.html#attr-meta-content">meta</a></code>
<td> Value of the element
<td> <a href="dom.html#attribute-text">Text</a>*
<tr><th> <code data-anolis-xref="">contenteditable</code>
- <td> <a data-anolis-xref="attr-contenteditable" href="editing.html#contenteditable-0">HTML elements</a>
+ <td> <a data-anolis-xref="attr-contenteditable" href="editing.html#attr-contenteditable">HTML elements</a>
<td> Whether the element is editable
<td> "<code data-anolis-xref="">true</code>"; "<code data-anolis-xref="">false</code>"
<tr><th> <code data-anolis-xref="">contextmenu</code>
- <td> <a data-anolis-xref="attr-contextmenu" href="interactive-elements.html#contextmenu">HTML elements</a>
+ <td> <a data-anolis-xref="attr-contextmenu" href="interactive-elements.html#attr-contextmenu">HTML elements</a>
<td> The element's context menu
- <td> <a data-anolis-xref="concept-id" href="infrastructure.html#unique-identifier-(id)">ID</a>*
+ <td> <a data-anolis-xref="concept-id" href="infrastructure.html#concept-id">ID</a>*
<tr><th> <code data-anolis-xref="">controls</code>
- <td> <code data-anolis-xref="attr-media-controls"><a href="embedded-content-0.html#controls">audio</a></code>;
- <code data-anolis-xref="attr-media-controls"><a href="embedded-content-0.html#controls">video</a></code>
+ <td> <code data-anolis-xref="attr-media-controls"><a href="embedded-content.html#attr-media-controls">audio</a></code>;
+ <code data-anolis-xref="attr-media-controls"><a href="embedded-content.html#attr-media-controls">video</a></code>
<td> Show user agent controls
- <td> <a href="infrastructure.html#boolean-attributes-0">Boolean attribute</a>
+ <td> <a href="infrastructure.html#boolean-attribute">Boolean attribute</a>
<tr><th> <code data-anolis-xref="">coords</code>
- <td> <code data-anolis-xref="attr-area-coords"><a href="embedded-content-0.html#coords">area</a></code>
- <td> Coordinates for the shape to be created in an <a href="embedded-content-0.html#image-map">image map</a>
+ <td> <code data-anolis-xref="attr-area-coords"><a href="embedded-content.html#attr-area-coords">area</a></code>
+ <td> Coordinates for the shape to be created in an <a href="embedded-content.html#image-map">image map</a>
<td> <a href="infrastructure.html#valid-list-of-integers">Valid list of integers</a>*
<tr><th> <code data-anolis-xref="">crossorigin</code>
- <td> <code data-anolis-xref="attr-media-crossorigin"><a href="embedded-content-0.html#crossorigin-3">audio</a></code>;
- <code data-anolis-xref="attr-img-crossorigin"><a href="embedded-content-0.html#crossorigin-1">img</a></code>;
- <code data-anolis-xref="attr-link-crossorigin"><a href="document-metadata.html#crossorigin">link</a></code>;
- <code data-anolis-xref="attr-script-crossorigin"><a href="scripting-1.html#crossorigin-5">script</a></code>;
- <code data-anolis-xref="attr-media-crossorigin"><a href="embedded-content-0.html#crossorigin-3">video</a></code>
+ <td> <code data-anolis-xref="attr-media-crossorigin"><a href="embedded-content.html#attr-media-crossorigin">audio</a></code>;
+ <code data-anolis-xref="attr-img-crossorigin"><a href="embedded-content.html#attr-img-crossorigin">img</a></code>;
+ <code data-anolis-xref="attr-link-crossorigin"><a href="document-metadata.html#attr-link-crossorigin">link</a></code>;
+ <code data-anolis-xref="attr-script-crossorigin"><a href="scripting-1.html#attr-script-crossorigin">script</a></code>;
+ <code data-anolis-xref="attr-media-crossorigin"><a href="embedded-content.html#attr-media-crossorigin">video</a></code>
<td> How the element handles crossorigin requests
- <td> "<code data-anolis-xref="attr-crossorigin-anonymous-keyword"><a href="infrastructure.html#anonymous">anonymous</a></code>"; "<code data-anolis-xref="attr-crossorigin-use-credentials-keyword"><a href="infrastructure.html#use-credentials">use-credentials</a></code>"
+ <td> "<code data-anolis-xref="attr-crossorigin-anonymous-keyword"><a href="infrastructure.html#attr-crossorigin-anonymous-keyword">anonymous</a></code>"; "<code data-anolis-xref="attr-crossorigin-use-credentials-keyword"><a href="infrastructure.html#attr-crossorigin-use-credentials-keyword">use-credentials</a></code>"
<tr><th> <code data-anolis-xref="">data</code>
- <td> <code data-anolis-xref="attr-object-data"><a href="embedded-content-0.html#data-1">object</a></code>
+ <td> <code data-anolis-xref="attr-object-data"><a href="embedded-content.html#attr-object-data">object</a></code>
<td> Address of the resource
<td> <a href="infrastructure.html#valid-non-empty-url-potentially-surrounded-by-spaces">Valid non-empty URL potentially surrounded by spaces</a>
<tr><th> <code data-anolis-xref="">datetime</code>
- <td> <code data-anolis-xref="attr-mod-datetime"><a href="edits.html#datetime-1">del</a></code>;
- <code data-anolis-xref="attr-mod-datetime"><a href="edits.html#datetime-1">ins</a></code>
+ <td> <code data-anolis-xref="attr-mod-datetime"><a href="edits.html#attr-mod-datetime">del</a></code>;
+ <code data-anolis-xref="attr-mod-datetime"><a href="edits.html#attr-mod-datetime">ins</a></code>
<td> Date and (optionally) time of the change
<td> <a href="infrastructure.html#valid-date-string-with-optional-time">Valid date string with optional time</a>
<tr><th> <code data-anolis-xref="">datetime</code>
- <td> <code data-anolis-xref="attr-time-datetime"><a href="text-level-semantics.html#datetime">time</a></code>
+ <td> <code data-anolis-xref="attr-time-datetime"><a href="text-level-semantics.html#attr-time-datetime">time</a></code>
<td> Machine-readable value
<td> <a href="infrastructure.html#valid-month-string">Valid month string</a>,
<a href="infrastructure.html#valid-date-string">valid date string</a>,
<a href="infrastructure.html#valid-yearless-date-string">valid yearless date string</a>,
<a href="infrastructure.html#valid-time-string">valid time string</a>,
- <a href="infrastructure.html#valid-local-date-and-time-string">valid local date and time string</a>,
+ <a href="infrastructure.html#valid-floating-date-and-time-string">valid floating date and time string</a>,
<a href="infrastructure.html#valid-time-zone-offset-string">valid time-zone offset string</a>,
<a href="infrastructure.html#valid-global-date-and-time-string">valid global date and time string</a>,
<a href="infrastructure.html#valid-week-string">valid week string</a>,
<a href="infrastructure.html#valid-non-negative-integer">valid non-negative integer</a>, or
<a href="infrastructure.html#valid-duration-string">valid duration string</a>
<tr><th> <code data-anolis-xref="">default</code>
- <td> <code data-anolis-xref="attr-menuitem-default"><a href="interactive-elements.html#default-4">menuitem</a></code>
+ <td> <code data-anolis-xref="attr-menuitem-default"><a href="interactive-elements.html#attr-menuitem-default">menuitem</a></code>
<td> Mark the command as being a default command
- <td> <a href="infrastructure.html#boolean-attributes-0">Boolean attribute</a>
+ <td> <a href="infrastructure.html#boolean-attribute">Boolean attribute</a>
<tr><th> <code data-anolis-xref="">default</code>
- <td> <code data-anolis-xref="attr-track-default"><a href="embedded-content-0.html#default">track</a></code>
- <td> Enable the track if no other <a href="embedded-content-0.html#text-tracks">text track</a> is more suitable
- <td> <a href="infrastructure.html#boolean-attributes-0">Boolean attribute</a>
+ <td> <code data-anolis-xref="attr-track-default"><a href="embedded-content.html#attr-track-default">track</a></code>
+ <td> Enable the track if no other <a href="embedded-content.html#text-track">text track</a> is more suitable
+ <td> <a href="infrastructure.html#boolean-attribute">Boolean attribute</a>
<tr><th> <code data-anolis-xref="">defer</code>
- <td> <code data-anolis-xref="attr-script-defer"><a href="scripting-1.html#defer">script</a></code>
+ <td> <code data-anolis-xref="attr-script-defer"><a href="scripting-1.html#attr-script-defer">script</a></code>
<td> Defer script execution
- <td> <a href="infrastructure.html#boolean-attributes-0">Boolean attribute</a>
+ <td> <a href="infrastructure.html#boolean-attribute">Boolean attribute</a>
<tr><th> <code data-anolis-xref="">dir</code>
<td> <a data-anolis-xref="attr-dir" href="dom.html#the-dir-attribute">HTML elements</a>
<td> <a data-anolis-xref="the directionality" href="dom.html#the-directionality">The text directionality</a> of the element
- <td> "<code data-anolis-xref="attr-dir-ltr"><a href="dom.html#ltr">ltr</a></code>"; "<code data-anolis-xref="attr-dir-rtl"><a href="dom.html#rtl">rtl</a></code>"; "<code data-anolis-xref="attr-dir-auto"><a href="dom.html#auto">auto</a></code>"
+ <td> "<code data-anolis-xref="attr-dir-ltr"><a href="dom.html#attr-dir-ltr">ltr</a></code>"; "<code data-anolis-xref="attr-dir-rtl"><a href="dom.html#attr-dir-rtl">rtl</a></code>"; "<code data-anolis-xref="attr-dir-auto"><a href="dom.html#attr-dir-auto">auto</a></code>"
<tr><th> <code data-anolis-xref="">dir</code>
<td> <code><a href="text-level-semantics.html#the-bdo-element">bdo</a></code>
<td> <a data-anolis-xref="the directionality" href="dom.html#the-directionality">The text directionality</a> of the element
- <td> "<code data-anolis-xref="attr-dir-ltr"><a href="dom.html#ltr">ltr</a></code>"; "<code data-anolis-xref="attr-dir-rtl"><a href="dom.html#rtl">rtl</a></code>"
+ <td> "<code data-anolis-xref="attr-dir-ltr"><a href="dom.html#attr-dir-ltr">ltr</a></code>"; "<code data-anolis-xref="attr-dir-rtl"><a href="dom.html#attr-dir-rtl">rtl</a></code>"
<tr><th> <code data-anolis-xref="">dirname</code>
- <td> <code data-anolis-xref="attr-fe-dirname"><a href="forms.html#dirname-1">input</a></code>;
- <code data-anolis-xref="attr-fe-dirname"><a href="forms.html#dirname-1">textarea</a></code>
+ <td> <code data-anolis-xref="attr-fe-dirname"><a href="forms.html#attr-fe-dirname">input</a></code>;
+ <code data-anolis-xref="attr-fe-dirname"><a href="forms.html#attr-fe-dirname">textarea</a></code>
<td> Name of form field to use for sending the element's <a data-anolis-xref="the directionality" href="dom.html#the-directionality">directionality</a> in <a href="forms.html#form-submission-0">form submission</a>
<td> <a href="dom.html#attribute-text">Text</a>*
<tr><th> <code data-anolis-xref="">disabled</code>
- <td> <code data-anolis-xref="attr-fe-disabled"><a href="forms.html#disabled-12">button</a></code>;
- <code data-anolis-xref="attr-menuitem-disabled"><a href="interactive-elements.html#disabled-15">menuitem</a></code>;
- <code data-anolis-xref="attr-fieldset-disabled"><a href="forms.html#disabled-10">fieldset</a></code>;
- <code data-anolis-xref="attr-fe-disabled"><a href="forms.html#disabled-12">input</a></code>;
- <code data-anolis-xref="attr-fe-disabled"><a href="forms.html#disabled-12">keygen</a></code>;
- <code data-anolis-xref="attr-optgroup-disabled"><a href="forms.html#disabled-5">optgroup</a></code>;
- <code data-anolis-xref="attr-option-disabled"><a href="forms.html#disabled-7">option</a></code>;
- <code data-anolis-xref="attr-fe-disabled"><a href="forms.html#disabled-12">select</a></code>;
- <code data-anolis-xref="attr-fe-disabled"><a href="forms.html#disabled-12">textarea</a></code>
+ <td> <code data-anolis-xref="attr-fe-disabled"><a href="forms.html#attr-fe-disabled">button</a></code>;
+ <code data-anolis-xref="attr-menuitem-disabled"><a href="interactive-elements.html#attr-menuitem-disabled">menuitem</a></code>;
+ <code data-anolis-xref="attr-fieldset-disabled"><a href="forms.html#attr-fieldset-disabled">fieldset</a></code>;
+ <code data-anolis-xref="attr-fe-disabled"><a href="forms.html#attr-fe-disabled">input</a></code>;
+ <code data-anolis-xref="attr-fe-disabled"><a href="forms.html#attr-fe-disabled">keygen</a></code>;
+ <code data-anolis-xref="attr-optgroup-disabled"><a href="forms.html#attr-optgroup-disabled">optgroup</a></code>;
+ <code data-anolis-xref="attr-option-disabled"><a href="forms.html#attr-option-disabled">option</a></code>;
+ <code data-anolis-xref="attr-fe-disabled"><a href="forms.html#attr-fe-disabled">select</a></code>;
+ <code data-anolis-xref="attr-fe-disabled"><a href="forms.html#attr-fe-disabled">textarea</a></code>
<td> Whether the form control is disabled
- <td> <a href="infrastructure.html#boolean-attributes-0">Boolean attribute</a>
+ <td> <a href="infrastructure.html#boolean-attribute">Boolean attribute</a>
<tr><th> <code data-anolis-xref="">download</code>
- <td> <code data-anolis-xref="attr-hyperlink-download"><a href="links.html#download-1">a</a></code>;
- <code data-anolis-xref="attr-hyperlink-download"><a href="links.html#download-1">area</a></code>
+ <td> <code data-anolis-xref="attr-hyperlink-download"><a href="links.html#attr-hyperlink-download">a</a></code>;
+ <code data-anolis-xref="attr-hyperlink-download"><a href="links.html#attr-hyperlink-download">area</a></code>
<td> Whether to download the resource instead of navigating to it, and its file name if so
<td> Text
<tr><th> <code data-anolis-xref="">draggable</code>
@@ -2233,132 +2247,129 @@
<td> Accepted item types for drag-and-drop
<td> <a href="infrastructure.html#unordered-set-of-unique-space-separated-tokens">Unordered set of unique space-separated tokens</a>, <a href="infrastructure.html#ascii-case-insensitive">ASCII case-insensitive</a>, consisting of accepted types and drag feedback*
<tr><th> <code data-anolis-xref="">enctype</code>
- <td> <code data-anolis-xref="attr-fs-enctype"><a href="forms.html#enctype">form</a></code>
+ <td> <code data-anolis-xref="attr-fs-enctype"><a href="forms.html#attr-fs-enctype">form</a></code>
<td> Form data set encoding type to use for <a href="forms.html#form-submission-0">form submission</a>
- <td> "<code data-anolis-xref="attr-fs-enctype-urlencoded"><a href="forms.html#application/x-www-form-urlencoded-0">application/x-www-form-urlencoded</a></code>"; "<code data-anolis-xref="attr-fs-enctype-formdata"><a href="forms.html#multipart/form-data">multipart/form-data</a></code>"; "<code data-anolis-xref="attr-fs-enctype-text"><a href="forms.html#text/plain">text/plain</a></code>"
+ <td> "<code data-anolis-xref="attr-fs-enctype-urlencoded"><a href="forms.html#attr-fs-enctype-urlencoded">application/x-www-form-urlencoded</a></code>"; "<code data-anolis-xref="attr-fs-enctype-formdata"><a href="forms.html#attr-fs-enctype-formdata">multipart/form-data</a></code>"; "<code data-anolis-xref="attr-fs-enctype-text"><a href="forms.html#attr-fs-enctype-text">text/plain</a></code>"
<tr><th> <code data-anolis-xref="">for</code>
- <td> <code data-anolis-xref="attr-label-for"><a href="forms.html#for">label</a></code>
+ <td> <code data-anolis-xref="attr-label-for"><a href="forms.html#attr-label-for">label</a></code>
<td> Associate the label with form control
- <td> <a data-anolis-xref="concept-id" href="infrastructure.html#unique-identifier-(id)">ID</a>*
+ <td> <a data-anolis-xref="concept-id" href="infrastructure.html#concept-id">ID</a>*
<tr><th> <code data-anolis-xref="">for</code>
- <td> <code data-anolis-xref="attr-output-for"><a href="forms.html#for-0">output</a></code>
+ <td> <code data-anolis-xref="attr-output-for"><a href="forms.html#attr-output-for">output</a></code>
<td> Specifies controls from which the output was calculated
<td> <a href="infrastructure.html#unordered-set-of-unique-space-separated-tokens">Unordered set of unique space-separated tokens</a>, <a href="infrastructure.html#case-sensitive">case-sensitive</a>, consisting of IDs*
<tr><th> <code data-anolis-xref="">form</code>
- <td> <code data-anolis-xref="attr-fae-form"><a href="forms.html#form-1">button</a></code>;
- <code data-anolis-xref="attr-fae-form"><a href="forms.html#form-1">fieldset</a></code>;
- <code data-anolis-xref="attr-fae-form"><a href="forms.html#form-1">input</a></code>;
- <code data-anolis-xref="attr-fae-form"><a href="forms.html#form-1">keygen</a></code>;
- <code data-anolis-xref="attr-fae-form"><a href="forms.html#form-1">label</a></code>;
- <code data-anolis-xref="attr-fae-form"><a href="forms.html#form-1">object</a></code>;
- <code data-anolis-xref="attr-fae-form"><a href="forms.html#form-1">output</a></code>;
- <code data-anolis-xref="attr-fae-form"><a href="forms.html#form-1">select</a></code>;
- <code data-anolis-xref="attr-fae-form"><a href="forms.html#form-1">textarea</a></code>
+ <td> <code data-anolis-xref="attr-fae-form"><a href="forms.html#attr-fae-form">button</a></code>;
+ <code data-anolis-xref="attr-fae-form"><a href="forms.html#attr-fae-form">fieldset</a></code>;
+ <code data-anolis-xref="attr-fae-form"><a href="forms.html#attr-fae-form">input</a></code>;
+ <code data-anolis-xref="attr-fae-form"><a href="forms.html#attr-fae-form">keygen</a></code>;
+ <code data-anolis-xref="attr-fae-form"><a href="forms.html#attr-fae-form">label</a></code>;
+ <code data-anolis-xref="attr-fae-form"><a href="forms.html#attr-fae-form">object</a></code>;
+ <code data-anolis-xref="attr-fae-form"><a href="forms.html#attr-fae-form">output</a></code>;
+ <code data-anolis-xref="attr-fae-form"><a href="forms.html#attr-fae-form">select</a></code>;
+ <code data-anolis-xref="attr-fae-form"><a href="forms.html#attr-fae-form">textarea</a></code>
<td> Associates the control with a <code><a href="forms.html#the-form-element">form</a></code> element
- <td> <a data-anolis-xref="concept-id" href="infrastructure.html#unique-identifier-(id)">ID</a>*
+ <td> <a data-anolis-xref="concept-id" href="infrastructure.html#concept-id">ID</a>*
<tr><th> <code data-anolis-xref="">formaction</code>
- <td> <code data-anolis-xref="attr-fs-formaction"><a href="forms.html#formaction">button</a></code>;
- <code data-anolis-xref="attr-fs-formaction"><a href="forms.html#formaction">input</a></code>
+ <td> <code data-anolis-xref="attr-fs-formaction"><a href="forms.html#attr-fs-formaction">button</a></code>;
+ <code data-anolis-xref="attr-fs-formaction"><a href="forms.html#attr-fs-formaction">input</a></code>
<td> <a href="infrastructure.html#url">URL</a> to use for <a href="forms.html#form-submission-0">form submission</a>
<td> <a href="infrastructure.html#valid-non-empty-url-potentially-surrounded-by-spaces">Valid non-empty URL potentially surrounded by spaces</a>
<tr><th> <code data-anolis-xref="">formenctype</code>
- <td> <code data-anolis-xref="attr-fs-formenctype"><a href="forms.html#formenctype">button</a></code>;
- <code data-anolis-xref="attr-fs-formenctype"><a href="forms.html#formenctype">input</a></code>
+ <td> <code data-anolis-xref="attr-fs-formenctype"><a href="forms.html#attr-fs-formenctype">button</a></code>;
+ <code data-anolis-xref="attr-fs-formenctype"><a href="forms.html#attr-fs-formenctype">input</a></code>
<td> Form data set encoding type to use for <a href="forms.html#form-submission-0">form submission</a>
- <td> "<code data-anolis-xref="attr-fs-enctype-urlencoded"><a href="forms.html#application/x-www-form-urlencoded-0">application/x-www-form-urlencoded</a></code>"; "<code data-anolis-xref="attr-fs-enctype-formdata"><a href="forms.html#multipart/form-data">multipart/form-data</a></code>"; "<code data-anolis-xref="attr-fs-enctype-text"><a href="forms.html#text/plain">text/plain</a></code>"
+ <td> "<code data-anolis-xref="attr-fs-enctype-urlencoded"><a href="forms.html#attr-fs-enctype-urlencoded">application/x-www-form-urlencoded</a></code>"; "<code data-anolis-xref="attr-fs-enctype-formdata"><a href="forms.html#attr-fs-enctype-formdata">multipart/form-data</a></code>"; "<code data-anolis-xref="attr-fs-enctype-text"><a href="forms.html#attr-fs-enctype-text">text/plain</a></code>"
<tr><th> <code data-anolis-xref="">formmethod</code>
- <td> <code data-anolis-xref="attr-fs-formmethod"><a href="forms.html#formmethod">button</a></code>;
- <code data-anolis-xref="attr-fs-formmethod"><a href="forms.html#formmethod">input</a></code>
+ <td> <code data-anolis-xref="attr-fs-formmethod"><a href="forms.html#attr-fs-formmethod">button</a></code>;
+ <code data-anolis-xref="attr-fs-formmethod"><a href="forms.html#attr-fs-formmethod">input</a></code>
<td> HTTP method to use for <a href="forms.html#form-submission-0">form submission</a>
<td> "<code data-anolis-xref="">GET</code>"; "<code data-anolis-xref="">POST</code>"
<tr><th> <code data-anolis-xref="">formnovalidate</code>
- <td> <code data-anolis-xref="attr-fs-formnovalidate"><a href="forms.html#formnovalidate">button</a></code>;
- <code data-anolis-xref="attr-fs-formnovalidate"><a href="forms.html#formnovalidate">input</a></code>
+ <td> <code data-anolis-xref="attr-fs-formnovalidate"><a href="forms.html#attr-fs-formnovalidate">button</a></code>;
+ <code data-anolis-xref="attr-fs-formnovalidate"><a href="forms.html#attr-fs-formnovalidate">input</a></code>
<td> Bypass form control validation for <a href="forms.html#form-submission-0">form submission</a>
- <td> <a href="infrastructure.html#boolean-attributes-0">Boolean attribute</a>
+ <td> <a href="infrastructure.html#boolean-attribute">Boolean attribute</a>
<tr><th> <code data-anolis-xref="">formtarget</code>
- <td> <code data-anolis-xref="attr-fs-formtarget"><a href="forms.html#formtarget">button</a></code>;
- <code data-anolis-xref="attr-fs-formtarget"><a href="forms.html#formtarget">input</a></code>
+ <td> <code data-anolis-xref="attr-fs-formtarget"><a href="forms.html#attr-fs-formtarget">button</a></code>;
+ <code data-anolis-xref="attr-fs-formtarget"><a href="forms.html#attr-fs-formtarget">input</a></code>
<td> <a href="browsers.html#browsing-context">Browsing context</a> for <a href="forms.html#form-submission-0">form submission</a>
<td> <a href="browsers.html#valid-browsing-context-name-or-keyword">Valid browsing context name or keyword</a>
<tr><th> <code data-anolis-xref="">headers</code>
- <td> <code data-anolis-xref="attr-tdth-headers"><a href="tabular-data.html#headers">td</a></code>;
- <code data-anolis-xref="attr-tdth-headers"><a href="tabular-data.html#headers">th</a></code>
+ <td> <code data-anolis-xref="attr-tdth-headers"><a href="tabular-data.html#attr-tdth-headers">td</a></code>;
+ <code data-anolis-xref="attr-tdth-headers"><a href="tabular-data.html#attr-tdth-headers">th</a></code>
<td> The header cells for this cell
<td> <a href="infrastructure.html#unordered-set-of-unique-space-separated-tokens">Unordered set of unique space-separated tokens</a>, <a href="infrastructure.html#case-sensitive">case-sensitive</a>, consisting of IDs*
<tr><th> <code data-anolis-xref="">height</code>
- <td> <code data-anolis-xref="attr-canvas-height"><a href="scripting-1.html#height-3">canvas</a></code>;
- <code data-anolis-xref="attr-dim-height"><a href="embedded-content-0.html#height-0">embed</a></code>;
- <code data-anolis-xref="attr-dim-height"><a href="embedded-content-0.html#height-0">iframe</a></code>;
- <code data-anolis-xref="attr-dim-height"><a href="embedded-content-0.html#height-0">img</a></code>;
- <code data-anolis-xref="attr-dim-height"><a href="embedded-content-0.html#height-0">input</a></code>;
- <code data-anolis-xref="attr-dim-height"><a href="embedded-content-0.html#height-0">object</a></code>;
- <code data-anolis-xref="attr-dim-height"><a href="embedded-content-0.html#height-0">video</a></code>
+ <td> <code data-anolis-xref="attr-canvas-height"><a href="scripting-1.html#attr-canvas-height">canvas</a></code>;
+ <code data-anolis-xref="attr-dim-height"><a href="embedded-content.html#attr-dim-height">embed</a></code>;
+ <code data-anolis-xref="attr-dim-height"><a href="embedded-content.html#attr-dim-height">iframe</a></code>;
+ <code data-anolis-xref="attr-dim-height"><a href="embedded-content.html#attr-dim-height">img</a></code>;
+ <code data-anolis-xref="attr-dim-height"><a href="embedded-content.html#attr-dim-height">input</a></code>;
+ <code data-anolis-xref="attr-dim-height"><a href="embedded-content.html#attr-dim-height">object</a></code>;
+ <code data-anolis-xref="attr-dim-height"><a href="embedded-content.html#attr-dim-height">video</a></code>
<td> Vertical dimension
<td> <a href="infrastructure.html#valid-non-negative-integer">Valid non-negative integer</a>
<tr><th> <code data-anolis-xref="">hidden</code>
<td> <a data-anolis-xref="attr-hidden" href="editing.html#the-hidden-attribute">HTML elements</a>
<td> Whether the element is relevant
- <td> <a href="infrastructure.html#boolean-attributes-0">Boolean attribute</a>
+ <td> <a href="infrastructure.html#boolean-attribute">Boolean attribute</a>
<tr><th> <code data-anolis-xref="">high</code>
- <td> <code data-anolis-xref="attr-meter-high"><a href="forms.html#high">meter</a></code>
+ <td> <code data-anolis-xref="attr-meter-high"><a href="forms.html#attr-meter-high">meter</a></code>
<td> Low limit of high range
<td> <a href="infrastructure.html#valid-floating-point-number">Valid floating-point number</a>*
<tr><th> <code data-anolis-xref="">href</code>
- <td> <code data-anolis-xref="attr-hyperlink-href"><a href="links.html#href-3">a</a></code>;
- <code data-anolis-xref="attr-hyperlink-href"><a href="links.html#href-3">area</a></code>
- <td> Address of the <a href="links.html#hyperlinks">hyperlink</a>
+ <td> <code data-anolis-xref="attr-hyperlink-href"><a href="links.html#attr-hyperlink-href">a</a></code>;
+ <code data-anolis-xref="attr-hyperlink-href"><a href="links.html#attr-hyperlink-href">area</a></code>
+ <td> Address of the <a href="links.html#hyperlink">hyperlink</a>
<td> <a href="infrastructure.html#valid-url-potentially-surrounded-by-spaces">Valid URL potentially surrounded by spaces</a>
<tr><th> <code data-anolis-xref="">href</code>
- <td> <code data-anolis-xref="attr-link-href"><a href="document-metadata.html#href-1">link</a></code>
- <td> Address of the <a href="links.html#hyperlinks">hyperlink</a>
+ <td> <code data-anolis-xref="attr-link-href"><a href="document-metadata.html#attr-link-href">link</a></code>
+ <td> Address of the <a href="links.html#hyperlink">hyperlink</a>
<td> <a href="infrastructure.html#valid-non-empty-url-potentially-surrounded-by-spaces">Valid non-empty URL potentially surrounded by spaces</a>
<tr><th> <code data-anolis-xref="">href</code>
- <td> <code data-anolis-xref="attr-base-href"><a href="document-metadata.html#href">base</a></code>
+ <td> <code data-anolis-xref="attr-base-href"><a href="document-metadata.html#attr-base-href">base</a></code>
<td> <a href="infrastructure.html#document-base-url">Document base URL</a>
<td> <a href="infrastructure.html#valid-url-potentially-surrounded-by-spaces">Valid URL potentially surrounded by spaces</a>
<tr><th> <code data-anolis-xref="">hreflang</code>
- <td> <code data-anolis-xref="attr-hyperlink-hreflang"><a href="links.html#hreflang-3">a</a></code>;
- <code data-anolis-xref="attr-hyperlink-hreflang"><a href="links.html#hreflang-3">area</a></code>;
- <code data-anolis-xref="attr-link-hreflang"><a href="document-metadata.html#hreflang">link</a></code>
+ <td> <code data-anolis-xref="attr-hyperlink-hreflang"><a href="links.html#attr-hyperlink-hreflang">a</a></code>;
+ <code data-anolis-xref="attr-hyperlink-hreflang"><a href="links.html#attr-hyperlink-hreflang">area</a></code>;
+ <code data-anolis-xref="attr-link-hreflang"><a href="document-metadata.html#attr-link-hreflang">link</a></code>
<td> Language of the linked resource
<td> Valid BCP 47 language tag
<tr><th> <code data-anolis-xref="">http-equiv</code>
- <td> <code data-anolis-xref="attr-meta-http-equiv"><a href="document-metadata.html#http-equiv">meta</a></code>
+ <td> <code data-anolis-xref="attr-meta-http-equiv"><a href="document-metadata.html#attr-meta-http-equiv">meta</a></code>
<td> Pragma directive
<td> <a href="dom.html#attribute-text">Text</a>*
<tr><th> <code data-anolis-xref="">icon</code>
- <td> <code data-anolis-xref="attr-menuitem-icon"><a href="interactive-elements.html#icon">menuitem</a></code>
+ <td> <code data-anolis-xref="attr-menuitem-icon"><a href="interactive-elements.html#attr-menuitem-icon">menuitem</a></code>
<td> Icon for the command
<td> <a href="infrastructure.html#valid-non-empty-url-potentially-surrounded-by-spaces">Valid non-empty URL potentially surrounded by spaces</a>
<tr><th> <code data-anolis-xref="">id</code>
<td> <a data-anolis-xref="attr-id" href="dom.html#the-id-attribute">HTML elements</a>
- <td> The element's <a data-anolis-xref="concept-id" href="infrastructure.html#unique-identifier-(id)">ID</a>
+ <td> The element's <a data-anolis-xref="concept-id" href="infrastructure.html#concept-id">ID</a>
<td> <a href="dom.html#attribute-text">Text</a>*
- <tr><th> <code data-anolis-xref="">inert</code>
- <td> <a data-anolis-xref="attr-inert" href="editing.html#the-inert-attribute">HTML elements</a>
- <td> Whether the element and its descendants are inert
- <td> <a href="infrastructure.html#boolean-attributes-0">Boolean attribute</a>
<tr><th> <code data-anolis-xref="">inputmode</code>
- <td> <code data-anolis-xref="attr-fe-inputmode"><a href="forms.html#inputmode-1">input</a></code>;
- <code data-anolis-xref="attr-fe-inputmode"><a href="forms.html#inputmode-1">textarea</a></code>
+ <td> <code data-anolis-xref="attr-fe-inputmode"><a href="forms.html#attr-fe-inputmode">input</a></code>;
+ <code data-anolis-xref="attr-fe-inputmode"><a href="forms.html#attr-fe-inputmode">textarea</a></code>
<td> Hint for selecting an input modality
- <td> <code data-anolis-xref="attr-fe-inputmode-keyword-verbatim"><a href="forms.html#verbatim">verbatim</a></code>;
- <code data-anolis-xref="attr-fe-inputmode-keyword-latin"><a href="forms.html#latin">latin</a></code>;
- <code data-anolis-xref="attr-fe-inputmode-keyword-latin-name"><a href="forms.html#latin-name">latin-name</a></code>;
- <code data-anolis-xref="attr-fe-inputmode-keyword-latin-prose"><a href="forms.html#latin-prose">latin-prose</a></code>;
- <code data-anolis-xref="attr-fe-inputmode-keyword-full-width-latin"><a href="forms.html#full-width-latin">full-width-latin</a></code>;
- <code data-anolis-xref="attr-fe-inputmode-keyword-kana"><a href="forms.html#kana">kana</a></code>;
- <code data-anolis-xref="attr-fe-inputmode-keyword-katakana"><a href="forms.html#katakana">katakana</a></code>;
- <!-- <code data-x="attr-fe-inputmode-keyword-half-width-katakana">half-width-katakana</code>; -->
- <code data-anolis-xref="attr-fe-inputmode-keyword-numeric"><a href="forms.html#numeric">numeric</a></code>;
- <code data-anolis-xref="attr-fe-inputmode-keyword-tel"><a href="forms.html#tel-0">tel</a></code>;
- <code data-anolis-xref="attr-fe-inputmode-keyword-email"><a href="forms.html#email-0">email</a></code>;
- <code data-anolis-xref="attr-fe-inputmode-keyword-url"><a href="forms.html#url-2">url</a></code>
+ <td> "<code data-anolis-xref="attr-fe-inputmode-keyword-verbatim"><a href="forms.html#attr-fe-inputmode-keyword-verbatim">verbatim</a></code>";
+ "<code data-anolis-xref="attr-fe-inputmode-keyword-latin"><a href="forms.html#attr-fe-inputmode-keyword-latin">latin</a></code>";
+ "<code data-anolis-xref="attr-fe-inputmode-keyword-latin-name"><a href="forms.html#attr-fe-inputmode-keyword-latin-name">latin-name</a></code>";
+ "<code data-anolis-xref="attr-fe-inputmode-keyword-latin-prose"><a href="forms.html#attr-fe-inputmode-keyword-latin-prose">latin-prose</a></code>";
+ "<code data-anolis-xref="attr-fe-inputmode-keyword-full-width-latin"><a href="forms.html#attr-fe-inputmode-keyword-full-width-latin">full-width-latin</a></code>";
+ "<code data-anolis-xref="attr-fe-inputmode-keyword-kana"><a href="forms.html#attr-fe-inputmode-keyword-kana">kana</a></code>";
+ "<code data-anolis-xref="attr-fe-inputmode-keyword-kana-name"><a href="forms.html#attr-fe-inputmode-keyword-kana-name">kana-name</a></code>";
+ "<code data-anolis-xref="attr-fe-inputmode-keyword-katakana"><a href="forms.html#attr-fe-inputmode-keyword-katakana">katakana</a></code>";
+ <!-- "<code data-x="attr-fe-inputmode-keyword-half-width-katakana">half-width-katakana</code>"; -->
+ "<code data-anolis-xref="attr-fe-inputmode-keyword-numeric"><a href="forms.html#attr-fe-inputmode-keyword-numeric">numeric</a></code>";
+ "<code data-anolis-xref="attr-fe-inputmode-keyword-tel"><a href="forms.html#attr-fe-inputmode-keyword-tel">tel</a></code>";
+ "<code data-anolis-xref="attr-fe-inputmode-keyword-email"><a href="forms.html#attr-fe-inputmode-keyword-email">email</a></code>";
+ "<code data-anolis-xref="attr-fe-inputmode-keyword-url"><a href="forms.html#attr-fe-inputmode-keyword-url">url</a></code>"
<tr><th> <code data-anolis-xref="">ismap</code>
- <td> <code data-anolis-xref="attr-img-ismap"><a href="embedded-content-0.html#ismap">img</a></code>
+ <td> <code data-anolis-xref="attr-img-ismap"><a href="embedded-content.html#attr-img-ismap">img</a></code>
<td> Whether the image is a server-side image map
- <td> <a href="infrastructure.html#boolean-attributes-0">Boolean attribute</a>
+ <td> <a href="infrastructure.html#boolean-attribute">Boolean attribute</a>
<tr><th> <code data-anolis-xref="">itemid</code>
<td> <span data-anolis-xref="attr-itemid">HTML elements</span>
<td> <span>Global identifier</span> for a microdata item
@@ -2374,300 +2385,303 @@
<tr><th> <code data-anolis-xref="">itemscope</code>
<td> <span data-anolis-xref="attr-itemscope">HTML elements</span>
<td> Introduces a microdata item
- <td> <a href="infrastructure.html#boolean-attributes-0">Boolean attribute</a>
+ <td> <a href="infrastructure.html#boolean-attribute">Boolean attribute</a>
<tr><th> <code data-anolis-xref="">itemtype</code>
<td> <span data-anolis-xref="attr-itemtype">HTML elements</span>
<td> <span>Item types</span> of a microdata item
<td> <a href="infrastructure.html#unordered-set-of-unique-space-separated-tokens">Unordered set of unique space-separated tokens</a>, <a href="infrastructure.html#case-sensitive">case-sensitive</a>, consisting of <a data-anolis-xref="absolute URL" href="infrastructure.html#absolute-url">valid absolute URL</a>*
<tr><th> <code data-anolis-xref="">keytype</code>
- <td> <code data-anolis-xref="attr-keygen-keytype"><a href="forms.html#keytype">keygen</a></code>
+ <td> <code data-anolis-xref="attr-keygen-keytype"><a href="forms.html#attr-keygen-keytype">keygen</a></code>
<td> The type of cryptographic key to generate
<td> <a href="dom.html#attribute-text">Text</a>*
<tr><th> <code data-anolis-xref="">kind</code>
- <td> <code data-anolis-xref="attr-track-kind"><a href="embedded-content-0.html#kind">track</a></code>
+ <td> <code data-anolis-xref="attr-track-kind"><a href="embedded-content.html#attr-track-kind">track</a></code>
<td> The type of text track
- <td> "<code data-anolis-xref="attr-track-kind-subtitles"><a href="embedded-content-0.html#subtitles-0">subtitles</a></code>";
- "<code data-anolis-xref="attr-track-kind-captions"><a href="embedded-content-0.html#captions-0">captions</a></code>";
- "<code data-anolis-xref="attr-track-kind-descriptions"><a href="embedded-content-0.html#descriptions-0">descriptions</a></code>";
- "<code data-anolis-xref="attr-track-kind-chapters"><a href="embedded-content-0.html#chapters-0">chapters</a></code>";
- "<code data-anolis-xref="attr-track-kind-metadata"><a href="embedded-content-0.html#metadata-0">metadata</a></code>"
+ <td> "<code data-anolis-xref="attr-track-kind-subtitles"><a href="embedded-content.html#attr-track-kind-subtitles">subtitles</a></code>";
+ "<code data-anolis-xref="attr-track-kind-captions"><a href="embedded-content.html#attr-track-kind-captions">captions</a></code>";
+ "<code data-anolis-xref="attr-track-kind-descriptions"><a href="embedded-content.html#attr-track-kind-descriptions">descriptions</a></code>";
+ "<code data-anolis-xref="attr-track-kind-chapters"><a href="embedded-content.html#attr-track-kind-chapters">chapters</a></code>";
+ "<code data-anolis-xref="attr-track-kind-metadata"><a href="embedded-content.html#attr-track-kind-metadata">metadata</a></code>"
<tr><th> <code data-anolis-xref="">label</code>
- <td> <code data-anolis-xref="attr-menuitem-label"><a href="interactive-elements.html#label-9">menuitem</a></code>;
- <code data-anolis-xref="attr-menu-label"><a href="interactive-elements.html#label-7">menu</a></code>;
- <code data-anolis-xref="attr-optgroup-label"><a href="forms.html#label-2">optgroup</a></code>;
- <code data-anolis-xref="attr-option-label"><a href="forms.html#label-4">option</a></code>;
- <code data-anolis-xref="attr-track-label"><a href="embedded-content-0.html#label">track</a></code>
+ <td> <code data-anolis-xref="attr-menuitem-label"><a href="interactive-elements.html#attr-menuitem-label">menuitem</a></code>;
+ <code data-anolis-xref="attr-menu-label"><a href="interactive-elements.html#attr-menu-label">menu</a></code>;
+ <code data-anolis-xref="attr-optgroup-label"><a href="forms.html#attr-optgroup-label">optgroup</a></code>;
+ <code data-anolis-xref="attr-option-label"><a href="forms.html#attr-option-label">option</a></code>;
+ <code data-anolis-xref="attr-track-label"><a href="embedded-content.html#attr-track-label">track</a></code>
<td> User-visible label
<td> <a href="dom.html#attribute-text">Text</a>
<tr><th> <code data-anolis-xref="">lang</code>
- <td> <a data-anolis-xref="attr-lang" href="dom.html#lang">HTML elements</a>
+ <td> <a data-anolis-xref="attr-lang" href="dom.html#attr-lang">HTML elements</a>
<td> <a href="dom.html#language">Language</a> of the element
<td> Valid BCP 47 language tag or the empty string
<tr><th> <code data-anolis-xref="">list</code>
- <td> <code data-anolis-xref="attr-input-list"><a href="forms.html#list">input</a></code>
+ <td> <code data-anolis-xref="attr-input-list"><a href="forms.html#attr-input-list">input</a></code>
<td> List of autocomplete options
- <td> <a data-anolis-xref="concept-id" href="infrastructure.html#unique-identifier-(id)">ID</a>*
+ <td> <a data-anolis-xref="concept-id" href="infrastructure.html#concept-id">ID</a>*
<tr><th> <code data-anolis-xref="">loop</code>
- <td> <code data-anolis-xref="attr-media-loop"><a href="embedded-content-0.html#loop">audio</a></code>;
- <code data-anolis-xref="attr-media-loop"><a href="embedded-content-0.html#loop">video</a></code>
- <td> Whether to loop the <a href="embedded-content-0.html#media-resource">media resource</a>
- <td> <a href="infrastructure.html#boolean-attributes-0">Boolean attribute</a>
+ <td> <code data-anolis-xref="attr-media-loop"><a href="embedded-content.html#attr-media-loop">audio</a></code>;
+ <code data-anolis-xref="attr-media-loop"><a href="embedded-content.html#attr-media-loop">video</a></code>
+ <td> Whether to loop the <a href="embedded-content.html#media-resource">media resource</a>
+ <td> <a href="infrastructure.html#boolean-attribute">Boolean attribute</a>
<tr><th> <code data-anolis-xref="">low</code>
- <td> <code data-anolis-xref="attr-meter-low"><a href="forms.html#low">meter</a></code>
+ <td> <code data-anolis-xref="attr-meter-low"><a href="forms.html#attr-meter-low">meter</a></code>
<td> High limit of low range
<td> <a href="infrastructure.html#valid-floating-point-number">Valid floating-point number</a>*
<tr><th> <code data-anolis-xref="">manifest</code>
- <td> <code data-anolis-xref="attr-html-manifest"><a href="semantics.html#manifest">html</a></code>
- <td> <a data-anolis-xref="concept-appcache-manifest" href="browsers.html#the-manifest">Application cache manifest</a>
+ <td> <code data-anolis-xref="attr-html-manifest"><a href="semantics.html#attr-html-manifest">html</a></code>
+ <td> <a data-anolis-xref="concept-appcache-manifest" href="browsers.html#concept-appcache-manifest">Application cache manifest</a>
<td> <a href="infrastructure.html#valid-non-empty-url-potentially-surrounded-by-spaces">Valid non-empty URL potentially surrounded by spaces</a>
<tr><th> <code data-anolis-xref="">max</code>
- <td> <code data-anolis-xref="attr-input-max"><a href="forms.html#max-0">input</a></code>
+ <td> <code data-anolis-xref="attr-input-max"><a href="forms.html#attr-input-max">input</a></code>
<td> Maximum value
<td> Varies*
<tr><th> <code data-anolis-xref="">max</code>
- <td> <code data-anolis-xref="attr-meter-max"><a href="forms.html#max-3">meter</a></code>;
- <code data-anolis-xref="attr-progress-max"><a href="forms.html#max-1">progress</a></code>
+ <td> <code data-anolis-xref="attr-meter-max"><a href="forms.html#attr-meter-max">meter</a></code>;
+ <code data-anolis-xref="attr-progress-max"><a href="forms.html#attr-progress-max">progress</a></code>
<td> Upper bound of range
<td> <a href="infrastructure.html#valid-floating-point-number">Valid floating-point number</a>*
<tr><th> <code data-anolis-xref="">maxlength</code>
- <td> <code data-anolis-xref="attr-input-maxlength"><a href="forms.html#maxlength-0">input</a></code>;
- <code data-anolis-xref="attr-textarea-maxlength"><a href="forms.html#maxlength-1">textarea</a></code>
+ <td> <code data-anolis-xref="attr-input-maxlength"><a href="forms.html#attr-input-maxlength">input</a></code>;
+ <code data-anolis-xref="attr-textarea-maxlength"><a href="forms.html#attr-textarea-maxlength">textarea</a></code>
<td> Maximum length of value
<td> <a href="infrastructure.html#valid-non-negative-integer">Valid non-negative integer</a>
<tr><th> <code data-anolis-xref="">media</code>
- <td> <code data-anolis-xref="attr-link-media"><a href="document-metadata.html#media">link</a></code>;
- <code data-anolis-xref="attr-source-media"><a href="embedded-content-0.html#media-3">source</a></code>;
- <code data-anolis-xref="attr-style-media"><a href="document-metadata.html#media-1">style</a></code>
+ <td> <code data-anolis-xref="attr-link-media"><a href="document-metadata.html#attr-link-media">link</a></code>;
+ <code data-anolis-xref="attr-style-media"><a href="document-metadata.html#attr-style-media">style</a></code>
<td> Applicable media
<td> <a href="infrastructure.html#valid-media-query">Valid media query</a>
<tr><th> <code data-anolis-xref="">mediagroup</code>
- <td> <code data-anolis-xref="attr-media-mediagroup"><a href="embedded-content-0.html#mediagroup">audio</a></code>;
- <code data-anolis-xref="attr-media-mediagroup"><a href="embedded-content-0.html#mediagroup">video</a></code>
- <td> Groups <a data-anolis-xref="media element" href="embedded-content-0.html#media-elements-0">media elements</a> together with an implicit <code><a href="embedded-content-0.html#mediacontroller">MediaController</a></code>
+ <td> <code data-anolis-xref="attr-media-mediagroup"><a href="embedded-content.html#attr-media-mediagroup">audio</a></code>;
+ <code data-anolis-xref="attr-media-mediagroup"><a href="embedded-content.html#attr-media-mediagroup">video</a></code>
+ <td> Groups <a data-anolis-xref="media element" href="embedded-content.html#media-element">media elements</a> together with an implicit <code><a href="embedded-content.html#mediacontroller">MediaController</a></code>
<td> <a href="dom.html#attribute-text">Text</a>
<tr><th> <code data-anolis-xref="">menu</code>
- <td> <code data-anolis-xref="attr-button-menu"><a href="forms.html#menu-1">button</a></code>
+ <td> <code data-anolis-xref="attr-button-menu"><a href="forms.html#attr-button-menu">button</a></code>
<td> Specifies the element's <a href="forms.html#designated-pop-up-menu">designated pop-up menu</a>
- <td> <a data-anolis-xref="concept-id" href="infrastructure.html#unique-identifier-(id)">ID</a>*
+ <td> <a data-anolis-xref="concept-id" href="infrastructure.html#concept-id">ID</a>*
<tr><th> <code data-anolis-xref="">method</code>
- <td> <code data-anolis-xref="attr-fs-method"><a href="forms.html#method">form</a></code>
+ <td> <code data-anolis-xref="attr-fs-method"><a href="forms.html#attr-fs-method">form</a></code>
<td> HTTP method to use for <a href="forms.html#form-submission-0">form submission</a>
- <td> "<code data-anolis-xref="attr-fs-method-GET-keyword"><a href="forms.html#get">GET</a></code>";
- "<code data-anolis-xref="attr-fs-method-POST-keyword"><a href="forms.html#post">POST</a></code>";
-<!--FORM-DIALOG-->
+ <td> "<code data-anolis-xref="attr-fs-method-GET-keyword"><a href="forms.html#attr-fs-method-get-keyword">GET</a></code>";
+ "<code data-anolis-xref="attr-fs-method-POST-keyword"><a href="forms.html#attr-fs-method-post-keyword">POST</a></code>";
+ "<code data-anolis-xref="attr-fs-method-dialog-keyword"><a href="forms.html#attr-fs-method-dialog-keyword">dialog</a></code>"
<tr><th> <code data-anolis-xref="">min</code>
- <td> <code data-anolis-xref="attr-input-min"><a href="forms.html#min-0">input</a></code>
+ <td> <code data-anolis-xref="attr-input-min"><a href="forms.html#attr-input-min">input</a></code>
<td> Minimum value
<td> Varies*
<tr><th> <code data-anolis-xref="">min</code>
- <td> <code data-anolis-xref="attr-meter-min"><a href="forms.html#min-1">meter</a></code>
+ <td> <code data-anolis-xref="attr-meter-min"><a href="forms.html#attr-meter-min">meter</a></code>
<td> Lower bound of range
<td> <a href="infrastructure.html#valid-floating-point-number">Valid floating-point number</a>*
<tr><th> <code data-anolis-xref="">minlength</code>
- <td> <code data-anolis-xref="attr-input-minlength"><a href="forms.html#minlength-0">input</a></code>;
- <code data-anolis-xref="attr-textarea-minlength"><a href="forms.html#minlength-1">textarea</a></code>
+ <td> <code data-anolis-xref="attr-input-minlength"><a href="forms.html#attr-input-minlength">input</a></code>;
+ <code data-anolis-xref="attr-textarea-minlength"><a href="forms.html#attr-textarea-minlength">textarea</a></code>
<td> Minimum length of value
<td> <a href="infrastructure.html#valid-non-negative-integer">Valid non-negative integer</a>
<tr><th> <code data-anolis-xref="">multiple</code>
- <td> <code data-anolis-xref="attr-input-multiple"><a href="forms.html#multiple-0">input</a></code>;
- <code data-anolis-xref="attr-select-multiple"><a href="forms.html#multiple-1">select</a></code>
+ <td> <code data-anolis-xref="attr-input-multiple"><a href="forms.html#attr-input-multiple">input</a></code>;
+ <code data-anolis-xref="attr-select-multiple"><a href="forms.html#attr-select-multiple">select</a></code>
<td> Whether to allow multiple values
- <td> <a href="infrastructure.html#boolean-attributes-0">Boolean attribute</a>
+ <td> <a href="infrastructure.html#boolean-attribute">Boolean attribute</a>
<tr><th> <code data-anolis-xref="">muted</code>
- <td> <code data-anolis-xref="attr-media-muted"><a href="embedded-content-0.html#muted-1">audio</a></code>;
- <code data-anolis-xref="attr-media-muted"><a href="embedded-content-0.html#muted-1">video</a></code>
- <td> Whether to mute the <a href="embedded-content-0.html#media-resource">media resource</a> by default
- <td> <a href="infrastructure.html#boolean-attributes-0">Boolean attribute</a>
+ <td> <code data-anolis-xref="attr-media-muted"><a href="embedded-content.html#attr-media-muted">audio</a></code>;
+ <code data-anolis-xref="attr-media-muted"><a href="embedded-content.html#attr-media-muted">video</a></code>
+ <td> Whether to mute the <a href="embedded-content.html#media-resource">media resource</a> by default
+ <td> <a href="infrastructure.html#boolean-attribute">Boolean attribute</a>
<tr><th> <code data-anolis-xref="">name</code>
- <td> <code data-anolis-xref="attr-fe-name"><a href="forms.html#name-11">button</a></code>;
- <code data-anolis-xref="attr-fe-name"><a href="forms.html#name-11">fieldset</a></code>;
- <code data-anolis-xref="attr-fe-name"><a href="forms.html#name-11">input</a></code>;
- <code data-anolis-xref="attr-fe-name"><a href="forms.html#name-11">keygen</a></code>;
- <code data-anolis-xref="attr-fe-name"><a href="forms.html#name-11">output</a></code>;
- <code data-anolis-xref="attr-fe-name"><a href="forms.html#name-11">select</a></code>;
- <code data-anolis-xref="attr-fe-name"><a href="forms.html#name-11">textarea</a></code>
- <td> Name of form control to use for <a href="forms.html#form-submission-0">form submission</a> and in the <code data-anolis-xref="dom-form-elements"><a href="forms.html#elements-2">form.elements</a></code> API
+ <td> <code data-anolis-xref="attr-fe-name"><a href="forms.html#attr-fe-name">button</a></code>;
+ <code data-anolis-xref="attr-fe-name"><a href="forms.html#attr-fe-name">fieldset</a></code>;
+ <code data-anolis-xref="attr-fe-name"><a href="forms.html#attr-fe-name">input</a></code>;
+ <code data-anolis-xref="attr-fe-name"><a href="forms.html#attr-fe-name">keygen</a></code>;
+ <code data-anolis-xref="attr-fe-name"><a href="forms.html#attr-fe-name">output</a></code>;
+ <code data-anolis-xref="attr-fe-name"><a href="forms.html#attr-fe-name">select</a></code>;
+ <code data-anolis-xref="attr-fe-name"><a href="forms.html#attr-fe-name">textarea</a></code>
+ <td> Name of form control to use for <a href="forms.html#form-submission-0">form submission</a> and in the <code data-anolis-xref="dom-form-elements"><a href="forms.html#dom-form-elements">form.elements</a></code> API <!--or: Name of form control to use in the <code data-x="dom-form-elements">form.elements</code> API -->
<td> <a href="dom.html#attribute-text">Text</a>*
<tr><th> <code data-anolis-xref="">name</code>
- <td> <code data-anolis-xref="attr-form-name"><a href="forms.html#name-9">form</a></code>
- <td> Name of form to use in the <code data-anolis-xref="dom-document-forms"><a href="dom.html#forms-0">document.forms</a></code> API
+ <td> <code data-anolis-xref="attr-form-name"><a href="forms.html#attr-form-name">form</a></code>
+ <td> Name of form to use in the <code data-anolis-xref="dom-document-forms"><a href="dom.html#dom-document-forms">document.forms</a></code> API
<td> <a href="dom.html#attribute-text">Text</a>*
<tr><th> <code data-anolis-xref="">name</code>
- <td> <code data-anolis-xref="attr-iframe-name"><a href="embedded-content-0.html#name-1">iframe</a></code>;
- <code data-anolis-xref="attr-object-name"><a href="embedded-content-0.html#name-3">object</a></code>
- <td> Name of <a href="browsers.html#nested-browsing-contexts-0">nested browsing context</a>
+ <td> <code data-anolis-xref="attr-iframe-name"><a href="embedded-content.html#attr-iframe-name">iframe</a></code>;
+ <code data-anolis-xref="attr-object-name"><a href="embedded-content.html#attr-object-name">object</a></code>
+ <td> Name of <a href="browsers.html#nested-browsing-context">nested browsing context</a>
<td> <a href="browsers.html#valid-browsing-context-name-or-keyword">Valid browsing context name or keyword</a>
<tr><th> <code data-anolis-xref="">name</code>
- <td> <code data-anolis-xref="attr-map-name"><a href="embedded-content-0.html#name-7">map</a></code>
- <td> Name of <a href="embedded-content-0.html#image-map">image map</a> to reference from the <code data-anolis-xref="attr-hyperlink-usemap"><a href="embedded-content-0.html#usemap-1">usemap</a></code> attribute
+ <td> <code data-anolis-xref="attr-map-name"><a href="embedded-content.html#attr-map-name">map</a></code>
+ <td> Name of <a href="embedded-content.html#image-map">image map</a> to reference from the <code data-anolis-xref="attr-hyperlink-usemap"><a href="embedded-content.html#attr-hyperlink-usemap">usemap</a></code> attribute
<td> <a href="dom.html#attribute-text">Text</a>*
<tr><th> <code data-anolis-xref="">name</code>
- <td> <code data-anolis-xref="attr-meta-name"><a href="document-metadata.html#name">meta</a></code>
+ <td> <code data-anolis-xref="attr-meta-name"><a href="document-metadata.html#attr-meta-name">meta</a></code>
<td> Metadata name
<td> <a href="dom.html#attribute-text">Text</a>*
<tr><th> <code data-anolis-xref="">name</code>
- <td> <code data-anolis-xref="attr-param-name"><a href="embedded-content-0.html#name-5">param</a></code>
+ <td> <code data-anolis-xref="attr-param-name"><a href="embedded-content.html#attr-param-name">param</a></code>
<td> Name of parameter
<td> <a href="dom.html#attribute-text">Text</a>
<tr><th> <code data-anolis-xref="">novalidate</code>
- <td> <code data-anolis-xref="attr-fs-novalidate"><a href="forms.html#novalidate">form</a></code>
+ <td> <code data-anolis-xref="attr-fs-novalidate"><a href="forms.html#attr-fs-novalidate">form</a></code>
<td> Bypass form control validation for <a href="forms.html#form-submission-0">form submission</a>
- <td> <a href="infrastructure.html#boolean-attributes-0">Boolean attribute</a>
+ <td> <a href="infrastructure.html#boolean-attribute">Boolean attribute</a>
<tr><th> <code data-anolis-xref="">open</code>
- <td> <code data-anolis-xref="attr-details-open"><a href="interactive-elements.html#open">details</a></code>
+ <td> <code data-anolis-xref="attr-details-open"><a href="interactive-elements.html#attr-details-open">details</a></code>
<td> Whether the details are visible
- <td> <a href="infrastructure.html#boolean-attributes-0">Boolean attribute</a>
+ <td> <a href="infrastructure.html#boolean-attribute">Boolean attribute</a>
<tr><th> <code data-anolis-xref="">open</code>
- <td> <code data-anolis-xref="attr-dialog-open"><a href="interactive-elements.html#open-1">dialog</a></code>
+ <td> <code data-anolis-xref="attr-dialog-open"><a href="interactive-elements.html#attr-dialog-open">dialog</a></code>
<td> Whether the dialog box is showing
- <td> <a href="infrastructure.html#boolean-attributes-0">Boolean attribute</a>
+ <td> <a href="infrastructure.html#boolean-attribute">Boolean attribute</a>
<tr><th> <code data-anolis-xref="">optimum</code>
- <td> <code data-anolis-xref="attr-meter-optimum"><a href="forms.html#optimum">meter</a></code>
+ <td> <code data-anolis-xref="attr-meter-optimum"><a href="forms.html#attr-meter-optimum">meter</a></code>
<td> Optimum value in gauge
<td> <a href="infrastructure.html#valid-floating-point-number">Valid floating-point number</a>*
<tr><th> <code data-anolis-xref="">pattern</code>
- <td> <code data-anolis-xref="attr-input-pattern"><a href="forms.html#pattern-0">input</a></code>
+ <td> <code data-anolis-xref="attr-input-pattern"><a href="forms.html#attr-input-pattern">input</a></code>
<td> Pattern to be matched by the form control's value
<td> Regular expression matching the JavaScript <i data-anolis-xref="">Pattern</i> production
<!--PING-->
<tr><th> <code data-anolis-xref="">placeholder</code>
- <td> <code data-anolis-xref="attr-input-placeholder"><a href="forms.html#placeholder-0">input</a></code>;
- <code data-anolis-xref="attr-textarea-placeholder"><a href="forms.html#placeholder-1">textarea</a></code>
+ <td> <code data-anolis-xref="attr-input-placeholder"><a href="forms.html#attr-input-placeholder">input</a></code>;
+ <code data-anolis-xref="attr-textarea-placeholder"><a href="forms.html#attr-textarea-placeholder">textarea</a></code>
<td> User-visible label to be placed within the form control
<td> <a href="dom.html#attribute-text">Text</a>*
<tr><th> <code data-anolis-xref="">poster</code>
- <td> <code data-anolis-xref="attr-video-poster"><a href="embedded-content-0.html#poster">video</a></code>
+ <td> <code data-anolis-xref="attr-video-poster"><a href="embedded-content.html#attr-video-poster">video</a></code>
<td> Poster frame to show prior to video playback
<td> <a href="infrastructure.html#valid-non-empty-url-potentially-surrounded-by-spaces">Valid non-empty URL potentially surrounded by spaces</a>
<tr><th> <code data-anolis-xref="">preload</code>
- <td> <code data-anolis-xref="attr-media-preload"><a href="embedded-content-0.html#preload">audio</a></code>;
- <code data-anolis-xref="attr-media-preload"><a href="embedded-content-0.html#preload">video</a></code>
- <td> Hints how much buffering the <a href="embedded-content-0.html#media-resource">media resource</a> will likely need
- <td> "<code data-anolis-xref="attr-media-preload-none"><a href="embedded-content-0.html#none-0">none</a></code>";
- "<code data-anolis-xref="attr-media-preload-metadata"><a href="embedded-content-0.html#metadata-1">metadata</a></code>";
- "<code data-anolis-xref="attr-media-preload-auto"><a href="embedded-content-0.html#auto-1">auto</a></code>"
+ <td> <code data-anolis-xref="attr-media-preload"><a href="embedded-content.html#attr-media-preload">audio</a></code>;
+ <code data-anolis-xref="attr-media-preload"><a href="embedded-content.html#attr-media-preload">video</a></code>
+ <td> Hints how much buffering the <a href="embedded-content.html#media-resource">media resource</a> will likely need
+ <td> "<code data-anolis-xref="attr-media-preload-none"><a href="embedded-content.html#attr-media-preload-none">none</a></code>";
+ "<code data-anolis-xref="attr-media-preload-metadata"><a href="embedded-content.html#attr-media-preload-metadata">metadata</a></code>";
+ "<code data-anolis-xref="attr-media-preload-auto"><a href="embedded-content.html#attr-media-preload-auto">auto</a></code>"
<tr><th> <code data-anolis-xref="">radiogroup</code>
- <td> <code data-anolis-xref="attr-menuitem-radiogroup"><a href="interactive-elements.html#radiogroup">menuitem</a></code>
+ <td> <code data-anolis-xref="attr-menuitem-radiogroup"><a href="interactive-elements.html#attr-menuitem-radiogroup">menuitem</a></code>
<td> Name of group of commands to treat as a radio button group
<td> <a href="dom.html#attribute-text">Text</a>
<tr><th> <code data-anolis-xref="">readonly</code>
- <td> <code data-anolis-xref="attr-input-readonly"><a href="forms.html#readonly-0">input</a></code>;
- <code data-anolis-xref="attr-textarea-readonly"><a href="forms.html#readonly-1">textarea</a></code>
+ <td> <code data-anolis-xref="attr-input-readonly"><a href="forms.html#attr-input-readonly">input</a></code>;
+ <code data-anolis-xref="attr-textarea-readonly"><a href="forms.html#attr-textarea-readonly">textarea</a></code>
<td> Whether to allow the value to be edited by the user
- <td> <a href="infrastructure.html#boolean-attributes-0">Boolean attribute</a>
+ <td> <a href="infrastructure.html#boolean-attribute">Boolean attribute</a>
<tr><th> <code data-anolis-xref="">rel</code>
- <td> <code data-anolis-xref="attr-hyperlink-rel"><a href="links.html#rel-3">a</a></code>;
- <code data-anolis-xref="attr-hyperlink-rel"><a href="links.html#rel-3">area</a></code>;
- <code data-anolis-xref="attr-link-rel"><a href="document-metadata.html#rel">link</a></code>
+ <td> <code data-anolis-xref="attr-hyperlink-rel"><a href="links.html#attr-hyperlink-rel">a</a></code>;
+ <code data-anolis-xref="attr-hyperlink-rel"><a href="links.html#attr-hyperlink-rel">area</a></code>;
+ <code data-anolis-xref="attr-link-rel"><a href="document-metadata.html#attr-link-rel">link</a></code>
<td> Relationship between the document containing the hyperlink and the destination resource
<td> <a href="infrastructure.html#set-of-space-separated-tokens">Set of space-separated tokens</a>*
<tr><th> <code data-anolis-xref="">required</code>
- <td> <code data-anolis-xref="attr-input-required"><a href="forms.html#required-0">input</a></code>;
- <code data-anolis-xref="attr-select-required"><a href="forms.html#required-2">select</a></code>;
- <code data-anolis-xref="attr-textarea-required"><a href="forms.html#required-4">textarea</a></code>
+ <td> <code data-anolis-xref="attr-input-required"><a href="forms.html#attr-input-required">input</a></code>;
+ <code data-anolis-xref="attr-select-required"><a href="forms.html#attr-select-required">select</a></code>;
+ <code data-anolis-xref="attr-textarea-required"><a href="forms.html#attr-textarea-required">textarea</a></code>
<td> Whether the control is required for <a href="forms.html#form-submission-0">form submission</a>
- <td> <a href="infrastructure.html#boolean-attributes-0">Boolean attribute</a>
+ <td> <a href="infrastructure.html#boolean-attribute">Boolean attribute</a>
<tr><th> <code data-anolis-xref="">reversed</code>
- <td> <code data-anolis-xref="attr-ol-reversed"><a href="grouping-content.html#reversed">ol</a></code>
+ <td> <code data-anolis-xref="attr-ol-reversed"><a href="grouping-content.html#attr-ol-reversed">ol</a></code>
<td> Number the list backwards
- <td> <a href="infrastructure.html#boolean-attributes-0">Boolean attribute</a>
+ <td> <a href="infrastructure.html#boolean-attribute">Boolean attribute</a>
<tr><th> <code data-anolis-xref="">rows</code>
- <td> <code data-anolis-xref="attr-textarea-rows"><a href="forms.html#rows-1">textarea</a></code>
+ <td> <code data-anolis-xref="attr-textarea-rows"><a href="forms.html#attr-textarea-rows">textarea</a></code>
<td> Number of lines to show
<td> <a href="infrastructure.html#valid-non-negative-integer">Valid non-negative integer</a> greater than zero
<tr><th> <code data-anolis-xref="">rowspan</code>
- <td> <code data-anolis-xref="attr-tdth-rowspan"><a href="tabular-data.html#rowspan">td</a></code>;
- <code data-anolis-xref="attr-tdth-rowspan"><a href="tabular-data.html#rowspan">th</a></code>
+ <td> <code data-anolis-xref="attr-tdth-rowspan"><a href="tabular-data.html#attr-tdth-rowspan">td</a></code>;
+ <code data-anolis-xref="attr-tdth-rowspan"><a href="tabular-data.html#attr-tdth-rowspan">th</a></code>
<td> Number of rows that the cell is to span
<td> <a href="infrastructure.html#valid-non-negative-integer">Valid non-negative integer</a>
<tr><th> <code data-anolis-xref="">sandbox</code>
- <td> <code data-anolis-xref="attr-iframe-sandbox"><a href="embedded-content-0.html#sandbox">iframe</a></code>
+ <td> <code data-anolis-xref="attr-iframe-sandbox"><a href="embedded-content.html#attr-iframe-sandbox">iframe</a></code>
<td> Security rules for nested content
<td> <a href="infrastructure.html#unordered-set-of-unique-space-separated-tokens">Unordered set of unique space-separated tokens</a>, <a href="infrastructure.html#ascii-case-insensitive">ASCII case-insensitive</a>, consisting of
- "<code data-anolis-xref="attr-iframe-sandbox-allow-forms"><a href="browsers.html#allow-forms">allow-forms</a></code>",
- "<code data-anolis-xref="attr-iframe-sandbox-allow-pointer-lock"><a href="browsers.html#allow-pointer-lock">allow-pointer-lock</a></code>",
- "<code data-anolis-xref="attr-iframe-sandbox-allow-popups"><a href="browsers.html#allow-popups">allow-popups</a></code>",
- "<code data-anolis-xref="attr-iframe-sandbox-allow-same-origin"><a href="browsers.html#allow-same-origin">allow-same-origin</a></code>",
- "<code data-anolis-xref="attr-iframe-sandbox-allow-scripts"><a href="browsers.html#allow-scripts">allow-scripts</a></code> and
- "<code data-anolis-xref="attr-iframe-sandbox-allow-top-navigation"><a href="browsers.html#allow-top-navigation">allow-top-navigation</a></code>"
+ "<code data-anolis-xref="attr-iframe-sandbox-allow-forms"><a href="browsers.html#attr-iframe-sandbox-allow-forms">allow-forms</a></code>",
+ "<code data-anolis-xref="attr-iframe-sandbox-allow-pointer-lock"><a href="browsers.html#attr-iframe-sandbox-allow-pointer-lock">allow-pointer-lock</a></code>",
+ "<code data-anolis-xref="attr-iframe-sandbox-allow-popups"><a href="browsers.html#attr-iframe-sandbox-allow-popups">allow-popups</a></code>",
+ "<code data-anolis-xref="attr-iframe-sandbox-allow-same-origin"><a href="browsers.html#attr-iframe-sandbox-allow-same-origin">allow-same-origin</a></code>",
+ "<code data-anolis-xref="attr-iframe-sandbox-allow-scripts"><a href="browsers.html#attr-iframe-sandbox-allow-scripts">allow-scripts</a></code> and
+ "<code data-anolis-xref="attr-iframe-sandbox-allow-top-navigation"><a href="browsers.html#attr-iframe-sandbox-allow-top-navigation">allow-top-navigation</a></code>"
<tr><th> <code data-anolis-xref="">spellcheck</code>
- <td> <a data-anolis-xref="attr-spellcheck" href="editing.html#spellcheck">HTML elements</a>
+ <td> <a data-anolis-xref="attr-spellcheck" href="editing.html#attr-spellcheck">HTML elements</a>
<td> Whether the element is to have its spelling and grammar checked
<td> "<code data-anolis-xref="">true</code>"; "<code data-anolis-xref="">false</code>"
<tr><th> <code data-anolis-xref="">scope</code>
- <td> <code data-anolis-xref="attr-th-scope"><a href="tabular-data.html#scope-0">th</a></code>
+ <td> <code data-anolis-xref="attr-th-scope"><a href="tabular-data.html#attr-th-scope">th</a></code>
<td> Specifies which cells the header cell applies to
- <td> "<code data-anolis-xref="attr-th-scope-row"><a href="tabular-data.html#row">row</a></code>";
- "<code data-anolis-xref="attr-th-scope-col"><a href="tabular-data.html#col">col</a></code>";
- "<code data-anolis-xref="attr-th-scope-rowgroup"><a href="tabular-data.html#rowgroup">rowgroup</a></code>";
- "<code data-anolis-xref="attr-th-scope-colgroup"><a href="tabular-data.html#colgroup">colgroup</a></code>"
+ <td> "<code data-anolis-xref="attr-th-scope-row"><a href="tabular-data.html#attr-th-scope-row">row</a></code>";
+ "<code data-anolis-xref="attr-th-scope-col"><a href="tabular-data.html#attr-th-scope-col">col</a></code>";
+ "<code data-anolis-xref="attr-th-scope-rowgroup"><a href="tabular-data.html#attr-th-scope-rowgroup">rowgroup</a></code>";
+ "<code data-anolis-xref="attr-th-scope-colgroup"><a href="tabular-data.html#attr-th-scope-colgroup">colgroup</a></code>"
<tr><th> <code data-anolis-xref="">scoped</code>
- <td> <code data-anolis-xref="attr-style-scoped"><a href="document-metadata.html#scoped">style</a></code>
+ <td> <code data-anolis-xref="attr-style-scoped"><a href="document-metadata.html#attr-style-scoped">style</a></code>
<td> Whether the styles apply to the entire document or just the parent subtree
- <td> <a href="infrastructure.html#boolean-attributes-0">Boolean attribute</a>
+ <td> <a href="infrastructure.html#boolean-attribute">Boolean attribute</a>
<tr><th> <code data-anolis-xref="">seamless</code>
- <td> <code data-anolis-xref="attr-iframe-seamless"><a href="embedded-content-0.html#seamless">iframe</a></code>
+ <td> <code data-anolis-xref="attr-iframe-seamless"><a href="embedded-content.html#attr-iframe-seamless">iframe</a></code>
<td> Whether to apply the document's styles to the nested content
- <td> <a href="infrastructure.html#boolean-attributes-0">Boolean attribute</a>
+ <td> <a href="infrastructure.html#boolean-attribute">Boolean attribute</a>
<tr><th> <code data-anolis-xref="">selected</code>
- <td> <code data-anolis-xref="attr-option-selected"><a href="forms.html#selected">option</a></code>
+ <td> <code data-anolis-xref="attr-option-selected"><a href="forms.html#attr-option-selected">option</a></code>
<td> Whether the option is selected by default
- <td> <a href="infrastructure.html#boolean-attributes-0">Boolean attribute</a>
+ <td> <a href="infrastructure.html#boolean-attribute">Boolean attribute</a>
<tr><th> <code data-anolis-xref="">shape</code>
- <td> <code data-anolis-xref="attr-area-shape"><a href="embedded-content-0.html#shape">area</a></code>
- <td> The kind of shape to be created in an <a href="embedded-content-0.html#image-map">image map</a>
- <td> "<code data-anolis-xref="attr-area-shape-keyword-circle"><a href="embedded-content-0.html#circle">circle</a></code>";
- "<code data-anolis-xref="attr-area-shape-keyword-default"><a href="embedded-content-0.html#default-1">default</a></code>";
- "<code data-anolis-xref="attr-area-shape-keyword-poly"><a href="embedded-content-0.html#poly">poly</a></code>";
- "<code data-anolis-xref="attr-area-shape-keyword-rect"><a href="embedded-content-0.html#rect">rect</a></code>"
+ <td> <code data-anolis-xref="attr-area-shape"><a href="embedded-content.html#attr-area-shape">area</a></code>
+ <td> The kind of shape to be created in an <a href="embedded-content.html#image-map">image map</a>
+ <td> "<code data-anolis-xref="attr-area-shape-keyword-circle"><a href="embedded-content.html#attr-area-shape-keyword-circle">circle</a></code>";
+ "<code data-anolis-xref="attr-area-shape-keyword-default"><a href="embedded-content.html#attr-area-shape-keyword-default">default</a></code>";
+ "<code data-anolis-xref="attr-area-shape-keyword-poly"><a href="embedded-content.html#attr-area-shape-keyword-poly">poly</a></code>";
+ "<code data-anolis-xref="attr-area-shape-keyword-rect"><a href="embedded-content.html#attr-area-shape-keyword-rect">rect</a></code>"
<tr><th> <code data-anolis-xref="">size</code>
- <td> <code data-anolis-xref="attr-input-size"><a href="forms.html#size-1">input</a></code>;
- <code data-anolis-xref="attr-select-size"><a href="forms.html#size-2">select</a></code>
+ <td> <code data-anolis-xref="attr-input-size"><a href="forms.html#attr-input-size">input</a></code>;
+ <code data-anolis-xref="attr-select-size"><a href="forms.html#attr-select-size">select</a></code>
<td> Size of the control
<td> <a href="infrastructure.html#valid-non-negative-integer">Valid non-negative integer</a> greater than zero
<tr><th> <code data-anolis-xref="">sizes</code>
- <td> <code data-anolis-xref="attr-link-sizes"><a href="links.html#sizes-0">link</a></code>
- <td> Sizes of the icons (for <code data-anolis-xref="attr-link-rel"><a href="document-metadata.html#rel">rel</a></code>="<code data-anolis-xref="rel-icon"><a href="links.html#rel-icon">icon</a></code>")
+ <td> <code data-anolis-xref="attr-link-sizes"><a href="links.html#attr-link-sizes">link</a></code>
+ <td> Sizes of the icons (for <code data-anolis-xref="attr-link-rel"><a href="document-metadata.html#attr-link-rel">rel</a></code>="<code data-anolis-xref="rel-icon"><a href="links.html#rel-icon">icon</a></code>")
<td> <a href="infrastructure.html#unordered-set-of-unique-space-separated-tokens">Unordered set of unique space-separated tokens</a>, <a href="infrastructure.html#ascii-case-insensitive">ASCII case-insensitive</a>, consisting of sizes*
<tr><th> <code data-anolis-xref="">sortable</code>
- <td> <code data-anolis-xref="attr-table-sortable"><a href="tabular-data.html#sortable-0">table</a></code>
+ <td> <code data-anolis-xref="attr-table-sortable"><a href="tabular-data.html#attr-table-sortable">table</a></code>
<td> Enables a sorting interface for the table
- <td> <a href="infrastructure.html#boolean-attributes-0">Boolean attribute</a>
+ <td> <a href="infrastructure.html#boolean-attribute">Boolean attribute</a>
<tr><th> <code data-anolis-xref="">sorted</code>
- <td> <code data-anolis-xref="attr-th-sorted"><a href="tabular-data.html#sorted-0">th</a></code>
+ <td> <code data-anolis-xref="attr-th-sorted"><a href="tabular-data.html#attr-th-sorted">th</a></code>
<td> <a href="tabular-data.html#column-sort-direction">Column sort direction</a> and <a data-anolis-xref="column key ordinality" href="tabular-data.html#column-key-ordinality">ordinality</a>
- <td> <a href="infrastructure.html#set-of-space-separated-tokens">Set of space-separated tokens</a>, <a href="infrastructure.html#ascii-case-insensitive">ASCII case-insensitive</a>, consisting of neither, one, or both of "<code data-anolis-xref="attr-th-sorted-reversed"><a href="tabular-data.html#reversed-1">reversed</a></code>" and a <a href="infrastructure.html#valid-non-negative-integer">valid non-negative integer</a> greater than zero
+ <td> <a href="infrastructure.html#set-of-space-separated-tokens">Set of space-separated tokens</a>, <a href="infrastructure.html#ascii-case-insensitive">ASCII case-insensitive</a>, consisting of neither, one, or both of "<code data-anolis-xref="attr-th-sorted-reversed"><a href="tabular-data.html#attr-th-sorted-reversed">reversed</a></code>" and a <a href="infrastructure.html#valid-non-negative-integer">valid non-negative integer</a> greater than zero
<tr><th> <code data-anolis-xref="">span</code>
- <td> <code data-anolis-xref="attr-col-span"><a href="tabular-data.html#span-1">col</a></code>;
- <code data-anolis-xref="attr-colgroup-span"><a href="tabular-data.html#span">colgroup</a></code>
+ <td> <code data-anolis-xref="attr-col-span"><a href="tabular-data.html#attr-col-span">col</a></code>;
+ <code data-anolis-xref="attr-colgroup-span"><a href="tabular-data.html#attr-colgroup-span">colgroup</a></code>
<td> Number of columns spanned by the element
<td> <a href="infrastructure.html#valid-non-negative-integer">Valid non-negative integer</a> greater than zero
<tr><th> <code data-anolis-xref="">src</code>
- <td> <code data-anolis-xref="attr-media-src"><a href="embedded-content-0.html#src-9">audio</a></code>;
- <code data-anolis-xref="attr-embed-src"><a href="embedded-content-0.html#src-3">embed</a></code>;
- <code data-anolis-xref="attr-iframe-src"><a href="embedded-content-0.html#src-1">iframe</a></code>;
- <code data-anolis-xref="attr-img-src"><a href="embedded-content-0.html#src">img</a></code>;
- <code data-anolis-xref="attr-input-src"><a href="forms.html#src-12">input</a></code>;
- <code data-anolis-xref="attr-script-src"><a href="scripting-1.html#src-13">script</a></code>;
- <code data-anolis-xref="attr-source-src"><a href="embedded-content-0.html#src-5">source</a></code>;
- <code data-anolis-xref="attr-track-src"><a href="embedded-content-0.html#src-7">track</a></code>;
- <code data-anolis-xref="attr-media-src"><a href="embedded-content-0.html#src-9">video</a></code>
+ <td> <code data-anolis-xref="attr-media-src"><a href="embedded-content.html#attr-media-src">audio</a></code>;
+ <code data-anolis-xref="attr-embed-src"><a href="embedded-content.html#attr-embed-src">embed</a></code>;
+ <code data-anolis-xref="attr-iframe-src"><a href="embedded-content.html#attr-iframe-src">iframe</a></code>;
+ <code data-anolis-xref="attr-img-src"><a href="embedded-content.html#attr-img-src">img</a></code>;
+ <code data-anolis-xref="attr-input-src"><a href="forms.html#attr-input-src">input</a></code>;
+ <code data-anolis-xref="attr-script-src"><a href="scripting-1.html#attr-script-src">script</a></code>;
+ <code data-anolis-xref="attr-source-src"><a href="embedded-content.html#attr-source-src">source</a></code>;
+ <code data-anolis-xref="attr-track-src"><a href="embedded-content.html#attr-track-src">track</a></code>;
+ <code data-anolis-xref="attr-media-src"><a href="embedded-content.html#attr-media-src">video</a></code>
<td> Address of the resource
<td> <a href="infrastructure.html#valid-non-empty-url-potentially-surrounded-by-spaces">Valid non-empty URL potentially surrounded by spaces</a>
<tr><th> <code data-anolis-xref="">srcdoc</code>
- <td> <code data-anolis-xref="attr-iframe-srcdoc"><a href="embedded-content-0.html#srcdoc">iframe</a></code>
- <td> A document to render in the <code><a href="embedded-content-0.html#the-iframe-element">iframe</a></code>
- <td> The source of <a href="embedded-content-0.html#an-iframe-srcdoc-document">an <code>iframe</code> <code data-anolis-xref="attr-iframe-srcdoc">srcdoc</code> document</a>*
+ <td> <code data-anolis-xref="attr-iframe-srcdoc"><a href="embedded-content.html#attr-iframe-srcdoc">iframe</a></code>
+ <td> A document to render in the <code><a href="embedded-content.html#the-iframe-element">iframe</a></code>
+ <td> The source of <a href="embedded-content.html#an-iframe-srcdoc-document">an <code>iframe</code> <code data-anolis-xref="attr-iframe-srcdoc">srcdoc</code> document</a>*
<tr><th> <code data-anolis-xref="">srclang</code>
- <td> <code data-anolis-xref="attr-track-srclang"><a href="embedded-content-0.html#srclang">track</a></code>
+ <td> <code data-anolis-xref="attr-track-srclang"><a href="embedded-content.html#attr-track-srclang">track</a></code>
<td> Language of the text track
<td> Valid BCP 47 language tag
+ <tr><th> <code data-anolis-xref="">srcset</code>
+ <td> <code data-anolis-xref="attr-img-srcset"><a href="embedded-content.html#attr-img-srcset">img</a></code>
+ <td> Images to use in different situations (e.g. high-resolution displays, small monitors, etc)
+ <td> Comma-separated list of <span>image candidate strings</span>
<tr><th> <code data-anolis-xref="">start</code>
- <td> <code data-anolis-xref="attr-ol-start"><a href="grouping-content.html#start-0">ol</a></code>
+ <td> <code data-anolis-xref="attr-ol-start"><a href="grouping-content.html#attr-ol-start">ol</a></code>
<td> <a href="grouping-content.html#ordinal-value">Ordinal value</a> of the first item
<td> <a href="infrastructure.html#valid-integer">Valid integer</a>
<tr><th> <code data-anolis-xref="">step</code>
- <td> <code data-anolis-xref="attr-input-step"><a href="forms.html#step-0">input</a></code>
+ <td> <code data-anolis-xref="attr-input-step"><a href="forms.html#attr-input-step">input</a></code>
<td> Granularity to be matched by the form control's value
<td> <a href="infrastructure.html#valid-floating-point-number">Valid floating-point number</a> greater than zero, or "<code data-anolis-xref="">any</code>"
<tr><th> <code data-anolis-xref="">style</code>
@@ -2675,145 +2689,145 @@
<td> Presentational and formatting instructions
<td> CSS declarations*
<tr><th> <code data-anolis-xref="">tabindex</code>
- <td> <a data-anolis-xref="attr-tabindex" href="editing.html#tabindex">HTML elements</a>
+ <td> <a data-anolis-xref="attr-tabindex" href="editing.html#attr-tabindex">HTML elements</a>
<td> Whether the element is focusable, and the relative order of the element for the purposes of sequential focus navigation
<td> <a href="infrastructure.html#valid-integer">Valid integer</a>
<tr><th> <code data-anolis-xref="">target</code>
- <td> <code data-anolis-xref="attr-hyperlink-target"><a href="links.html#target-4">a</a></code>;
- <code data-anolis-xref="attr-hyperlink-target"><a href="links.html#target-4">area</a></code>
- <td> <a href="browsers.html#browsing-context">Browsing context</a> for <a href="links.html#hyperlinks">hyperlink</a> <a data-anolis-xref="navigate" href="browsers.html#navigated">navigation</a>
+ <td> <code data-anolis-xref="attr-hyperlink-target"><a href="links.html#attr-hyperlink-target">a</a></code>;
+ <code data-anolis-xref="attr-hyperlink-target"><a href="links.html#attr-hyperlink-target">area</a></code>
+ <td> <a href="browsers.html#browsing-context">Browsing context</a> for <a href="links.html#hyperlink">hyperlink</a> <a data-anolis-xref="navigate" href="browsers.html#navigate">navigation</a>
<td> <a href="browsers.html#valid-browsing-context-name-or-keyword">Valid browsing context name or keyword</a>
<tr><th> <code data-anolis-xref="">target</code>
- <td> <code data-anolis-xref="attr-base-target"><a href="document-metadata.html#target-0">base</a></code>
- <td> Default <a href="browsers.html#browsing-context">browsing context</a> for <a href="links.html#hyperlinks">hyperlink</a> <a data-anolis-xref="navigate" href="browsers.html#navigated">navigation</a> and <a href="forms.html#form-submission-0">form submission</a>
+ <td> <code data-anolis-xref="attr-base-target"><a href="document-metadata.html#attr-base-target">base</a></code>
+ <td> Default <a href="browsers.html#browsing-context">browsing context</a> for <a href="links.html#hyperlink">hyperlink</a> <a data-anolis-xref="navigate" href="browsers.html#navigate">navigation</a> and <a href="forms.html#form-submission-0">form submission</a>
<td> <a href="browsers.html#valid-browsing-context-name-or-keyword">Valid browsing context name or keyword</a>
<tr><th> <code data-anolis-xref="">target</code>
- <td> <code data-anolis-xref="attr-fs-target"><a href="forms.html#target-5">form</a></code>
+ <td> <code data-anolis-xref="attr-fs-target"><a href="forms.html#attr-fs-target">form</a></code>
<td> <a href="browsers.html#browsing-context">Browsing context</a> for <a href="forms.html#form-submission-0">form submission</a>
<td> <a href="browsers.html#valid-browsing-context-name-or-keyword">Valid browsing context name or keyword</a>
<tr><th> <code data-anolis-xref="">title</code>
- <td> <a data-anolis-xref="attr-title" href="dom.html#title">HTML elements</a>
+ <td> <a data-anolis-xref="attr-title" href="dom.html#attr-title">HTML elements</a>
<td> Advisory information for the element
<td> <a href="dom.html#attribute-text">Text</a>
<tr><th> <code data-anolis-xref="">title</code>
- <td> <code data-anolis-xref="attr-abbr-title"><a href="text-level-semantics.html#title-4">abbr</a></code>;
- <code data-anolis-xref="attr-dfn-title"><a href="text-level-semantics.html#title-3">dfn</a></code>
+ <td> <code data-anolis-xref="attr-abbr-title"><a href="text-level-semantics.html#attr-abbr-title">abbr</a></code>;
+ <code data-anolis-xref="attr-dfn-title"><a href="text-level-semantics.html#attr-dfn-title">dfn</a></code>
<td> Full term or expansion of abbreviation
<td> <a href="dom.html#attribute-text">Text</a>
<tr><th> <code data-anolis-xref="">title</code>
<td> <code data-anolis-xref="attr-input-title">input</code>
- <td> Description of pattern (when used with <code data-anolis-xref="attr-input-pattern"><a href="forms.html#pattern-0">pattern</a></code> attribute)
+ <td> Description of pattern (when used with <code data-anolis-xref="attr-input-pattern"><a href="forms.html#attr-input-pattern">pattern</a></code> attribute)
<td> <a href="dom.html#attribute-text">Text</a>
<tr><th> <code data-anolis-xref="">title</code>
- <td> <code data-anolis-xref="attr-menuitem-title"><a href="interactive-elements.html#title-5">menuitem</a></code>
+ <td> <code data-anolis-xref="attr-menuitem-title"><a href="interactive-elements.html#attr-menuitem-title">menuitem</a></code>
<td> Hint describing the command
<td> <a href="dom.html#attribute-text">Text</a>
<tr><th> <code data-anolis-xref="">title</code>
- <td> <code data-anolis-xref="attr-link-title"><a href="document-metadata.html#title-1">link</a></code>
+ <td> <code data-anolis-xref="attr-link-title"><a href="document-metadata.html#attr-link-title">link</a></code>
<td> Title of the link
<td> <a href="dom.html#attribute-text">Text</a>
<tr><th> <code data-anolis-xref="">title</code>
- <td> <code data-anolis-xref="attr-link-title"><a href="document-metadata.html#title-1">link</a></code>;
- <code data-anolis-xref="attr-style-title"><a href="document-metadata.html#title-2">style</a></code>
+ <td> <code data-anolis-xref="attr-link-title"><a href="document-metadata.html#attr-link-title">link</a></code>;
+ <code data-anolis-xref="attr-style-title"><a href="document-metadata.html#attr-style-title">style</a></code>
<td> Alternative style sheet set name
<td> <a href="dom.html#attribute-text">Text</a>
<tr><th> <code data-anolis-xref="">translate</code>
- <td> <a data-anolis-xref="attr-translate" href="dom.html#translate">HTML elements</a>
+ <td> <a data-anolis-xref="attr-translate" href="dom.html#attr-translate">HTML elements</a>
<td> Whether the element is to be translated when the page is localized
<td> "<code data-anolis-xref="">yes</code>"; "<code data-anolis-xref="">no</code>"
<tr><th> <code data-anolis-xref="">type</code>
- <td> <code data-anolis-xref="attr-hyperlink-type"><a href="links.html#type-14">a</a></code>;
- <code data-anolis-xref="attr-hyperlink-type"><a href="links.html#type-14">area</a></code>;
- <code data-anolis-xref="attr-link-type"><a href="document-metadata.html#type-0">link</a></code>
+ <td> <code data-anolis-xref="attr-hyperlink-type"><a href="links.html#attr-hyperlink-type">a</a></code>;
+ <code data-anolis-xref="attr-hyperlink-type"><a href="links.html#attr-hyperlink-type">area</a></code>;
+ <code data-anolis-xref="attr-link-type"><a href="document-metadata.html#attr-link-type">link</a></code>
<td> Hint for the type of the referenced resource
<td> <a href="infrastructure.html#valid-mime-type">Valid MIME type</a>
<tr><th> <code data-anolis-xref="">type</code>
- <td> <code data-anolis-xref="attr-button-type"><a href="forms.html#type-17">button</a></code>
+ <td> <code data-anolis-xref="attr-button-type"><a href="forms.html#attr-button-type">button</a></code>
<td> Type of button
- <td> "<code data-anolis-xref="attr-button-type-submit"><a href="forms.html#submit-0">submit</a></code>";
- "<code data-anolis-xref="attr-button-type-reset"><a href="forms.html#reset-0">reset</a></code>";
- "<code data-anolis-xref="attr-button-type-button"><a href="forms.html#button-0">button</a></code>";
- "<code data-anolis-xref="attr-button-type-menu"><a href="forms.html#menu">menu</a></code>"
+ <td> "<code data-anolis-xref="attr-button-type-submit"><a href="forms.html#attr-button-type-submit">submit</a></code>";
+ "<code data-anolis-xref="attr-button-type-reset"><a href="forms.html#attr-button-type-reset">reset</a></code>";
+ "<code data-anolis-xref="attr-button-type-button"><a href="forms.html#attr-button-type-button">button</a></code>";
+ "<code data-anolis-xref="attr-button-type-menu"><a href="forms.html#attr-button-type-menu">menu</a></code>"
<tr><th> <code data-anolis-xref="">type</code>
- <td> <code data-anolis-xref="attr-embed-type"><a href="embedded-content-0.html#type-7">embed</a></code>;
- <code data-anolis-xref="attr-object-type"><a href="embedded-content-0.html#type-9">object</a></code>;
- <code data-anolis-xref="attr-script-type"><a href="scripting-1.html#type-29">script</a></code>;
- <code data-anolis-xref="attr-source-type"><a href="embedded-content-0.html#type-11">source</a></code>;
- <code data-anolis-xref="attr-style-type"><a href="document-metadata.html#type-2">style</a></code>
+ <td> <code data-anolis-xref="attr-embed-type"><a href="embedded-content.html#attr-embed-type">embed</a></code>;
+ <code data-anolis-xref="attr-object-type"><a href="embedded-content.html#attr-object-type">object</a></code>;
+ <code data-anolis-xref="attr-script-type"><a href="scripting-1.html#attr-script-type">script</a></code>;
+ <code data-anolis-xref="attr-source-type"><a href="embedded-content.html#attr-source-type">source</a></code>;
+ <code data-anolis-xref="attr-style-type"><a href="document-metadata.html#attr-style-type">style</a></code>
<td> Type of embedded resource
<td> <a href="infrastructure.html#valid-mime-type">Valid MIME type</a>
<tr><th> <code data-anolis-xref="">type</code>
- <td> <code data-anolis-xref="attr-input-type"><a href="forms.html#type-15">input</a></code>
+ <td> <code data-anolis-xref="attr-input-type"><a href="forms.html#attr-input-type">input</a></code>
<td> Type of form control
- <td> <a data-anolis-xref="attr-input-type" href="forms.html#type-15"><code>input</code> type keyword</a>
+ <td> <a data-anolis-xref="attr-input-type" href="forms.html#attr-input-type"><code>input</code> type keyword</a>
<tr><th> <code data-anolis-xref="">type</code>
- <td> <code data-anolis-xref="attr-menu-type"><a href="interactive-elements.html#type-24">menu</a></code>
+ <td> <code data-anolis-xref="attr-menu-type"><a href="interactive-elements.html#attr-menu-type">menu</a></code>
<td> Type of menu
- <td> "<code data-anolis-xref="popup menu state"><a href="interactive-elements.html#popup-menu">popup</a></code>"; "<code data-anolis-xref="toolbar state"><a href="interactive-elements.html#toolbar">toolbar</a></code>"
+ <td> "<code data-anolis-xref="popup menu state"><a href="interactive-elements.html#popup-menu-state">popup</a></code>"; "<code data-anolis-xref="toolbar state"><a href="interactive-elements.html#toolbar-state">toolbar</a></code>"
<tr><th> <code data-anolis-xref="">type</code>
- <td> <code data-anolis-xref="attr-menuitem-type"><a href="interactive-elements.html#type-26">menuitem</a></code>
+ <td> <code data-anolis-xref="attr-menuitem-type"><a href="interactive-elements.html#attr-menuitem-type">menuitem</a></code>
<td> Type of command
- <td> "<code data-anolis-xref="attr-menuitem-type-keyword-command"><a href="interactive-elements.html#command">command</a></code>";
- "<code data-anolis-xref="attr-menuitem-type-keyword-checkbox"><a href="interactive-elements.html#checkbox-0">checkbox</a></code>";
- "<code data-anolis-xref="attr-menuitem-type-keyword-radio"><a href="interactive-elements.html#radio-0">radio</a></code>"
+ <td> "<code data-anolis-xref="attr-menuitem-type-keyword-command"><a href="interactive-elements.html#attr-menuitem-type-keyword-command">command</a></code>";
+ "<code data-anolis-xref="attr-menuitem-type-keyword-checkbox"><a href="interactive-elements.html#attr-menuitem-type-keyword-checkbox">checkbox</a></code>";
+ "<code data-anolis-xref="attr-menuitem-type-keyword-radio"><a href="interactive-elements.html#attr-menuitem-type-keyword-radio">radio</a></code>"
<tr><th> <code data-anolis-xref="">type</code>
- <td> <code data-anolis-xref="attr-ol-type"><a href="grouping-content.html#type-4">ol</a></code>
+ <td> <code data-anolis-xref="attr-ol-type"><a href="grouping-content.html#attr-ol-type">ol</a></code>
<td> Kind of list marker
- <td> "<code data-anolis-xref="attr-ol-type-keyword-decimal"><a href="grouping-content.html#1">1</a></code>";
- "<code data-anolis-xref="attr-ol-type-keyword-lower-alpha"><a href="grouping-content.html#a">a</a></code>";
- "<code data-anolis-xref="attr-ol-type-keyword-upper-alpha"><a href="grouping-content.html#a-0">A</a></code>";
- "<code data-anolis-xref="attr-ol-type-keyword-lower-roman"><a href="grouping-content.html#i">i</a></code>";
- "<code data-anolis-xref="attr-ol-type-keyword-upper-roman"><a href="grouping-content.html#i-0">I</a></code>"
+ <td> "<code data-anolis-xref="attr-ol-type-keyword-decimal"><a href="grouping-content.html#attr-ol-type-keyword-decimal">1</a></code>";
+ "<code data-anolis-xref="attr-ol-type-keyword-lower-alpha"><a href="grouping-content.html#attr-ol-type-keyword-lower-alpha">a</a></code>";
+ "<code data-anolis-xref="attr-ol-type-keyword-upper-alpha"><a href="grouping-content.html#attr-ol-type-keyword-upper-alpha">A</a></code>";
+ "<code data-anolis-xref="attr-ol-type-keyword-lower-roman"><a href="grouping-content.html#attr-ol-type-keyword-lower-roman">i</a></code>";
+ "<code data-anolis-xref="attr-ol-type-keyword-upper-roman"><a href="grouping-content.html#attr-ol-type-keyword-upper-roman">I</a></code>"
<tr><th> <code data-anolis-xref="">typemustmatch</code>
- <td> <code data-anolis-xref="attr-object-typemustmatch"><a href="embedded-content-0.html#typemustmatch">object</a></code>
- <td> Whether the <code data-anolis-xref="attr-object-type"><a href="embedded-content-0.html#type-9">type</a></code> attribute and the <a href="infrastructure.html#content-type-metadata">Content-Type</a> value need to match for the resource to be used
- <td> <a href="infrastructure.html#boolean-attributes-0">Boolean attribute</a>
+ <td> <code data-anolis-xref="attr-object-typemustmatch"><a href="embedded-content.html#attr-object-typemustmatch">object</a></code>
+ <td> Whether the <code data-anolis-xref="attr-object-type"><a href="embedded-content.html#attr-object-type">type</a></code> attribute and the <a href="infrastructure.html#content-type">Content-Type</a> value need to match for the resource to be used
+ <td> <a href="infrastructure.html#boolean-attribute">Boolean attribute</a>
<tr><th> <code data-anolis-xref="">usemap</code>
- <td> <code data-anolis-xref="attr-hyperlink-usemap"><a href="embedded-content-0.html#usemap-1">img</a></code>;
- <code data-anolis-xref="attr-hyperlink-usemap"><a href="embedded-content-0.html#usemap-1">object</a></code>
- <td> Name of <a href="embedded-content-0.html#image-map">image map</a> to use
+ <td> <code data-anolis-xref="attr-hyperlink-usemap"><a href="embedded-content.html#attr-hyperlink-usemap">img</a></code>;
+ <code data-anolis-xref="attr-hyperlink-usemap"><a href="embedded-content.html#attr-hyperlink-usemap">object</a></code>
+ <td> Name of <a href="embedded-content.html#image-map">image map</a> to use
<td> <a href="infrastructure.html#valid-hash-name-reference">Valid hash-name reference</a>*
<tr><th> <code data-anolis-xref="">value</code>
- <td> <code data-anolis-xref="attr-button-value"><a href="forms.html#value-9">button</a></code>;
- <code data-anolis-xref="attr-option-value"><a href="forms.html#value-12">option</a></code>
+ <td> <code data-anolis-xref="attr-button-value"><a href="forms.html#attr-button-value">button</a></code>;
+ <code data-anolis-xref="attr-option-value"><a href="forms.html#attr-option-value">option</a></code>
<td> Value to be used for <a href="forms.html#form-submission-0">form submission</a>
<td> <a href="dom.html#attribute-text">Text</a>
<tr><th> <code data-anolis-xref="">value</code>
- <td> <code data-anolis-xref="attr-data-value"><a href="text-level-semantics.html#value-2">data</a></code>
+ <td> <code data-anolis-xref="attr-data-value"><a href="text-level-semantics.html#attr-data-value">data</a></code>
<td> Machine-readable value
<td> <a href="dom.html#attribute-text">Text</a>*
<tr><th> <code data-anolis-xref="">value</code>
- <td> <code data-anolis-xref="attr-input-value"><a href="forms.html#value-6">input</a></code>
+ <td> <code data-anolis-xref="attr-input-value"><a href="forms.html#attr-input-value">input</a></code>
<td> Value of the form control
<td> Varies*
<tr><th> <code data-anolis-xref="">value</code>
- <td> <code data-anolis-xref="attr-li-value"><a href="grouping-content.html#value-0">li</a></code>
+ <td> <code data-anolis-xref="attr-li-value"><a href="grouping-content.html#attr-li-value">li</a></code>
<td> <a href="grouping-content.html#ordinal-value">Ordinal value</a> of the list item
<td> <a href="infrastructure.html#valid-integer">Valid integer</a>
<tr><th> <code data-anolis-xref="">value</code>
- <td> <code data-anolis-xref="attr-meter-value"><a href="forms.html#value-19">meter</a></code>;
- <code data-anolis-xref="attr-progress-value"><a href="forms.html#value-17">progress</a></code>
+ <td> <code data-anolis-xref="attr-meter-value"><a href="forms.html#attr-meter-value">meter</a></code>;
+ <code data-anolis-xref="attr-progress-value"><a href="forms.html#attr-progress-value">progress</a></code>
<td> Current value of the element
<td> <a href="infrastructure.html#valid-floating-point-number">Valid floating-point number</a>
<tr><th> <code data-anolis-xref="">value</code>
- <td> <code data-anolis-xref="attr-param-value"><a href="embedded-content-0.html#value-4">param</a></code>
+ <td> <code data-anolis-xref="attr-param-value"><a href="embedded-content.html#attr-param-value">param</a></code>
<td> Value of parameter
<td> <a href="dom.html#attribute-text">Text</a>
<tr><th> <code data-anolis-xref="">width</code>
- <td> <code data-anolis-xref="attr-canvas-width"><a href="scripting-1.html#width-3">canvas</a></code>;
- <code data-anolis-xref="attr-dim-width"><a href="embedded-content-0.html#width-0">embed</a></code>;
- <code data-anolis-xref="attr-dim-width"><a href="embedded-content-0.html#width-0">iframe</a></code>;
- <code data-anolis-xref="attr-dim-width"><a href="embedded-content-0.html#width-0">img</a></code>;
- <code data-anolis-xref="attr-dim-width"><a href="embedded-content-0.html#width-0">input</a></code>;
- <code data-anolis-xref="attr-dim-width"><a href="embedded-content-0.html#width-0">object</a></code>;
- <code data-anolis-xref="attr-dim-width"><a href="embedded-content-0.html#width-0">video</a></code>
+ <td> <code data-anolis-xref="attr-canvas-width"><a href="scripting-1.html#attr-canvas-width">canvas</a></code>;
+ <code data-anolis-xref="attr-dim-width"><a href="embedded-content.html#attr-dim-width">embed</a></code>;
+ <code data-anolis-xref="attr-dim-width"><a href="embedded-content.html#attr-dim-width">iframe</a></code>;
+ <code data-anolis-xref="attr-dim-width"><a href="embedded-content.html#attr-dim-width">img</a></code>;
+ <code data-anolis-xref="attr-dim-width"><a href="embedded-content.html#attr-dim-width">input</a></code>;
+ <code data-anolis-xref="attr-dim-width"><a href="embedded-content.html#attr-dim-width">object</a></code>;
+ <code data-anolis-xref="attr-dim-width"><a href="embedded-content.html#attr-dim-width">video</a></code>
<td> Horizontal dimension
<td> <a href="infrastructure.html#valid-non-negative-integer">Valid non-negative integer</a>
<tr><th> <code data-anolis-xref="">wrap</code>
- <td> <code data-anolis-xref="attr-textarea-wrap"><a href="forms.html#wrap">textarea</a></code>
+ <td> <code data-anolis-xref="attr-textarea-wrap"><a href="forms.html#attr-textarea-wrap">textarea</a></code>
<td> How the value of the form control is to be wrapped for <a href="forms.html#form-submission-0">form submission</a>
- <td> "<code data-anolis-xref="attr-textarea-wrap-soft"><a href="forms.html#soft">soft</a></code>";
- "<code data-anolis-xref="attr-textarea-wrap-hard"><a href="forms.html#hard">hard</a></code>"
+ <td> "<code data-anolis-xref="attr-textarea-wrap-soft"><a href="forms.html#attr-textarea-wrap-soft">soft</a></code>";
+ "<code data-anolis-xref="attr-textarea-wrap-hard"><a href="forms.html#attr-textarea-wrap-hard">hard</a></code>"
</table><p class="tablenote"><small>An asterisk (*) in a cell indicates that the actual rules are more
complicated than indicated in the table above.</small></p>
@@ -2823,374 +2837,389 @@
<th> Description
<th> Value
<tbody><tr><th id="ix-handler-onabort"> <code data-anolis-xref="">onabort</code>
- <td> <a data-anolis-xref="handler-onabort" href="webappapis.html#onabort">HTML elements</a>
- <td> <code data-anolis-xref="event-abort">abort</code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onabort" href="webappapis.html#handler-onabort">HTML elements</a>
+ <td> <code data-anolis-xref="event-abort"><a href="#event-abort">abort</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
+
+ <tr><th id="ix-handler-onautocomplete"> <code data-anolis-xref="">onautocomplete</code>
+ <td> <a data-anolis-xref="handler-onautocomplete" href="webappapis.html#handler-onautocomplete">HTML elements</a>
+ <td> <code data-anolis-xref="event-autocomplete"><a href="#event-autocomplete">autocomplete</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
+
+ <tr><th id="ix-handler-onautocompleteerror"> <code data-anolis-xref="">onautocompleteerror</code>
+ <td> <a data-anolis-xref="handler-onautocompleteerror" href="webappapis.html#handler-onautocompleteerror">HTML elements</a>
+ <td> <code data-anolis-xref="event-autocompleteerror"><a href="#event-autocompleteerror">autocompleteerror</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-window-onafterprint"> <code data-anolis-xref="">onafterprint</code>
- <td> <code data-anolis-xref="handler-window-onafterprint"><a href="webappapis.html#onafterprint">body</a></code>
- <td> <code data-anolis-xref="event-afterprint">afterprint</code> event handler for <code><a href="browsers.html#window">Window</a></code> object
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <code data-anolis-xref="handler-window-onafterprint"><a href="webappapis.html#handler-window-onafterprint">body</a></code>
+ <td> <code data-anolis-xref="event-afterprint"><a href="#event-afterprint">afterprint</a></code> event handler for <code><a href="browsers.html#window">Window</a></code> object
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-window-onbeforeprint"> <code data-anolis-xref="">onbeforeprint</code>
- <td> <code data-anolis-xref="handler-window-onbeforeprint"><a href="webappapis.html#onbeforeprint">body</a></code>
- <td> <code data-anolis-xref="event-beforeprint">beforeprint</code> event handler for <code><a href="browsers.html#window">Window</a></code> object
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <code data-anolis-xref="handler-window-onbeforeprint"><a href="webappapis.html#handler-window-onbeforeprint">body</a></code>
+ <td> <code data-anolis-xref="event-beforeprint"><a href="#event-beforeprint">beforeprint</a></code> event handler for <code><a href="browsers.html#window">Window</a></code> object
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-window-onbeforeunload"> <code data-anolis-xref="">onbeforeunload</code>
- <td> <code data-anolis-xref="handler-window-onbeforeunload"><a href="webappapis.html#onbeforeunload">body</a></code>
- <td> <code data-anolis-xref="event-beforeunload">beforeunload</code> event handler for <code><a href="browsers.html#window">Window</a></code> object
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <code data-anolis-xref="handler-window-onbeforeunload"><a href="webappapis.html#handler-window-onbeforeunload">body</a></code>
+ <td> <code data-anolis-xref="event-beforeunload"><a href="#event-beforeunload">beforeunload</a></code> event handler for <code><a href="browsers.html#window">Window</a></code> object
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onblur"> <code data-anolis-xref="">onblur</code>
- <td> <a data-anolis-xref="handler-onblur" href="webappapis.html#onblur">HTML elements</a>
- <td> <code data-anolis-xref="event-blur">blur</code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onblur" href="webappapis.html#handler-onblur">HTML elements</a>
+ <td> <code data-anolis-xref="event-blur"><a href="#event-blur">blur</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-oncancel"> <code data-anolis-xref="">oncancel</code>
- <td> <a data-anolis-xref="handler-oncancel" href="webappapis.html#oncancel">HTML elements</a>
- <td> <code data-anolis-xref="event-cancel"><a href="interactive-elements.html#cancel">cancel</a></code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-oncancel" href="webappapis.html#handler-oncancel">HTML elements</a>
+ <td> <code data-anolis-xref="event-cancel"><a href="#event-cancel">cancel</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-oncanplay"> <code data-anolis-xref="">oncanplay</code>
- <td> <a data-anolis-xref="handler-oncanplay" href="webappapis.html#oncanplay-0">HTML elements</a>
- <td> <code data-anolis-xref="event-media-canplay"><a href="embedded-content-0.html#canplay">canplay</a></code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-oncanplay" href="webappapis.html#handler-oncanplay">HTML elements</a>
+ <td> <code data-anolis-xref="event-media-canplay"><a href="embedded-content.html#event-media-canplay">canplay</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-oncanplaythrough"> <code data-anolis-xref="">oncanplaythrough</code>
- <td> <a data-anolis-xref="handler-oncanplaythrough" href="webappapis.html#oncanplaythrough-0">HTML elements</a>
- <td> <code data-anolis-xref="event-media-canplaythrough"><a href="embedded-content-0.html#canplaythrough">canplaythrough</a></code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-oncanplaythrough" href="webappapis.html#handler-oncanplaythrough">HTML elements</a>
+ <td> <code data-anolis-xref="event-media-canplaythrough"><a href="embedded-content.html#event-media-canplaythrough">canplaythrough</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onchange"> <code data-anolis-xref="">onchange</code>
- <td> <a data-anolis-xref="handler-onchange" href="webappapis.html#onchange-1">HTML elements</a>
- <td> <code data-anolis-xref="event-change">change</code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onchange" href="webappapis.html#handler-onchange">HTML elements</a>
+ <td> <code data-anolis-xref="event-change"><a href="#event-change">change</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onclick"> <code data-anolis-xref="">onclick</code>
- <td> <a data-anolis-xref="handler-onclick" href="webappapis.html#onclick">HTML elements</a>
- <td> <code data-anolis-xref="event-click"><a href="infrastructure.html#click">click</a></code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onclick" href="webappapis.html#handler-onclick">HTML elements</a>
+ <td> <code data-anolis-xref="event-click"><a href="infrastructure.html#event-click">click</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onclose"> <code data-anolis-xref="">onclose</code>
- <td> <a data-anolis-xref="handler-onclose" href="webappapis.html#onclose">HTML elements</a>
- <td> <code data-anolis-xref="event-close"><a href="interactive-elements.html#close">close</a></code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onclose" href="webappapis.html#handler-onclose">HTML elements</a>
+ <td> <code data-anolis-xref="event-close"><a href="#event-close">close</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-oncontextmenu"> <code data-anolis-xref="">oncontextmenu</code>
- <td> <a data-anolis-xref="handler-oncontextmenu" href="webappapis.html#oncontextmenu">HTML elements</a>
- <td> <code data-anolis-xref="event-contextmenu">contextmenu</code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-oncontextmenu" href="webappapis.html#handler-oncontextmenu">HTML elements</a>
+ <td> <code data-anolis-xref="event-contextmenu"><a href="#event-contextmenu">contextmenu</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-oncuechange"> <code data-anolis-xref="">oncuechange</code>
- <td> <a data-anolis-xref="handler-oncuechange" href="webappapis.html#oncuechange-0">HTML elements</a>
- <td> <code data-anolis-xref="event-cuechange">cuechange</code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-oncuechange" href="webappapis.html#handler-oncuechange">HTML elements</a>
+ <td> <code data-anolis-xref="event-media-cuechange"><a href="embedded-content.html#event-media-cuechange">cuechange</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-ondblclick"> <code data-anolis-xref="">ondblclick</code>
- <td> <a data-anolis-xref="handler-ondblclick" href="webappapis.html#ondblclick">HTML elements</a>
- <td> <code data-anolis-xref="event-dblclick">dblclick</code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-ondblclick" href="webappapis.html#handler-ondblclick">HTML elements</a>
+ <td> <code data-anolis-xref="event-dblclick"><a href="infrastructure.html#event-dblclick">dblclick</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-ondrag"> <code data-anolis-xref="">ondrag</code>
- <td> <a data-anolis-xref="handler-ondrag" href="webappapis.html#ondrag">HTML elements</a>
- <td> <code data-anolis-xref="event-drag"><a href="editing.html#drag">drag</a></code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-ondrag" href="webappapis.html#handler-ondrag">HTML elements</a>
+ <td> <code data-anolis-xref="event-dnd-drag"><a href="editing.html#event-dnd-drag">drag</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-ondragend"> <code data-anolis-xref="">ondragend</code>
- <td> <a data-anolis-xref="handler-ondragend" href="webappapis.html#ondragend">HTML elements</a>
- <td> <code data-anolis-xref="event-dragend"><a href="editing.html#dragend">dragend</a></code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-ondragend" href="webappapis.html#handler-ondragend">HTML elements</a>
+ <td> <code data-anolis-xref="event-dnd-dragend"><a href="editing.html#event-dnd-dragend">dragend</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-ondragenter"> <code data-anolis-xref="">ondragenter</code>
- <td> <a data-anolis-xref="handler-ondragenter" href="webappapis.html#ondragenter">HTML elements</a>
- <td> <code data-anolis-xref="event-dragenter"><a href="editing.html#dragenter">dragenter</a></code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-ondragenter" href="webappapis.html#handler-ondragenter">HTML elements</a>
+ <td> <code data-anolis-xref="event-dnd-dragenter"><a href="editing.html#event-dnd-dragenter">dragenter</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-ondragexit"> <code data-anolis-xref="">ondragexit</code>
- <td> <a data-anolis-xref="handler-ondragexit" href="webappapis.html#ondragexit">HTML elements</a>
- <td> <code data-anolis-xref="event-dragexit"><a href="editing.html#dragexit">dragexit</a></code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-ondragexit" href="webappapis.html#handler-ondragexit">HTML elements</a>
+ <td> <code data-anolis-xref="event-dnd-dragexit"><a href="editing.html#event-dnd-dragexit">dragexit</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-ondragleave"> <code data-anolis-xref="">ondragleave</code>
- <td> <a data-anolis-xref="handler-ondragleave" href="webappapis.html#ondragleave">HTML elements</a>
- <td> <code data-anolis-xref="event-dragleave"><a href="editing.html#dragleave">dragleave</a></code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-ondragleave" href="webappapis.html#handler-ondragleave">HTML elements</a>
+ <td> <code data-anolis-xref="event-dnd-dragleave"><a href="editing.html#event-dnd-dragleave">dragleave</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-ondragover"> <code data-anolis-xref="">ondragover</code>
- <td> <a data-anolis-xref="handler-ondragover" href="webappapis.html#ondragover">HTML elements</a>
- <td> <code data-anolis-xref="event-dragover"><a href="editing.html#dragover">dragover</a></code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-ondragover" href="webappapis.html#handler-ondragover">HTML elements</a>
+ <td> <code data-anolis-xref="event-dnd-dragover"><a href="editing.html#event-dnd-dragover">dragover</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-ondragstart"> <code data-anolis-xref="">ondragstart</code>
- <td> <a data-anolis-xref="handler-ondragstart" href="webappapis.html#ondragstart">HTML elements</a>
- <td> <code data-anolis-xref="event-dragstart"><a href="editing.html#dragstart">dragstart</a></code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-ondragstart" href="webappapis.html#handler-ondragstart">HTML elements</a>
+ <td> <code data-anolis-xref="event-dnd-dragstart"><a href="editing.html#event-dnd-dragstart">dragstart</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-ondrop"> <code data-anolis-xref="">ondrop</code>
- <td> <a data-anolis-xref="handler-ondrop" href="webappapis.html#ondrop">HTML elements</a>
- <td> <code data-anolis-xref="event-drop"><a href="editing.html#drop">drop</a></code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-ondrop" href="webappapis.html#handler-ondrop">HTML elements</a>
+ <td> <code data-anolis-xref="event-dnd-drop"><a href="editing.html#event-dnd-drop">drop</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-ondurationchange"> <code data-anolis-xref="">ondurationchange</code>
- <td> <a data-anolis-xref="handler-ondurationchange" href="webappapis.html#ondurationchange-0">HTML elements</a>
- <td> <code data-anolis-xref="event-media-durationchange"><a href="embedded-content-0.html#durationchange">durationchange</a></code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-ondurationchange" href="webappapis.html#handler-ondurationchange">HTML elements</a>
+ <td> <code data-anolis-xref="event-media-durationchange"><a href="embedded-content.html#event-media-durationchange">durationchange</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onemptied"> <code data-anolis-xref="">onemptied</code>
- <td> <a data-anolis-xref="handler-onemptied" href="webappapis.html#onemptied-0">HTML elements</a>
- <td> <code data-anolis-xref="event-media-emptied"><a href="embedded-content-0.html#emptied">emptied</a></code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onemptied" href="webappapis.html#handler-onemptied">HTML elements</a>
+ <td> <code data-anolis-xref="event-media-emptied"><a href="embedded-content.html#event-media-emptied">emptied</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onended"> <code data-anolis-xref="">onended</code>
- <td> <a data-anolis-xref="handler-onended" href="webappapis.html#onended-0">HTML elements</a>
- <td> <code data-anolis-xref="event-media-ended"><a href="embedded-content-0.html#ended-1">ended</a></code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onended" href="webappapis.html#handler-onended">HTML elements</a>
+ <td> <code data-anolis-xref="event-media-ended"><a href="embedded-content.html#event-media-ended">ended</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onerror"> <code data-anolis-xref="">onerror</code>
- <td> <a data-anolis-xref="handler-onerror" href="webappapis.html#onerror-0">HTML elements</a>
- <td> <code data-anolis-xref="event-error">error</code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onerror" href="webappapis.html#handler-onerror">HTML elements</a>
+ <td> <code data-anolis-xref="event-error"><a href="#event-error">error</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onfocus"> <code data-anolis-xref="">onfocus</code>
- <td> <a data-anolis-xref="handler-onfocus" href="webappapis.html#onfocus">HTML elements</a>
- <td> <code data-anolis-xref="event-focus">focus</code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onfocus" href="webappapis.html#handler-onfocus">HTML elements</a>
+ <td> <code data-anolis-xref="event-focus"><a href="#event-focus">focus</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-window-onhashchange"> <code data-anolis-xref="">onhashchange</code>
- <td> <code data-anolis-xref="handler-window-onhashchange"><a href="webappapis.html#onhashchange">body</a></code>
- <td> <code data-anolis-xref="event-hashchange"><a href="browsers.html#hashchange">hashchange</a></code> event handler for <code><a href="browsers.html#window">Window</a></code> object
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <code data-anolis-xref="handler-window-onhashchange"><a href="webappapis.html#handler-window-onhashchange">body</a></code>
+ <td> <code data-anolis-xref="event-hashchange"><a href="#event-hashchange">hashchange</a></code> event handler for <code><a href="browsers.html#window">Window</a></code> object
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-oninput"> <code data-anolis-xref="">oninput</code>
- <td> <a data-anolis-xref="handler-oninput" href="webappapis.html#oninput">HTML elements</a>
- <td> <code data-anolis-xref="event-input">input</code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-oninput" href="webappapis.html#handler-oninput">HTML elements</a>
+ <td> <code data-anolis-xref="event-input"><a href="#event-input">input</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-oninvalid"> <code data-anolis-xref="">oninvalid</code>
- <td> <a data-anolis-xref="handler-oninvalid" href="webappapis.html#oninvalid">HTML elements</a>
- <td> <code data-anolis-xref="event-invalid">invalid</code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-oninvalid" href="webappapis.html#handler-oninvalid">HTML elements</a>
+ <td> <code data-anolis-xref="event-invalid"><a href="#event-invalid">invalid</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onkeydown"> <code data-anolis-xref="">onkeydown</code>
- <td> <a data-anolis-xref="handler-onkeydown" href="webappapis.html#onkeydown">HTML elements</a>
- <td> <code data-anolis-xref="event-keydown">keydown</code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onkeydown" href="webappapis.html#handler-onkeydown">HTML elements</a>
+ <td> <code data-anolis-xref="event-keydown"><a href="infrastructure.html#event-keydown">keydown</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onkeypress"> <code data-anolis-xref="">onkeypress</code>
- <td> <a data-anolis-xref="handler-onkeypress" href="webappapis.html#onkeypress">HTML elements</a>
- <td> <code data-anolis-xref="event-keypress">keypress</code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onkeypress" href="webappapis.html#handler-onkeypress">HTML elements</a>
+ <td> <code data-anolis-xref="event-keypress"><a href="infrastructure.html#event-keypress">keypress</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onkeyup"> <code data-anolis-xref="">onkeyup</code>
- <td> <a data-anolis-xref="handler-onkeyup" href="webappapis.html#onkeyup">HTML elements</a>
- <td> <code data-anolis-xref="event-keyup">keyup</code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onkeyup" href="webappapis.html#handler-onkeyup">HTML elements</a>
+ <td> <code data-anolis-xref="event-keyup"><a href="infrastructure.html#event-keyup">keyup</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
+
+ <tr><th id="ix-handler-window-onlanguagechange"> <code data-anolis-xref="">onlanguagechange</code>
+ <td> <code data-anolis-xref="handler-window-onlanguagechange"><a href="webappapis.html#handler-window-onlanguagechange">body</a></code>
+ <td> <code data-anolis-xref="event-languagechange"><a href="#event-languagechange">languagechange</a></code> event handler for <code><a href="browsers.html#window">Window</a></code> object
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onload"> <code data-anolis-xref="">onload</code>
- <td> <a data-anolis-xref="handler-onload" href="webappapis.html#onload">HTML elements</a>
- <td> <code data-anolis-xref="event-load">load</code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onload" href="webappapis.html#handler-onload">HTML elements</a>
+ <td> <code data-anolis-xref="event-load"><a href="#event-load">load</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onloadeddata"> <code data-anolis-xref="">onloadeddata</code>
- <td> <a data-anolis-xref="handler-onloadeddata" href="webappapis.html#onloadeddata-0">HTML elements</a>
- <td> <code data-anolis-xref="event-media-loadeddata"><a href="embedded-content-0.html#loadeddata">loadeddata</a></code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onloadeddata" href="webappapis.html#handler-onloadeddata">HTML elements</a>
+ <td> <code data-anolis-xref="event-media-loadeddata"><a href="embedded-content.html#event-media-loadeddata">loadeddata</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onloadedmetadata"> <code data-anolis-xref="">onloadedmetadata</code>
- <td> <a data-anolis-xref="handler-onloadedmetadata" href="webappapis.html#onloadedmetadata-0">HTML elements</a>
- <td> <code data-anolis-xref="event-media-loadedmetadata"><a href="embedded-content-0.html#loadedmetadata">loadedmetadata</a></code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onloadedmetadata" href="webappapis.html#handler-onloadedmetadata">HTML elements</a>
+ <td> <code data-anolis-xref="event-media-loadedmetadata"><a href="embedded-content.html#event-media-loadedmetadata">loadedmetadata</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onloadstart"> <code data-anolis-xref="">onloadstart</code>
- <td> <a data-anolis-xref="handler-onloadstart" href="webappapis.html#onloadstart">HTML elements</a>
- <td> <code data-anolis-xref="event-media-loadstart"><a href="embedded-content-0.html#loadstart">loadstart</a></code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onloadstart" href="webappapis.html#handler-onloadstart">HTML elements</a>
+ <td> <code data-anolis-xref="event-media-loadstart"><a href="embedded-content.html#event-media-loadstart">loadstart</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-window-onmessage"> <code data-anolis-xref="">onmessage</code>
- <td> <code data-anolis-xref="handler-window-onmessage"><a href="webappapis.html#onmessage">body</a></code>
- <td> <code data-anolis-xref="event-message">message</code> event handler for <code><a href="browsers.html#window">Window</a></code> object
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <code data-anolis-xref="handler-window-onmessage"><a href="webappapis.html#handler-window-onmessage">body</a></code>
+ <td> <code data-anolis-xref="event-message"><a href="#event-message">message</a></code> event handler for <code><a href="browsers.html#window">Window</a></code> object
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onmousedown"> <code data-anolis-xref="">onmousedown</code>
- <td> <a data-anolis-xref="handler-onmousedown" href="webappapis.html#onmousedown">HTML elements</a>
- <td> <code data-anolis-xref="event-mousedown">mousedown</code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onmousedown" href="webappapis.html#handler-onmousedown">HTML elements</a>
+ <td> <code data-anolis-xref="event-mousedown"><a href="infrastructure.html#event-mousedown">mousedown</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onmouseenter"> <code data-anolis-xref="">onmouseenter</code>
- <td> <a data-anolis-xref="handler-onmouseenter" href="webappapis.html#onmouseenter">HTML elements</a>
- <td> <code data-anolis-xref="event-mouseenter">mouseenter</code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onmouseenter" href="webappapis.html#handler-onmouseenter">HTML elements</a>
+ <td> <code data-anolis-xref="event-mouseenter"><a href="infrastructure.html#event-mouseenter">mouseenter</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onmouseleave"> <code data-anolis-xref="">onmouseleave</code>
- <td> <a data-anolis-xref="handler-onmouseleave" href="webappapis.html#onmouseleave">HTML elements</a>
- <td> <code data-anolis-xref="event-mouseleave">mouseleave</code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onmouseleave" href="webappapis.html#handler-onmouseleave">HTML elements</a>
+ <td> <code data-anolis-xref="event-mouseleave"><a href="infrastructure.html#event-mouseleave">mouseleave</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onmousemove"> <code data-anolis-xref="">onmousemove</code>
- <td> <a data-anolis-xref="handler-onmousemove" href="webappapis.html#onmousemove">HTML elements</a>
- <td> <code data-anolis-xref="event-mousemove">mousemove</code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onmousemove" href="webappapis.html#handler-onmousemove">HTML elements</a>
+ <td> <code data-anolis-xref="event-mousemove"><a href="infrastructure.html#event-mousemove">mousemove</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onmouseout"> <code data-anolis-xref="">onmouseout</code>
- <td> <a data-anolis-xref="handler-onmouseout" href="webappapis.html#onmouseout">HTML elements</a>
- <td> <code data-anolis-xref="event-mouseout">mouseout</code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onmouseout" href="webappapis.html#handler-onmouseout">HTML elements</a>
+ <td> <code data-anolis-xref="event-mouseout"><a href="infrastructure.html#event-mouseout">mouseout</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onmouseover"> <code data-anolis-xref="">onmouseover</code>
- <td> <a data-anolis-xref="handler-onmouseover" href="webappapis.html#onmouseover">HTML elements</a>
- <td> <code data-anolis-xref="event-mouseover">mouseover</code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onmouseover" href="webappapis.html#handler-onmouseover">HTML elements</a>
+ <td> <code data-anolis-xref="event-mouseover"><a href="infrastructure.html#event-mouseover">mouseover</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onmouseup"> <code data-anolis-xref="">onmouseup</code>
- <td> <a data-anolis-xref="handler-onmouseup" href="webappapis.html#onmouseup">HTML elements</a>
- <td> <code data-anolis-xref="event-mouseup">mouseup</code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onmouseup" href="webappapis.html#handler-onmouseup">HTML elements</a>
+ <td> <code data-anolis-xref="event-mouseup"><a href="infrastructure.html#event-mouseup">mouseup</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onmousewheel"> <code data-anolis-xref="">onmousewheel</code>
- <td> <a data-anolis-xref="handler-onmousewheel" href="webappapis.html#onmousewheel">HTML elements</a>
- <td> <code data-anolis-xref="event-mousewheel">mousewheel</code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onmousewheel" href="webappapis.html#handler-onmousewheel">HTML elements</a>
+ <td> <code data-anolis-xref="event-mousewheel"><a href="infrastructure.html#event-mousewheel">mousewheel</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-window-onoffline"> <code data-anolis-xref="">onoffline</code>
- <td> <code data-anolis-xref="handler-window-onoffline"><a href="webappapis.html#onoffline">body</a></code>
- <td> <code data-anolis-xref="event-offline"><a href="browsers.html#offline-0">offline</a></code> event handler for <code><a href="browsers.html#window">Window</a></code> object
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <code data-anolis-xref="handler-window-onoffline"><a href="webappapis.html#handler-window-onoffline">body</a></code>
+ <td> <code data-anolis-xref="event-offline"><a href="#event-offline">offline</a></code> event handler for <code><a href="browsers.html#window">Window</a></code> object
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-window-ononline"> <code data-anolis-xref="">ononline</code>
- <td> <code data-anolis-xref="handler-window-ononline"><a href="webappapis.html#ononline">body</a></code>
- <td> <code data-anolis-xref="event-online"><a href="browsers.html#online">online</a></code> event handler for <code><a href="browsers.html#window">Window</a></code> object
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <code data-anolis-xref="handler-window-ononline"><a href="webappapis.html#handler-window-ononline">body</a></code>
+ <td> <code data-anolis-xref="event-online"><a href="#event-online">online</a></code> event handler for <code><a href="browsers.html#window">Window</a></code> object
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-window-onpagehide"> <code data-anolis-xref="">onpagehide</code>
- <td> <code data-anolis-xref="handler-window-onpagehide"><a href="webappapis.html#onpagehide">body</a></code>
- <td> <code data-anolis-xref="event-pagehide"><a href="browsers.html#pagehide">pagehide</a></code> event handler for <code><a href="browsers.html#window">Window</a></code> object
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <code data-anolis-xref="handler-window-onpagehide"><a href="webappapis.html#handler-window-onpagehide">body</a></code>
+ <td> <code data-anolis-xref="event-pagehide"><a href="#event-pagehide">pagehide</a></code> event handler for <code><a href="browsers.html#window">Window</a></code> object
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-window-onpageshow"> <code data-anolis-xref="">onpageshow</code>
- <td> <code data-anolis-xref="handler-window-onpageshow"><a href="webappapis.html#onpageshow">body</a></code>
- <td> <code data-anolis-xref="event-pageshow"><a href="browsers.html#pageshow">pageshow</a></code> event handler for <code><a href="browsers.html#window">Window</a></code> object
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <code data-anolis-xref="handler-window-onpageshow"><a href="webappapis.html#handler-window-onpageshow">body</a></code>
+ <td> <code data-anolis-xref="event-pageshow"><a href="#event-pageshow">pageshow</a></code> event handler for <code><a href="browsers.html#window">Window</a></code> object
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onpause"> <code data-anolis-xref="">onpause</code>
- <td> <a data-anolis-xref="handler-onpause" href="webappapis.html#onpause-0">HTML elements</a>
- <td> <code data-anolis-xref="event-media-pause"><a href="embedded-content-0.html#pause">pause</a></code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onpause" href="webappapis.html#handler-onpause">HTML elements</a>
+ <td> <code data-anolis-xref="event-media-pause"><a href="embedded-content.html#event-media-pause">pause</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onplay"> <code data-anolis-xref="">onplay</code>
- <td> <a data-anolis-xref="handler-onplay" href="webappapis.html#onplay-0">HTML elements</a>
- <td> <code data-anolis-xref="event-media-play"><a href="embedded-content-0.html#play">play</a></code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onplay" href="webappapis.html#handler-onplay">HTML elements</a>
+ <td> <code data-anolis-xref="event-media-play"><a href="embedded-content.html#event-media-play">play</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onplaying"> <code data-anolis-xref="">onplaying</code>
- <td> <a data-anolis-xref="handler-onplaying" href="webappapis.html#onplaying-0">HTML elements</a>
- <td> <code data-anolis-xref="event-media-playing"><a href="embedded-content-0.html#playing-0">playing</a></code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onplaying" href="webappapis.html#handler-onplaying">HTML elements</a>
+ <td> <code data-anolis-xref="event-media-playing"><a href="embedded-content.html#event-media-playing">playing</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-window-onpopstate"> <code data-anolis-xref="">onpopstate</code>
- <td> <code data-anolis-xref="handler-window-onpopstate"><a href="webappapis.html#onpopstate">body</a></code>
- <td> <code data-anolis-xref="event-popstate"><a href="browsers.html#popstate">popstate</a></code> event handler for <code><a href="browsers.html#window">Window</a></code> object
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <code data-anolis-xref="handler-window-onpopstate"><a href="webappapis.html#handler-window-onpopstate">body</a></code>
+ <td> <code data-anolis-xref="event-popstate"><a href="#event-popstate">popstate</a></code> event handler for <code><a href="browsers.html#window">Window</a></code> object
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onprogress"> <code data-anolis-xref="">onprogress</code>
- <td> <a data-anolis-xref="handler-onprogress" href="webappapis.html#onprogress-0">HTML elements</a>
- <td> <code data-anolis-xref="event-media-progress"><a href="embedded-content-0.html#progress">progress</a></code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onprogress" href="webappapis.html#handler-onprogress">HTML elements</a>
+ <td> <code data-anolis-xref="event-media-progress"><a href="embedded-content.html#event-media-progress">progress</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onratechange"> <code data-anolis-xref="">onratechange</code>
- <td> <a data-anolis-xref="handler-onratechange" href="webappapis.html#onratechange-0">HTML elements</a>
- <td> <code data-anolis-xref="event-media-ratechange"><a href="embedded-content-0.html#ratechange">ratechange</a></code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onratechange" href="webappapis.html#handler-onratechange">HTML elements</a>
+ <td> <code data-anolis-xref="event-media-ratechange"><a href="embedded-content.html#event-media-ratechange">ratechange</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onreset"> <code data-anolis-xref="">onreset</code>
- <td> <a data-anolis-xref="handler-onreset" href="webappapis.html#onreset">HTML elements</a>
- <td> <code data-anolis-xref="event-reset">reset</code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onreset" href="webappapis.html#handler-onreset">HTML elements</a>
+ <td> <code data-anolis-xref="event-reset"><a href="#event-reset">reset</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onresize"> <code data-anolis-xref="">onresize</code>
- <td> <a data-anolis-xref="handler-onresize" href="webappapis.html#onresize">HTML elements</a>
- <td> <code data-anolis-xref="event-resize">resize</code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onresize" href="webappapis.html#handler-onresize">HTML elements</a>
+ <td> <code data-anolis-xref="event-resize"><a href="infrastructure.html#event-resize">resize</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onscroll"> <code data-anolis-xref="">onscroll</code>
- <td> <a data-anolis-xref="handler-onscroll" href="webappapis.html#onscroll">HTML elements</a>
- <td> <code data-anolis-xref="event-scroll">scroll</code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onscroll" href="webappapis.html#handler-onscroll">HTML elements</a>
+ <td> <code data-anolis-xref="event-scroll"><a href="infrastructure.html#event-scroll">scroll</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onseeked"> <code data-anolis-xref="">onseeked</code>
- <td> <a data-anolis-xref="handler-onseeked" href="webappapis.html#onseeked">HTML elements</a>
- <td> <code data-anolis-xref="event-media-seeked"><a href="embedded-content-0.html#seeked">seeked</a></code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onseeked" href="webappapis.html#handler-onseeked">HTML elements</a>
+ <td> <code data-anolis-xref="event-media-seeked"><a href="embedded-content.html#event-media-seeked">seeked</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onseeking"> <code data-anolis-xref="">onseeking</code>
- <td> <a data-anolis-xref="handler-onseeking" href="webappapis.html#onseeking">HTML elements</a>
- <td> <code data-anolis-xref="event-media-seeking"><a href="embedded-content-0.html#seeking-1">seeking</a></code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onseeking" href="webappapis.html#handler-onseeking">HTML elements</a>
+ <td> <code data-anolis-xref="event-media-seeking"><a href="embedded-content.html#event-media-seeking">seeking</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onselect"> <code data-anolis-xref="">onselect</code>
- <td> <a data-anolis-xref="handler-onselect" href="webappapis.html#onselect">HTML elements</a>
- <td> <code data-anolis-xref="event-select">select</code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onselect" href="webappapis.html#handler-onselect">HTML elements</a>
+ <td> <code data-anolis-xref="event-select"><a href="#event-select">select</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onshow"> <code data-anolis-xref="">onshow</code>
- <td> <a data-anolis-xref="handler-onshow" href="webappapis.html#onshow">HTML elements</a>
- <td> <code data-anolis-xref="event-show">show</code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onshow" href="webappapis.html#handler-onshow">HTML elements</a>
+ <td> <code data-anolis-xref="event-show"><a href="#event-show">show</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onsort"> <code data-anolis-xref="">onsort</code>
- <td> <a data-anolis-xref="handler-onsort" href="webappapis.html#onsort">HTML elements</a>
- <td> <code data-anolis-xref="event-sort">sort</code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onsort" href="webappapis.html#handler-onsort">HTML elements</a>
+ <td> <code data-anolis-xref="event-sort"><a href="#event-sort">sort</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onstalled"> <code data-anolis-xref="">onstalled</code>
- <td> <a data-anolis-xref="handler-onstalled" href="webappapis.html#onstalled">HTML elements</a>
- <td> <code data-anolis-xref="event-media-stalled"><a href="embedded-content-0.html#stalled">stalled</a></code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onstalled" href="webappapis.html#handler-onstalled">HTML elements</a>
+ <td> <code data-anolis-xref="event-media-stalled"><a href="embedded-content.html#event-media-stalled">stalled</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-window-onstorage"> <code data-anolis-xref="">onstorage</code>
- <td> <code data-anolis-xref="handler-window-onstorage"><a href="webappapis.html#onstorage">body</a></code>
- <td> <code data-anolis-xref="event-storage">storage</code> event handler for <code><a href="browsers.html#window">Window</a></code> object
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <code data-anolis-xref="handler-window-onstorage"><a href="webappapis.html#handler-window-onstorage">body</a></code>
+ <td> <code data-anolis-xref="event-storage"><a href="#event-storage">storage</a></code> event handler for <code><a href="browsers.html#window">Window</a></code> object
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onsubmit"> <code data-anolis-xref="">onsubmit</code>
- <td> <a data-anolis-xref="handler-onsubmit" href="webappapis.html#onsubmit">HTML elements</a>
- <td> <code data-anolis-xref="event-submit">submit</code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onsubmit" href="webappapis.html#handler-onsubmit">HTML elements</a>
+ <td> <code data-anolis-xref="event-submit"><a href="#event-submit">submit</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onsuspend"> <code data-anolis-xref="">onsuspend</code>
- <td> <a data-anolis-xref="handler-onsuspend" href="webappapis.html#onsuspend">HTML elements</a>
- <td> <code data-anolis-xref="event-media-suspend"><a href="embedded-content-0.html#suspend">suspend</a></code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onsuspend" href="webappapis.html#handler-onsuspend">HTML elements</a>
+ <td> <code data-anolis-xref="event-media-suspend"><a href="embedded-content.html#event-media-suspend">suspend</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-ontimeupdate"> <code data-anolis-xref="">ontimeupdate</code>
- <td> <a data-anolis-xref="handler-ontimeupdate" href="webappapis.html#ontimeupdate-0">HTML elements</a>
- <td> <code data-anolis-xref="event-media-timeupdate"><a href="embedded-content-0.html#timeupdate">timeupdate</a></code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-ontimeupdate" href="webappapis.html#handler-ontimeupdate">HTML elements</a>
+ <td> <code data-anolis-xref="event-media-timeupdate"><a href="embedded-content.html#event-media-timeupdate">timeupdate</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-ontoggle"> <code data-anolis-xref="">ontoggle</code>
- <td> <a data-anolis-xref="handler-ontoggle" href="webappapis.html#ontoggle">HTML elements</a>
- <td> <code data-anolis-xref="event-toggle">toggle</code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-ontoggle" href="webappapis.html#handler-ontoggle">HTML elements</a>
+ <td> <code data-anolis-xref="event-toggle"><a href="#event-toggle">toggle</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-window-onunload"> <code data-anolis-xref="">onunload</code>
- <td> <code data-anolis-xref="handler-window-onunload"><a href="webappapis.html#onunload">body</a></code>
- <td> <code data-anolis-xref="event-unload">unload</code> event handler for <code><a href="browsers.html#window">Window</a></code> object
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <code data-anolis-xref="handler-window-onunload"><a href="webappapis.html#handler-window-onunload">body</a></code>
+ <td> <code data-anolis-xref="event-unload"><a href="#event-unload">unload</a></code> event handler for <code><a href="browsers.html#window">Window</a></code> object
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onvolumechange"> <code data-anolis-xref="">onvolumechange</code>
- <td> <a data-anolis-xref="handler-onvolumechange" href="webappapis.html#onvolumechange-0">HTML elements</a>
- <td> <code data-anolis-xref="event-media-volumechange"><a href="embedded-content-0.html#volumechange">volumechange</a></code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onvolumechange" href="webappapis.html#handler-onvolumechange">HTML elements</a>
+ <td> <code data-anolis-xref="event-media-volumechange"><a href="embedded-content.html#event-media-volumechange">volumechange</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
<tr><th id="ix-handler-onwaiting"> <code data-anolis-xref="">onwaiting</code>
- <td> <a data-anolis-xref="handler-onwaiting" href="webappapis.html#onwaiting-0">HTML elements</a>
- <td> <code data-anolis-xref="event-media-waiting"><a href="embedded-content-0.html#waiting-0">waiting</a></code> event handler
- <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attribute">Event handler content attribute</a>
+ <td> <a data-anolis-xref="handler-onwaiting" href="webappapis.html#handler-onwaiting">HTML elements</a>
+ <td> <code data-anolis-xref="event-media-waiting"><a href="embedded-content.html#event-media-waiting">waiting</a></code> event handler
+ <td> <a data-anolis-xref="event handler content attributes" href="webappapis.html#event-handler-content-attributes">Event handler content attribute</a>
</table><!-- v2 for completeness: (also search for REFLECTIDL)
<h3 class="no-num">Reflecting IDL attributes</h3>
- <!- -END dev-html- -><p><i>This section is non-normative.</i></p><!- -START dev-html- ->
+ <p><i>This section is non-normative.</i></p>
<table>
<caption>List of <dfn>reflecting IDL attributes</dfn></caption>
@@ -3217,6 +3246,7 @@
--><h3 class="no-num" id="element-interfaces">Element Interfaces</h3>
<p><i>This section is non-normative.</i></p>
+
<table><caption>List of interfaces for elements</caption>
<thead><tr><th> Element(s)
<th> Interface(s)
@@ -3229,8 +3259,8 @@
<tr><td> <code><a href="sections.html#the-address-element">address</a></code>
<td> <code><a href="dom.html#htmlelement">HTMLElement</a></code>
- <tr><td> <code><a href="embedded-content-0.html#the-area-element">area</a></code>
- <td> <code><a href="embedded-content-0.html#htmlareaelement">HTMLAreaElement</a></code> : <code><a href="dom.html#htmlelement">HTMLElement</a></code>
+ <tr><td> <code><a href="embedded-content.html#the-area-element">area</a></code>
+ <td> <code><a href="embedded-content.html#htmlareaelement">HTMLAreaElement</a></code> : <code><a href="dom.html#htmlelement">HTMLElement</a></code>
<tr><td> <code><a href="sections.html#the-article-element">article</a></code>
<td> <code><a href="dom.html#htmlelement">HTMLElement</a></code>
@@ -3238,8 +3268,8 @@
<tr><td> <code><a href="sections.html#the-aside-element">aside</a></code>
<td> <code><a href="dom.html#htmlelement">HTMLElement</a></code>
- <tr><td> <code><a href="embedded-content-0.html#the-audio-element">audio</a></code>
- <td> <code><a href="embedded-content-0.html#htmlaudioelement">HTMLAudioElement</a></code> : <code><a href="embedded-content-0.html#htmlmediaelement">HTMLMediaElement</a></code> : <code><a href="dom.html#htmlelement">HTMLElement</a></code>
+ <tr><td> <code><a href="embedded-content.html#the-audio-element">audio</a></code>
+ <td> <code><a href="embedded-content.html#htmlaudioelement">HTMLAudioElement</a></code> : <code><a href="embedded-content.html#htmlmediaelement">HTMLMediaElement</a></code> : <code><a href="dom.html#htmlelement">HTMLElement</a></code>
<tr><td> <code><a href="text-level-semantics.html#the-b-element">b</a></code>
<td> <code><a href="dom.html#htmlelement">HTMLElement</a></code>
@@ -3319,8 +3349,8 @@
<tr><td> <code><a href="text-level-semantics.html#the-em-element">em</a></code>
<td> <code><a href="dom.html#htmlelement">HTMLElement</a></code>
- <tr><td> <code><a href="embedded-content-0.html#the-embed-element">embed</a></code>
- <td> <code><a href="embedded-content-0.html#htmlembedelement">HTMLEmbedElement</a></code> : <code><a href="dom.html#htmlelement">HTMLElement</a></code>
+ <tr><td> <code><a href="embedded-content.html#the-embed-element">embed</a></code>
+ <td> <code><a href="embedded-content.html#htmlembedelement">HTMLEmbedElement</a></code> : <code><a href="dom.html#htmlelement">HTMLElement</a></code>
<tr><td> <code><a href="forms.html#the-fieldset-element">fieldset</a></code>
<td> <code><a href="forms.html#htmlfieldsetelement">HTMLFieldSetElement</a></code> : <code><a href="dom.html#htmlelement">HTMLElement</a></code>
@@ -3372,11 +3402,11 @@
<tr><td> <code><a href="text-level-semantics.html#the-i-element">i</a></code>
<td> <code><a href="dom.html#htmlelement">HTMLElement</a></code>
- <tr><td> <code><a href="embedded-content-0.html#the-iframe-element">iframe</a></code>
- <td> <code><a href="embedded-content-0.html#htmliframeelement">HTMLIFrameElement</a></code> : <code><a href="dom.html#htmlelement">HTMLElement</a></code>
+ <tr><td> <code><a href="embedded-content.html#the-iframe-element">iframe</a></code>
+ <td> <code><a href="embedded-content.html#htmliframeelement">HTMLIFrameElement</a></code> : <code><a href="dom.html#htmlelement">HTMLElement</a></code>
- <tr><td> <code><a href="embedded-content-0.html#the-img-element">img</a></code>
- <td> <code><a href="embedded-content-0.html#htmlimageelement">HTMLImageElement</a></code> : <code><a href="dom.html#htmlelement">HTMLElement</a></code>
+ <tr><td> <code><a href="embedded-content.html#the-img-element">img</a></code>
+ <td> <code><a href="embedded-content.html#htmlimageelement">HTMLImageElement</a></code> : <code><a href="dom.html#htmlelement">HTMLElement</a></code>
<tr><td> <code><a href="forms.html#the-input-element">input</a></code>
<td> <code><a href="forms.html#htmlinputelement">HTMLInputElement</a></code> : <code><a href="dom.html#htmlelement">HTMLElement</a></code>
@@ -3405,8 +3435,8 @@
<tr><td> <code><a href="grouping-content.html#the-main-element">main</a></code>
<td> <code><a href="dom.html#htmlelement">HTMLElement</a></code>
- <tr><td> <code><a href="embedded-content-0.html#the-map-element">map</a></code>
- <td> <code><a href="embedded-content-0.html#htmlmapelement">HTMLMapElement</a></code> : <code><a href="dom.html#htmlelement">HTMLElement</a></code>
+ <tr><td> <code><a href="embedded-content.html#the-map-element">map</a></code>
+ <td> <code><a href="embedded-content.html#htmlmapelement">HTMLMapElement</a></code> : <code><a href="dom.html#htmlelement">HTMLElement</a></code>
<tr><td> <code><a href="text-level-semantics.html#the-mark-element">mark</a></code>
<td> <code><a href="dom.html#htmlelement">HTMLElement</a></code>
@@ -3426,8 +3456,8 @@
<tr><td> <code><a href="scripting-1.html#the-noscript-element">noscript</a></code>
<td> <code><a href="dom.html#htmlelement">HTMLElement</a></code>
- <tr><td> <code><a href="embedded-content-0.html#the-object-element">object</a></code>
- <td> <code><a href="embedded-content-0.html#htmlobjectelement">HTMLObjectElement</a></code> : <code><a href="dom.html#htmlelement">HTMLElement</a></code>
+ <tr><td> <code><a href="embedded-content.html#the-object-element">object</a></code>
+ <td> <code><a href="embedded-content.html#htmlobjectelement">HTMLObjectElement</a></code> : <code><a href="dom.html#htmlelement">HTMLElement</a></code>
<tr><td> <code><a href="grouping-content.html#the-ol-element">ol</a></code>
<td> <code><a href="grouping-content.html#htmlolistelement">HTMLOListElement</a></code> : <code><a href="dom.html#htmlelement">HTMLElement</a></code>
@@ -3444,8 +3474,8 @@
<tr><td> <code><a href="grouping-content.html#the-p-element">p</a></code>
<td> <code><a href="grouping-content.html#htmlparagraphelement">HTMLParagraphElement</a></code> : <code><a href="dom.html#htmlelement">HTMLElement</a></code>
- <tr><td> <code><a href="embedded-content-0.html#the-param-element">param</a></code>
- <td> <code><a href="embedded-content-0.html#htmlparamelement">HTMLParamElement</a></code> : <code><a href="dom.html#htmlelement">HTMLElement</a></code>
+ <tr><td> <code><a href="embedded-content.html#the-param-element">param</a></code>
+ <td> <code><a href="embedded-content.html#htmlparamelement">HTMLParamElement</a></code> : <code><a href="dom.html#htmlelement">HTMLElement</a></code>
<tr><td> <code><a href="grouping-content.html#the-pre-element">pre</a></code>
<td> <code><a href="grouping-content.html#htmlpreelement">HTMLPreElement</a></code> : <code><a href="dom.html#htmlelement">HTMLElement</a></code>
@@ -3493,8 +3523,8 @@
<tr><td> <code><a href="text-level-semantics.html#the-small-element">small</a></code>
<td> <code><a href="dom.html#htmlelement">HTMLElement</a></code>
- <tr><td> <code><a href="embedded-content-0.html#the-source-element">source</a></code>
- <td> <code><a href="embedded-content-0.html#htmlsourceelement">HTMLSourceElement</a></code> : <code><a href="dom.html#htmlelement">HTMLElement</a></code>
+ <tr><td> <code><a href="embedded-content.html#the-source-element">source</a></code>
+ <td> <code><a href="embedded-content.html#htmlsourceelement">HTMLSourceElement</a></code> : <code><a href="dom.html#htmlelement">HTMLElement</a></code>
<tr><td> <code><a href="text-level-semantics.html#the-span-element">span</a></code>
<td> <code><a href="text-level-semantics.html#htmlspanelement">HTMLSpanElement</a></code> : <code><a href="dom.html#htmlelement">HTMLElement</a></code>
@@ -3547,8 +3577,8 @@
<tr><td> <code><a href="tabular-data.html#the-tr-element">tr</a></code>
<td> <code><a href="tabular-data.html#htmltablerowelement">HTMLTableRowElement</a></code> : <code><a href="dom.html#htmlelement">HTMLElement</a></code>
- <tr><td> <code><a href="embedded-content-0.html#the-track-element">track</a></code>
- <td> <code><a href="embedded-content-0.html#htmltrackelement">HTMLTrackElement</a></code> : <code><a href="dom.html#htmlelement">HTMLElement</a></code>
+ <tr><td> <code><a href="embedded-content.html#the-track-element">track</a></code>
+ <td> <code><a href="embedded-content.html#htmltrackelement">HTMLTrackElement</a></code> : <code><a href="dom.html#htmlelement">HTMLElement</a></code>
<tr><td> <code><a href="text-level-semantics.html#the-u-element">u</a></code>
<td> <code><a href="dom.html#htmlelement">HTMLElement</a></code>
@@ -3559,8 +3589,8 @@
<tr><td> <code><a href="text-level-semantics.html#the-var-element">var</a></code>
<td> <code><a href="dom.html#htmlelement">HTMLElement</a></code>
- <tr><td> <code><a href="embedded-content-0.html#the-video-element">video</a></code>
- <td> <code><a href="embedded-content-0.html#htmlvideoelement">HTMLVideoElement</a></code> : <code><a href="embedded-content-0.html#htmlmediaelement">HTMLMediaElement</a></code> : <code><a href="dom.html#htmlelement">HTMLElement</a></code>
+ <tr><td> <code><a href="embedded-content.html#the-video-element">video</a></code>
+ <td> <code><a href="embedded-content.html#htmlvideoelement">HTMLVideoElement</a></code> : <code><a href="embedded-content.html#htmlmediaelement">HTMLMediaElement</a></code> : <code><a href="dom.html#htmlelement">HTMLElement</a></code>
<tr><td> <code><a href="text-level-semantics.html#the-wbr-element">wbr</a></code>
<td> <code><a href="dom.html#htmlelement">HTMLElement</a></code>
@@ -3568,123 +3598,229 @@
</table><h3 class="no-num" id="all-interfaces">All Interfaces</h3>
<p><i>This section is non-normative.</i></p>
- <ul></ul><!-- (only has events from HTML5) --><h3 class="no-num" id="events-0">Events</h3>
+
+ <ul></ul><h3 class="no-num" id="events-0">Events</h3>
<p><i>This section is non-normative.</i></p>
+
<table><caption>List of events</caption>
<thead><tr><th> Event
<th> Interface
+ <th> Interesting targets
<th> Description
- <tbody><tr><td> <code data-anolis-xref="event-abort">abort</code>
+ <tbody><tr><!-- abort --><td> <dfn data-anolis-xref="event-abort" id="event-abort"><code>abort</code></dfn>
<td> <code><a href="infrastructure.html#event">Event</a></code>
+ <td> <code><a href="browsers.html#window">Window</a></code>
<td> Fired at the <code><a href="browsers.html#window">Window</a></code> when the download was aborted by the user
- <tr><td> <code data-anolis-xref="event-afterprint">afterprint</code>
+ <tr><!-- autocomplete --><td> <dfn data-anolis-xref="event-autocomplete" id="event-autocomplete"><code>autocomplete</code></dfn>
+ <td> <code><a href="infrastructure.html#event">Event</a></code>
+ <td> <code><a href="forms.html#the-form-element">form</a></code> elements
+ <td> Fired at a <code><a href="forms.html#the-form-element">form</a></code> element when it is <a data-anolis-xref="dom-form-requestAutocomplete" href="forms.html#dom-form-requestautocomplete">autofilled</a>
+
+ <tr><!-- autocompleteerror --><td> <dfn data-anolis-xref="event-autocompleteerror" id="event-autocompleteerror"><code>autocompleteerror</code></dfn>
+ <td> <code><a href="infrastructure.html#event">Event</a></code>
+ <td> <code><a href="forms.html#the-form-element">form</a></code> elements
+ <td> Fired at a <code><a href="forms.html#the-form-element">form</a></code> element when a <a data-anolis-xref="dom-form-requestAutocomplete" href="forms.html#dom-form-requestautocomplete">bulk autofill</a> fails
+
+ <tr><!-- DOMContentLoaded --><td> <dfn data-anolis-xref="event-DOMContentLoaded" id="event-domcontentloaded"><code>DOMContentLoaded</code></dfn>
+ <td> <code><a href="infrastructure.html#event">Event</a></code>
+ <td> <code><a href="dom.html#document">Document</a></code>
+ <td> Fired at the <code><a href="dom.html#document">Document</a></code> once the parser has finished
+
+ <tr><!-- afterprint --><td> <dfn data-anolis-xref="event-afterprint" id="event-afterprint"><code>afterprint</code></dfn>
<td> <code><a href="infrastructure.html#event">Event</a></code>
+ <td> <code><a href="browsers.html#window">Window</a></code>
<td> Fired at the <code><a href="browsers.html#window">Window</a></code> after printing
- <tr><td> <code data-anolis-xref="event-beforeprint">beforeprint</code>
+ <tr><!-- afterscriptexecute --><td> <dfn data-anolis-xref="event-afterscriptexecute" id="event-afterscriptexecute"><code>afterscriptexecute</code></dfn>
<td> <code><a href="infrastructure.html#event">Event</a></code>
+ <td> <code><a href="scripting-1.html#the-script-element">script</a></code> elements
+ <td> Fired at <code><a href="scripting-1.html#the-script-element">script</a></code> elements after the script runs (just before the corresponding <code data-anolis-xref="event-load"><a href="#event-load">load</a></code> event)
+
+ <tr><!-- beforeprint --><td> <dfn data-anolis-xref="event-beforeprint" id="event-beforeprint"><code>beforeprint</code></dfn>
+ <td> <code><a href="infrastructure.html#event">Event</a></code>
+ <td> <code><a href="browsers.html#window">Window</a></code>
<td> Fired at the <code><a href="browsers.html#window">Window</a></code> before printing
- <tr><td> <code data-anolis-xref="event-beforeunload">beforeunload</code>
+ <tr><!-- beforescriptexecute --><td> <dfn data-anolis-xref="event-beforescriptexecute" id="event-beforescriptexecute"><code>beforescriptexecute</code></dfn>
+ <td> <code><a href="infrastructure.html#event">Event</a></code>
+ <td> <code><a href="scripting-1.html#the-script-element">script</a></code> elements
+ <td> Fired at <code><a href="scripting-1.html#the-script-element">script</a></code> elements just before the script runs; canceling the event cancels the running of the script
+
+ <tr><!-- beforeunload --><td> <dfn data-anolis-xref="event-beforeunload" id="event-beforeunload"><code>beforeunload</code></dfn>
<td> <code><a href="browsers.html#beforeunloadevent">BeforeUnloadEvent</a></code>
+ <td> <code><a href="browsers.html#window">Window</a></code>
<td> Fired at the <code><a href="browsers.html#window">Window</a></code> when the page is about to be unloaded, in case the page would like to show a warning prompt
- <tr><td> <code data-anolis-xref="event-blur">blur</code>
+ <tr><!-- blur --><td> <dfn data-anolis-xref="event-blur" id="event-blur"><code>blur</code></dfn>
<td> <code><a href="infrastructure.html#event">Event</a></code>
- <td> Fired at nodes losing focus
+ <td> <code><a href="browsers.html#window">Window</a></code>, elements
+ <td> Fired at nodes losing focus <!-- XXX bug 23475 -->
- <tr><td> <code data-anolis-xref="event-change">change</code>
+ <tr><!-- cancel --><td> <dfn data-anolis-xref="event-cancel" id="event-cancel"><code>cancel</code></dfn>
<td> <code><a href="infrastructure.html#event">Event</a></code>
- <td> Fired at controls when the user commits a value change
+ <td> <code><a href="interactive-elements.html#the-dialog-element">dialog</a></code> elements
+ <td> Fired at <code><a href="interactive-elements.html#the-dialog-element">dialog</a></code> elements when they are canceled by the user (e.g. by pressing the Escape key)
- <tr><td> <code data-anolis-xref="event-click"><a href="infrastructure.html#click">click</a></code>
+ <tr><!-- change --><td> <dfn data-anolis-xref="event-change" id="event-change"><code>change</code></dfn>
<td> <code><a href="infrastructure.html#event">Event</a></code>
- <td> Fired at an element before its <a href="dom.html#activation-behavior">activation behavior</a> is run
+ <td> Form controls
+ <td> Fired at controls when the user commits a value change (see also the <code data-anolis-xref="event-input-change"><a href="forms.html#event-input-change">change</a></code> event of <code><a href="forms.html#the-input-element">input</a></code> elements)
- <tr><td> <code data-anolis-xref="event-contextmenu">contextmenu</code>
+ <tr><!-- click --><td> <code data-anolis-xref="event-click"><a href="infrastructure.html#event-click">click</a></code>
+ <td> <code><a href="infrastructure.html#mouseevent">MouseEvent</a></code>
+ <td> Elements
+ <td> Normally a mouse event; also synthetically fired at an element before its <a href="editing.html#activation-behavior">activation behavior</a> is run, when an element is activated from a non-pointer input device (e.g. a keyboard)
+
+ <tr><!-- close --><td> <dfn data-anolis-xref="event-close" id="event-close"><code>close</code></dfn>
<td> <code><a href="infrastructure.html#event">Event</a></code>
- <td> Fired at elements when the user requests their context menu
+ <td> <code><a href="interactive-elements.html#the-dialog-element">dialog</a></code> elements, <code>WebSocket</code>
+ <td> Fired at <code><a href="interactive-elements.html#the-dialog-element">dialog</a></code> elements when they are closed, and at <code>WebSocket</code> elements when the connection is terminated
+
+ <tr><!-- connect --><td> <dfn data-anolis-xref="event-WorkerGlobalScope-connect" id="event-workerglobalscope-connect"><code>connect</code></dfn>
+ <td> <code>MessageEvent</code>
+ <td> <code>SharedWorkerGlobalScope</code>
+ <td> Fired at a shared worker's global scope when a new client connects
- <tr><td> <code data-anolis-xref="event-DOMContentLoaded">DOMContentLoaded</code>
+ <tr><!-- contextmenu --><td> <dfn data-anolis-xref="event-contextmenu" id="event-contextmenu"><code>contextmenu</code></dfn>
<td> <code><a href="infrastructure.html#event">Event</a></code>
- <td> Fired at the <code><a href="dom.html#document-0">Document</a></code> once the parser has finished
+ <td> Elements
+ <td> Fired at elements when the user requests their context menu
- <tr><td> <code data-anolis-xref="event-error">error</code>
+ <tr><!-- error --><td> <dfn data-anolis-xref="event-error" id="event-error"><code>error</code></dfn>
<td> <code><a href="infrastructure.html#event">Event</a></code>
- <td> Fired at elements when network and script errors occur
+ <td> Global scope objects, <code>Worker</code> objects, elements, networking-related objects
+ <td> Fired when unexpected errors occur (e.g. networking errors, script errors, decoding errors)
- <tr><td> <code data-anolis-xref="event-focus">focus</code>
+ <tr><!-- focus --><td> <dfn data-anolis-xref="event-focus" id="event-focus"><code>focus</code></dfn>
<td> <code><a href="infrastructure.html#event">Event</a></code>
- <td> Fired at nodes gaining focus
+ <td> <code><a href="browsers.html#window">Window</a></code>, elements
+ <td> Fired at nodes gaining focus <!-- XXX bug 23475 -->
- <tr><td> <code data-anolis-xref="event-hashchange"><a href="browsers.html#hashchange">hashchange</a></code>
+ <tr><!-- hashchange --><td> <dfn data-anolis-xref="event-hashchange" id="event-hashchange"><code>hashchange</code></dfn>
<td> <code><a href="browsers.html#hashchangeevent">HashChangeEvent</a></code>
+ <td> <code><a href="browsers.html#window">Window</a></code>
<td> Fired at the <code><a href="browsers.html#window">Window</a></code> when the fragment identifier part of <a href="dom.html#the-document's-address">the document's address</a> changes
- <tr><td> <code data-anolis-xref="event-input">input</code>
+ <tr><!-- input --><td> <dfn data-anolis-xref="event-input" id="event-input"><code>input</code></dfn>
<td> <code><a href="infrastructure.html#event">Event</a></code>
- <td> Fired at controls when the user changes the value
+ <td> Form controls
+ <td> Fired at controls when the user changes the value (see also the <code data-anolis-xref="event-input-change"><a href="forms.html#event-input-change">change</a></code> event of <code><a href="forms.html#the-input-element">input</a></code> elements)
- <tr><td> <code data-anolis-xref="event-invalid">invalid</code>
+ <tr><!-- invalid --><td> <dfn data-anolis-xref="event-invalid" id="event-invalid"><code>invalid</code></dfn>
<td> <code><a href="infrastructure.html#event">Event</a></code>
+ <td> Form controls
<td> Fired at controls during form validation if they do not satisfy their constraints
- <tr><td> <code data-anolis-xref="event-load">load</code>
+ <tr><!-- languagechange --><td> <dfn data-anolis-xref="event-languagechange" id="event-languagechange"><code>languagechange</code></dfn>
+ <td> <code><a href="infrastructure.html#event">Event</a></code>
+ <td> Global scope objects
+ <td> Fired at the global scope object when the user's preferred languages change
+
+ <tr><!-- load --><td> <dfn data-anolis-xref="event-load" id="event-load"><code>load</code></dfn>
<td> <code><a href="infrastructure.html#event">Event</a></code>
- <td> Fired at the <code><a href="browsers.html#window">Window</a></code> when the document has finished loading; fired at an element containing a resource (e.g. <code><a href="embedded-content-0.html#the-img-element">img</a></code>, <code><a href="embedded-content-0.html#the-embed-element">embed</a></code>) when its resource has finished loading
+ <td> <code><a href="browsers.html#window">Window</a></code>, elements
+ <td> Fired at the <code><a href="browsers.html#window">Window</a></code> when the document has finished loading; fired at an element containing a resource (e.g. <code><a href="embedded-content.html#the-img-element">img</a></code>, <code><a href="embedded-content.html#the-embed-element">embed</a></code>) when its resource has finished loading
- <tr><td> <code data-anolis-xref="event-message">message</code>
+ <tr><!-- loadend --><td> <dfn data-anolis-xref="event-loadend" id="event-loadend"><code>loadend</code></dfn>
+ <td> <code><a href="infrastructure.html#event">Event</a></code> or <code><a href="infrastructure.html#progressevent">ProgressEvent</a></code>
+ <td> <code><a href="embedded-content.html#the-img-element">img</a></code> elements
+ <td> Fired at <code><a href="embedded-content.html#the-img-element">img</a></code> elements after a successful load (see also <span data-anolis-xref="event-media-loadend">media element events</span>)
+
+ <tr><!-- loadstart --><td> <dfn data-anolis-xref="event-loadstart" id="event-loadstart"><code>loadstart</code></dfn>
+ <td> <code><a href="infrastructure.html#progressevent">ProgressEvent</a></code>
+ <td> <code><a href="embedded-content.html#the-img-element">img</a></code> elements
+ <td> Fired at <code><a href="embedded-content.html#the-img-element">img</a></code> elements when a load begins (see also <a data-anolis-xref="event-media-loadstart" href="embedded-content.html#event-media-loadstart">media element events</a>)
+
+ <tr><!-- message --><td> <dfn data-anolis-xref="event-message" id="event-message"><code>message</code></dfn>
<td> <code>MessageEvent</code>
- <td> Fired at an object when the object receives a message
+ <td> <code><a href="browsers.html#window">Window</a></code>, <code><a href="infrastructure.html#eventsource">EventSource</a></code>, <code>WebSocket</code>, <code>MessagePort</code>, <code>BroadcastChannel</code>, <code>DedicatedWorkerGlobalScope</code>, <code>Worker</code>
+ <td> Fired at an object when it receives a message
+
+ <tr><!-- offline --><td> <dfn data-anolis-xref="event-offline" id="event-offline"><code>offline</code></dfn>
+ <td> <code><a href="infrastructure.html#event">Event</a></code>
+ <td> Global scope objects
+ <td> Fired at the global scope object when the network connections fails
- <tr><td> <code data-anolis-xref="event-offline"><a href="browsers.html#offline-0">offline</a></code>
+ <tr><!-- online --><td> <dfn data-anolis-xref="event-online" id="event-online"><code>online</code></dfn>
<td> <code><a href="infrastructure.html#event">Event</a></code>
- <td> Fired at the <code><a href="browsers.html#window">Window</a></code> when the network connections fails
+ <td> Global scope objects
+ <td> Fired at the global scope object when the network connections returns
- <tr><td> <code data-anolis-xref="event-online"><a href="browsers.html#online">online</a></code>
+ <tr><!-- open --><td> <dfn data-anolis-xref="event-open" id="event-open"><code>open</code></dfn>
<td> <code><a href="infrastructure.html#event">Event</a></code>
- <td> Fired at the <code><a href="browsers.html#window">Window</a></code> when the network connections returns
+ <td> <code><a href="infrastructure.html#eventsource">EventSource</a></code>, <code>WebSocket</code>
+ <td> Fired at networking-related objects when a connection is established
- <tr><td> <code data-anolis-xref="event-pagehide"><a href="browsers.html#pagehide">pagehide</a></code>
+ <tr><!-- pagehide --><td> <dfn data-anolis-xref="event-pagehide" id="event-pagehide"><code>pagehide</code></dfn>
<td> <code><a href="browsers.html#pagetransitionevent">PageTransitionEvent</a></code>
+ <td> <code><a href="browsers.html#window">Window</a></code>
<td> Fired at the <code><a href="browsers.html#window">Window</a></code> when the page's entry in the <a href="browsers.html#session-history">session history</a> stops being the <a href="browsers.html#current-entry">current entry</a>
- <tr><td> <code data-anolis-xref="event-pageshow"><a href="browsers.html#pageshow">pageshow</a></code>
+ <tr><!-- pageshow --><td> <dfn data-anolis-xref="event-pageshow" id="event-pageshow"><code>pageshow</code></dfn>
<td> <code><a href="browsers.html#pagetransitionevent">PageTransitionEvent</a></code>
+ <td> <code><a href="browsers.html#window">Window</a></code>
<td> Fired at the <code><a href="browsers.html#window">Window</a></code> when the page's entry in the <a href="browsers.html#session-history">session history</a> becomes the <a href="browsers.html#current-entry">current entry</a>
- <tr><td> <code data-anolis-xref="event-popstate"><a href="browsers.html#popstate">popstate</a></code>
+ <tr><!-- popstate --><td> <dfn data-anolis-xref="event-popstate" id="event-popstate"><code>popstate</code></dfn>
<td> <code><a href="browsers.html#popstateevent">PopStateEvent</a></code>
+ <td> <code><a href="browsers.html#window">Window</a></code>
<td> Fired at the <code><a href="browsers.html#window">Window</a></code> when the user navigates the <a href="browsers.html#session-history">session history</a>
- <tr><td> <code data-anolis-xref="event-readystatechange"><a href="dom.html#readystatechange">readystatechange</a></code>
+ <tr><!-- progress --><td> <dfn data-anolis-xref="event-progress" id="event-progress"><code>progress</code></dfn>
+ <td> <code><a href="infrastructure.html#progressevent">ProgressEvent</a></code>
+ <td> <code><a href="embedded-content.html#the-img-element">img</a></code> elements
+ <td> Fired at <code><a href="embedded-content.html#the-img-element">img</a></code> elements during a <a href="infrastructure.html#cors-same-origin">CORS-same-origin</a> image load (see also <a data-anolis-xref="event-media-progress" href="embedded-content.html#event-media-progress">media element events</a>)
+
+ <tr><!-- readystatechange --><td> <dfn data-anolis-xref="event-readystatechange" id="event-readystatechange"><code>readystatechange</code></dfn>
<td> <code><a href="infrastructure.html#event">Event</a></code>
- <td> Fired at the <code><a href="dom.html#document-0">Document</a></code> when it finishes parsing and again when all its subresources have finished loading
+ <td> <code><a href="dom.html#document">Document</a></code>
+ <td> Fired at the <code><a href="dom.html#document">Document</a></code> when it finishes parsing and again when all its subresources have finished loading
- <tr><td> <code data-anolis-xref="event-reset">reset</code>
+ <tr><!-- reset --><td> <dfn data-anolis-xref="event-reset" id="event-reset"><code>reset</code></dfn>
<td> <code><a href="infrastructure.html#event">Event</a></code>
- <td> Fired at a <code><a href="forms.html#the-form-element">form</a></code> element when it is <a data-anolis-xref="concept-form-reset" href="forms.html#reset-1">reset</a>
+ <td> <code><a href="forms.html#the-form-element">form</a></code> elements
+ <td> Fired at a <code><a href="forms.html#the-form-element">form</a></code> element when it is <a data-anolis-xref="concept-form-reset" href="forms.html#concept-form-reset">reset</a>
- <tr><td> <code data-anolis-xref="event-show">show</code>
+ <tr><!-- select --><td> <dfn data-anolis-xref="event-select" id="event-select"><code>select</code></dfn>
<td> <code><a href="infrastructure.html#event">Event</a></code>
+ <td> Form controls
+ <td> Fired at form controls when their text selection is adjusted (whether by an API or by the user)
+
+ <tr><!-- show --><td> <dfn data-anolis-xref="event-show" id="event-show"><code>show</code></dfn>
+ <td> <code><a href="interactive-elements.html#relatedevent">RelatedEvent</a></code>
+ <td> <code><a href="interactive-elements.html#the-menu-element">menu</a></code> elements
<td> Fired at a <code><a href="interactive-elements.html#the-menu-element">menu</a></code> element when it is shown as a context menu
- <tr><td> <code data-anolis-xref="event-submit">submit</code>
+ <tr><!-- sort --><td> <dfn data-anolis-xref="event-sort" id="event-sort"><code>sort</code></dfn>
<td> <code><a href="infrastructure.html#event">Event</a></code>
- <td> Fired at a <code><a href="forms.html#the-form-element">form</a></code> element when it is <a data-anolis-xref="concept-form-submit" href="forms.html#submitted">submitted</a>
+ <td> <code><a href="tabular-data.html#the-table-element">table</a></code> elements
+ <td> Fired at <code><a href="tabular-data.html#the-table-element">table</a></code> elements before it is sorted; canceling the event cancels the sorting of the table
+
+ <tr><!-- storage --><td> <dfn data-anolis-xref="event-storage" id="event-storage"><code>storage</code></dfn>
+ <td> <code>StorageEvent</code>
+ <td> <code><a href="browsers.html#window">Window</a></code>
+ <td> Fired at <code><a href="browsers.html#window">Window</a></code> event when the corresponding <code data-anolis-xref="dom-localStorage">localStorage</code> or <code data-anolis-xref="dom-sessionStorage">sessionStorage</code> storage areas change
- <tr><td> <code data-anolis-xref="event-unload">unload</code>
+ <tr><!-- submit --><td> <dfn data-anolis-xref="event-submit" id="event-submit"><code>submit</code></dfn>
<td> <code><a href="infrastructure.html#event">Event</a></code>
+ <td> <code><a href="forms.html#the-form-element">form</a></code> elements
+ <td> Fired at a <code><a href="forms.html#the-form-element">form</a></code> element when it is <a data-anolis-xref="concept-form-submit" href="forms.html#concept-form-submit">submitted</a>
+
+ <tr><!-- toggle --><td> <dfn data-anolis-xref="event-toggle" id="event-toggle"><code>toggle</code></dfn>
+ <td> <code><a href="infrastructure.html#event">Event</a></code>
+ <td> <code><a href="interactive-elements.html#the-details-element">details</a></code> element
+ <td> Fired at <code><a href="interactive-elements.html#the-details-element">details</a></code> elements when they open or close
+
+ <tr><!-- unload --><td> <dfn data-anolis-xref="event-unload" id="event-unload"><code>unload</code></dfn>
+ <td> <code><a href="infrastructure.html#event">Event</a></code>
+ <td> <code><a href="browsers.html#window">Window</a></code>
<td> Fired at the <code><a href="browsers.html#window">Window</a></code> object when the page is going away
- </table><p class="note">See also <a href="embedded-content-0.html#mediaevents">media element
- events</a>, <a href="browsers.html#appcacheevents">application cache events</a>,
- and <a href="editing.html#dndevents">drag-and-drop events</a>.</p>
+ </table><p class="note">See also <a href="embedded-content.html#mediaevents">media element events</a>, <a href="browsers.html#appcacheevents">application cache events</a>, and <a href="editing.html#dndevents">drag-and-drop
+ events</a>.</p>
-
-
<!--FIXUP 2dcontext -4-->
\ No newline at end of file
diff --git a/xml/impl/src/com/intellij/xml/util/documentation/html5TagTableGen.rb b/xml/impl/src/com/intellij/xml/util/documentation/html5TagTableGen.rb
index 6d0ddd19ed56..df1cd71994fe 100644
--- a/xml/impl/src/com/intellij/xml/util/documentation/html5TagTableGen.rb
+++ b/xml/impl/src/com/intellij/xml/util/documentation/html5TagTableGen.rb
@@ -20,7 +20,7 @@ file.close
# read html5 spec
generatedTags = Set.new
-result = '<html-property-table baseHelpRef="http://dev.w3.org/html5/spec/">'
+result = "<html-property-table baseHelpRef=\"http://www.w3.org/html/wg/drafts/html/master/\">\n"
file = File.new("html5.html")
content = file.read
offset = 0
diff --git a/xml/relaxng/test/org/intellij/plugins/relaxNG/HighlightingTestBase.java b/xml/relaxng/test/org/intellij/plugins/relaxNG/HighlightingTestBase.java
index 2b6f0b36e71e..bc8f0511be55 100644
--- a/xml/relaxng/test/org/intellij/plugins/relaxNG/HighlightingTestBase.java
+++ b/xml/relaxng/test/org/intellij/plugins/relaxNG/HighlightingTestBase.java
@@ -139,6 +139,8 @@ public abstract class HighlightingTestBase extends UsefulTestCase implements Ide
@Override
protected void tearDown() throws Exception {
myTestFixture.tearDown();
+ myTestFixture = null;
+
super.tearDown();
}
diff --git a/xml/xml-psi-impl/src/com/intellij/psi/xml/XmlElementType.java b/xml/xml-psi-impl/src/com/intellij/psi/xml/XmlElementType.java
index 04f5d67d3694..cd2625b33117 100644
--- a/xml/xml-psi-impl/src/com/intellij/psi/xml/XmlElementType.java
+++ b/xml/xml-psi-impl/src/com/intellij/psi/xml/XmlElementType.java
@@ -55,7 +55,7 @@ public interface XmlElementType extends XmlTokenType {
//todo: move to html
IElementType HTML_DOCUMENT = new IXmlElementType("HTML_DOCUMENT");
IElementType HTML_TAG = new IXmlElementType("HTML_TAG");
- IFileElementType HTML_FILE = new IFileElementType(HTMLLanguage.INSTANCE);
+ IFileElementType HTML_FILE = new IStubFileElementType(HTMLLanguage.INSTANCE);
IElementType HTML_EMBEDDED_CONTENT = new EmbeddedHtmlContentElementType();
IElementType XML_TEXT = new XmlTextElementType();
diff --git a/xml/xml-psi-impl/src/com/intellij/xml/util/documentation/html5table.xml b/xml/xml-psi-impl/src/com/intellij/xml/util/documentation/html5table.xml
index bd4aa46595fb..145b4e7e2c46 100644
--- a/xml/xml-psi-impl/src/com/intellij/xml/util/documentation/html5table.xml
+++ b/xml/xml-psi-impl/src/com/intellij/xml/util/documentation/html5table.xml
@@ -1,4 +1,5 @@
-<html-property-table baseHelpRef="http://dev.w3.org/html5/spec/"><tag name = "article"
+<html-property-table baseHelpRef="http://www.w3.org/html/wg/drafts/html/master/">
+<tag name = "article"
helpref = "sections.html#the-article-element"
description = "Self-contained syndicatable or reusable composition"
startTag = "true"
@@ -15,7 +16,7 @@
dtd = ""
/>
<tag name = "audio"
- helpref = "embedded-content-0.html#the-audio-element"
+ helpref = "embedded-content.html#the-audio-element"
description = "Audio player"
startTag = "true"
endTag = "true"
@@ -71,7 +72,7 @@
dtd = ""
/>
<tag name = "embed"
- helpref = "embedded-content-0.html#the-embed-element"
+ helpref = "embedded-content.html#the-embed-element"
description = "Plugin"
startTag = "true"
endTag = "true"
@@ -224,7 +225,7 @@
dtd = ""
/>
<tag name = "source"
- helpref = "embedded-content-0.html#the-source-element"
+ helpref = "embedded-content.html#the-source-element"
description = "Media source for "
startTag = "true"
endTag = "true"
@@ -256,7 +257,7 @@
dtd = ""
/>
<tag name = "track"
- helpref = "embedded-content-0.html#the-track-element"
+ helpref = "embedded-content.html#the-track-element"
description = "Timed text track"
startTag = "true"
endTag = "true"
@@ -264,7 +265,7 @@
dtd = ""
/>
<tag name = "video"
- helpref = "embedded-content-0.html#the-video-element"
+ helpref = "embedded-content.html#the-video-element"
description = "Video player"
startTag = "true"
endTag = "true"
@@ -280,7 +281,7 @@
dtd = ""
/>
<attribute name = "allowfullscreen"
- helpref = "embedded-content-0.html#allowfullscreen"
+ helpref = "embedded-content.html#attr-iframe-allowfullscreen"
description = "Whether to allow the iframe's contents to use requestFullscreen()"
relatedTags = "iframe"
dtd = ""
@@ -288,7 +289,7 @@
default = "true"
/>
<attribute name = "async"
- helpref = "scripting-1.html#async"
+ helpref = "scripting-1.html#attr-script-async"
description = "Execute script asynchronously"
relatedTags = "script"
dtd = ""
@@ -296,7 +297,7 @@
default = "true"
/>
<attribute name = "autocomplete"
- helpref = "forms.html#autocomplete"
+ helpref = "forms.html#attr-form-autocomplete"
description = "Default setting for autofill feature for controls in the form"
relatedTags = "form"
dtd = ""
@@ -304,7 +305,7 @@
default = "true"
/>
<attribute name = "autocomplete"
- helpref = "forms.html#autocomplete-1"
+ helpref = "forms.html#attr-fe-autocomplete"
description = "Hint for form autofill feature"
relatedTags = "input; select; textarea"
dtd = ""
@@ -312,7 +313,7 @@
default = "true"
/>
<attribute name = "autofocus"
- helpref = "forms.html#autofocus"
+ helpref = "forms.html#attr-fe-autofocus"
description = "Automatically focus the form control when the page is loaded"
relatedTags = "button; input; keygen; select; textarea"
dtd = ""
@@ -320,7 +321,7 @@
default = "true"
/>
<attribute name = "autoplay"
- helpref = "embedded-content-0.html#autoplay"
+ helpref = "embedded-content.html#attr-media-autoplay"
description = "Hint that the media resource can be started automatically when the page is loaded"
relatedTags = "audio; video"
dtd = ""
@@ -328,7 +329,7 @@
default = "true"
/>
<attribute name = "challenge"
- helpref = "forms.html#challenge"
+ helpref = "forms.html#attr-keygen-challenge"
description = "String to package with the generated and signed public key"
relatedTags = "keygen"
dtd = ""
@@ -336,7 +337,7 @@
default = "true"
/>
<attribute name = "command"
- helpref = "interactive-elements.html#command-1"
+ helpref = "interactive-elements.html#attr-menuitem-command"
description = "Command definition"
relatedTags = "menuitem"
dtd = ""
@@ -360,7 +361,7 @@
default = "true"
/>
<attribute name = "controls"
- helpref = "embedded-content-0.html#controls"
+ helpref = "embedded-content.html#attr-media-controls"
description = "Show user agent controls"
relatedTags = "audio; video"
dtd = ""
@@ -368,7 +369,7 @@
default = "true"
/>
<attribute name = "crossorigin"
- helpref = "embedded-content-0.html#crossorigin-3"
+ helpref = "embedded-content.html#attr-media-crossorigin"
description = "How the element handles crossorigin requests"
relatedTags = "audio; img; link; script; video"
dtd = ""
@@ -376,7 +377,7 @@
default = "true"
/>
<attribute name = "default"
- helpref = "interactive-elements.html#default-4"
+ helpref = "interactive-elements.html#attr-menuitem-default"
description = "Mark the command as being a default command"
relatedTags = "menuitem"
dtd = ""
@@ -384,7 +385,7 @@
default = "true"
/>
<attribute name = "default"
- helpref = "embedded-content-0.html#default"
+ helpref = "embedded-content.html#attr-track-default"
description = "Enable the track if no other text track is more suitable"
relatedTags = "track"
dtd = ""
@@ -392,7 +393,7 @@
default = "true"
/>
<attribute name = "dirname"
- helpref = "forms.html#dirname-1"
+ helpref = "forms.html#attr-fe-dirname"
description = "Name of form field to use for sending the element's directionality in form submission"
relatedTags = "input; textarea"
dtd = ""
@@ -400,7 +401,7 @@
default = "true"
/>
<attribute name = "download"
- helpref = "links.html#download-1"
+ helpref = "links.html#attr-hyperlink-download"
description = "Whether to download the resource instead of navigating to it, and its file name if so"
relatedTags = "a; area"
dtd = ""
@@ -424,7 +425,7 @@
default = "true"
/>
<attribute name = "form"
- helpref = "forms.html#form-1"
+ helpref = "forms.html#attr-fae-form"
description = "Associates the control with a form element"
relatedTags = "button; fieldset; input; keygen; label; object; output; select; textarea"
dtd = ""
@@ -432,7 +433,7 @@
default = "true"
/>
<attribute name = "formaction"
- helpref = "forms.html#formaction"
+ helpref = "forms.html#attr-fs-formaction"
description = "URL to use for form submission"
relatedTags = "button; input"
dtd = ""
@@ -440,7 +441,7 @@
default = "true"
/>
<attribute name = "formenctype"
- helpref = "forms.html#formenctype"
+ helpref = "forms.html#attr-fs-formenctype"
description = "Form data set encoding type to use for form submission"
relatedTags = "button; input"
dtd = ""
@@ -448,7 +449,7 @@
default = "true"
/>
<attribute name = "formmethod"
- helpref = "forms.html#formmethod"
+ helpref = "forms.html#attr-fs-formmethod"
description = "HTTP method to use for form submission"
relatedTags = "button; input"
dtd = ""
@@ -456,7 +457,7 @@
default = "true"
/>
<attribute name = "formnovalidate"
- helpref = "forms.html#formnovalidate"
+ helpref = "forms.html#attr-fs-formnovalidate"
description = "Bypass form control validation for form submission"
relatedTags = "button; input"
dtd = ""
@@ -464,7 +465,7 @@
default = "true"
/>
<attribute name = "formtarget"
- helpref = "forms.html#formtarget"
+ helpref = "forms.html#attr-fs-formtarget"
description = "Browsing context for form submission"
relatedTags = "button; input"
dtd = ""
@@ -480,7 +481,7 @@
default = "true"
/>
<attribute name = "high"
- helpref = "forms.html#high"
+ helpref = "forms.html#attr-meter-high"
description = "Low limit of high range"
relatedTags = "meter"
dtd = ""
@@ -488,27 +489,19 @@
default = "true"
/>
<attribute name = "icon"
- helpref = "interactive-elements.html#icon"
+ helpref = "interactive-elements.html#attr-menuitem-icon"
description = "Icon for the command"
relatedTags = "menuitem"
dtd = ""
type = "Valid non-empty URL potentially surrounded by spaces"
default = "true"
/>
-<attribute name = "inert"
- helpref = ""
- description = "Whether the element and its descendants are inert"
- relatedTags = "HTML elements"
- dtd = ""
- type = "Boolean attribute"
- default = "true"
-/>
<attribute name = "inputmode"
- helpref = "forms.html#inputmode-1"
+ helpref = "forms.html#attr-fe-inputmode"
description = "Hint for selecting an input modality"
relatedTags = "input; textarea"
dtd = ""
- type = "verbatim; "
+ type = "verbatim"
default = "true"
/>
<attribute name = "itemid"
@@ -552,7 +545,7 @@
default = "true"
/>
<attribute name = "keytype"
- helpref = "forms.html#keytype"
+ helpref = "forms.html#attr-keygen-keytype"
description = "The type of cryptographic key to generate"
relatedTags = "keygen"
dtd = ""
@@ -560,7 +553,7 @@
default = "true"
/>
<attribute name = "kind"
- helpref = "embedded-content-0.html#kind"
+ helpref = "embedded-content.html#attr-track-kind"
description = "The type of text track"
relatedTags = "track"
dtd = ""
@@ -568,7 +561,7 @@
default = "true"
/>
<attribute name = "list"
- helpref = "forms.html#list"
+ helpref = "forms.html#attr-input-list"
description = "List of autocomplete options"
relatedTags = "input"
dtd = ""
@@ -576,7 +569,7 @@
default = "true"
/>
<attribute name = "loop"
- helpref = "embedded-content-0.html#loop"
+ helpref = "embedded-content.html#attr-media-loop"
description = "Whether to loop the media resource"
relatedTags = "audio; video"
dtd = ""
@@ -584,7 +577,7 @@
default = "true"
/>
<attribute name = "low"
- helpref = "forms.html#low"
+ helpref = "forms.html#attr-meter-low"
description = "High limit of low range"
relatedTags = "meter"
dtd = ""
@@ -592,7 +585,7 @@
default = "true"
/>
<attribute name = "manifest"
- helpref = "semantics.html#manifest"
+ helpref = "semantics.html#attr-html-manifest"
description = "Application cache manifest"
relatedTags = "html"
dtd = ""
@@ -600,7 +593,7 @@
default = "true"
/>
<attribute name = "max"
- helpref = "forms.html#max-0"
+ helpref = "forms.html#attr-input-max"
description = "Maximum value"
relatedTags = "input"
dtd = ""
@@ -608,7 +601,7 @@
default = "true"
/>
<attribute name = "max"
- helpref = "forms.html#max-3"
+ helpref = "forms.html#attr-meter-max"
description = "Upper bound of range"
relatedTags = "meter; progress"
dtd = ""
@@ -616,7 +609,7 @@
default = "true"
/>
<attribute name = "mediagroup"
- helpref = "embedded-content-0.html#mediagroup"
+ helpref = "embedded-content.html#attr-media-mediagroup"
description = "Groups media elements together with an implicit MediaController"
relatedTags = "audio; video"
dtd = ""
@@ -624,7 +617,7 @@
default = "true"
/>
<attribute name = "menu"
- helpref = "forms.html#menu-1"
+ helpref = "forms.html#attr-button-menu"
description = "Specifies the element's designated pop-up menu"
relatedTags = "button"
dtd = ""
@@ -632,7 +625,7 @@
default = "true"
/>
<attribute name = "min"
- helpref = "forms.html#min-0"
+ helpref = "forms.html#attr-input-min"
description = "Minimum value"
relatedTags = "input"
dtd = ""
@@ -640,7 +633,7 @@
default = "true"
/>
<attribute name = "min"
- helpref = "forms.html#min-1"
+ helpref = "forms.html#attr-meter-min"
description = "Lower bound of range"
relatedTags = "meter"
dtd = ""
@@ -648,7 +641,7 @@
default = "true"
/>
<attribute name = "minlength"
- helpref = "forms.html#minlength-0"
+ helpref = "forms.html#attr-input-minlength"
description = "Minimum length of value"
relatedTags = "input; textarea"
dtd = ""
@@ -656,7 +649,7 @@
default = "true"
/>
<attribute name = "muted"
- helpref = "embedded-content-0.html#muted-1"
+ helpref = "embedded-content.html#attr-media-muted"
description = "Whether to mute the media resource by default"
relatedTags = "audio; video"
dtd = ""
@@ -664,7 +657,7 @@
default = "true"
/>
<attribute name = "novalidate"
- helpref = "forms.html#novalidate"
+ helpref = "forms.html#attr-fs-novalidate"
description = "Bypass form control validation for form submission"
relatedTags = "form"
dtd = ""
@@ -672,7 +665,7 @@
default = "true"
/>
<attribute name = "open"
- helpref = "interactive-elements.html#open"
+ helpref = "interactive-elements.html#attr-details-open"
description = "Whether the details are visible"
relatedTags = "details"
dtd = ""
@@ -680,7 +673,7 @@
default = "true"
/>
<attribute name = "open"
- helpref = "interactive-elements.html#open-1"
+ helpref = "interactive-elements.html#attr-dialog-open"
description = "Whether the dialog box is showing"
relatedTags = "dialog"
dtd = ""
@@ -688,7 +681,7 @@
default = "true"
/>
<attribute name = "optimum"
- helpref = "forms.html#optimum"
+ helpref = "forms.html#attr-meter-optimum"
description = "Optimum value in gauge"
relatedTags = "meter"
dtd = ""
@@ -696,7 +689,7 @@
default = "true"
/>
<attribute name = "pattern"
- helpref = "forms.html#pattern-0"
+ helpref = "forms.html#attr-input-pattern"
description = "Pattern to be matched by the form control's value"
relatedTags = "input"
dtd = ""
@@ -704,7 +697,7 @@
default = "true"
/>
<attribute name = "placeholder"
- helpref = "forms.html#placeholder-0"
+ helpref = "forms.html#attr-input-placeholder"
description = "User-visible label to be placed within the form control"
relatedTags = "input; textarea"
dtd = ""
@@ -712,7 +705,7 @@
default = "true"
/>
<attribute name = "poster"
- helpref = "embedded-content-0.html#poster"
+ helpref = "embedded-content.html#attr-video-poster"
description = "Poster frame to show prior to video playback"
relatedTags = "video"
dtd = ""
@@ -720,7 +713,7 @@
default = "true"
/>
<attribute name = "preload"
- helpref = "embedded-content-0.html#preload"
+ helpref = "embedded-content.html#attr-media-preload"
description = "Hints how much buffering the media resource will likely need"
relatedTags = "audio; video"
dtd = ""
@@ -728,7 +721,7 @@
default = "true"
/>
<attribute name = "radiogroup"
- helpref = "interactive-elements.html#radiogroup"
+ helpref = "interactive-elements.html#attr-menuitem-radiogroup"
description = "Name of group of commands to treat as a radio button group"
relatedTags = "menuitem"
dtd = ""
@@ -736,7 +729,7 @@
default = "true"
/>
<attribute name = "required"
- helpref = "forms.html#required-0"
+ helpref = "forms.html#attr-input-required"
description = "Whether the control is required for form submission"
relatedTags = "input; select; textarea"
dtd = ""
@@ -744,7 +737,7 @@
default = "true"
/>
<attribute name = "reversed"
- helpref = "grouping-content.html#reversed"
+ helpref = "grouping-content.html#attr-ol-reversed"
description = "Number the list backwards"
relatedTags = "ol"
dtd = ""
@@ -752,7 +745,7 @@
default = "true"
/>
<attribute name = "sandbox"
- helpref = "embedded-content-0.html#sandbox"
+ helpref = "embedded-content.html#attr-iframe-sandbox"
description = "Security rules for nested content"
relatedTags = "iframe"
dtd = ""
@@ -768,7 +761,7 @@
default = "true"
/>
<attribute name = "scoped"
- helpref = "document-metadata.html#scoped"
+ helpref = "document-metadata.html#attr-style-scoped"
description = "Whether the styles apply to the entire document or just the parent subtree"
relatedTags = "style"
dtd = ""
@@ -776,7 +769,7 @@
default = "true"
/>
<attribute name = "seamless"
- helpref = "embedded-content-0.html#seamless"
+ helpref = "embedded-content.html#attr-iframe-seamless"
description = "Whether to apply the document's styles to the nested content"
relatedTags = "iframe"
dtd = ""
@@ -784,7 +777,7 @@
default = "true"
/>
<attribute name = "sizes"
- helpref = "links.html#sizes-0"
+ helpref = "links.html#attr-link-sizes"
description = "Sizes of the icons (for rel=icon)"
relatedTags = "link"
dtd = ""
@@ -792,7 +785,7 @@
default = "true"
/>
<attribute name = "sortable"
- helpref = "tabular-data.html#sortable-0"
+ helpref = "tabular-data.html#attr-table-sortable"
description = "Enables a sorting interface for the table"
relatedTags = "table"
dtd = ""
@@ -800,7 +793,7 @@
default = "true"
/>
<attribute name = "sorted"
- helpref = "tabular-data.html#sorted-0"
+ helpref = "tabular-data.html#attr-th-sorted"
description = "Column sort direction and ordinality"
relatedTags = "th"
dtd = ""
@@ -808,7 +801,7 @@
default = "true"
/>
<attribute name = "srcdoc"
- helpref = "embedded-content-0.html#srcdoc"
+ helpref = "embedded-content.html#attr-iframe-srcdoc"
description = "A document to render in the iframe"
relatedTags = "iframe"
dtd = ""
@@ -816,15 +809,23 @@
default = "true"
/>
<attribute name = "srclang"
- helpref = "embedded-content-0.html#srclang"
+ helpref = "embedded-content.html#attr-track-srclang"
description = "Language of the text track"
relatedTags = "track"
dtd = ""
type = "Valid BCP 47 language tag"
default = "true"
/>
+<attribute name = "srcset"
+ helpref = "embedded-content.html#attr-img-srcset"
+ description = "Images to use in different situations (e.g. high-resolution displays, small monitors, etc)"
+ relatedTags = "img"
+ dtd = ""
+ type = "Comma-separated list of image candidate strings"
+ default = "true"
+/>
<attribute name = "step"
- helpref = "forms.html#step-0"
+ helpref = "forms.html#attr-input-step"
description = "Granularity to be matched by the form control's value"
relatedTags = "input"
dtd = ""
@@ -840,7 +841,7 @@
default = "true"
/>
<attribute name = "typemustmatch"
- helpref = "embedded-content-0.html#typemustmatch"
+ helpref = "embedded-content.html#attr-object-typemustmatch"
description = "Whether the type attribute and the Content-Type value need to match for the resource to be used"
relatedTags = "object"
dtd = ""
@@ -848,7 +849,7 @@
default = "true"
/>
<attribute name = "wrap"
- helpref = "forms.html#wrap"
+ helpref = "forms.html#attr-textarea-wrap"
description = "How the value of the form control is to be wrapped for form submission"
relatedTags = "textarea"
dtd = ""