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.js.translate.utils;
018    
019    import com.intellij.psi.tree.IElementType;
020    import org.jetbrains.annotations.NotNull;
021    import org.jetbrains.annotations.Nullable;
022    import org.jetbrains.kotlin.descriptors.CallableDescriptor;
023    import org.jetbrains.kotlin.js.translate.context.TranslationContext;
024    import org.jetbrains.kotlin.lexer.KtToken;
025    import org.jetbrains.kotlin.lexer.KtTokens;
026    import org.jetbrains.kotlin.psi.*;
027    import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
028    import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
029    import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall;
030    
031    import java.util.Collections;
032    import java.util.List;
033    
034    public final class PsiUtils {
035    
036        private PsiUtils() {
037        }
038    
039        @Nullable
040        public static KtSimpleNameExpression getSimpleName(@NotNull KtExpression expression) {
041            if (expression instanceof KtSimpleNameExpression) {
042                return (KtSimpleNameExpression) expression;
043            }
044    
045            if (expression instanceof KtQualifiedExpression) {
046                return getSelectorAsSimpleName((KtQualifiedExpression) expression);
047            }
048    
049            return null;
050        }
051    
052        @Nullable
053        public static KtSimpleNameExpression getSelectorAsSimpleName(@NotNull KtQualifiedExpression expression) {
054            KtExpression selectorExpression = getSelector(expression);
055            if (!(selectorExpression instanceof KtSimpleNameExpression)) {
056                return null;
057            }
058            return (KtSimpleNameExpression) selectorExpression;
059        }
060    
061        @NotNull
062        public static KtExpression getSelector(@NotNull KtQualifiedExpression expression) {
063            KtExpression selectorExpression = expression.getSelectorExpression();
064            assert selectorExpression != null : "Selector should not be null.";
065            return selectorExpression;
066        }
067    
068        @NotNull
069        public static KtSimpleNameExpression getNotNullSimpleNameSelector(@NotNull KtQualifiedExpression expression) {
070            KtSimpleNameExpression selectorAsSimpleName = getSelectorAsSimpleName(expression);
071            assert selectorAsSimpleName != null;
072            return selectorAsSimpleName;
073        }
074    
075        @NotNull
076        public static KtToken getOperationToken(@NotNull KtOperationExpression expression) {
077            KtSimpleNameExpression operationExpression = expression.getOperationReference();
078            IElementType elementType = operationExpression.getReferencedNameElementType();
079            assert elementType instanceof KtToken : "Expected KtToken type, but " + elementType.getClass() + ", expression: " + expression.getText();
080            return (KtToken) elementType;
081        }
082    
083        @NotNull
084        public static KtExpression getBaseExpression(@NotNull KtUnaryExpression expression) {
085            KtExpression baseExpression = expression.getBaseExpression();
086            assert baseExpression != null;
087            return baseExpression;
088        }
089    
090        public static boolean isPrefix(@NotNull KtUnaryExpression expression) {
091            return (expression instanceof KtPrefixExpression);
092        }
093    
094        public static boolean isAssignment(KtToken token) {
095            return (token == KtTokens.EQ);
096        }
097    
098        public static boolean isInOrNotInOperation(@NotNull KtBinaryExpression binaryExpression) {
099            return isInOperation(binaryExpression) || isNotInOperation(binaryExpression);
100        }
101    
102        public static boolean isNotInOperation(@NotNull KtBinaryExpression binaryExpression) {
103            return (binaryExpression.getOperationToken() == KtTokens.NOT_IN);
104        }
105    
106        public static boolean isNegatedOperation(@NotNull KtBinaryExpression binaryExpression) {
107            return (binaryExpression.getOperationToken() == KtTokens.EXCLEQ) || isNotInOperation(binaryExpression);
108        }
109    
110        private static boolean isInOperation(@NotNull KtBinaryExpression binaryExpression) {
111            return (binaryExpression.getOperationToken() == KtTokens.IN_KEYWORD);
112        }
113    
114        @Nullable
115        public static KtParameter getLoopParameter(@NotNull KtForExpression expression) {
116            return expression.getLoopParameter();
117        }
118    
119        @NotNull
120        public static List<KtParameter> getPrimaryConstructorParameters(@NotNull KtClassOrObject classDeclaration) {
121            if (classDeclaration instanceof KtClass) {
122                return classDeclaration.getPrimaryConstructorParameters();
123            }
124            return Collections.emptyList();
125        }
126    
127        @NotNull
128        public static KtExpression getLoopRange(@NotNull KtForExpression expression) {
129            KtExpression rangeExpression = expression.getLoopRange();
130            assert rangeExpression != null;
131            return rangeExpression;
132        }
133    
134        @NotNull
135        public static CallableDescriptor getFunctionDescriptor(
136                @NotNull KtCallExpression expression,
137                @NotNull TranslationContext context
138        ) {
139            ResolvedCall<?> resolvedCall = CallUtilKt.getResolvedCall(expression, context.bindingContext());
140            assert resolvedCall != null;
141    
142            return getFunctionDescriptor(resolvedCall);
143        }
144    
145        @NotNull
146        public static CallableDescriptor getFunctionDescriptor(ResolvedCall<?> resolvedCall) {
147            if (resolvedCall instanceof VariableAsFunctionResolvedCall) {
148                return  ((VariableAsFunctionResolvedCall) resolvedCall).getVariableCall().getCandidateDescriptor();
149            }
150    
151            return resolvedCall.getCandidateDescriptor();
152        }
153    }