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.collections.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.KtClassOrObject;
037 import org.jetbrains.kotlin.psi.KtDeclaration;
038 import org.jetbrains.kotlin.psi.KtProperty;
039 import org.jetbrains.kotlin.psi.KtPropertyAccessor;
040
041 import java.util.List;
042
043 public abstract class KtWrappingLightClass extends AbstractLightClass implements KtLightClass, PsiExtensibleClass {
044 private final ClassInnerStuffCache myInnersCache = new ClassInnerStuffCache(this);
045
046 protected KtWrappingLightClass(PsiManager manager) {
047 super(manager, KotlinLanguage.INSTANCE);
048 }
049
050 @Nullable
051 @Override
052 public abstract KtClassOrObject getOrigin();
053
054 @NotNull
055 @Override
056 public abstract PsiClass getDelegate();
057
058 @Override
059 @NotNull
060 public PsiField[] getFields() {
061 return myInnersCache.getFields();
062 }
063
064 @Override
065 @NotNull
066 public PsiMethod[] getMethods() {
067 return myInnersCache.getMethods();
068 }
069
070 @Override
071 @NotNull
072 public PsiMethod[] getConstructors() {
073 return myInnersCache.getConstructors();
074 }
075
076 @Override
077 @NotNull
078 public PsiClass[] getInnerClasses() {
079 return myInnersCache.getInnerClasses();
080 }
081
082 @Override
083 @NotNull
084 public PsiField[] getAllFields() {
085 return PsiClassImplUtil.getAllFields(this);
086 }
087
088 @Override
089 @NotNull
090 public PsiMethod[] getAllMethods() {
091 return PsiClassImplUtil.getAllMethods(this);
092 }
093
094 @Override
095 @NotNull
096 public PsiClass[] getAllInnerClasses() {
097 return PsiClassImplUtil.getAllInnerClasses(this);
098 }
099
100 @Override
101 public PsiField findFieldByName(String name, boolean checkBases) {
102 return myInnersCache.findFieldByName(name, checkBases);
103 }
104
105 @Override
106 @NotNull
107 public PsiMethod[] findMethodsByName(String name, boolean checkBases) {
108 return myInnersCache.findMethodsByName(name, checkBases);
109 }
110
111 @Override
112 public PsiClass findInnerClassByName(String name, boolean checkBases) {
113 return myInnersCache.findInnerClassByName(name, checkBases);
114 }
115
116 /**
117 * @see org.jetbrains.kotlin.codegen.binding.CodegenBinding#ENUM_ENTRY_CLASS_NEED_SUBCLASS
118 */
119 @NotNull
120 @Override
121 public List<PsiField> getOwnFields() {
122 return ContainerUtil.map(getDelegate().getFields(), new Function<PsiField, PsiField>() {
123 @Override
124 public PsiField fun(PsiField field) {
125 LightMemberOrigin origin = ClsWrapperStubPsiFactory.getMemberOrigin(field);
126 return KtLightFieldImpl.Factory.create(origin != null ? origin.getOriginalElement() : null, field, KtWrappingLightClass.this);
127 }
128 });
129 }
130
131 @NotNull
132 @Override
133 public List<PsiMethod> getOwnMethods() {
134 return ArraysKt.map(getDelegate().getMethods(), new Function1<PsiMethod, PsiMethod>() {
135 @Override
136 public PsiMethod invoke(PsiMethod method) {
137 LightMemberOrigin origin = ClsWrapperStubPsiFactory.getMemberOrigin(method);
138 KtDeclaration originalElement = origin != null ? origin.getOriginalElement() : null;
139 if (originalElement instanceof KtPropertyAccessor) {
140 //noinspection ConstantConditions
141 origin = origin.copy(PsiTreeUtil.getParentOfType(originalElement, KtProperty.class), origin.getOriginKind());
142 }
143
144 return KtLightMethodImpl.Factory.create(method, origin, KtWrappingLightClass.this);
145 }
146 });
147 }
148
149 @Override
150 public boolean processDeclarations(
151 @NotNull PsiScopeProcessor processor, @NotNull ResolveState state, PsiElement lastParent, @NotNull PsiElement place
152 ) {
153 if (isEnum()) {
154 if (!PsiClassImplUtil.processDeclarationsInEnum(processor, state, myInnersCache)) return false;
155 }
156
157 return super.processDeclarations(processor, state, lastParent, place);
158 }
159
160 @Override
161 public String getText() {
162 KtClassOrObject origin = getOrigin();
163 return origin == null ? "" : origin.getText();
164 }
165
166 @NotNull
167 @Override
168 public Language getLanguage() {
169 return KotlinLanguage.INSTANCE;
170 }
171
172 @Override
173 public ItemPresentation getPresentation() {
174 return ItemPresentationProviders.getItemPresentation(this);
175 }
176
177 @Override
178 public abstract boolean equals(Object obj);
179
180 @Override
181 public abstract int hashCode();
182
183 @Override
184 public PsiElement getContext() {
185 return getParent();
186 }
187 }