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.psi.PsiAnnotationOwner;
021    import com.intellij.psi.PsiFile;
022    import com.intellij.psi.PsiModifierList;
023    import com.intellij.psi.PsiParameter;
024    import com.intellij.psi.search.GlobalSearchScope;
025    import com.intellij.psi.search.SearchScope;
026    import com.intellij.util.ArrayUtil;
027    import org.jetbrains.annotations.NotNull;
028    import org.jetbrains.annotations.Nullable;
029    import org.jetbrains.kotlin.idea.JetLanguage;
030    import org.jetbrains.kotlin.psi.*;
031    import org.jetbrains.kotlin.psi.psiUtil.PsiUtilPackage;
032    
033    import java.util.List;
034    
035    public class KotlinLightParameter extends LightParameter implements KotlinLightElement<JetParameter, PsiParameter> {
036        private static String getName(PsiParameter delegate, int index) {
037            String name = delegate.getName();
038            return name != null ? name : "p" + index;
039        }
040    
041        private final PsiModifierList modifierList;
042        private final PsiParameter delegate;
043        private final int index;
044        private final KotlinLightMethod method;
045    
046        public KotlinLightParameter(final PsiParameter delegate, int index, KotlinLightMethod method) {
047            super(getName(delegate, index), delegate.getType(), method, JetLanguage.INSTANCE);
048    
049            this.delegate = delegate;
050            this.index = index;
051            this.method = method;
052    
053            this.modifierList = new KotlinLightModifierList(method.getManager(), ArrayUtil.EMPTY_STRING_ARRAY) {
054                @Override
055                public PsiAnnotationOwner getDelegate() {
056                    return delegate.getModifierList();
057                }
058            };
059        }
060    
061        @NotNull
062        @Override
063        public PsiModifierList getModifierList() {
064            return modifierList;
065        }
066    
067        @NotNull
068        @Override
069        public PsiParameter getDelegate() {
070            return delegate;
071        }
072    
073        @Nullable
074        @Override
075        public JetParameter getOrigin() {
076            JetDeclaration declaration = method.getOrigin();
077            if (declaration == null) return null;
078    
079            int jetIndex = PsiUtilPackage.isExtensionDeclaration(declaration) ? index - 1 : index;
080            if (jetIndex < 0) return null;
081    
082            if (declaration instanceof JetNamedFunction) {
083                List<JetParameter> paramList = ((JetNamedFunction) declaration).getValueParameters();
084                return jetIndex < paramList.size() ? paramList.get(jetIndex) : null;
085            }
086    
087            if (declaration instanceof JetClass) {
088                List<JetParameter> paramList = ((JetClass) declaration).getPrimaryConstructorParameters();
089                return jetIndex < paramList.size() ? paramList.get(jetIndex) : null;
090            }
091    
092            if (jetIndex != 0) return null;
093    
094            JetPropertyAccessor setter = null;
095            if (declaration instanceof JetPropertyAccessor) {
096                JetPropertyAccessor accessor = (JetPropertyAccessor) declaration;
097                setter = accessor.isSetter() ? accessor : null;
098            }
099            else if (declaration instanceof JetProperty) {
100                setter = ((JetProperty) declaration).getSetter();
101            }
102    
103            return setter != null ? setter.getParameter() : null;
104        }
105    
106        @Override
107        public PsiFile getContainingFile() {
108            JetDeclaration declaration = method.getOrigin();
109            return declaration != null ? declaration.getContainingFile() : super.getContainingFile();
110        }
111    
112        @NotNull
113        @Override
114        public Language getLanguage() {
115            return JetLanguage.INSTANCE;
116        }
117    
118        @NotNull
119        @Override
120        public SearchScope getUseScope() {
121            JetParameter origin = getOrigin();
122            return origin != null ? origin.getUseScope() : GlobalSearchScope.EMPTY_SCOPE;
123        }
124    }