summaryrefslogtreecommitdiff
path: root/java/java-impl/src/com/intellij/codeInsight/template
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/codeInsight/template
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/codeInsight/template')
-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
31 files changed, 657 insertions, 239 deletions
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;
+ }
}