001 /*
002 * Copyright 2010-2016 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.elements;
018
019 import com.intellij.lang.Language;
020 import com.intellij.openapi.util.TextRange;
021 import com.intellij.psi.*;
022 import com.intellij.psi.search.GlobalSearchScope;
023 import com.intellij.psi.search.SearchScope;
024 import com.intellij.util.ArrayUtil;
025 import com.intellij.util.IncorrectOperationException;
026 import org.jetbrains.annotations.NonNls;
027 import org.jetbrains.annotations.NotNull;
028 import org.jetbrains.annotations.Nullable;
029 import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration;
030 import org.jetbrains.kotlin.idea.KotlinLanguage;
031 import org.jetbrains.kotlin.psi.*;
032 import org.jetbrains.kotlin.psi.psiUtil.KtPsiUtilKt;
033
034 import java.util.List;
035
036 public class KtLightParameter extends LightParameter implements KtLightDeclaration<KtParameter, PsiParameter> {
037 private static String getName(PsiParameter delegate, int index) {
038 String name = delegate.getName();
039 return name != null ? name : "p" + index;
040 }
041
042 private final PsiModifierList modifierList;
043 private final PsiParameter delegate;
044 private final int index;
045 private final KtLightMethod method;
046 private KtLightIdentifier lightIdentifier = null;
047
048 public KtLightParameter(final PsiParameter delegate, int index, KtLightMethod method) {
049 super(getName(delegate, index), delegate.getType(), method, KotlinLanguage.INSTANCE);
050
051 this.delegate = delegate;
052 this.index = index;
053 this.method = method;
054
055 if (method.getLightMethodOrigin() instanceof LightMemberOriginForDeclaration) {
056 this.modifierList = new KtLightModifierListWithExplicitModifiers(this, ArrayUtil.EMPTY_STRING_ARRAY) {
057 @Override
058 public PsiAnnotationOwner getDelegate() {
059 return delegate.getModifierList();
060 }
061 };
062 }
063 else {
064 this.modifierList = super.getModifierList();
065 }
066 }
067
068 @NotNull
069 @Override
070 public PsiModifierList getModifierList() {
071 return modifierList;
072 }
073
074 @NotNull
075 @Override
076 public PsiParameter getClsDelegate() {
077 return delegate;
078 }
079
080 @Nullable
081 @Override
082 public KtParameter getKotlinOrigin() {
083 KtDeclaration declaration = method.getKotlinOrigin();
084 if (declaration == null) return null;
085
086 int jetIndex = KtPsiUtilKt.isExtensionDeclaration(declaration) ? index - 1 : index;
087 if (jetIndex < 0) return null;
088
089 if (declaration instanceof KtFunction) {
090 List<KtParameter> paramList = ((KtFunction) declaration).getValueParameters();
091 return jetIndex < paramList.size() ? paramList.get(jetIndex) : null;
092 }
093
094 if (jetIndex != 0) return null;
095
096 KtPropertyAccessor setter = null;
097 if (declaration instanceof KtPropertyAccessor) {
098 KtPropertyAccessor accessor = (KtPropertyAccessor) declaration;
099 setter = accessor.isSetter() ? accessor : null;
100 }
101 else if (declaration instanceof KtProperty) {
102 setter = ((KtProperty) declaration).getSetter();
103 }
104 else if (declaration instanceof KtParameter) {
105 return (KtParameter) declaration;
106 }
107
108 return setter != null ? setter.getParameter() : null;
109 }
110
111 @NotNull
112 @Override
113 public PsiElement getNavigationElement() {
114 KtParameter origin = getKotlinOrigin();
115 return origin != null ? origin : super.getNavigationElement();
116 }
117
118 @Override
119 public boolean isValid() {
120 return method.isValid();
121 }
122
123 @Override
124 public PsiElement setName(@NonNls @NotNull String name) throws IncorrectOperationException {
125 KtParameter origin = getKotlinOrigin();
126 if (origin != null) {
127 origin.setName(name);
128 }
129 return this;
130 }
131
132 @Override
133 public PsiFile getContainingFile() {
134 return method.getContainingFile();
135 }
136
137 @NotNull
138 @Override
139 public Language getLanguage() {
140 return KotlinLanguage.INSTANCE;
141 }
142
143 @NotNull
144 @Override
145 public SearchScope getUseScope() {
146 KtParameter origin = getKotlinOrigin();
147 return origin != null ? origin.getUseScope() : GlobalSearchScope.EMPTY_SCOPE;
148 }
149
150 public KtLightMethod getMethod() {
151 return method;
152 }
153
154 @Override
155 public String getText() {
156 return "";
157 }
158
159 @Override
160 public TextRange getTextRange() {
161 KtParameter origin = getKotlinOrigin();
162 return origin != null ? origin.getTextRange() : TextRange.EMPTY_RANGE;
163 }
164
165 @Override
166 public PsiIdentifier getNameIdentifier() {
167 if (lightIdentifier == null) {
168 lightIdentifier = new KtLightIdentifier(this, getKotlinOrigin());
169 }
170 return lightIdentifier;
171 }
172
173 @Override
174 public PsiElement getParent() {
175 return getMethod().getParameterList();
176 }
177
178 @Override
179 public boolean isEquivalentTo(PsiElement another) {
180 KtParameter kotlinOrigin = getKotlinOrigin();
181 if (another instanceof KtLightParameter && kotlinOrigin != null) {
182 KtLightParameter anotherParam = (KtLightParameter) another;
183 return kotlinOrigin.equals(anotherParam.getKotlinOrigin()) && getClsDelegate().equals(anotherParam.getClsDelegate());
184 }
185 return super.isEquivalentTo(another);
186 }
187 }