2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com
.intellij
.codeInsight
.template
.macro
;
18 import com
.intellij
.codeInsight
.CodeInsightBundle
;
19 import com
.intellij
.codeInsight
.lookup
.LookupElement
;
20 import com
.intellij
.codeInsight
.lookup
.LookupElementBuilder
;
21 import com
.intellij
.codeInsight
.template
.*;
22 import com
.intellij
.psi
.*;
23 import com
.intellij
.psi
.search
.GlobalSearchScope
;
24 import com
.intellij
.psi
.search
.PsiElementProcessor
;
25 import com
.intellij
.psi
.search
.PsiElementProcessorAdapter
;
26 import com
.intellij
.psi
.search
.searches
.ClassInheritorsSearch
;
27 import org
.jetbrains
.annotations
.NotNull
;
28 import org
.jetbrains
.annotations
.Nullable
;
30 import java
.util
.ArrayList
;
31 import java
.util
.LinkedHashSet
;
32 import java
.util
.List
;
35 public class DescendantClassesEnumMacro
implements Macro
{
36 public String
getName() {
37 return "descendantClassesEnum";
40 public String
getDescription() {
41 return CodeInsightBundle
.message("macro.descendant.classes.enum");
44 public String
getDefaultValue() {
48 public Result
calculateResult(@NotNull Expression
[] params
, ExpressionContext context
) {
49 final List
<PsiClass
> classes
= findDescendants(context
, params
);
50 if (classes
== null || classes
.size() == 0) return null;
51 Result
[] results
= calculateResults(classes
);
56 private static Result
[] calculateResults(final List
<PsiClass
> classes
) {
57 Result
[] results
= new Result
[classes
.size()];
60 for (final PsiClass aClass
: classes
) {
61 results
[i
++] = new JavaPsiElementResult(aClass
);
67 private static List
<PsiClass
> findDescendants(ExpressionContext context
, Expression
[] params
) {
68 if (params
== null || params
.length
== 0) return null;
69 PsiManager instance
= PsiManager
.getInstance(context
.getProject());
71 final String paramResult
= params
[0].calculateResult(context
).toString();
72 if (paramResult
== null) return null;
74 final boolean isAllowAbstract
= isAllowAbstract(context
, params
);
75 final PsiClass myBaseClass
=
76 JavaPsiFacade
.getInstance(instance
.getProject()).findClass(paramResult
, GlobalSearchScope
.allScope(context
.getProject()));
78 if (myBaseClass
!= null) {
79 final List
<PsiClass
> classes
= new ArrayList
<PsiClass
>();
81 ClassInheritorsSearch
.search(myBaseClass
, myBaseClass
.getUseScope(), true).forEach(new PsiElementProcessorAdapter
<PsiClass
>(new PsiElementProcessor
<PsiClass
>() {
82 public boolean execute(PsiClass element
) {
83 if (isAllowAbstract
|| !isAbstractOrInterface(element
)) {
97 public Result
calculateQuickResult(@NotNull Expression
[] params
, ExpressionContext context
) {
98 final List
<PsiClass
> classes
= findDescendants(context
, params
);
99 if (classes
== null || classes
.size() == 0) return null;
100 Result
[] results
= calculateResults(classes
);
105 public LookupElement
[] calculateLookupItems(@NotNull Expression
[] params
, ExpressionContext context
) {
106 final List
<PsiClass
> classes
= findDescendants(context
, params
);
107 if (classes
== null || classes
.size() == 0) return null;
109 Set
<LookupElement
> set
= new LinkedHashSet
<LookupElement
>();
110 boolean isShortName
= params
.length
> 1 && !Boolean
.valueOf(params
[1].calculateResult(context
).toString());
112 for (PsiClass object
: classes
) {
113 final String name
= isShortName ? object
.getName() : object
.getQualifiedName();
114 if (name
!= null && name
.length() > 0) {
115 set
.add(LookupElementBuilder
.create(name
));
119 return set
.toArray(new LookupElement
[set
.size()]);
122 private static boolean isAbstractOrInterface(final PsiClass psiClass
) {
123 final PsiModifierList modifierList
= psiClass
.getModifierList();
125 return psiClass
.isInterface() || (modifierList
!= null && modifierList
.hasModifierProperty(PsiModifier
.ABSTRACT
));
128 private static boolean isAllowAbstract(final ExpressionContext context
, final Expression
[] params
) {
129 return params
.length
> 2 ? Boolean
.valueOf(params
[2].calculateResult(context
).toString()) : true;