001 /*
002 * Copyright 2010-2015 JetBrains s.r.o.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 package org.jetbrains.kotlin.asJava;
018
019 import com.intellij.lang.Language;
020 import com.intellij.navigation.ItemPresentation;
021 import com.intellij.navigation.ItemPresentationProviders;
022 import com.intellij.psi.*;
023 import com.intellij.psi.impl.PsiClassImplUtil;
024 import com.intellij.psi.impl.light.AbstractLightClass;
025 import com.intellij.psi.impl.source.ClassInnerStuffCache;
026 import com.intellij.psi.impl.source.PsiExtensibleClass;
027 import com.intellij.psi.scope.PsiScopeProcessor;
028 import com.intellij.psi.util.PsiTreeUtil;
029 import com.intellij.util.Function;
030 import com.intellij.util.containers.ContainerUtil;
031 import kotlin.ArraysKt;
032 import kotlin.jvm.functions.Function1;
033 import org.jetbrains.annotations.NotNull;
034 import org.jetbrains.annotations.Nullable;
035 import org.jetbrains.kotlin.idea.KotlinLanguage;
036 import org.jetbrains.kotlin.psi.*;
037
038 import java.util.List;
039
040 public abstract class KtWrappingLightClass extends AbstractLightClass implements KtLightClass, PsiExtensibleClass {
041 private final ClassInnerStuffCache myInnersCache = new ClassInnerStuffCache(this);
042
043 protected KtWrappingLightClass(PsiManager manager) {
044 super(manager, KotlinLanguage.INSTANCE);
045 }
046
047 @Nullable
048 @Override
049 public abstract KtClassOrObject getOrigin();
050
051 @NotNull
052 @Override
053 public abstract PsiClass getDelegate();
054
055 @Override
056 @NotNull
057 public PsiField[] getFields() {
058 return myInnersCache.getFields();
059 }
060
061 @Override
062 @NotNull
063 public PsiMethod[] getMethods() {
064 return myInnersCache.getMethods();
065 }
066
067 @Override
068 @NotNull
069 public PsiMethod[] getConstructors() {
070 return myInnersCache.getConstructors();
071 }
072
073 @Override
074 @NotNull
075 public PsiClass[] getInnerClasses() {
076 return myInnersCache.getInnerClasses();
077 }
078
079 @Override
080 @NotNull
081 public PsiField[] getAllFields() {
082 return PsiClassImplUtil.getAllFields(this);
083 }
084
085 @Override
086 @NotNull
087 public PsiMethod[] getAllMethods() {
088 return PsiClassImplUtil.getAllMethods(this);
089 }
090
091 @Override
092 @NotNull
093 public PsiClass[] getAllInnerClasses() {
094 return PsiClassImplUtil.getAllInnerClasses(this);
095 }
096
097 @Override
098 public PsiField findFieldByName(String name, boolean checkBases) {
099 return myInnersCache.findFieldByName(name, checkBases);
100 }
101
102 @Override
103 @NotNull
104 public PsiMethod[] findMethodsByName(String name, boolean checkBases) {
105 return myInnersCache.findMethodsByName(name, checkBases);
106 }
107
108 @Override
109 public PsiClass findInnerClassByName(String name, boolean checkBases) {
110 return myInnersCache.findInnerClassByName(name, checkBases);
111 }
112
113 /**
114 * @see org.jetbrains.kotlin.codegen.binding.CodegenBinding#ENUM_ENTRY_CLASS_NEED_SUBCLASS
115 */
116 @NotNull
117 @Override
118 public List<PsiField> getOwnFields() {
119 return ContainerUtil.map(getDelegate().getFields(), new Function<PsiField, PsiField>() {
120 @Override
121 public PsiField fun(PsiField field) {
122 KtDeclaration declaration = ClsWrapperStubPsiFactory.getOriginalDeclaration(field);
123 return KtLightFieldImpl.Factory.create(declaration, field, KtWrappingLightClass.this);
124 }
125 });
126 }
127
128 @NotNull
129 @Override
130 public List<PsiMethod> getOwnMethods() {
131 return ArraysKt.map(getDelegate().getMethods(), new Function1<PsiMethod, PsiMethod>() {
132 @Override
133 public PsiMethod invoke(PsiMethod method) {
134 KtDeclaration declaration = ClsWrapperStubPsiFactory.getOriginalDeclaration(method);
135 if (declaration instanceof KtPropertyAccessor) {
136 declaration = PsiTreeUtil.getParentOfType(declaration, KtProperty.class);
137 }
138
139 return KtLightMethodImpl.Factory.create(method, declaration, KtWrappingLightClass.this);
140 }
141 });
142 }
143
144 @Override
145 public boolean processDeclarations(
146 @NotNull PsiScopeProcessor processor, @NotNull ResolveState state, PsiElement lastParent, @NotNull PsiElement place
147 ) {
148 if (isEnum()) {
149 if (!PsiClassImplUtil.processDeclarationsInEnum(processor, state, myInnersCache)) return false;
150 }
151
152 return super.processDeclarations(processor, state, lastParent, place);
153 }
154
155 @Override
156 public String getText() {
157 KtClassOrObject origin = getOrigin();
158 return origin == null ? "" : origin.getText();
159 }
160
161 @NotNull
162 @Override
163 public Language getLanguage() {
164 return KotlinLanguage.INSTANCE;
165 }
166
167 @Override
168 public ItemPresentation getPresentation() {
169 return ItemPresentationProviders.getItemPresentation(this);
170 }
171
172 @Override
173 public abstract boolean equals(Object obj);
174
175 @Override
176 public abstract int hashCode();
177
178 @Override
179 public PsiElement getContext() {
180 return getParent();
181 }
182 }