summaryrefslogtreecommitdiff
path: root/java/java-impl/src/com/intellij
diff options
context:
space:
mode:
authorTor Norbye <tnorbye@google.com>2014-04-25 07:38:52 -0700
committerTor Norbye <tnorbye@google.com>2014-04-25 07:38:58 -0700
commit0f831a730c50607e2ffd95020875af6185e17734 (patch)
tree3caf947bbfceeb37eda9c4a1bee319fdd7678fe5 /java/java-impl/src/com/intellij
parent92584642bab4fdb27ac1067c124f4636be762978 (diff)
downloadidea-0f831a730c50607e2ffd95020875af6185e17734.tar.gz
Snapshot idea/136.1761 from git://git.jetbrains.org/idea/community.git
3608216: Merge remote-tracking branch 'origin/master' 0d16248: Django inspection HTMLs moved to appropriate place 1ed8715: PY-1194 Provide completion and navigation for url tag in django template Inspection added. 4c6ec52: Naive fix for EA-53569 44c2a03: Do not wrap border with TitledBorder if there is not title 8591130: omg2 [r=ignatov] dce57e7: omg 3b164b9: Merge remote-tracking branch 'origin/master' 9c04fe7: Ctrl-Q: process java 8 signature style as 1.8 javadoc could also be run on sources 1.6 (IDEA-124175) b073132: javadoc: ensure that generic arguments are shown in error presentation b8fb550: IDEA-124271 209d176: disable stream api conversion on iterable (IDEA-124222) 6ca89eb: default external javadoc url for java 8 fixed (IDEA-124175) 2fe28f0: Merge remote-tracking branch 'origin/master' f65712c: Merge remote-tracking branch 'origin/master' 7de60e2f: Don't escape spaces as it brakes mappings and they are escaped later in GeneralCommandLine (PY-12550). 2bd67bc: IDEA-90194 Ability to disable drag & drop in Project View f772fb2: Merge remote-tracking branch 'origin/master' 817908d: fixed importing for the iron python 053b716: Merge remote-tracking branch 'origin/master' 1d04dc7: fixed unittest folder tests 76f35f3: suppress doCancelAction 0d9b47d: IDEA-124260 Data Sources and Drivers: can't apply changes to schemas that are shown and used to resolve f72e4f5: testdata for IDEA-124148 1c431a8: create meth reference from usage: substitute param types (IDEA-124322) c160fc5: copy to temp/array for non-effectively final variables used in lambda expressions 265f0dc: lambda -> anonymous: static calls (IDEA-124187) 2200bba: method hierarchy: search functional expressions by current method only (IDEA-124320); navigation (IDEA-124319) 54ced00: highlight all pairs of methods with same erasures (IDEA-124116) f3efd90: IDEA-120865 jre7 osx fullscreen: "space" is not freed when project is closed 6924cc4: IDEA-118062 Gradle Run Configuration: 'working directory' is set incorrectly 09333b1: External system: source package prefix support added; fix for out-of-process mode support 6de52dc: Gradle: update Tooling API version up to 1.12-rc-1, fix classpath for out-of-process mode 4ff20d5: InconsistentResourceBundle test fixed 90bb5ab: IDEA-124301 jdk9 builds cannot be used for project/module compilation 1236318: always go to file if nothing found 43f40bf: Merge remote-tracking branch 'origin/master' b2d0942: Add default mapping to /vagrant only in case of absent mappings in Vagrantfile (PY-12700). fc31680: IDEA-124290 773f103: Offer to launch Vagrant if it is down on getting ssh-config (PY-12672). 460ef41: DumbService.smartInvokeLater(...) 577579d: cleanup after extracting java postfix template provider 214f99b: IDEA-103836 a41e7d8: Merge remote-tracking branch 'origin/master' 4076596: fixed memory leak c5207b2: fixed PY-12543 Project Interpreters: too big or too small details popup 40d91f5: IDEA-63106 new inspections added to InconsistentResourceBundleInspection 4bc9f42: fixed PY-12690 Detected from creating virtualenv interpreter has invalid slashes e6d8c98: extract right arrow 43b861b: don't use borders and insets in output html/rtf (IDEA-67767) 6c4dbea: use service instead of application component (IDEA-67767) aa6fb9f: remove 'Strip common indent' setting from UI (IDEA-67767) 5651ab5: IDEA-123775 (String.equals("") inspection fixes code incorrectly) c1d9f5f: fixed PY-12696 Create VirtualEnv: when adding first base interpreter it is not selected right away 482491a: Platform: Local History can survive for more than 30 days now (int overflow fixed) a0125dc: Platform: always allow writing module files (IDEA-123899) 3a294e9: removed unused component methods 7cc124e: optimisation: avoid containingfile calculation 06f574a: readable toString() 60f2a36: perforce tests fixed 46fea0f: fewer create/delete operations 7269bce: drain file type detection queue in tests d0c6ef5: cleanup 9df7136: Gradle: installer build fix 152c230: Platform: Local History can survive for more than 30 days now f5e7215: do not rely on memory index storage isBufferedFlag to process physical file contents ebe62cf: customize password field labels 97ade8d: ability to enable only visible components 3541938: introduce beforeOKAction() 13bf7e1: cleanup 4a12b1f: junit: workaround for old junit versions (IDEA-124201) 21003e0: Merge remote-tracking branch 'origin/master' c2067ff: PY-1194 Provide completion and navigation for url tag in django template PY-3591 Support {% url %} tag arguments completion 5f295fe: do not cancel offline inspections 2b8e2e8: add unchecked warning calls also for method references 57e886f: testdata: check that method ref on static interface method is accepted 8bad807: lambda: do not skip generic method when non-generic method exist in the same class 7d74b9d: NPE 0da9f91: testdata: ensure overload resolution prefer correct one from methods with boxed types 2c49817: NPE d5107d6: testdata: ensure intersection type is not missed during inference 7898108: testdata: ensure lambda can't be inferred from type parameter 5b91054: testdata: ensure overload resolution by return type should not take place for interrupted control flow 9aa2f3a: testdata: ensure correct parameters number in functional interface method 1698f7b: testdata: ensure method ref qualified are checked over static problems b49d8e75: testdata f1f6fcf: functional interfaces: ignore methods with type parameters during abstract method choosing a55db18: lambda: accept intersection type when exactly one conjunct is functional 4a34bd5: do not report unrelated return type error only for generics methods 76a9293: testdata 17b020f: new overload resolution: covariant comparison of return types 98ab76f: new overload resolution: most specific check on invalid class exceptions fixed 552dfe9: lambda: intersection type produces conjunction of abstract methods bd9dbfc: testdata 9914757: warn about underscore identifier 72ae579: IDEA-109187 new HgReference validator implemented d86307e: tip reference moved as a separated static constant to HgUtil 71cd276: Fix scrolling in module aware configurables [r=ushakov] 37ed33e: Missed commit for IDEA-79312 da52f84: IDEA-79312 text cursor gets lost - could bee disabled by focus.fix.lost.cursor key a39b289: [git log] IDEA-122305 Fix structure filter. 339dd23: beforeShown() & preselect laf-default editor scheme 2 f9d8704: PY-1194 Provide completion and navigation for url tag in django template PY-3591 Support {% url %} tag arguments completion 17e8b30: ctrl+delete/ctrl+backspace enhancements IDEA-100906 Ruby-Editor: CTRL+BACKSPACE Could Not Delete A String a95fd00: remove copyright messages bf06d9d: read-action for getFilesForFastWordSearch cdcd770: IDEA-123687 Velocity formatter inserts wrong linebreak 562443f: Fixed WI-17474 Custom Folding: defaultstate="collapsed" does not seem to have any effect (the node itself is already a line comment) d86998d: Cleanup warnings 4bbd22c: jb v8 debug protocol: evaluate 46eaf0b: NPE 4101b8c: cleanup 399e745: write action required 004dfc4: IDEA-124220 Auto-popup parameter info should work after smart completion which inserted a comma 0bd06e5: More on comparison that is always false due to being out of type range on implicit type conversion (IDEA-124210) b6bccb7: AppCode: minimum OS X version specified in .app ca8a657: add aliases for Lafs e254ebf: Merge branch 'master' of git.labs.intellij.net:idea/community 5c594f6: Gradle: update Tooling API version up to 1.12-rc-1 17fcca3: Merge remote-tracking branch 'origin/master' 5248eb0: IDEA-119996 FilePathImpl: avoid VFS refresh from getVirtualFile etc. 9c69111: [vcs] Reuse the VirtualFile instead of creating FilePathImpl on File c08f50b: fixed EA-54835 - NPE: PythonNoseTestConfigurationProducer.isAvailable d627711: fixed EA-55749 - AIOOBE: PyStructuredDocstringFormatter.formatDocstring c9a1c11: apply laf once, fix stale bg, add beforeShown() & preselect laf-default editor scheme 3e576c2: fixed EA-55872 - NPE: PyProtectedMemberInspection$Visitor.checkReference 147c647: use ValueType enum instead of plain numbers 2e517c5: IDEA-112050 vcs: fix ByteBuffer to array conversion 97a6a21: possible race condition fixed cb20ef5: Prevent horizontal scrollbar appearance if an error message is too long cbb86d4: IDEA-124021 Cannot resolve method 'print(int)' with JSP custom tags: comment 362b4d7: IDEA-123986 New project wizard: remove highlighting from disabled templates cc57b39: do not include runtime dependencies to compilation scope (ZD-25927) 7ac3c11: paste rich-text data: NPE fixed 89ca157: Extract Java live postfix templates provider e5eb7aa: EA-31437 - assert: DocumentFoldingInfo.writeExternal e2461d5: use JBImageIcon e9eb171: initial ed33f35: fix Keymap page on Mac/Darcula. see same in LafManager for more info. 99bc2e9: open some API d9aed3f: process class names just once in completion 094f040: IDEA-122362 'getClass()' should be suggested in smart completion if Class<? extends SomeAncestorOfCurrentClass> is expected 1a34573: IDEA-120139 Autopopup doesn't popup sometimes after completion e8c981a: create LookupUi and move there some ui-related code from LookupImpl; skip this code in tests 89d771e: @NotNull 8d25ba3: Merge remote-tracking branch 'origin/master' 7fcce27: fix darcula lafinfo bfef59e: Start plugins wizard #19 usability improvements 5cbd491: minor fix 58d2f15: fix bg 40fa260: don't create content entry for temp directory of temp project when opening single file e31a4c1: Correctly handle custom folding "desc" attribute followed by "defaultstate" 448e9f8: don't report on incomplete code or comparisons that are already reported by "Constant conditions & exceptions" 6e68111: remove superfluous inspection a2cc5ba: expand description 814378f: Gradle: gradle distribution pattern updated e9485f0: use TransparentPanel db66426: initial a712571: suppress unused params inspection 640ddf3: make labels have constant height to avoid relayout and blinking 921f39e: don't fill bg if component is not opaque a43d7f8: added new test for live postfix templates 50addd3: IDEA-123935 New Project wizard: no project/global libraries are created on new module adding via project structure 6021da6: Merge remote-tracking branch 'origin/master' 36848a5: fixed test data 7a63d2b: Gradle: tooling extensions integration tests, avoid dependency for explicit distributions downloading in a separate run configuration (like this one http://buildserver.labs.intellij.net/viewType.html?buildTypeId=IDEATrunk_GradleDownloads) 405332a: make richCopy functionality work properly on Linux (IDEA-67767) 3dca908: some 'finally' blocks 00a4968: reverted content-dependent flag 6064460: Merge remote-tracking branch 'origin/master' 5f203cb: Fixed IDEA-124191 Code style preference : space within empty method call/declaration parentheses are not saved 0419dcc: EA-56035 - NCDFE: UnixProcessManager.<clinit> 0285ece: cleanup: use ordinary invokeLater and avoid unnecessary synchronization 0922a97: Vagrant error messaging fixed. 2676330: Save vagrant executable path to application settings (PY-12680). 947d8ab: missing test data 6154126: IDEA-124137 (Inspection: "equals() between objects of inconvertible types" should support java.util.Objects.equals() or com.google.common.base.Objects.equal()) c9fd1bb: fix name f3ec0f7: lookup arranger tweak [zolotov, shrago] relates to IDEA-121998 SQL code completion too aggressive c324511: fix escaping, parse decimal literals #WEB-11938 fixed a5bcae9: Github: fix error message 95d057d: Github: fix invalid condition dda5341: Github: log invalid requests d493d76: it is even better to store deltas for direct mapping values a67ac0b: proper unpacking code 3ea5951: Properties AST factory moved to impl c0550f7: save keys of particular snapshot before and out of index update optimistically load keys of particular snapshot before and out of index update d6a5968: custom implementation for IdIndex inputs mapping: -20% for saving deltas b52691e: saving / reading longs in compact variable byte format + using it for simplier code in PersistentHashMapValueStorage 0ae869e: cleanup 3222cd0: cleanup e96aa7b: use Gray.TRANSPARENT 2861f10: use Gray.TRANSPARENT c009821: Merge remote-tracking branch 'origin/master' caa86fc: what a nice NPE! 3c769ac: goto popup calculations should be cancellable even after Ctrl+Space (IDEA-123714 ?) c6fcabf: IDEA-122250 New Package: qualified name is checked against ignored directories as a whole 3af306c: IDEA-55556 Inspection suggestion: Comparison that is always false due to being out of type range on implicit type conversion 996d0c6: IDEA-123782 "Complete current statement" doesn't put colon for case branches 7a2cc54: IDEA-122383 PageUp/PageDown don't work in ShowUsages popup (Ctrl-Alt-F7) 29fec22: IDEA-123948 Constant condition and exceptions: false positive on MappedByteBuffer.getInt 0fd86de: IDEA-122946 final modifier not inserted when completing a sequence of parameters from an inner method IDEA-123493 Smart completion makes completed variable final 019a68b: IDEA-123289 Infer nullability of 'for each' variable from type annotations of the collection parameter c18c4ff: IDEA-120964 Make it more obvious that background compiler is disabled in power save mode dc2f64a: use superclass for inner class variable name suggestion (IDEA-122109) c47713f: prefer T if Class<? extends T> is expected (IDEA-121339) c960901: OC-9559 IDEA-107592 64fc873: cleanup c159a1a: Start plugins wizard #17 043fa14: extra assert 7eac40c: larger btree block size / load factor increased for better space utilization a4598a1: enable snapshot mapping e80c2b3: trigram index enabled in internal mode 527f139: delta encoding of file id set to decrease output size ~3x a47785b: move to MnemonicHelper 5b12f32: cleanup 27ef5f4: bg progresses for presentation mode 656e311: add transparent color ddce960: EA-55788 - assert: GitRepositoryImpl dfc2ef7: external-system: project import fixed to use correct fileToImport 675d14e: OC-9559 IDEA-107592 e6d5ea6: IDEA-86665 hg annotate: ignore whitespace changes 6e551ba: test hg executor updated with ignoreNonZeroExitCode addition option 8798162d: cleanup 45f98c5: IDEA-124021 Cannot resolve method 'print(int)' with JSP custom tags 67f1d44: Better fix for IDEA-124096 open commit actions popup on ctrl+alt+P 8aab4ce: IDEA-123691 Minor project wizard edits: moving settings to the first page 9cb1c40: IDEA-122845 Try to fetch issues, if resource with information about user is not available in this version of Redmine a2c9393: Add key to JiraRepository to enable old behavior where credentials were sent with every request via basic auth ce17994: Add special type of exception to indicate request failure from response handlers and other callbacks. ResponseHandler has option to suppress exceptions, if requested resource was not found. de0f3df: notnull, toString 10c30e2: IDEA-123886, dropped UTF guessing setting bf14e11: remove obsolete cruft 7b15687: notnull c82fb9d: mem leak de48566: test 8a9b3d0: doc leak d163e52: comment 1274dba: removed confusing createTempPath() 057c5f9: do not expand usage tree if there are too many nodes e7f245f: debugging IDEA-120167 Phantom eternal Ant task on make 6bf1671: Merge remote-tracking branch 'origin/master' be70ee8: PY-2880: Django: provide completion for context_object_name value in django template * test added * fixture:complete() is reenterable now 1a99a14: Start plugins wizard #16 and it works 30f6e0e: fix false positive with smart tabs 76fcb91: use provided value description instead of just classname don't compute object presentation by custom configured properties if value description is not equals to class name 014c0e3: jb v8 debug protocol: load full string value 223f19a: typo 339e7d6: WEB-11834 IIS ACL Permissions when creating foundation/bootstrap projects from templates b875e62: remove freemarker leftovers from html lexer #WEB-11907 fixed b84c236: push language levels synchronously for non-refresh vfs events (IDEA-123876) a32e2eb: code style a593533: Github: mark invalid password as invalid 10d5070: [git] IDEA-124081 implement IDEA-98189 for clone a9fa3a2: IDEA-124096 open commit actions popup on ctrl+alt+P 83bc60b: AppCode: Xcode keymap tunes for tool windows +review CR-IC-5162 c976200: Merge remote-tracking branch 'origin/master' 48d5f8c: Refactoring: getImportSourceQName() is used d324bc0: GeneratedFolder icon 5d90886: Add "try-with-resources" live postfix template cfec5b0: cleanup e587000: Platform: bug-typo in DnDSupport 814a79a: Unify prefix calculation rules for live templates f447531: IDEA-124005 Reading resources out of a source directory doesn't make it a resource directory Change-Id: Ie2989b1157ae12b92c48d9556db64999ea68e83e
Diffstat (limited to 'java/java-impl/src/com/intellij')
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/AllClassesGetter.java23
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java4
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionSorting.java28
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java4
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/PreferByKindWeigher.java6
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/SameSignatureCallParametersProvider.java18
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/SmartCompletionDecorator.java9
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/scope/JavaCompletionProcessor.java28
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodFromMethodReferenceFix.java5
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodFromUsageFix.java8
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableAccessFromInnerClassFix.java38
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/CaseColonFixer.java35
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/JavaSmartEnterProcessor.java1
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/intention/impl/config/QuickFixFactoryImpl.java4
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/lookup/VariableLookupItem.java23
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/completion/PostfixTemplateCompletionContributor.java21
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/completion/PostfixTemplateLookupElement.java13
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/completion/PostfixTemplatesCompletionProvider.java8
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/settings/PostfixTemplatesConfigurable.java18
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/settings/PostfixTemplatesListPanel.java29
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/BooleanPostfixTemplate.java2
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ElseStatementPostfixTemplate.java17
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ExpressionPostfixTemplateWithChooser.java19
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ForIndexedPostfixTemplate.java4
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ForeachPostfixTemplate.java4
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/FormatPostfixTemplate.java2
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/IfStatementPostfixTemplate.java17
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/InstanceofExpressionPostfixTemplate.java16
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaPostfixTemplateProvider.java130
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/LanguagePostfixTemplate.java27
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NonVoidPostfixTemplate.java2
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NotExpressionPostfixTemplate.java6
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NotNullCheckPostfixTemplate.java24
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NullCheckPostfixTemplate.java4
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixLiveTemplate.java285
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplate.java14
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplateProvider.java52
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ReturnStatementPostfixTemplate.java3
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/StatementPostfixTemplateBase.java18
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SwitchStatementPostfixTemplate.java3
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SynchronizedStatementPostfixTemplate.java3
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ThrowExceptionPostfixTemplate.java2
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/TryWithResourcesPostfixTemplate.java110
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/WhileStatementPostfixTemplate.java18
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/util/Aliases.java15
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/util/PostfixTemplatesUtils.java10
-rw-r--r--java/java-impl/src/com/intellij/ide/fileTemplates/JavaCreateFromTemplateHandler.java4
-rw-r--r--java/java-impl/src/com/intellij/ide/hierarchy/method/MethodHierarchyNodeDescriptor.java2
-rw-r--r--java/java-impl/src/com/intellij/ide/hierarchy/method/MethodHierarchyTreeStructure.java17
-rw-r--r--java/java-impl/src/com/intellij/lang/java/JavaDocumentationProvider.java22
-rw-r--r--java/java-impl/src/com/intellij/openapi/projectRoots/impl/JavaSdkImpl.java17
-rw-r--r--java/java-impl/src/com/intellij/psi/impl/source/codeStyle/ImportHelper.java6
-rw-r--r--java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaCodeStyleManagerImpl.java26
-rw-r--r--java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaReferenceAdjuster.java3
-rw-r--r--java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReference.java42
-rw-r--r--java/java-impl/src/com/intellij/psi/impl/source/tree/JavaTreeCopyHandler.java4
56 files changed, 894 insertions, 379 deletions
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/AllClassesGetter.java b/java/java-impl/src/com/intellij/codeInsight/completion/AllClassesGetter.java
index a5431b56082a..270d6f93f767 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/AllClassesGetter.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/AllClassesGetter.java
@@ -22,20 +22,20 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
+import com.intellij.psi.impl.search.AllClassesSearchExecutor;
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
import com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl;
import com.intellij.psi.search.GlobalSearchScope;
-import com.intellij.psi.search.searches.AllClassesSearch;
import com.intellij.util.Consumer;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.Processor;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
+import java.util.LinkedHashSet;
import java.util.Set;
/**
@@ -184,18 +184,17 @@ public class AllClassesGetter {
@NotNull Project project,
@NotNull GlobalSearchScope scope,
@NotNull Processor<PsiClass> processor) {
- AllClassesSearch.search(scope, project, new Condition<String>() {
+ final Set<String> names = new THashSet<String>(10000);
+ AllClassesSearchExecutor.processClassNames(project, scope, new Consumer<String>() {
@Override
- public boolean value(String s) {
- return prefixMatcher.isStartMatch(s);
- }
- }).forEach(processor);
- AllClassesSearch.search(scope, project, new Condition<String>() {
- @Override
- public boolean value(String s) {
- return prefixMatcher.prefixMatches(s);
+ public void consume(String s) {
+ if (prefixMatcher.prefixMatches(s)) {
+ names.add(s);
+ }
}
- }).forEach(processor);
+ });
+ LinkedHashSet<String> sorted = CompletionUtil.sortMatching(prefixMatcher, names);
+ AllClassesSearchExecutor.processClassesByNames(project, scope, sorted, processor);
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java
index d64529008ca4..28767e6ce422 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.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.
@@ -400,7 +400,7 @@ public class JavaCompletionContributor extends CompletionContributor {
if (((PsiJavaCodeReferenceElement)parent).getQualifier() != null) return isSecondCompletion;
if (parent instanceof PsiJavaCodeReferenceElementImpl &&
- ((PsiJavaCodeReferenceElementImpl)parent).getKind() == PsiJavaCodeReferenceElementImpl.PACKAGE_NAME_KIND) {
+ ((PsiJavaCodeReferenceElementImpl)parent).getKind(parent.getContainingFile()) == PsiJavaCodeReferenceElementImpl.PACKAGE_NAME_KIND) {
return false;
}
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 b66073e2f6f0..d144a67fcb69 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionSorting.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionSorting.java
@@ -34,6 +34,7 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.Function;
+import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
@@ -425,20 +426,35 @@ public class JavaCompletionSorting {
}
private static class PreferExpected extends LookupElementWeigher {
- private final boolean myAcceptClasses;
+ private final boolean myConstructorPossible;
private final ExpectedTypeInfo[] myExpectedTypes;
+ private final List<PsiType> myExpectedClasses = new SmartList<PsiType>();
- public PreferExpected(boolean acceptClasses, ExpectedTypeInfo[] expectedTypes) {
+ public PreferExpected(boolean constructorPossible, ExpectedTypeInfo[] expectedTypes) {
super("expectedType");
- myAcceptClasses = acceptClasses;
+ myConstructorPossible = constructorPossible;
myExpectedTypes = expectedTypes;
+ for (ExpectedTypeInfo info : expectedTypes) {
+ ContainerUtil.addIfNotNull(myExpectedClasses, PsiUtil.substituteTypeParameter(info.getDefaultType(), CommonClassNames.JAVA_LANG_CLASS, 0, false));
+ }
}
@NotNull
@Override
- public Comparable weigh(@NotNull LookupElement item) {
- return item.getObject() instanceof PsiClass && !myAcceptClasses
- ? ExpectedTypeMatching.normal : getExpectedTypeMatching(item, myExpectedTypes);
+ public ExpectedTypeMatching weigh(@NotNull LookupElement item) {
+ if (item.getObject() instanceof PsiClass && !myConstructorPossible) {
+ PsiType itemType = JavaCompletionUtil.getLookupElementType(item);
+ if (itemType != null) {
+ for (PsiType expectedClass : myExpectedClasses) {
+ if (expectedClass.isAssignableFrom(itemType)) {
+ return ExpectedTypeMatching.expected;
+ }
+ }
+ }
+ return ExpectedTypeMatching.normal;
+ }
+
+ return getExpectedTypeMatching(item, myExpectedTypes);
}
}
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 fd0de03cd792..bb0d339ffa80 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java
@@ -330,7 +330,9 @@ public class JavaCompletionUtil {
PsiScopesUtil.processTypeDeclarations(qualifierType, member, new MyProcessor());
- PsiType rawType = member instanceof PsiField ? ((PsiField) member).getType() : ((PsiMethod) member).getReturnType();
+ PsiType rawType = member instanceof PsiField ? ((PsiField) member).getType() :
+ member instanceof PsiMethod ? ((PsiMethod) member).getReturnType() :
+ JavaPsiFacade.getElementFactory(member.getProject()).createType((PsiClass)member);
return subst.get().substitute(rawType);
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/PreferByKindWeigher.java b/java/java-impl/src/com/intellij/codeInsight/completion/PreferByKindWeigher.java
index e8c828a6c4bc..2960bd797dea 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/PreferByKindWeigher.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/PreferByKindWeigher.java
@@ -144,10 +144,8 @@ public class PreferByKindWeigher extends LookupElementWeigher {
}
}
- if (myCompletionType == CompletionType.SMART) {
- if (object instanceof PsiLocalVariable || object instanceof PsiParameter || object instanceof PsiThisExpression) {
- return MyResult.localOrParameter;
- }
+ if (object instanceof PsiLocalVariable || object instanceof PsiParameter || object instanceof PsiThisExpression) {
+ return MyResult.localOrParameter;
}
if (object instanceof String && item.getUserData(JavaCompletionUtil.SUPER_METHOD_PARAMETERS) == Boolean.TRUE) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/SameSignatureCallParametersProvider.java b/java/java-impl/src/com/intellij/codeInsight/completion/SameSignatureCallParametersProvider.java
index d3f0b2e62782..d898bb77ae5a 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/SameSignatureCallParametersProvider.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/SameSignatureCallParametersProvider.java
@@ -19,6 +19,7 @@ import com.intellij.codeInsight.ExpectedTypesProvider;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.codeInsight.lookup.TailTypeDecorator;
+import com.intellij.codeInsight.lookup.VariableLookupItem;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
@@ -72,8 +73,8 @@ class SameSignatureCallParametersProvider extends CompletionProvider<CompletionP
}
}
- private static LookupElement createParametersLookupElement(PsiMethod takeParametersFrom, PsiElement call, PsiMethod invoked) {
- PsiParameter[] parameters = takeParametersFrom.getParameterList().getParameters();
+ private static LookupElement createParametersLookupElement(final PsiMethod takeParametersFrom, PsiElement call, PsiMethod invoked) {
+ final PsiParameter[] parameters = takeParametersFrom.getParameterList().getParameters();
final String lookupString = StringUtil.join(parameters, new Function<PsiParameter, String>() {
@Override
public String fun(PsiParameter psiParameter) {
@@ -86,7 +87,18 @@ class SameSignatureCallParametersProvider extends CompletionProvider<CompletionP
icon.setIcon(PlatformIcons.PARAMETER_ICON, 0, 2*w/5, 0);
icon.setIcon(PlatformIcons.PARAMETER_ICON, 1);
- final LookupElement element = LookupElementBuilder.create(lookupString).withIcon(icon);
+ LookupElementBuilder element = LookupElementBuilder.create(lookupString).withIcon(icon);
+ if (PsiTreeUtil.isAncestor(takeParametersFrom, call, true)) {
+ element = element.withInsertHandler(new InsertHandler<LookupElement>() {
+ @Override
+ public void handleInsert(InsertionContext context, LookupElement item) {
+ context.commitDocument();
+ for (PsiParameter parameter : CompletionUtil.getOriginalOrSelf(takeParametersFrom).getParameterList().getParameters()) {
+ VariableLookupItem.makeFinalIfNeeded(context, parameter);
+ }
+ }
+ });
+ }
element.putUserData(JavaCompletionUtil.SUPER_METHOD_PARAMETERS, Boolean.TRUE);
return TailTypeDecorator.withTail(element, ExpectedTypesProvider.getFinalCallParameterTailType(call, invoked.getReturnType(), invoked));
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/SmartCompletionDecorator.java b/java/java-impl/src/com/intellij/codeInsight/completion/SmartCompletionDecorator.java
index e5a9ee43de69..e2cc1330f88e 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/SmartCompletionDecorator.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/SmartCompletionDecorator.java
@@ -15,6 +15,7 @@
*/
package com.intellij.codeInsight.completion;
+import com.intellij.codeInsight.AutoPopupController;
import com.intellij.codeInsight.CodeInsightSettings;
import com.intellij.codeInsight.ExpectedTypeInfo;
import com.intellij.codeInsight.TailType;
@@ -117,8 +118,14 @@ public class SmartCompletionDecorator extends TailTypeDecorator<LookupElement> {
context.commitDocument();
}
myPosition = getPosition(context, this);
-
+
+ TailType tailType = computeTailType(context);
+
super.handleInsert(context);
+
+ if (tailType == TailType.COMMA) {
+ AutoPopupController.getInstance(context.getProject()).autoPopupParameterInfo(context.getEditor(), null);
+ }
}
public static boolean hasUnboundTypeParams(final PsiMethod method, PsiType expectedType) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/scope/JavaCompletionProcessor.java b/java/java-impl/src/com/intellij/codeInsight/completion/scope/JavaCompletionProcessor.java
index fb7878dba26c..4e13baf779f2 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/scope/JavaCompletionProcessor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/scope/JavaCompletionProcessor.java
@@ -25,6 +25,7 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.filters.ElementFilter;
+import com.intellij.psi.impl.light.LightMethodBuilder;
import com.intellij.psi.impl.source.resolve.JavaResolveUtil;
import com.intellij.psi.infos.CandidateInfo;
import com.intellij.psi.scope.BaseScopeProcessor;
@@ -100,14 +101,11 @@ public class JavaCompletionProcessor extends BaseScopeProcessor implements Eleme
if (qualifier instanceof PsiSuperExpression) {
final PsiJavaCodeReferenceElement qSuper = ((PsiSuperExpression)qualifier).getQualifier();
if (qSuper == null) {
- myQualifierClass = JavaResolveUtil.getContextClass( myElement);
+ myQualifierClass = JavaResolveUtil.getContextClass(myElement);
} else {
final PsiElement target = qSuper.resolve();
myQualifierClass = target instanceof PsiClass ? (PsiClass)target : null;
}
- if (myQualifierClass != null) {
- myQualifierType = JavaPsiFacade.getInstance(element.getProject()).getElementFactory().createType(myQualifierClass);
- }
}
else if (qualifier != null) {
setQualifierType(qualifier.getType());
@@ -117,8 +115,13 @@ public class JavaCompletionProcessor extends BaseScopeProcessor implements Eleme
myQualifierClass = (PsiClass)target;
}
}
+ } else {
+ myQualifierClass = JavaResolveUtil.getContextClass(myElement);
}
}
+ if (myQualifierClass != null && myQualifierType == null) {
+ myQualifierType = JavaPsiFacade.getElementFactory(element.getProject()).createType(myQualifierClass);
+ }
if (myOptions.checkInitialized) {
myNonInitializedFields.addAll(getNonInitializedFields(element));
@@ -219,6 +222,19 @@ public class JavaCompletionProcessor extends BaseScopeProcessor implements Eleme
return true;
}
+ if (element instanceof PsiMethod) {
+ PsiMethod method = (PsiMethod)element;
+ if (PsiTypesUtil.isGetClass(method) && PsiUtil.isLanguageLevel5OrHigher(myElement)) {
+ PsiType patchedType = PsiTypesUtil.createJavaLangClassType(myElement, myQualifierType, false);
+ if (patchedType != null) {
+ element = new LightMethodBuilder(element.getManager(), method.getName()).
+ addModifier(PsiModifier.PUBLIC).
+ setMethodReturnType(patchedType).
+ setContainingClass(method.getContainingClass());
+ }
+ }
+ }
+
if (satisfies(element, state) && isAccessible(element)) {
CompletionElement element1 = new CompletionElement(element, state.get(PsiSubstitutor.KEY));
if (myResultNames.add(element1.getUniqueId())) {
@@ -288,7 +304,9 @@ public class JavaCompletionProcessor extends BaseScopeProcessor implements Eleme
if (!(element instanceof PsiMember)) return true;
PsiMember member = (PsiMember)element;
- return JavaPsiFacade.getInstance(element.getProject()).getResolveHelper().isAccessible(member, member.getModifierList(), myElement, myQualifierClass, myDeclarationHolder);
+ PsiClass accessObjectClass = member instanceof PsiClass ? null : myQualifierClass;
+ return JavaPsiFacade.getInstance(element.getProject()).getResolveHelper().isAccessible(member, member.getModifierList(), myElement,
+ accessObjectClass, myDeclarationHolder);
}
public void setCompletionElements(@NotNull Object[] elements) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodFromMethodReferenceFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodFromMethodReferenceFix.java
index b0c29bf641e3..74df48381201 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodFromMethodReferenceFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodFromMethodReferenceFix.java
@@ -124,15 +124,16 @@ public class CreateMethodFromMethodReferenceFix extends CreateFromUsageBaseFix {
final PsiType interfaceReturnType = LambdaUtil.getFunctionalInterfaceReturnType(functionalInterfaceType);
LOG.assertTrue(interfaceReturnType != null);
+ final PsiSubstitutor substitutor = LambdaUtil.getSubstitutor(interfaceMethod, classResolveResult);
final ExpectedTypeInfo[] expectedTypes = {new ExpectedTypeInfoImpl(interfaceReturnType, ExpectedTypeInfo.TYPE_OR_SUBTYPE, interfaceReturnType, TailType.NONE, null, ExpectedTypeInfoImpl.NULL)};
CreateMethodFromUsageFix.doCreate(targetClass, method, false,
ContainerUtil.map2List(interfaceMethod.getParameterList().getParameters(), new Function<PsiParameter, Pair<PsiExpression, PsiType>>() {
@Override
public Pair<PsiExpression, PsiType> fun(PsiParameter parameter) {
- return Pair.create(null, parameter.getType());
+ return Pair.create(null, substitutor.substitute(parameter.getType()));
}
}),
- LambdaUtil.getSubstitutor(interfaceMethod, classResolveResult),
+ PsiSubstitutor.EMPTY,
expectedTypes, context);
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodFromUsageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodFromUsageFix.java
index 3ce012705c0f..b7cd8af73084 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodFromUsageFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodFromUsageFix.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,14 +17,14 @@ package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.CodeInsightUtilCore;
import com.intellij.codeInsight.ExpectedTypeInfo;
-import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerEx;
import com.intellij.codeInsight.daemon.QuickFixBundle;
+import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerEx;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.codeInsight.template.Template;
import com.intellij.codeInsight.template.TemplateBuilderImpl;
import com.intellij.codeInsight.template.TemplateEditingAdapter;
import com.intellij.lang.annotation.HighlightSeverity;
-import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
@@ -259,7 +259,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageBaseFix {
startTemplate(newEditor, template, project, new TemplateEditingAdapter() {
@Override
public void templateFinished(Template template, boolean brokenOff) {
- ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ WriteCommandAction.runWriteCommandAction(project, new Runnable() {
@Override
public void run() {
PsiDocumentManager.getInstance(project).commitDocument(newEditor.getDocument());
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableAccessFromInnerClassFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableAccessFromInnerClassFix.java
index 98a271629093..47ed78e48760 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableAccessFromInnerClassFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableAccessFromInnerClassFix.java
@@ -42,16 +42,16 @@ import java.util.*;
public class VariableAccessFromInnerClassFix implements IntentionAction {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.quickfix.VariableAccessFromInnerClassFix");
private final PsiVariable myVariable;
- private final PsiClass myClass;
+ private final PsiElement myContext;
private final int myFixType;
private static final int MAKE_FINAL = 0;
private static final int MAKE_ARRAY = 1;
private static final int COPY_TO_FINAL = 2;
private static final Key<Map<PsiVariable,Boolean>>[] VARS = new Key[] {Key.create("VARS_TO_MAKE_FINAL"), Key.create("VARS_TO_TRANSFORM"), Key.create("???")};
- public VariableAccessFromInnerClassFix(@NotNull PsiVariable variable, @NotNull PsiClass aClass) {
+ public VariableAccessFromInnerClassFix(@NotNull PsiVariable variable, @NotNull PsiElement element) {
myVariable = variable;
- myClass = aClass;
+ myContext = element;
myFixType = getQuickFixType(variable);
if (myFixType == -1) return;
@@ -87,21 +87,21 @@ public class VariableAccessFromInnerClassFix implements IntentionAction {
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
- return myClass.isValid() &&
- myClass.getManager().isInProject(myClass) &&
+ return myContext.isValid() &&
+ myContext.getManager().isInProject(myContext) &&
myVariable.isValid() &&
myFixType != -1 &&
!getVariablesToFix().isEmpty() &&
- !inOwnInitializer(myVariable, myClass);
+ !inOwnInitializer(myVariable, myContext);
}
- private static boolean inOwnInitializer(PsiVariable variable, PsiClass aClass) {
- return PsiTreeUtil.isAncestor(variable, aClass, false);
+ private static boolean inOwnInitializer(PsiVariable variable, PsiElement context) {
+ return PsiTreeUtil.isAncestor(variable, context, false);
}
@Override
public void invoke(@NotNull Project project, Editor editor, PsiFile file) {
- if (!FileModificationService.getInstance().preparePsiElementsForWrite(myClass, myVariable)) return;
+ if (!FileModificationService.getInstance().preparePsiElementsForWrite(myContext, myVariable)) return;
try {
switch (myFixType) {
case MAKE_FINAL:
@@ -131,8 +131,8 @@ public class VariableAccessFromInnerClassFix implements IntentionAction {
@NotNull
private Collection<PsiVariable> getVariablesToFix() {
- Map<PsiVariable, Boolean> vars = myClass.getUserData(VARS[myFixType]);
- if (vars == null) myClass.putUserData(VARS[myFixType], vars = new ConcurrentWeakHashMap<PsiVariable, Boolean>(1));
+ Map<PsiVariable, Boolean> vars = myContext.getUserData(VARS[myFixType]);
+ if (vars == null) myContext.putUserData(VARS[myFixType], vars = new ConcurrentWeakHashMap<PsiVariable, Boolean>(1));
final Map<PsiVariable, Boolean> finalVars = vars;
return new AbstractCollection<PsiVariable>() {
@Override
@@ -164,7 +164,7 @@ public class VariableAccessFromInnerClassFix implements IntentionAction {
private void makeArray(PsiVariable variable) throws IncorrectOperationException {
PsiType type = variable.getType();
- PsiElementFactory factory = JavaPsiFacade.getInstance(myClass.getProject()).getElementFactory();
+ PsiElementFactory factory = JavaPsiFacade.getInstance(myContext.getProject()).getElementFactory();
PsiType newType = type.createArrayType();
PsiDeclarationStatement variableDeclarationStatement;
@@ -195,9 +195,9 @@ public class VariableAccessFromInnerClassFix implements IntentionAction {
}
private void copyToFinal() throws IncorrectOperationException {
- PsiManager psiManager = myClass.getManager();
+ PsiManager psiManager = myContext.getManager();
PsiElementFactory factory = JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory();
- PsiExpression initializer = factory.createExpressionFromText(myVariable.getName(), myClass);
+ PsiExpression initializer = factory.createExpressionFromText(myVariable.getName(), myContext);
String newName = suggestNewName(psiManager.getProject(), myVariable);
PsiType type = myVariable.getType();
PsiDeclarationStatement copyDecl = factory.createVariableDeclarationStatement(newName, type, initializer);
@@ -206,7 +206,7 @@ public class VariableAccessFromInnerClassFix implements IntentionAction {
PsiElement statement = getStatementToInsertBefore();
if (statement == null) return;
PsiExpression newExpression = factory.createExpressionFromText(newName, myVariable);
- replaceReferences(myClass, myVariable, newExpression);
+ replaceReferences(myContext, myVariable, newExpression);
if (RefactoringUtil.isLoopOrIf(statement.getParent())) {
RefactoringUtil.putStatementInLoopBody(copyDecl, statement.getParent(), statement);
} else {
@@ -219,7 +219,7 @@ public class VariableAccessFromInnerClassFix implements IntentionAction {
? ((PsiParameter)myVariable).getDeclarationScope() : PsiUtil.getVariableCodeBlock(myVariable, null);
if (declarationScope == null) return null;
- PsiElement statement = myClass;
+ PsiElement statement = myContext;
nextInnerClass:
do {
statement = RefactoringUtil.getParentStatement(statement, false);
@@ -291,11 +291,11 @@ public class VariableAccessFromInnerClassFix implements IntentionAction {
int type = MAKE_FINAL;
for (PsiReferenceExpression expression : outerReferences) {
// if it happens that variable referenced from another inner class, make sure it can be make final from there
- PsiClass innerClass = HighlightControlFlowUtil.getInnerClassVariableReferencedFrom(variable, expression);
+ PsiElement innerScope = HighlightControlFlowUtil.getInnerClassVariableReferencedFrom(variable, expression);
- if (innerClass != null) {
+ if (innerScope != null) {
int thisType = MAKE_FINAL;
- if (writtenInside(variable, innerClass)) {
+ if (writtenInside(variable, innerScope)) {
// cannot make parameter array
if (variable instanceof PsiParameter) return -1;
thisType = MAKE_ARRAY;
diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/CaseColonFixer.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/CaseColonFixer.java
new file mode 100644
index 000000000000..de32027c4616
--- /dev/null
+++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/CaseColonFixer.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.codeInsight.editorActions.smartEnter;
+
+import com.intellij.openapi.editor.Editor;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiSwitchLabelStatement;
+import com.intellij.util.IncorrectOperationException;
+
+/**
+ * @author peter
+ */
+public class CaseColonFixer implements Fixer {
+ @Override
+ public void apply(Editor editor, JavaSmartEnterProcessor processor, PsiElement psiElement) throws IncorrectOperationException {
+ if (psiElement instanceof PsiSwitchLabelStatement &&
+ ((PsiSwitchLabelStatement)psiElement).getCaseValue() != null &&
+ !psiElement.getText().endsWith(":")) {
+ editor.getDocument().insertString(psiElement.getTextRange().getEndOffset(), ":");
+ }
+ }
+}
diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/JavaSmartEnterProcessor.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/JavaSmartEnterProcessor.java
index 4df807f561b2..cea07113fe24 100644
--- a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/JavaSmartEnterProcessor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/JavaSmartEnterProcessor.java
@@ -58,6 +58,7 @@ public class JavaSmartEnterProcessor extends SmartEnterProcessor {
fixers.add(new WhileConditionFixer());
fixers.add(new CatchDeclarationFixer());
fixers.add(new SwitchExpressionFixer());
+ fixers.add(new CaseColonFixer());
fixers.add(new DoWhileConditionFixer());
fixers.add(new BlockBraceFixer());
fixers.add(new MissingIfBranchesFixer());
diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/config/QuickFixFactoryImpl.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/config/QuickFixFactoryImpl.java
index 5f95da053db3..c8a6cfa0271f 100644
--- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/config/QuickFixFactoryImpl.java
+++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/config/QuickFixFactoryImpl.java
@@ -547,8 +547,8 @@ public class QuickFixFactoryImpl extends QuickFixFactory {
@NotNull
@Override
- public IntentionAction createVariableAccessFromInnerClassFix(@NotNull PsiVariable variable, @NotNull PsiClass aClass) {
- return new VariableAccessFromInnerClassFix(variable, aClass);
+ public IntentionAction createVariableAccessFromInnerClassFix(@NotNull PsiVariable variable, @NotNull PsiElement scope) {
+ return new VariableAccessFromInnerClassFix(variable, scope);
}
@NotNull
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 9f23dba0b7df..21e32a3e3aeb 100644
--- a/java/java-impl/src/com/intellij/codeInsight/lookup/VariableLookupItem.java
+++ b/java/java-impl/src/com/intellij/codeInsight/lookup/VariableLookupItem.java
@@ -123,7 +123,10 @@ public class VariableLookupItem extends LookupItem<PsiVariable> implements Typed
}
ref = PsiTreeUtil.findElementOfClassAtOffset(context.getFile(), context.getTailOffset() - 1, PsiReferenceExpression.class, false);
- makeVariableFinalIfNeeded(context, ref);
+ PsiElement target = ref == null ? null : ref.resolve();
+ if (target instanceof PsiLocalVariable || target instanceof PsiParameter) {
+ makeFinalIfNeeded(context, (PsiVariable)target);
+ }
final char completionChar = context.getCompletionChar();
if (completionChar == '=') {
@@ -151,22 +154,16 @@ public class VariableLookupItem extends LookupItem<PsiVariable> implements Typed
}
}
- private static void makeVariableFinalIfNeeded(InsertionContext context, @Nullable PsiReferenceExpression ref) {
+ public static void makeFinalIfNeeded(@NotNull InsertionContext context, @NotNull PsiVariable variable) {
+ PsiElement place = context.getFile().findElementAt(context.getTailOffset() - 1);
if (!Registry.is("java.completion.make.outer.variables.final") ||
- ref == null || PsiUtil.isLanguageLevel8OrHigher(ref) || JspPsiUtil.isInJspFile(ref)) {
+ place == null || PsiUtil.isLanguageLevel8OrHigher(place) || JspPsiUtil.isInJspFile(place)) {
return;
}
- PsiElement target = ref.resolve();
- if (target instanceof PsiLocalVariable || target instanceof PsiParameter) {
- PsiClass placeClass = PsiTreeUtil.findElementOfClassAtOffset(context.getFile(), context.getTailOffset() - 1, PsiClass.class, false);
- if (placeClass != null && !PsiTreeUtil.isAncestor(placeClass, target, true) &&
- !HighlightControlFlowUtil.isReassigned((PsiVariable)target, new HashMap<PsiElement, Collection<ControlFlowUtil.VariableInfo>>())) {
- PsiModifierList modifierList = ((PsiVariable)target).getModifierList();
- if (modifierList != null) {
- modifierList.setModifierProperty(PsiModifier.FINAL, true);
- }
- }
+ if (HighlightControlFlowUtil.getInnerClassVariableReferencedFrom(variable, place) != null &&
+ !HighlightControlFlowUtil.isReassigned(variable, new HashMap<PsiElement, Collection<ControlFlowUtil.VariableInfo>>())) {
+ PsiUtil.setModifierProperty(variable, PsiModifier.FINAL, true);
}
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/completion/PostfixTemplateCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/completion/PostfixTemplateCompletionContributor.java
index b6a7b5f687ce..eb6b585f0ec1 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/completion/PostfixTemplateCompletionContributor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/completion/PostfixTemplateCompletionContributor.java
@@ -21,34 +21,19 @@ import com.intellij.codeInsight.template.CustomLiveTemplate;
import com.intellij.codeInsight.template.impl.TemplateManagerImpl;
import com.intellij.codeInsight.template.postfix.templates.PostfixLiveTemplate;
import com.intellij.openapi.editor.Editor;
-import com.intellij.patterns.ElementPattern;
-import com.intellij.psi.JavaTokenType;
-import com.intellij.psi.PsiElement;
+import com.intellij.patterns.PlatformPatterns;
import com.intellij.psi.PsiFile;
-import com.intellij.psi.impl.source.tree.ElementType;
-import com.intellij.psi.tree.TokenSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import static com.intellij.patterns.PsiJavaPatterns.psiElement;
-import static com.intellij.patterns.StandardPatterns.string;
-
public class PostfixTemplateCompletionContributor extends CompletionContributor {
- private static final TokenSet SUITABLE_ELEMENTS = TokenSet.orSet(ElementType.KEYWORD_BIT_SET,
- ElementType.LITERAL_BIT_SET,
- TokenSet.create(JavaTokenType.IDENTIFIER));
-
public PostfixTemplateCompletionContributor() {
- extend(CompletionType.BASIC, identifierAfterDot(), new PostfixTemplatesCompletionProvider());
+ extend(CompletionType.BASIC, PlatformPatterns.psiElement(), new PostfixTemplatesCompletionProvider());
}
@Nullable
- public static PostfixLiveTemplate getPostfixLiveTemplate(@NotNull PsiFile file, @NotNull Editor editor) {
+ public static PostfixLiveTemplate getPostfixLiveTemplate(@NotNull PsiFile file, @NotNull Editor editor) {
PostfixLiveTemplate postfixLiveTemplate = CustomLiveTemplate.EP_NAME.findExtension(PostfixLiveTemplate.class);
return postfixLiveTemplate != null && TemplateManagerImpl.isApplicable(postfixLiveTemplate, editor, file) ? postfixLiveTemplate : null;
}
-
- private static ElementPattern<? extends PsiElement> identifierAfterDot() {
- return psiElement().withElementType(SUITABLE_ELEMENTS).afterLeaf(psiElement().withText(string().contains(".")));
- }
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/completion/PostfixTemplateLookupElement.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/completion/PostfixTemplateLookupElement.java
index 0aeba2baaced..c01f6073845a 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/completion/PostfixTemplateLookupElement.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/completion/PostfixTemplateLookupElement.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,8 @@ import com.intellij.codeInsight.lookup.LookupElementPresentation;
import com.intellij.codeInsight.template.impl.CustomLiveTemplateLookupElement;
import com.intellij.codeInsight.template.postfix.templates.PostfixLiveTemplate;
import com.intellij.codeInsight.template.postfix.templates.PostfixTemplate;
-import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
public class PostfixTemplateLookupElement extends CustomLiveTemplateLookupElement {
@@ -30,7 +31,7 @@ public class PostfixTemplateLookupElement extends CustomLiveTemplateLookupElemen
@NotNull PostfixTemplate postfixTemplate,
@NotNull String templateKey,
boolean sudden) {
- super(liveTemplate, templateKey, postfixTemplate.getPresentableName(), postfixTemplate.getDescription(), sudden, true);
+ super(liveTemplate, templateKey, StringUtil.trimStart(templateKey, "."), postfixTemplate.getDescription(), sudden, true);
myTemplate = postfixTemplate;
}
@@ -43,15 +44,11 @@ public class PostfixTemplateLookupElement extends CustomLiveTemplateLookupElemen
public void renderElement(LookupElementPresentation presentation) {
super.renderElement(presentation);
if (sudden) {
- presentation.setTailText(" " + arrow() + " " + myTemplate.getExample());
+ presentation.setTailText(" " + UIUtil.rightArrow() + " " + myTemplate.getExample());
}
else {
presentation.setTypeText(myTemplate.getExample());
presentation.setTypeGrayed(true);
}
}
-
- private static String arrow() {
- return SystemInfo.isMac ? "→" : "->";
- }
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/completion/PostfixTemplatesCompletionProvider.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/completion/PostfixTemplatesCompletionProvider.java
index db253a6808b1..ec0aead68085 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/completion/PostfixTemplatesCompletionProvider.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/completion/PostfixTemplatesCompletionProvider.java
@@ -19,6 +19,7 @@ import com.intellij.codeInsight.completion.CompletionParameters;
import com.intellij.codeInsight.completion.CompletionProvider;
import com.intellij.codeInsight.completion.CompletionResultSet;
import com.intellij.codeInsight.completion.PrefixMatcher;
+import com.intellij.codeInsight.template.CustomTemplateCallback;
import com.intellij.codeInsight.template.impl.LiveTemplateCompletionContributor;
import com.intellij.codeInsight.template.postfix.settings.PostfixTemplatesSettings;
import com.intellij.codeInsight.template.postfix.templates.PostfixLiveTemplate;
@@ -42,11 +43,12 @@ class PostfixTemplatesCompletionProvider extends CompletionProvider<CompletionPa
PostfixLiveTemplate postfixLiveTemplate = getPostfixLiveTemplate(parameters.getOriginalFile(), parameters.getEditor());
if (postfixLiveTemplate != null) {
postfixLiveTemplate.addCompletions(parameters, result.withPrefixMatcher(new MyPrefixMatcher(result.getPrefixMatcher().getPrefix())));
- CharSequence documentContent = parameters.getEditor().getDocument().getCharsSequence();
- String possibleKey = postfixLiveTemplate.computeTemplateKeyWithoutContextChecking(documentContent, parameters.getOffset());
+ String possibleKey = postfixLiveTemplate.computeTemplateKeyWithoutContextChecking(
+ new CustomTemplateCallback(parameters.getEditor(), parameters.getOriginalFile(), false));
if (possibleKey != null) {
result = result.withPrefixMatcher(possibleKey);
- result.restartCompletionOnPrefixChange(StandardPatterns.string().oneOf(postfixLiveTemplate.getAllTemplateKeys()));
+ result.restartCompletionOnPrefixChange(
+ StandardPatterns.string().oneOf(postfixLiveTemplate.getAllTemplateKeys(parameters.getOriginalFile(), parameters.getOffset())));
}
}
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/settings/PostfixTemplatesConfigurable.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/settings/PostfixTemplatesConfigurable.java
index 75c7d93b515a..90d4eed6e2b9 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/settings/PostfixTemplatesConfigurable.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/settings/PostfixTemplatesConfigurable.java
@@ -19,7 +19,11 @@ import com.intellij.application.options.editor.EditorOptionsProvider;
import com.intellij.codeInsight.CodeInsightBundle;
import com.intellij.codeInsight.template.impl.LiveTemplateCompletionContributor;
import com.intellij.codeInsight.template.impl.TemplateSettings;
+import com.intellij.codeInsight.template.postfix.templates.LanguagePostfixTemplate;
import com.intellij.codeInsight.template.postfix.templates.PostfixTemplate;
+import com.intellij.codeInsight.template.postfix.templates.PostfixTemplateProvider;
+import com.intellij.lang.LanguageExtensionPoint;
+import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SearchableConfigurable;
@@ -34,8 +38,9 @@ import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
-import java.util.*;
+import java.util.Comparator;
import java.util.List;
+import java.util.Map;
public class PostfixTemplatesConfigurable implements SearchableConfigurable, EditorOptionsProvider, Configurable.NoScroll {
@Nullable
@@ -61,7 +66,14 @@ public class PostfixTemplatesConfigurable implements SearchableConfigurable, Edi
}
myTemplatesSettings = settings;
- List<PostfixTemplate> templates = Arrays.asList(PostfixTemplate.EP_NAME.getExtensions());
+
+ LanguageExtensionPoint[] extensions = new ExtensionPointName<LanguageExtensionPoint>(LanguagePostfixTemplate.EP_NAME).getExtensions();
+
+ List<PostfixTemplate> templates = ContainerUtil.newArrayList();
+ for (LanguageExtensionPoint extension : extensions) {
+ templates.addAll(((PostfixTemplateProvider)extension.getInstance()).getTemplates());
+ }
+
ContainerUtil.sort(templates, new Comparator<PostfixTemplate>() {
@Override
public int compare(PostfixTemplate o1, PostfixTemplate o2) {
@@ -184,7 +196,7 @@ public class PostfixTemplatesConfigurable implements SearchableConfigurable, Edi
private static String shortcutToString(char shortcut) {
if (shortcut == TemplateSettings.SPACE_CHAR) {
return SPACE;
- }
+ }
if (shortcut == TemplateSettings.ENTER_CHAR) {
return ENTER;
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/settings/PostfixTemplatesListPanel.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/settings/PostfixTemplatesListPanel.java
index 0c21e04b4c97..4ecc8c0ee4ac 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/settings/PostfixTemplatesListPanel.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/settings/PostfixTemplatesListPanel.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.template.postfix.settings;
import com.intellij.codeInsight.template.postfix.templates.PostfixTemplate;
@@ -29,7 +44,7 @@ public class PostfixTemplatesListPanel {
@NotNull
@Override
public String fun(@NotNull PostfixTemplate template) {
- return template.getKey().replaceFirst(".", "");
+ return template.getKey().replaceFirst("\\.", "");
}
};
@@ -114,7 +129,9 @@ public class PostfixTemplatesListPanel {
public void setState(@NotNull Map<String, Boolean> templatesState) {
myTemplatesState.clear();
for (Map.Entry<String, Boolean> entry : templatesState.entrySet()) {
- myTemplatesState.put(entry.getKey(), entry.getValue());
+ if (!entry.getValue()) {
+ myTemplatesState.put(entry.getKey(), entry.getValue());
+ }
}
}
@@ -172,7 +189,13 @@ public class PostfixTemplatesListPanel {
@Override
public void setValue(@NotNull PostfixTemplate template, Boolean value) {
- myTemplatesState.put(template.getKey(), value);
+ String key = template.getKey();
+ if (value) {
+ myTemplatesState.remove(key);
+ }
+ else {
+ myTemplatesState.put(key, value);
+ }
}
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/BooleanPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/BooleanPostfixTemplate.java
index ab6f90eaa752..f8700bed4644 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/BooleanPostfixTemplate.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/BooleanPostfixTemplate.java
@@ -28,7 +28,7 @@ abstract public class BooleanPostfixTemplate extends PostfixTemplate {
@Override
public boolean isApplicable(@NotNull PsiElement context, @NotNull Document copyDocument, int newOffset) {
- PsiExpression topmostExpression = getTopmostExpression(context);
+ PsiExpression topmostExpression = PostfixTemplatesUtils.getTopmostExpression(context);
return topmostExpression != null && PostfixTemplatesUtils.isBoolean(topmostExpression.getType());
}
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ElseStatementPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ElseStatementPostfixTemplate.java
index 37187455f40c..a148a1bf8896 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ElseStatementPostfixTemplate.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ElseStatementPostfixTemplate.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.template.postfix.templates;
import com.intellij.codeInsight.CodeInsightServicesUtil;
@@ -15,7 +30,7 @@ public class ElseStatementPostfixTemplate extends BooleanPostfixTemplate {
@Override
public void expand(@NotNull PsiElement context, @NotNull Editor editor) {
- PsiExpression expression = getTopmostExpression(context);
+ PsiExpression expression = PostfixTemplatesUtils.getTopmostExpression(context);
assert expression != null;
PsiExpression invertedExpression = (PsiExpression)expression.replace(CodeInsightServicesUtil.invertCondition(expression));
TextRange range = PostfixTemplatesUtils.ifStatement(invertedExpression.getProject(), editor, invertedExpression);
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ExpressionPostfixTemplateWithChooser.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ExpressionPostfixTemplateWithChooser.java
index 8de536551ab5..3bd7928c3e1c 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ExpressionPostfixTemplateWithChooser.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ExpressionPostfixTemplateWithChooser.java
@@ -42,6 +42,13 @@ public abstract class ExpressionPostfixTemplateWithChooser extends PostfixTempla
super(name, description, example);
}
+ protected ExpressionPostfixTemplateWithChooser(@NotNull String name,
+ @NotNull String key,
+ @NotNull String description,
+ @NotNull String example) {
+ super(name, key, description, example);
+ }
+
@Override
public boolean isApplicable(@NotNull PsiElement context, @NotNull Document copyDocument, int newOffset) {
return !getExpressions(context, copyDocument, newOffset).isEmpty();
@@ -75,20 +82,22 @@ public abstract class ExpressionPostfixTemplateWithChooser extends PostfixTempla
}
},
new PsiExpressionTrimRenderer.RenderFunction(),
- "Expressions", 0, ScopeHighlighter.NATURAL_RANGER);
+ "Expressions", 0, ScopeHighlighter.NATURAL_RANGER
+ );
}
}
@NotNull
protected List<PsiExpression> getExpressions(@NotNull PsiElement context, @NotNull Document document, final int offset) {
- List<PsiExpression> expressions = ContainerUtil.filter(IntroduceVariableBase.collectExpressions(context.getContainingFile(), document,
- Math.max(offset - 1, 0), false),
+ List<PsiExpression> expressions = ContainerUtil.filter(IntroduceVariableBase.collectExpressions(context.getContainingFile(), document,
+ Math.max(offset - 1, 0), false),
new Condition<PsiExpression>() {
@Override
public boolean value(PsiExpression expression) {
return expression.getTextRange().getEndOffset() == offset;
}
- });
+ }
+ );
return ContainerUtil.filter(expressions.isEmpty() ? maybeTopmostExpression(context) : expressions, getTypeCondition());
}
@@ -100,7 +109,7 @@ public abstract class ExpressionPostfixTemplateWithChooser extends PostfixTempla
@NotNull
private static List<PsiExpression> maybeTopmostExpression(@NotNull PsiElement context) {
- PsiExpression expression = getTopmostExpression(context);
+ PsiExpression expression = PostfixTemplatesUtils.getTopmostExpression(context);
PsiType type = expression != null ? expression.getType() : null;
if (type == null || PsiType.VOID.equals(type)) return ContainerUtil.emptyList();
return ContainerUtil.createMaybeSingletonList(expression);
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ForIndexedPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ForIndexedPostfixTemplate.java
index c353c8d39145..bf025d17741f 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ForIndexedPostfixTemplate.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ForIndexedPostfixTemplate.java
@@ -37,7 +37,7 @@ public abstract class ForIndexedPostfixTemplate extends PostfixTemplate {
@Override
public boolean isApplicable(@NotNull PsiElement context, @NotNull Document copyDocument, int newOffset) {
- PsiExpression expr = getTopmostExpression(context);
+ PsiExpression expr = PostfixTemplatesUtils.getTopmostExpression(context);
return expr != null && (PostfixTemplatesUtils.isNumber(expr.getType()) ||
PostfixTemplatesUtils.isArray(expr.getType()) ||
PostfixTemplatesUtils.isIterable(expr.getType()));
@@ -45,7 +45,7 @@ public abstract class ForIndexedPostfixTemplate extends PostfixTemplate {
@Override
public void expand(@NotNull PsiElement context, @NotNull Editor editor) {
- PsiExpression expr = getTopmostExpression(context);
+ PsiExpression expr = PostfixTemplatesUtils.getTopmostExpression(context);
if (expr == null) {
PostfixTemplatesUtils.showErrorHint(context.getProject(), editor);
return;
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ForeachPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ForeachPostfixTemplate.java
index aabf47c8eaa1..72bbb4f703bf 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ForeachPostfixTemplate.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ForeachPostfixTemplate.java
@@ -37,13 +37,13 @@ public class ForeachPostfixTemplate extends PostfixTemplate {
@Override
public boolean isApplicable(@NotNull PsiElement context, @NotNull Document copyDocument, int newOffset) {
- PsiExpression expr = getTopmostExpression(context);
+ PsiExpression expr = PostfixTemplatesUtils.getTopmostExpression(context);
return expr != null && (PostfixTemplatesUtils.isArray(expr.getType()) || PostfixTemplatesUtils.isIterable(expr.getType()));
}
@Override
public void expand(@NotNull PsiElement context, @NotNull Editor editor) {
- PsiExpression expr = getTopmostExpression(context);
+ PsiExpression expr = PostfixTemplatesUtils.getTopmostExpression(context);
if (expr == null) return;
Project project = context.getProject();
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/FormatPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/FormatPostfixTemplate.java
index 5d99745168a4..a799f39ca466 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/FormatPostfixTemplate.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/FormatPostfixTemplate.java
@@ -36,7 +36,7 @@ public class FormatPostfixTemplate extends PostfixTemplate {
@Override
public boolean isApplicable(@NotNull PsiElement context, @NotNull Document copyDocument, int newOffset) {
- PsiExpression expr = getTopmostExpression(context);
+ PsiExpression expr = PostfixTemplatesUtils.getTopmostExpression(context);
PsiType type = expr != null ? expr.getType() : null;
return expr != null && type != null && CommonClassNames.JAVA_LANG_STRING.equals(type.getCanonicalText());
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/IfStatementPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/IfStatementPostfixTemplate.java
index 9610ec57c23d..812247428e51 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/IfStatementPostfixTemplate.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/IfStatementPostfixTemplate.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.template.postfix.templates;
import com.intellij.codeInsight.template.postfix.util.PostfixTemplatesUtils;
@@ -14,7 +29,7 @@ public class IfStatementPostfixTemplate extends BooleanPostfixTemplate {
@Override
public void expand(@NotNull PsiElement context, @NotNull final Editor editor) {
- PsiExpression expression = getTopmostExpression(context);
+ PsiExpression expression = PostfixTemplatesUtils.getTopmostExpression(context);
assert expression != null;
TextRange range = PostfixTemplatesUtils.ifStatement(expression.getProject(), editor, expression);
if (range != null) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/InstanceofExpressionPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/InstanceofExpressionPostfixTemplate.java
index 8c5b58e79123..1884d099edcd 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/InstanceofExpressionPostfixTemplate.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/InstanceofExpressionPostfixTemplate.java
@@ -19,7 +19,6 @@ import com.intellij.codeInsight.guess.GuessManager;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.PsiTypeLookupItem;
import com.intellij.codeInsight.template.*;
-import com.intellij.codeInsight.template.postfix.util.Aliases;
import com.intellij.codeInsight.template.postfix.util.PostfixTemplatesUtils;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
@@ -35,25 +34,30 @@ import org.jetbrains.annotations.NotNull;
import java.util.LinkedHashSet;
import java.util.Set;
-@Aliases(".inst")
public class InstanceofExpressionPostfixTemplate extends PostfixTemplate {
+
public InstanceofExpressionPostfixTemplate() {
- super("instanceof", "Surrounds expression with instanceof", "expr instanceof SomeType ? ((SomeType) expr). : null");
+ this("instanceof");
+ }
+
+ public InstanceofExpressionPostfixTemplate(String alias) {
+ super(alias, "Surrounds expression with instanceof", "expr instanceof SomeType ? ((SomeType) expr). : null");
}
@Override
public boolean isApplicable(@NotNull PsiElement context, @NotNull Document copyDocument, int newOffset) {
- return PostfixTemplatesUtils.isNotPrimitiveTypeExpression(getTopmostExpression(context));
+ return PostfixTemplatesUtils.isNotPrimitiveTypeExpression(PostfixTemplatesUtils.getTopmostExpression(context));
}
@Override
public void expand(@NotNull PsiElement context, @NotNull Editor editor) {
- PsiExpression expression = getTopmostExpression(context);
+ PsiExpression expression = PostfixTemplatesUtils.getTopmostExpression(context);
if (!PostfixTemplatesUtils.isNotPrimitiveTypeExpression(expression)) return;
surroundExpression(context.getProject(), editor, expression);
}
- private static void surroundExpression(@NotNull Project project, @NotNull Editor editor, @NotNull PsiExpression expr) throws IncorrectOperationException {
+ private static void surroundExpression(@NotNull Project project, @NotNull Editor editor, @NotNull PsiExpression expr)
+ throws IncorrectOperationException {
assert expr.isValid();
PsiType[] types = GuessManager.getInstance(project).guessTypeToCast(expr);
final boolean parenthesesNeeded = expr instanceof PsiPolyadicExpression ||
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaPostfixTemplateProvider.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaPostfixTemplateProvider.java
new file mode 100644
index 000000000000..2ee071b98559
--- /dev/null
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaPostfixTemplateProvider.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.template.postfix.templates;
+
+import com.intellij.codeInsight.completion.CompletionInitializationContext;
+import com.intellij.codeInsight.completion.JavaCompletionContributor;
+import com.intellij.codeInsight.template.CustomTemplateCallback;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.command.CommandProcessor;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.util.Ref;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Set;
+
+
+public class JavaPostfixTemplateProvider implements PostfixTemplateProvider {
+ private final Set<PostfixTemplate> templates;
+
+
+ public JavaPostfixTemplateProvider() {
+ templates = ContainerUtil.newHashSet(new AssertStatementPostfixTemplate(),
+ new CastExpressionPostfixTemplate(),
+ new ElseStatementPostfixTemplate(),
+ new ForAscendingPostfixTemplate(),
+ new ForDescendingPostfixTemplate(),
+ new ForeachPostfixTemplate(),
+ new FormatPostfixTemplate(),
+ new IfStatementPostfixTemplate(),
+ new InstanceofExpressionPostfixTemplate(),
+ new InstanceofExpressionPostfixTemplate("inst"),
+ new IntroduceFieldPostfixTemplate(),
+ new IntroduceVariablePostfixTemplate(),
+ new IsNullCheckPostfixTemplate(),
+ new NotExpressionPostfixTemplate(),
+ new NotExpressionPostfixTemplate("!"),
+ new NotNullCheckPostfixTemplate(),
+ new NotNullCheckPostfixTemplate("nn"),
+ new ParenthesizedExpressionPostfixTemplate(),
+ new ReturnStatementPostfixTemplate(),
+ new SoutPostfixTemplate(),
+ new SwitchStatementPostfixTemplate(),
+ new SynchronizedStatementPostfixTemplate(),
+ new ThrowExceptionPostfixTemplate(),
+ new TryStatementPostfixTemplate(),
+ new TryWithResourcesPostfixTemplate(),
+ new WhileStatementPostfixTemplate());
+ }
+
+ @NotNull
+ @Override
+ public Set<PostfixTemplate> getTemplates() {
+ return templates;
+ }
+
+ @Override
+ public boolean isTerminalSymbol(char currentChar) {
+ return currentChar == '.' || currentChar == '!';
+ }
+
+ @NotNull
+ @Override
+ public PsiElement preExpand(@NotNull Editor editor, @NotNull PsiElement context, int offset, @NotNull final String key) {
+
+ return addSemicolonIfNeeded(editor, editor.getDocument(), context, offset - key.length());
+ }
+
+ @NotNull
+ @Override
+ public PsiFile preCheck(@NotNull Editor editor, @NotNull PsiFile copyFile, int currentOffset) {
+ Document document = copyFile.getViewProvider().getDocument();
+ assert document != null;
+ CharSequence sequence = document.getCharsSequence();
+ StringBuilder fileContentWithoutKey = new StringBuilder(sequence);
+ if (isSemicolonNeeded(copyFile, editor)) {
+ fileContentWithoutKey.insert(currentOffset, ';');
+ copyFile = PostfixLiveTemplate.copyFile(copyFile, fileContentWithoutKey);
+ }
+
+ return copyFile;
+ }
+
+ @NotNull
+ private static PsiElement addSemicolonIfNeeded(@NotNull final Editor editor,
+ @NotNull final Document document,
+ @NotNull final PsiElement context,
+ final int offset) {
+ ApplicationManager.getApplication().assertIsDispatchThread();
+
+ final Ref<PsiElement> newContext = Ref.create(context);
+ final PsiFile file = context.getContainingFile();
+ if (isSemicolonNeeded(file, editor)) {
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() {
+ public void run() {
+ document.insertString(offset, ";");
+ PsiDocumentManager.getInstance(context.getProject()).commitDocument(document);
+ newContext.set(CustomTemplateCallback.getContext(file, offset - 1));
+ }
+ });
+ }
+ });
+ }
+ return newContext.get();
+ }
+
+ private static boolean isSemicolonNeeded(@NotNull PsiFile file, @NotNull Editor editor) {
+ return JavaCompletionContributor.semicolonNeeded(editor, file, CompletionInitializationContext.calcStartOffset(editor));
+ }
+}
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/LanguagePostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/LanguagePostfixTemplate.java
new file mode 100644
index 000000000000..2360d9721ab8
--- /dev/null
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/LanguagePostfixTemplate.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.template.postfix.templates;
+
+import com.intellij.lang.LanguageExtension;
+
+public class LanguagePostfixTemplate extends LanguageExtension<PostfixTemplateProvider> {
+ public static final LanguagePostfixTemplate LANG_EP = new LanguagePostfixTemplate();
+ public static final String EP_NAME = "com.intellij.codeInsight.template.postfixTemplateProvider";
+
+ private LanguagePostfixTemplate() {
+ super(EP_NAME);
+ }
+}
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NonVoidPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NonVoidPostfixTemplate.java
index 906a943e15e6..09757e53e826 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NonVoidPostfixTemplate.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NonVoidPostfixTemplate.java
@@ -28,7 +28,7 @@ abstract public class NonVoidPostfixTemplate extends PostfixTemplate {
@Override
public boolean isApplicable(@NotNull PsiElement context, @NotNull Document copyDocument, int newOffset) {
- PsiExpression expr = getTopmostExpression(context);
+ PsiExpression expr = PostfixTemplatesUtils.getTopmostExpression(context);
return expr != null && PostfixTemplatesUtils.isNonVoid(expr.getType());
}
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NotExpressionPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NotExpressionPostfixTemplate.java
index 9900c0a4c57d..e2e3db8b8be6 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NotExpressionPostfixTemplate.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NotExpressionPostfixTemplate.java
@@ -16,14 +16,12 @@
package com.intellij.codeInsight.template.postfix.templates;
import com.intellij.codeInsight.CodeInsightServicesUtil;
-import com.intellij.codeInsight.template.postfix.util.Aliases;
import com.intellij.codeInsight.template.postfix.util.PostfixTemplatesUtils;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.Condition;
import com.intellij.psi.PsiExpression;
import org.jetbrains.annotations.NotNull;
-@Aliases("!")
public class NotExpressionPostfixTemplate extends ExpressionPostfixTemplateWithChooser {
private static final Condition<PsiExpression> BOOLEAN_TYPE_CONDITION = new Condition<PsiExpression>() {
@Override
@@ -36,6 +34,10 @@ public class NotExpressionPostfixTemplate extends ExpressionPostfixTemplateWithC
super("not", "Negates boolean expression", "!expr");
}
+ public NotExpressionPostfixTemplate(String alias) {
+ super(alias, alias, "Negates boolean expression", "!expr");
+ }
+
@Override
protected void doIt(@NotNull Editor editor, @NotNull PsiExpression expression) {
expression.replace(CodeInsightServicesUtil.invertCondition(expression));
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NotNullCheckPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NotNullCheckPostfixTemplate.java
index e4bde3241fee..ea2480f86a0e 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NotNullCheckPostfixTemplate.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NotNullCheckPostfixTemplate.java
@@ -1,12 +1,30 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.intellij.codeInsight.template.postfix.templates;
-import com.intellij.codeInsight.template.postfix.util.Aliases;
import org.jetbrains.annotations.NotNull;
-@Aliases(".nn")
public class NotNullCheckPostfixTemplate extends NullCheckPostfixTemplate {
+
public NotNullCheckPostfixTemplate() {
- super("notnull", "Checks expression to be not-null", "if (expr != null)");
+ this("notnull");
+ }
+
+ public NotNullCheckPostfixTemplate(String alias) {
+ super(alias, "Checks expression to be not-null", "if (expr != null)");
}
@NotNull
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NullCheckPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NullCheckPostfixTemplate.java
index 6a9b6769e548..c7ad21b2fb11 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NullCheckPostfixTemplate.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NullCheckPostfixTemplate.java
@@ -39,12 +39,12 @@ public abstract class NullCheckPostfixTemplate extends PostfixTemplate {
@Override
public boolean isApplicable(@NotNull PsiElement context, @NotNull Document copyDocument, int newOffset) {
- return PostfixTemplatesUtils.isNotPrimitiveTypeExpression(getTopmostExpression(context));
+ return PostfixTemplatesUtils.isNotPrimitiveTypeExpression(PostfixTemplatesUtils.getTopmostExpression(context));
}
@Override
public void expand(@NotNull PsiElement context, @NotNull Editor editor) {
- PsiExpression expr = getTopmostExpression(context);
+ PsiExpression expr = PostfixTemplatesUtils.getTopmostExpression(context);
if (!PostfixTemplatesUtils.isNotPrimitiveTypeExpression(expr)) return;
Project project = expr.getProject();
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixLiveTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixLiveTemplate.java
index a165dcb0ed17..8fd2e725d560 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixLiveTemplate.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixLiveTemplate.java
@@ -15,17 +15,15 @@
*/
package com.intellij.codeInsight.template.postfix.templates;
-import com.intellij.codeInsight.completion.CompletionInitializationContext;
-import com.intellij.codeInsight.completion.JavaCompletionContributor;
+import com.google.common.collect.Sets;
import com.intellij.codeInsight.template.CustomLiveTemplateBase;
import com.intellij.codeInsight.template.CustomTemplateCallback;
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.codeInsight.template.postfix.util.Aliases;
import com.intellij.featureStatistics.FeatureUsageTracker;
-import com.intellij.lang.java.JavaLanguage;
+import com.intellij.lang.Language;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.command.undo.UndoConstants;
@@ -33,7 +31,6 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.Condition;
-import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDocumentManager;
@@ -42,71 +39,41 @@ import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileFactory;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.containers.ContainerUtil;
-import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
import java.util.Set;
+import static com.intellij.codeInsight.template.postfix.templates.LanguagePostfixTemplate.LANG_EP;
+
public class PostfixLiveTemplate extends CustomLiveTemplateBase {
public static final String POSTFIX_TEMPLATE_ID = "POSTFIX_TEMPLATE_ID";
-
private static final Logger LOG = Logger.getInstance(PostfixLiveTemplate.class);
- private final HashMap<String, PostfixTemplate> myTemplates = ContainerUtil.newHashMap();
-
- public PostfixLiveTemplate() {
- for (PostfixTemplate template : PostfixTemplate.EP_NAME.getExtensions()) {
- register(template.getKey(), template);
- Aliases aliases = template.getClass().getAnnotation(Aliases.class);
- if (aliases != null) {
- for (String key : aliases.value()) {
- register(key, template);
- }
- }
- }
- }
- private void register(@NotNull String key, @NotNull PostfixTemplate template) {
- PostfixTemplate registered = myTemplates.put(key, template);
- if (registered != null) {
- LOG.error("Can't register postfix template. Duplicated key: " + template.getKey());
+ @NotNull
+ public Set<String> getAllTemplateKeys(PsiFile file, int offset) {
+ Set<String> keys = Sets.newHashSet();
+ Language language = PsiUtilCore.getLanguageAtOffset(file, offset);
+ for (PostfixTemplateProvider provider : LANG_EP.allForLanguage(language)) {
+ keys.addAll(getKeys(provider));
}
+ return keys;
}
@Nullable
- @Override
- public String computeTemplateKey(@NotNull CustomTemplateCallback callback) {
- Editor editor = callback.getEditor();
- String key = computeTemplateKeyWithoutContextChecking(editor.getDocument().getCharsSequence(), editor.getCaretModel().getOffset());
- if (key == null) return null;
- return isApplicableTemplate(getTemplateByKey(key), key, callback.getContext().getContainingFile(), editor) ? key : null;
- }
-
- @Nullable
- @Override
- public String computeTemplateKeyWithoutContextChecking(@NotNull CustomTemplateCallback callback) {
- Editor editor = callback.getEditor();
- return computeTemplateKeyWithoutContextChecking(editor.getDocument().getCharsSequence(), editor.getCaretModel().getOffset());
- }
-
- @Override
- public boolean supportsMultiCaret() {
- return false;
- }
-
- @Nullable
- public String computeTemplateKeyWithoutContextChecking(@NotNull CharSequence documentContent, int currentOffset) {
+ private static String computeTemplateKeyWithoutContextChecking(@NotNull PostfixTemplateProvider provider,
+ @NotNull CharSequence documentContent,
+ int currentOffset) {
int startOffset = currentOffset;
if (documentContent.length() < startOffset) {
return null;
}
+
while (startOffset > 0) {
char currentChar = documentContent.charAt(startOffset - 1);
if (!Character.isJavaIdentifierPart(currentChar)) {
- if (currentChar != '.' && currentChar != '!') {
+ if (!provider.isTerminalSymbol(currentChar)) {
return null;
}
startOffset--;
@@ -117,23 +84,64 @@ public class PostfixLiveTemplate extends CustomLiveTemplateBase {
return String.valueOf(documentContent.subSequence(startOffset, currentOffset));
}
+ @Nullable
+ @Override
+ public String computeTemplateKey(@NotNull CustomTemplateCallback callback) {
+ Editor editor = callback.getEditor();
+ CharSequence charsSequence = editor.getDocument().getCharsSequence();
+ int offset = editor.getCaretModel().getOffset();
+ for (PostfixTemplateProvider provider : LANG_EP.allForLanguage(getLanguage(callback))) {
+ String key = computeTemplateKeyWithoutContextChecking(provider, charsSequence, offset);
+ if (key != null && isApplicableTemplate(provider, key, callback.getFile(), editor)) {
+ return key;
+ }
+ }
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public String computeTemplateKeyWithoutContextChecking(@NotNull CustomTemplateCallback callback) {
+ Editor editor = callback.getEditor();
+ int currentOffset = editor.getCaretModel().getOffset();
+ for (PostfixTemplateProvider provider : LANG_EP.allForLanguage(getLanguage(callback))) {
+ String key = computeTemplateKeyWithoutContextChecking(provider, editor.getDocument().getCharsSequence(), currentOffset);
+ if (key != null) return key;
+ }
+ return null;
+ }
+
+ @Override
+ public boolean supportsMultiCaret() {
+ return false;
+ }
+
@Override
public void expand(@NotNull final String key, @NotNull final CustomTemplateCallback callback) {
ApplicationManager.getApplication().assertIsDispatchThread();
-
FeatureUsageTracker.getInstance().triggerFeatureUsed("editing.completion.postfix");
- final PostfixTemplate template = getTemplateByKey(key);
- final Editor editor = callback.getEditor();
- final PsiFile file = callback.getContext().getContainingFile();
- if (isApplicableTemplate(template, key, file, editor)) {
- int currentOffset = editor.getCaretModel().getOffset();
- PsiElement newContext = deleteTemplateKey(file, editor.getDocument(), currentOffset, key);
- newContext = addSemicolonIfNeeded(editor, editor.getDocument(), newContext, currentOffset - key.length());
- expandTemplate(template, editor, newContext);
+ Editor editor = callback.getEditor();
+ for (PostfixTemplateProvider provider : LANG_EP.allForLanguage(getLanguage(callback))) {
+ PostfixTemplate postfixTemplate = getTemplate(provider, key);
+ if (postfixTemplate != null) {
+ final PsiFile file = callback.getContext().getContainingFile();
+ if (isApplicableTemplate(provider, key, file, editor)) {
+ int currentOffset = editor.getCaretModel().getOffset();
+ PsiElement newContext = deleteTemplateKey(file, editor.getDocument(), currentOffset, key);
+ newContext = provider.preExpand(editor, newContext, currentOffset, key);
+ expandTemplate(postfixTemplate, editor, newContext);
+ }
+ // don't care about errors in multiCaret mode
+ else if (editor.getCaretModel().getAllCarets().size() == 1) {
+ LOG.error("Template not found by key: " + key);
+ }
+ return;
+ }
}
+
// don't care about errors in multiCaret mode
- else if (editor.getCaretModel().getAllCarets().size() == 1) {
+ if (editor.getCaretModel().getAllCarets().size() == 1) {
LOG.error("Template not found by key: " + key);
}
}
@@ -141,11 +149,16 @@ public class PostfixLiveTemplate extends CustomLiveTemplateBase {
@Override
public boolean isApplicable(PsiFile file, int offset, boolean wrapping) {
PostfixTemplatesSettings settings = PostfixTemplatesSettings.getInstance();
- if (wrapping || file == null || settings == null || !settings.isPostfixTemplatesEnabled() ||
- PsiUtilCore.getLanguageAtOffset(file, offset) != JavaLanguage.INSTANCE) {
+ if (wrapping || file == null || settings == null || !settings.isPostfixTemplatesEnabled()) {
return false;
}
- return StringUtil.isNotEmpty(computeTemplateKeyWithoutContextChecking(file.getText(), offset + 1));
+ Language language = PsiUtilCore.getLanguageAtOffset(file, offset);
+ for (PostfixTemplateProvider provider : LANG_EP.allForLanguage(language)) {
+ if (StringUtil.isNotEmpty(computeTemplateKeyWithoutContextChecking(provider, file.getText(), offset + 1))) {
+ return true;
+ }
+ }
+ return false;
}
@Override
@@ -177,30 +190,24 @@ public class PostfixLiveTemplate extends CustomLiveTemplateBase {
@NotNull
@Override
- public Collection<? extends CustomLiveTemplateLookupElement> getLookupElements(@NotNull PsiFile file, @NotNull Editor editor, int offset) {
- String key = computeTemplateKeyWithoutContextChecking(editor.getDocument().getCharsSequence(), offset);
- if (key != null && editor.getCaretModel().getCaretCount() == 1) {
- Map<String, CustomLiveTemplateLookupElement> result = ContainerUtil.newHashMap();
- Condition<PostfixTemplate> isApplicationTemplateFunction = createIsApplicationTemplateFunction(key, file, editor);
- for (Map.Entry<String, PostfixTemplate> entry : myTemplates.entrySet()) {
- PostfixTemplate postfixTemplate = entry.getValue();
- if (entry.getKey().startsWith(key) && isApplicationTemplateFunction.value(postfixTemplate)) {
- result.put(postfixTemplate.getKey(), new PostfixTemplateLookupElement(this, postfixTemplate, entry.getKey(), false));
+ public Collection<? extends CustomLiveTemplateLookupElement> getLookupElements(@NotNull PsiFile file,
+ @NotNull Editor editor,
+ int offset) {
+ Collection<CustomLiveTemplateLookupElement> result = ContainerUtil.newHashSet();
+ CustomTemplateCallback callback = new CustomTemplateCallback(editor, file, false);
+ for (PostfixTemplateProvider provider : LANG_EP.allForLanguage(getLanguage(callback))) {
+ String key = computeTemplateKeyWithoutContextChecking(callback);
+ if (key != null && editor.getCaretModel().getCaretCount() == 1) {
+ Condition<PostfixTemplate> isApplicationTemplateFunction = createIsApplicationTemplateFunction(provider, key, file, editor);
+ for (PostfixTemplate postfixTemplate : provider.getTemplates()) {
+ if (isApplicationTemplateFunction.value(postfixTemplate)) {
+ result.add(new PostfixTemplateLookupElement(this, postfixTemplate, postfixTemplate.getKey(), false));
+ }
}
}
- return result.values();
}
- return super.getLookupElements(file, editor, offset);
- }
-
- @NotNull
- public Set<String> getAllTemplateKeys() {
- return myTemplates.keySet();
- }
- @Nullable
- public PostfixTemplate getTemplateByKey(@NotNull String key) {
- return myTemplates.get(key);
+ return result;
}
private static void expandTemplate(@NotNull final PostfixTemplate template,
@@ -218,16 +225,36 @@ public class PostfixLiveTemplate extends CustomLiveTemplateBase {
});
}
- @Contract("null, _, _, _ -> false")
- private static boolean isApplicableTemplate(@Nullable PostfixTemplate template, @NotNull String key, @NotNull PsiFile file, @NotNull Editor editor) {
- return createIsApplicationTemplateFunction(key, file, editor).value(template);
+
+ @NotNull
+ private static PsiElement deleteTemplateKey(@NotNull final PsiFile file,
+ @NotNull final Document document,
+ final int currentOffset,
+ @NotNull final String key) {
+ ApplicationManager.getApplication().assertIsDispatchThread();
+
+ final int startOffset = currentOffset - key.length();
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() {
+ public void run() {
+ document.deleteString(startOffset, currentOffset);
+ PsiDocumentManager.getInstance(file.getProject()).commitDocument(document);
+ }
+ });
+ }
+ });
+ return CustomTemplateCallback.getContext(file, startOffset > 0 ? startOffset - 1 : startOffset);
}
-
- private static Condition<PostfixTemplate> createIsApplicationTemplateFunction(@NotNull String key, @NotNull PsiFile file, @NotNull Editor editor) {
+
+ private static Condition<PostfixTemplate> createIsApplicationTemplateFunction(@NotNull PostfixTemplateProvider provider,
+ @NotNull String key,
+ @NotNull PsiFile file,
+ @NotNull Editor editor) {
int currentOffset = editor.getCaretModel().getOffset();
final int newOffset = currentOffset - key.length();
CharSequence fileContent = editor.getDocument().getCharsSequence();
-
StringBuilder fileContentWithoutKey = new StringBuilder();
fileContentWithoutKey.append(fileContent.subSequence(0, newOffset));
fileContentWithoutKey.append(fileContent.subSequence(currentOffset, fileContent.length()));
@@ -238,14 +265,11 @@ public class PostfixLiveTemplate extends CustomLiveTemplateBase {
return Condition.FALSE;
}
- if (isSemicolonNeeded(copyFile, editor)) {
- fileContentWithoutKey.insert(newOffset, ';');
- copyFile = copyFile(file, fileContentWithoutKey);
- copyDocument = copyFile.getViewProvider().getDocument();
- if (copyDocument == null) {
- //noinspection unchecked
- return Condition.FALSE;
- }
+ copyFile = provider.preCheck(editor, copyFile, newOffset);
+ copyDocument = copyFile.getViewProvider().getDocument();
+ if (copyDocument == null) {
+ //noinspection unchecked
+ return Condition.FALSE;
}
final PsiElement context = CustomTemplateCallback.getContext(copyFile, newOffset > 0 ? newOffset - 1 : newOffset);
@@ -258,8 +282,9 @@ public class PostfixLiveTemplate extends CustomLiveTemplateBase {
};
}
+
@NotNull
- private static PsiFile copyFile(@NotNull PsiFile file, @NotNull StringBuilder fileContentWithoutKey) {
+ public static PsiFile copyFile(@NotNull PsiFile file, @NotNull StringBuilder fileContentWithoutKey) {
final PsiFileFactory psiFileFactory = PsiFileFactory.getInstance(file.getProject());
PsiFile copy = psiFileFactory.createFileFromText(file.getName(), file.getFileType(), fileContentWithoutKey);
VirtualFile vFile = copy.getVirtualFile();
@@ -269,55 +294,35 @@ public class PostfixLiveTemplate extends CustomLiveTemplateBase {
return copy;
}
- @NotNull
- private static PsiElement deleteTemplateKey(@NotNull final PsiFile file,
- @NotNull final Document document,
- final int currentOffset,
- @NotNull final String key) {
- ApplicationManager.getApplication().assertIsDispatchThread();
-
- final int startOffset = currentOffset - key.length();
- ApplicationManager.getApplication().runWriteAction(new Runnable() {
- @Override
- public void run() {
- CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() {
- public void run() {
- document.deleteString(startOffset, currentOffset);
- PsiDocumentManager.getInstance(file.getProject()).commitDocument(document);
- }
- });
- }
- });
- return CustomTemplateCallback.getContext(file, startOffset > 0 ? startOffset - 1 : startOffset);
+ public static boolean isApplicableTemplate(@NotNull PostfixTemplateProvider provider,
+ @NotNull String key,
+ @NotNull PsiFile file,
+ @NotNull Editor editor) {
+ return createIsApplicationTemplateFunction(provider, key, file, editor).value(getTemplate(provider, key));
}
+
@NotNull
- private static PsiElement addSemicolonIfNeeded(@NotNull final Editor editor,
- @NotNull final Document document,
- @NotNull final PsiElement context,
- final int offset) {
- ApplicationManager.getApplication().assertIsDispatchThread();
+ private static Set<String> getKeys(@NotNull PostfixTemplateProvider provider) {
+ Set<String> result = ContainerUtil.newHashSet();
+ for (PostfixTemplate template : provider.getTemplates()) {
+ result.add(template.getKey());
+ }
- final Ref<PsiElement> newContext = Ref.create(context);
- final PsiFile file = context.getContainingFile();
- if (isSemicolonNeeded(file, editor)) {
- ApplicationManager.getApplication().runWriteAction(new Runnable() {
- @Override
- public void run() {
- CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() {
- public void run() {
- document.insertString(offset, ";");
- PsiDocumentManager.getInstance(context.getProject()).commitDocument(document);
- newContext.set(CustomTemplateCallback.getContext(file, offset - 1));
- }
- });
- }
- });
+ return result;
+ }
+
+ @Nullable
+ private static PostfixTemplate getTemplate(@NotNull PostfixTemplateProvider provider, @Nullable String key) {
+ for (PostfixTemplate template : provider.getTemplates()) {
+ if (template.getKey().equals(key)) {
+ return template;
+ }
}
- return newContext.get();
+ return null;
}
- private static boolean isSemicolonNeeded(@NotNull PsiFile file, @NotNull Editor editor) {
- return JavaCompletionContributor.semicolonNeeded(editor, file, CompletionInitializationContext.calcStartOffset(editor));
+ private static Language getLanguage(@NotNull CustomTemplateCallback callback) {
+ return callback.getContext().getLanguage();
}
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplate.java
index 80a68ab26650..747366d1832f 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplate.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplate.java
@@ -18,13 +18,8 @@ package com.intellij.codeInsight.template.postfix.templates;
import com.intellij.codeInsight.template.postfix.settings.PostfixTemplatesSettings;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiExpression;
-import com.intellij.psi.PsiExpressionStatement;
-import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
public abstract class PostfixTemplate {
@NotNull private final String myPresentableName;
@@ -32,9 +27,6 @@ public abstract class PostfixTemplate {
@NotNull private final String myDescription;
@NotNull private final String myExample;
- @NotNull
- public static final ExtensionPointName<PostfixTemplate> EP_NAME = ExtensionPointName.create("com.intellij.postfixTemplate");
-
protected PostfixTemplate(@NotNull String name, @NotNull String description, @NotNull String example) {
this(name, "." + name, description, example);
}
@@ -71,12 +63,6 @@ public abstract class PostfixTemplate {
return settings != null && settings.isPostfixTemplatesEnabled() && settings.isTemplateEnabled(this);
}
- @Nullable
- public static PsiExpression getTopmostExpression(PsiElement context) {
- PsiExpressionStatement statement = PsiTreeUtil.getNonStrictParentOfType(context, PsiExpressionStatement.class);
- return statement != null ? PsiTreeUtil.getChildOfType(statement, PsiExpression.class) : null;
- }
-
public abstract boolean isApplicable(@NotNull PsiElement context, @NotNull Document copyDocument, int newOffset);
public abstract void expand(@NotNull PsiElement context, @NotNull Editor editor);
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplateProvider.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplateProvider.java
new file mode 100644
index 000000000000..eeea9a19f62e
--- /dev/null
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplateProvider.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.template.postfix.templates;
+
+
+import com.intellij.openapi.editor.Editor;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Set;
+
+public interface PostfixTemplateProvider {
+
+ /**
+ * Return all templates registered in the provider
+ */
+ @NotNull
+ Set<PostfixTemplate> getTemplates();
+
+ /**
+ * Check symbol can separate template keys
+ */
+ boolean isTerminalSymbol(char currentChar);
+
+ /**
+ * Prepare original file content for template expanding
+ * Return context after transformation
+ */
+ @NotNull
+ PsiElement preExpand(@NotNull Editor editor, @NotNull PsiElement context, int offset, @NotNull String key);
+
+ /**
+ * Do some actions with the file content before check applicable.
+ * Return copyFile or another copy of file after processing
+ */
+ @NotNull
+ PsiFile preCheck(@NotNull Editor editor, @NotNull PsiFile copyFile, int currentOffset);
+}
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ReturnStatementPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ReturnStatementPostfixTemplate.java
index 277a6f2c0d30..afc3236b8319 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ReturnStatementPostfixTemplate.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ReturnStatementPostfixTemplate.java
@@ -15,6 +15,7 @@
*/
package com.intellij.codeInsight.template.postfix.templates;
+import com.intellij.codeInsight.template.postfix.util.PostfixTemplatesUtils;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.*;
import org.jetbrains.annotations.NotNull;
@@ -26,7 +27,7 @@ public class ReturnStatementPostfixTemplate extends NonVoidPostfixTemplate {
@Override
public void expand(@NotNull PsiElement context, @NotNull Editor editor) {
- PsiExpression expr = getTopmostExpression(context);
+ PsiExpression expr = PostfixTemplatesUtils.getTopmostExpression(context);
PsiElement parent = expr != null ? expr.getParent() : null;
if (!(parent instanceof PsiExpressionStatement)) return;
PsiElementFactory factory = JavaPsiFacade.getInstance(expr.getProject()).getElementFactory();
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/StatementPostfixTemplateBase.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/StatementPostfixTemplateBase.java
index 4449c551dbfc..8f26ec08fae0 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/StatementPostfixTemplateBase.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/StatementPostfixTemplateBase.java
@@ -1,6 +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.codeInsight.template.postfix.templates;
import com.intellij.codeInsight.CodeInsightUtilCore;
+import com.intellij.codeInsight.template.postfix.util.PostfixTemplatesUtils;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
@@ -17,7 +33,7 @@ public abstract class StatementPostfixTemplateBase extends PostfixTemplate {
}
protected void surroundWith(PsiElement context, Editor editor, String text) {
- PsiExpression expr = getTopmostExpression(context);
+ PsiExpression expr = PostfixTemplatesUtils.getTopmostExpression(context);
PsiElement parent = expr != null ? expr.getParent() : null;
if (!(parent instanceof PsiExpressionStatement)) return;
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SwitchStatementPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SwitchStatementPostfixTemplate.java
index 880c0455775b..20a7299af8ec 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SwitchStatementPostfixTemplate.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SwitchStatementPostfixTemplate.java
@@ -15,6 +15,7 @@
*/
package com.intellij.codeInsight.template.postfix.templates;
+import com.intellij.codeInsight.template.postfix.util.PostfixTemplatesUtils;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
@@ -51,7 +52,7 @@ public class SwitchStatementPostfixTemplate extends StatementPostfixTemplateBase
@Override
public boolean isApplicable(@NotNull PsiElement context, @NotNull Document copyDocument, int newOffset) {
- PsiExpression expr = getTopmostExpression(context);
+ PsiExpression expr = PostfixTemplatesUtils.getTopmostExpression(context);
return expr != null && isSwitchCompatibleType(expr.getType(), context);
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SynchronizedStatementPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SynchronizedStatementPostfixTemplate.java
index 044dadc81c8c..eb46ba9f0540 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SynchronizedStatementPostfixTemplate.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SynchronizedStatementPostfixTemplate.java
@@ -15,6 +15,7 @@
*/
package com.intellij.codeInsight.template.postfix.templates;
+import com.intellij.codeInsight.template.postfix.util.PostfixTemplatesUtils;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiElement;
@@ -30,7 +31,7 @@ public class SynchronizedStatementPostfixTemplate extends StatementPostfixTempla
@Override
public boolean isApplicable(@NotNull PsiElement context, @NotNull Document copyDocument, int newOffset) {
- PsiExpression expression = getTopmostExpression(context);
+ PsiExpression expression = PostfixTemplatesUtils.getTopmostExpression(context);
PsiType type = expression != null ? expression.getType() : null;
return type != null && !(type instanceof PsiPrimitiveType);
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ThrowExceptionPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ThrowExceptionPostfixTemplate.java
index b1bb654d6dff..7b0aaa00f4c1 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ThrowExceptionPostfixTemplate.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ThrowExceptionPostfixTemplate.java
@@ -29,7 +29,7 @@ public class ThrowExceptionPostfixTemplate extends PostfixTemplate {
@Override
public boolean isApplicable(@NotNull PsiElement context, @NotNull Document copyDocument, int newOffset) {
- PsiExpression expression = getTopmostExpression(context);
+ PsiExpression expression = PostfixTemplatesUtils.getTopmostExpression(context);
return expression != null && PostfixTemplatesUtils.isThrowable(expression.getType());
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/TryWithResourcesPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/TryWithResourcesPostfixTemplate.java
new file mode 100644
index 000000000000..843c19e072c0
--- /dev/null
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/TryWithResourcesPostfixTemplate.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.template.postfix.templates;
+
+import com.intellij.codeInsight.ExceptionUtil;
+import com.intellij.codeInsight.intention.impl.TypeExpression;
+import com.intellij.codeInsight.template.Template;
+import com.intellij.codeInsight.template.TemplateManager;
+import com.intellij.codeInsight.template.impl.MacroCallNode;
+import com.intellij.codeInsight.template.impl.TextExpression;
+import com.intellij.codeInsight.template.macro.SuggestVariableNameMacro;
+import com.intellij.codeInsight.template.postfix.util.PostfixTemplatesUtils;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.*;
+import com.intellij.psi.search.ProjectScope;
+import com.intellij.psi.util.InheritanceUtil;
+import com.intellij.psi.util.PsiUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+import java.util.Collections;
+
+
+public class TryWithResourcesPostfixTemplate extends PostfixTemplate {
+ protected TryWithResourcesPostfixTemplate() {
+ super("twr", "Description", "Example");
+ }
+
+ @Override
+ public boolean isApplicable(@NotNull PsiElement element, @NotNull Document copyDocument, int newOffset) {
+ if (!PsiUtil.isLanguageLevel7OrHigher(element)) return false;
+
+ PsiExpression initializer = PostfixTemplatesUtils.getTopmostExpression(element);
+
+ if (initializer == null) return false;
+
+ final PsiType type = initializer.getType();
+ if (!(type instanceof PsiClassType)) return false;
+ final PsiClass aClass = ((PsiClassType)type).resolve();
+ Project project = element.getProject();
+ final JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
+ final PsiClass autoCloseable = facade.findClass(CommonClassNames.JAVA_LANG_AUTO_CLOSEABLE, ProjectScope.getLibrariesScope(project));
+ if (!InheritanceUtil.isInheritorOrSelf(aClass, autoCloseable, true)) return false;
+
+ return true;
+ }
+
+ @Override
+ public void expand(@NotNull PsiElement context, @NotNull Editor editor) {
+ PsiExpression expression = PostfixTemplatesUtils.getTopmostExpression(context);
+ assert expression != null;
+
+ Project project = context.getProject();
+
+ editor.getDocument().deleteString(expression.getTextRange().getStartOffset(), expression.getTextRange().getEndOffset());
+
+ TemplateManager manager = TemplateManager.getInstance(project);
+ Template template = manager.createTemplate("", "");
+ template.setToReformat(true);
+ template.addTextSegment("try (");
+ MacroCallNode name = new MacroCallNode(new SuggestVariableNameMacro());
+
+ template.addVariable("type", new TypeExpression(project, new PsiType[]{expression.getType()}), false);
+ template.addTextSegment(" ");
+ template.addVariable("name", name, name, true);
+ template.addTextSegment(" = ");
+ template.addVariable("variable", new TextExpression(expression.getText()), false);
+ template.addTextSegment(") {\n");
+ template.addEndVariable();
+ template.addTextSegment("\n}");
+
+ Collection<PsiClassType> unhandled = getUnhandled(expression);
+ for (PsiClassType exception : unhandled) {
+ MacroCallNode variable = new MacroCallNode(new SuggestVariableNameMacro());
+ template.addTextSegment("catch(");
+ template.addVariable("type " + exception.getClassName(), new TypeExpression(project, new PsiType[]{exception}), false);
+ template.addTextSegment(" ");
+ template.addVariable("name " + exception.getClassName(), variable, variable, false);
+ template.addTextSegment(") {}");
+ }
+
+ manager.startTemplate(editor, template);
+ }
+
+ @NotNull
+ private static Collection<PsiClassType> getUnhandled(@NotNull PsiExpression expression) {
+ assert expression.getType() != null;
+ PsiMethod methodCloser = PsiUtil.getResourceCloserMethodForType((PsiClassType)expression.getType(), expression.getProject());
+ PsiSubstitutor substitutor = PsiUtil.resolveGenericsClassInType(expression.getType()).getSubstitutor();
+
+ return methodCloser != null
+ ? ExceptionUtil.getUnhandledExceptions(methodCloser, expression, null, substitutor)
+ : Collections.<PsiClassType>emptyList();
+ }
+}
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/WhileStatementPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/WhileStatementPostfixTemplate.java
index 03d91b2235af..4c856f7e8299 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/WhileStatementPostfixTemplate.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/WhileStatementPostfixTemplate.java
@@ -1,5 +1,21 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.intellij.codeInsight.template.postfix.templates;
+import com.intellij.codeInsight.template.postfix.util.PostfixTemplatesUtils;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.*;
import org.jetbrains.annotations.NotNull;
@@ -11,7 +27,7 @@ public class WhileStatementPostfixTemplate extends BooleanPostfixTemplate {
@Override
public void expand(@NotNull PsiElement context, @NotNull Editor editor) {
- PsiExpression expression = getTopmostExpression(context);
+ PsiExpression expression = PostfixTemplatesUtils.getTopmostExpression(context);
assert expression != null;
PsiElementFactory factory = JavaPsiFacade.getElementFactory(context.getProject());
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/util/Aliases.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/util/Aliases.java
deleted file mode 100644
index 3de07c310f50..000000000000
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/util/Aliases.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.intellij.codeInsight.template.postfix.util;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * @author ignatov
- */
-@Target(value = ElementType.TYPE)
-@Retention(value = RetentionPolicy.RUNTIME)
-public @interface Aliases {
- String[] value();
-}
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/util/PostfixTemplatesUtils.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/util/PostfixTemplatesUtils.java
index 370c986c5f48..7b92ffdb1ae0 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/util/PostfixTemplatesUtils.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/util/PostfixTemplatesUtils.java
@@ -17,12 +17,12 @@ package com.intellij.codeInsight.template.postfix.util;
import com.intellij.codeInsight.generation.surroundWith.JavaExpressionSurrounder;
import com.intellij.codeInsight.generation.surroundWith.JavaWithIfExpressionSurrounder;
-import com.intellij.codeInsight.template.postfix.templates.PostfixTemplate;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.util.InheritanceUtil;
+import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.util.CommonRefactoringUtil;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
@@ -45,7 +45,7 @@ public abstract class PostfixTemplatesUtils {
}
public static void createStatement(@NotNull PsiElement context, @NotNull Editor editor, @NotNull String prefix, @NotNull String suffix, int offset) {
- PsiExpression expr = PostfixTemplate.getTopmostExpression(context);
+ PsiExpression expr = getTopmostExpression(context);
PsiElement parent = expr != null ? expr.getParent() : null;
assert parent instanceof PsiStatement;
PsiElementFactory factory = JavaPsiFacade.getInstance(context.getProject()).getElementFactory();
@@ -121,5 +121,11 @@ public abstract class PostfixTemplatesUtils {
}
return null;
}
+
+ @Nullable
+ public static PsiExpression getTopmostExpression(PsiElement context) {
+ PsiExpressionStatement statement = PsiTreeUtil.getNonStrictParentOfType(context, PsiExpressionStatement.class);
+ return statement != null ? PsiTreeUtil.getChildOfType(statement, PsiExpression.class) : null;
+ }
}
diff --git a/java/java-impl/src/com/intellij/ide/fileTemplates/JavaCreateFromTemplateHandler.java b/java/java-impl/src/com/intellij/ide/fileTemplates/JavaCreateFromTemplateHandler.java
index 26e4adfa0bbb..f511eac9320d 100644
--- a/java/java-impl/src/com/intellij/ide/fileTemplates/JavaCreateFromTemplateHandler.java
+++ b/java/java-impl/src/com/intellij/ide/fileTemplates/JavaCreateFromTemplateHandler.java
@@ -26,6 +26,7 @@ import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.impl.file.JavaDirectoryServiceImpl;
import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
import java.util.Map;
@@ -100,8 +101,9 @@ public class JavaCreateFromTemplateHandler implements CreateFromTemplateHandler
return fileType.equals(StdFileTypes.JAVA) && !FileTemplateUtil.INTERNAL_PACKAGE_INFO_TEMPLATE_NAME.equals(template.getName());
}
+ @NotNull
public PsiElement createFromTemplate(final Project project, final PsiDirectory directory, final String fileName, FileTemplate template,
- String templateText, Map<String, Object> props) throws IncorrectOperationException {
+ String templateText, @NotNull Map<String, Object> props) throws IncorrectOperationException {
String extension = template.getExtension();
PsiElement result = createClassOrInterface(project, directory, templateText, template.isReformatCode(), extension);
hackAwayEmptyPackage((PsiJavaFile)result.getContainingFile(), template, props);
diff --git a/java/java-impl/src/com/intellij/ide/hierarchy/method/MethodHierarchyNodeDescriptor.java b/java/java-impl/src/com/intellij/ide/hierarchy/method/MethodHierarchyNodeDescriptor.java
index 61e530339ffa..dbdcff0f798b 100644
--- a/java/java-impl/src/com/intellij/ide/hierarchy/method/MethodHierarchyNodeDescriptor.java
+++ b/java/java-impl/src/com/intellij/ide/hierarchy/method/MethodHierarchyNodeDescriptor.java
@@ -52,7 +52,7 @@ public final class MethodHierarchyNodeDescriptor extends HierarchyNodeDescriptor
myTreeStructure = treeStructure;
}
- private PsiMethod getMethod(final PsiClass aClass, final boolean checkBases) {
+ PsiMethod getMethod(final PsiClass aClass, final boolean checkBases) {
return MethodHierarchyUtil.findBaseMethodInClass(myTreeStructure.getBaseMethod(), aClass, checkBases);
}
diff --git a/java/java-impl/src/com/intellij/ide/hierarchy/method/MethodHierarchyTreeStructure.java b/java/java-impl/src/com/intellij/ide/hierarchy/method/MethodHierarchyTreeStructure.java
index 7a5e86953689..922fc2d85644 100644
--- a/java/java-impl/src/com/intellij/ide/hierarchy/method/MethodHierarchyTreeStructure.java
+++ b/java/java-impl/src/com/intellij/ide/hierarchy/method/MethodHierarchyTreeStructure.java
@@ -172,13 +172,16 @@ public final class MethodHierarchyTreeStructure extends HierarchyTreeStructure {
descriptors.add(d);
}
- FunctionalExpressionSearch.search(getBaseMethod()).forEach(new Processor<PsiFunctionalExpression>() {
- @Override
- public boolean process(PsiFunctionalExpression expression) {
- descriptors.add(new MethodHierarchyNodeDescriptor(myProject, descriptor, expression, false, MethodHierarchyTreeStructure.this));
- return true;
- }
- });
+ final PsiMethod existingMethod = ((MethodHierarchyNodeDescriptor)descriptor).getMethod(psiClass, false);
+ if (existingMethod != null) {
+ FunctionalExpressionSearch.search(existingMethod).forEach(new Processor<PsiFunctionalExpression>() {
+ @Override
+ public boolean process(PsiFunctionalExpression expression) {
+ descriptors.add(new MethodHierarchyNodeDescriptor(myProject, descriptor, expression, false, MethodHierarchyTreeStructure.this));
+ return true;
+ }
+ });
+ }
return descriptors.toArray(new HierarchyNodeDescriptor[descriptors.size()]);
}
diff --git a/java/java-impl/src/com/intellij/lang/java/JavaDocumentationProvider.java b/java/java-impl/src/com/intellij/lang/java/JavaDocumentationProvider.java
index 6a267f692ab0..56f376ffbf06 100644
--- a/java/java-impl/src/com/intellij/lang/java/JavaDocumentationProvider.java
+++ b/java/java-impl/src/com/intellij/lang/java/JavaDocumentationProvider.java
@@ -34,7 +34,6 @@ import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.*;
-import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
@@ -56,8 +55,10 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
/**
* @author Maxim.Mossienko
@@ -591,13 +592,16 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider, Ext
if (classUrls != null) {
urls = ContainerUtil.newSmartList();
- String rawSignature = formatMethodSignature(method, true);
- for (String classUrl : classUrls) {
- urls.add(classUrl + "#" + rawSignature);
- }
+ final boolean useJava8Format = PsiUtil.isLanguageLevel8OrHigher(method);
+
+ final Set<String> signatures = new LinkedHashSet<String>();
+ signatures.add(formatMethodSignature(method, true, useJava8Format));
+ signatures.add(formatMethodSignature(method, false, useJava8Format));
+
+ signatures.add(formatMethodSignature(method, true, !useJava8Format));
+ signatures.add(formatMethodSignature(method, false, !useJava8Format));
- String signature = formatMethodSignature(method, false);
- if (Comparing.compare(rawSignature, signature) != 0) {
+ for (String signature : signatures) {
for (String classUrl : classUrls) {
urls.add(classUrl + "#" + signature);
}
@@ -626,7 +630,7 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider, Ext
}
}
- private static String formatMethodSignature(PsiMethod method, boolean raw) {
+ private static String formatMethodSignature(PsiMethod method, boolean raw, boolean java8Format) {
int options = PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_PARAMETERS;
int parameterOptions = PsiFormatUtilBase.SHOW_TYPE | PsiFormatUtilBase.SHOW_FQ_CLASS_NAMES;
if (raw) {
@@ -636,7 +640,7 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider, Ext
String signature = PsiFormatUtil.formatMethod(method, PsiSubstitutor.EMPTY, options, parameterOptions, 999);
- if (PsiUtil.isLanguageLevel8OrHigher(method)) {
+ if (java8Format) {
signature = signature.replaceAll("\\(|\\)|, ", "-").replaceAll("\\[\\]", ":A");
}
diff --git a/java/java-impl/src/com/intellij/openapi/projectRoots/impl/JavaSdkImpl.java b/java/java-impl/src/com/intellij/openapi/projectRoots/impl/JavaSdkImpl.java
index 2aa495c42694..f3d6575e9fd9 100644
--- a/java/java-impl/src/com/intellij/openapi/projectRoots/impl/JavaSdkImpl.java
+++ b/java/java-impl/src/com/intellij/openapi/projectRoots/impl/JavaSdkImpl.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.
@@ -98,7 +98,7 @@ public class JavaSdkImpl extends JavaSdk {
return "http://docs.oracle.com/javase/7/docs/api/";
}
if (version == JavaSdkVersion.JDK_1_8) {
- return "http://download.java.net/jdk8/docs/api/";
+ return "http://docs.oracle.com/javase/8/docs/api";
}
return null;
}
@@ -416,19 +416,6 @@ public class JavaSdkImpl extends JavaSdk {
}
@Override
- @NotNull
- public String getComponentName() {
- return getName();
- }
-
- @Override
- public void initComponent() { }
-
- @Override
- public void disposeComponent() {
- }
-
- @Override
public int compareTo(@NotNull String versionString, @NotNull String versionNumber) {
return getVersionNumber(versionString).compareTo(versionNumber);
}
diff --git a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/ImportHelper.java b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/ImportHelper.java
index 9ade1c2a4495..0770a04f4dce 100644
--- a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/ImportHelper.java
+++ b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/ImportHelper.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.
@@ -766,7 +766,7 @@ public class ImportHelper{
continue;
}
if (reference instanceof PsiJavaCodeReferenceElementImpl
- && ((PsiJavaCodeReferenceElementImpl)reference).getKind() == PsiJavaCodeReferenceElementImpl.CLASS_IN_QUALIFIED_NEW_KIND) {
+ && ((PsiJavaCodeReferenceElementImpl)reference).getKind(((PsiJavaCodeReferenceElementImpl)reference).getContainingFile()) == PsiJavaCodeReferenceElementImpl.CLASS_IN_QUALIFIED_NEW_KIND) {
continue;
}
}
@@ -774,7 +774,7 @@ public class ImportHelper{
final JavaResolveResult resolveResult = javaReference.advancedResolve(true);
PsiElement refElement = resolveResult.getElement();
if (refElement == null && referenceElement != null) {
- refElement = ResolveClassUtil.resolveClass(referenceElement); // might be uncomplete code
+ refElement = ResolveClassUtil.resolveClass(referenceElement, referenceElement.getContainingFile()); // might be uncomplete code
}
if (refElement == null) continue;
diff --git a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaCodeStyleManagerImpl.java b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaCodeStyleManagerImpl.java
index b151628781d7..844ef00880ae 100644
--- a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaCodeStyleManagerImpl.java
+++ b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaCodeStyleManagerImpl.java
@@ -27,14 +27,11 @@ import com.intellij.psi.impl.CheckUtil;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
import com.intellij.psi.impl.source.jsp.jspJava.JspxImportStatement;
import com.intellij.psi.statistics.JavaStatisticsManager;
-import com.intellij.psi.util.PsiElementFilter;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.psi.util.PsiUtil;
-import com.intellij.psi.util.TypeConversionUtil;
+import com.intellij.psi.util.*;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
-import com.intellij.psi.util.FileTypeUtils;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -309,7 +306,7 @@ public class JavaCodeStyleManagerImpl extends JavaCodeStyleManager {
return suggestVariableNameByType(type, variableKind, correctKeywords, false);
}
- private String[] suggestVariableNameByType(PsiType type, final VariableKind variableKind, boolean correctKeywords, boolean skipIndices) {
+ private String[] suggestVariableNameByType(final PsiType type, final VariableKind variableKind, final boolean correctKeywords, boolean skipIndices) {
String longTypeName = skipIndices ? type.getCanonicalText():getLongTypeName(type);
CodeStyleSettings.TypeToNameMap map = getMapByVariableKind(variableKind);
if (map != null && longTypeName != null) {
@@ -322,7 +319,7 @@ public class JavaCodeStyleManagerImpl extends JavaCodeStyleManager {
}
}
- Collection<String> suggestions = new LinkedHashSet<String>();
+ final Collection<String> suggestions = new LinkedHashSet<String>();
if (!skipIndices) {
suggestNamesForCollectionInheritors(type, variableKind, suggestions, correctKeywords);
@@ -336,6 +333,21 @@ public class JavaCodeStyleManagerImpl extends JavaCodeStyleManager {
ContainerUtil.addAll(suggestions, getSuggestionsByName(typeName, variableKind, type instanceof PsiArrayType, correctKeywords));
}
+ if (!skipIndices && type instanceof PsiClassType) {
+ final PsiClass psiClass = ((PsiClassType)type).resolve();
+ if (psiClass != null && psiClass.getContainingClass() != null) {
+ InheritanceUtil.processSupers(psiClass, false, new Processor<PsiClass>() {
+ @Override
+ public boolean process(PsiClass superClass) {
+ if (PsiTreeUtil.isAncestor(superClass, psiClass, true)) {
+ ContainerUtil.addAll(suggestions, getSuggestionsByName(superClass.getName(), variableKind, false, correctKeywords));
+ }
+ return false;
+ }
+ });
+ }
+ }
+
return ArrayUtil.toStringArray(suggestions);
}
diff --git a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaReferenceAdjuster.java b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaReferenceAdjuster.java
index 42d3098b7b07..3d1e1c01c586 100644
--- a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaReferenceAdjuster.java
+++ b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaReferenceAdjuster.java
@@ -55,7 +55,8 @@ public class JavaReferenceAdjuster implements ReferenceAdjuster {
boolean rightKind = true;
if (elementType == JavaElementType.JAVA_CODE_REFERENCE) {
- int kind = ((PsiJavaCodeReferenceElementImpl)element).getKind();
+ PsiJavaCodeReferenceElementImpl impl = (PsiJavaCodeReferenceElementImpl)element;
+ int kind = impl.getKind(impl.getContainingFile());
rightKind = kind == PsiJavaCodeReferenceElementImpl.CLASS_NAME_KIND || kind == PsiJavaCodeReferenceElementImpl.CLASS_OR_PACKAGE_NAME_KIND;
}
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 71e40e5b0ac6..a0243dfc241a 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
@@ -268,10 +268,11 @@ public class JavaClassReference extends GenericReference implements PsiJavaRefer
return JavaClassReferenceProvider.EXTEND_CLASS_NAMES.getValue(getOptions());
}
- private LookupElement[] processPackage(final PsiPackage aPackage) {
+ @NotNull
+ private LookupElement[] processPackage(@NotNull PsiPackage aPackage) {
final ArrayList<LookupElement> list = ContainerUtil.newArrayList();
final int startOffset = StringUtil.isEmpty(aPackage.getName()) ? 0 : aPackage.getQualifiedName().length() + 1;
- final GlobalSearchScope scope = getScope();
+ 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)) {
@@ -355,7 +356,8 @@ public class JavaClassReference extends GenericReference implements PsiJavaRefer
return (JavaResolveResult) resolveCache.resolveWithCaching(this, MyResolver.INSTANCE, false, false,file)[0];
}
- private JavaResolveResult doAdvancedResolve() {
+ @NotNull
+ private JavaResolveResult doAdvancedResolve(@NotNull PsiFile containingFile) {
final PsiElement psiElement = getElement();
if (!psiElement.isValid()) return JavaResolveResult.EMPTY;
@@ -366,7 +368,9 @@ public class JavaClassReference extends GenericReference implements PsiJavaRefer
if (context instanceof PsiClass) {
if (isStaticClassReference(elementText, false)) {
final PsiClass psiClass = ((PsiClass)context).findInnerClassByName(getCanonicalText(), false);
- if (psiClass != null) return new ClassCandidateInfo(psiClass, PsiSubstitutor.EMPTY, false, psiElement);
+ if (psiClass != null) {
+ return new ClassCandidateInfo(psiClass, PsiSubstitutor.EMPTY, false, psiElement);
+ }
PsiElement member = doResolveMember((PsiClass)context, myText);
return member == null ? JavaResolveResult.EMPTY : new CandidateInfo(member, PsiSubstitutor.EMPTY, false, false, psiElement);
}
@@ -382,18 +386,18 @@ public class JavaClassReference extends GenericReference implements PsiJavaRefer
if (!qName.contains(".")) {
final String defaultPackage = JavaClassReferenceProvider.DEFAULT_PACKAGE.getValue(getOptions());
if (StringUtil.isNotEmpty(defaultPackage)) {
- final JavaResolveResult resolveResult = advancedResolveInner(psiElement, defaultPackage + "." + qName);
+ final JavaResolveResult resolveResult = advancedResolveInner(psiElement, defaultPackage + "." + qName, containingFile);
if (resolveResult != JavaResolveResult.EMPTY) {
return resolveResult;
}
}
}
- return advancedResolveInner(psiElement, qName);
+ return advancedResolveInner(psiElement, qName, containingFile);
}
- private JavaResolveResult advancedResolveInner(final PsiElement psiElement, final String qName) {
- final PsiManager manager = psiElement.getManager();
- final GlobalSearchScope scope = getScope();
+ private JavaResolveResult advancedResolveInner(@NotNull PsiElement psiElement, @NotNull String qName, @NotNull PsiFile containingFile) {
+ final PsiManager manager = containingFile.getManager();
+ final GlobalSearchScope scope = getScope(containingFile);
if (myIndex == myJavaClassReferenceSet.getReferences().length - 1) {
final PsiClass aClass = JavaPsiFacade.getInstance(manager.getProject()).findClass(qName, scope);
if (aClass != null) {
@@ -413,8 +417,6 @@ public class JavaClassReference extends GenericReference implements PsiJavaRefer
resolveResult = resolveMember(qName, manager, getElement().getResolveScope());
}
if (resolveResult == null) {
- PsiFile containingFile = psiElement.getContainingFile();
-
if (containingFile instanceof PsiJavaFile) {
if (containingFile instanceof ServerPageFile) {
containingFile = containingFile.getViewProvider().getPsi(JavaLanguage.INSTANCE);
@@ -448,12 +450,12 @@ public class JavaClassReference extends GenericReference implements PsiJavaRefer
: JavaResolveResult.EMPTY;
}
- private GlobalSearchScope getScope() {
- Project project = getElement().getProject();
+ private GlobalSearchScope getScope(@NotNull PsiFile containingFile) {
+ Project project = containingFile.getProject();
GlobalSearchScope scope = myJavaClassReferenceSet.getProvider().getScope(project);
if (scope == null) {
- Module module = ModuleUtilCore.findModuleForPsiElement(getElement());
- return module != null ? module.getModuleWithDependenciesAndLibrariesScope(true) : GlobalSearchScope.allScope(project);
+ Module module = ModuleUtilCore.findModuleForPsiElement(containingFile);
+ return module == null ? GlobalSearchScope.allScope(project) : module.getModuleWithDependenciesAndLibrariesScope(true);
}
return scope;
}
@@ -472,7 +474,7 @@ public class JavaClassReference extends GenericReference implements PsiJavaRefer
}
@Nullable
- private List<? extends LocalQuickFix> registerFixes(final HighlightInfo info) {
+ private List<? extends LocalQuickFix> registerFixes(HighlightInfo info) {
final List<LocalQuickFix> list = OrderEntryFix.registerFixes(new QuickFixActionRegistrarImpl(info), this);
@@ -498,7 +500,7 @@ public class JavaClassReference extends GenericReference implements PsiJavaRefer
final TextRange range = new TextRange(references[0].getRangeInElement().getStartOffset(),
getRangeInElement().getEndOffset());
final String qualifiedName = range.substring(getElement().getText());
- final CreateClassOrPackageFix action = CreateClassOrPackageFix.createFix(qualifiedName, getScope(), getElement(), contextPackage,
+ final CreateClassOrPackageFix action = CreateClassOrPackageFix.createFix(qualifiedName, getScope(getElement().getContainingFile()), getElement(), contextPackage,
kind, extendClass, templateName);
if (action != null) {
QuickFixAction.registerQuickFixAction(info, action);
@@ -591,13 +593,13 @@ public class JavaClassReference extends GenericReference implements PsiJavaRefer
return myJavaClassReferenceSet.getUnresolvedMessagePattern(myIndex);
}
- private static class MyResolver implements ResolveCache.PolyVariantResolver<JavaClassReference> {
+ private static class MyResolver implements ResolveCache.PolyVariantContextResolver<JavaClassReference> {
private static final MyResolver INSTANCE = new MyResolver();
@NotNull
@Override
- public JavaResolveResult[] resolve(@NotNull JavaClassReference javaClassReference, boolean incompleteCode) {
- return new JavaResolveResult[]{javaClassReference.doAdvancedResolve()};
+ public ResolveResult[] resolve(@NotNull JavaClassReference ref, @NotNull PsiFile containingFile, boolean incompleteCode) {
+ return new JavaResolveResult[]{ref.doAdvancedResolve(containingFile)};
}
}
diff --git a/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaTreeCopyHandler.java b/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaTreeCopyHandler.java
index 283e8578e146..a0234777aa86 100644
--- a/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaTreeCopyHandler.java
+++ b/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaTreeCopyHandler.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.
@@ -200,7 +200,7 @@ public class JavaTreeCopyHandler implements TreeCopyHandler {
}
}
else if (original.getElementType() == JavaElementType.JAVA_CODE_REFERENCE) {
- switch (((PsiJavaCodeReferenceElementImpl)original).getKind()) {
+ switch (((PsiJavaCodeReferenceElementImpl)original).getKind(((PsiJavaCodeReferenceElementImpl)original).getContainingFile())) {
case PsiJavaCodeReferenceElementImpl.CLASS_NAME_KIND:
case PsiJavaCodeReferenceElementImpl.CLASS_OR_PACKAGE_NAME_KIND:
case PsiJavaCodeReferenceElementImpl.CLASS_IN_QUALIFIED_NEW_KIND: