3 * Copyright (c) 2008 Your Corporation. All Rights Reserved.
5 package com
.intellij
.codeInsight
.completion
.impl
;
7 import com
.intellij
.codeInsight
.CodeInsightSettings
;
8 import com
.intellij
.codeInsight
.completion
.PrefixMatcher
;
9 import com
.intellij
.codeInsight
.lookup
.LookupElement
;
10 import com
.intellij
.codeInsight
.lookup
.LookupElementBuilder
;
11 import com
.intellij
.codeInsight
.lookup
.LookupItem
;
12 import com
.intellij
.openapi
.util
.text
.StringUtil
;
13 import com
.intellij
.psi
.codeStyle
.NameUtil
;
14 import com
.intellij
.util
.containers
.hash
.LinkedHashMap
;
15 import org
.jetbrains
.annotations
.NotNull
;
22 public class CamelHumpMatcher
extends PrefixMatcher
{
23 private static int ourLastCompletionCaseSetting
= -1;
24 private static final Map
<String
, NameUtil
.Matcher
> ourPatternCache
= new LinkedHashMap
<String
, NameUtil
.Matcher
>() {
26 protected boolean removeEldestEntry(Map
.Entry
<String
, NameUtil
.Matcher
> eldest
) {
30 private NameUtil
.Matcher myMatcher
;
31 private final boolean myCaseSensitive
;
33 public CamelHumpMatcher(@NotNull final String prefix
) {
37 public CamelHumpMatcher(String prefix
, boolean caseSensitive
) {
39 myCaseSensitive
= caseSensitive
;
42 public boolean prefixMatches(@NotNull final String name
) {
43 final int currentSetting
= CodeInsightSettings
.getInstance().COMPLETION_CASE_SENSITIVE
;
44 synchronized (ourPatternCache
) {
45 if (myMatcher
== null) {
46 if (ourLastCompletionCaseSetting
!= currentSetting
) {
47 ourPatternCache
.clear();
48 ourLastCompletionCaseSetting
= currentSetting
;
51 NameUtil
.Matcher pattern
= ourPatternCache
.get(myPrefix
);
52 if (pattern
== null) {
53 pattern
= createCamelHumpsMatcher();
54 ourPatternCache
.put(myPrefix
, pattern
);
58 return myMatcher
.matches(name
);
63 public boolean prefixMatches(@NotNull final LookupElement element
) {
64 final LookupItem item
= element
.as(LookupItem
.class); //must die, use LookupElementBuilder or CompletionResultSet.caseInsensitive
65 final LookupElementBuilder builder
= element
.as(LookupElementBuilder
.class);
66 boolean itemCaseInsensitive
= item
!= null && Boolean
.TRUE
.equals(item
.getAttribute(LookupItem
.CASE_INSENSITIVE
)) ||
67 builder
!= null && !builder
.isCaseSensitive();
69 return prefixMatchersInternal(element
, itemCaseInsensitive
);
72 private boolean prefixMatchersInternal(final LookupElement element
, final boolean itemCaseInsensitive
) {
73 for (final String name
: element
.getAllLookupStrings()) {
74 if (itemCaseInsensitive
&& StringUtil
.startsWithIgnoreCase(name
, myPrefix
) || prefixMatches(name
)) {
77 if (itemCaseInsensitive
&& CodeInsightSettings
.ALL
!= CodeInsightSettings
.getInstance().COMPLETION_CASE_SENSITIVE
&& name
.length() > 0) {
78 final char c
= name
.charAt(0);
79 String swappedCase
= (Character
.isUpperCase(c
) ? Character
.toLowerCase(c
) : Character
.toUpperCase(c
)) + name
.substring(1);
80 if (prefixMatches(swappedCase
)) {
89 public PrefixMatcher
cloneWithPrefix(@NotNull final String prefix
) {
90 return new CamelHumpMatcher(prefix
);
93 private NameUtil
.Matcher
createCamelHumpsMatcher() {
94 if (!myCaseSensitive
) {
95 return NameUtil
.buildMatcher(myPrefix
, 0, true, true);
98 final CodeInsightSettings settings
= CodeInsightSettings
.getInstance();
99 int variant
= settings
.COMPLETION_CASE_SENSITIVE
;
102 case CodeInsightSettings
.NONE
:
103 return NameUtil
.buildMatcher(myPrefix
, 0, true, true);
104 case CodeInsightSettings
.FIRST_LETTER
:
105 return NameUtil
.buildMatcher(myPrefix
, 1, true, true);
106 case CodeInsightSettings
.ALL
:
107 return NameUtil
.buildMatcher(myPrefix
, 0, false, false);
109 return NameUtil
.buildMatcher(myPrefix
, 0, true, false);
114 public String
toString() {