001    /*
002     * Copyright 2010-2013 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.jet.lang.resolve.constants;
018    
019    import org.jetbrains.annotations.NotNull;
020    import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
021    import org.jetbrains.jet.lang.psi.JetExpression;
022    import org.jetbrains.jet.lang.psi.JetQualifiedExpression;
023    import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
024    import org.jetbrains.jet.lang.resolve.BindingContext;
025    import org.jetbrains.jet.lang.resolve.BindingContextUtils;
026    import org.jetbrains.jet.lang.resolve.BindingTrace;
027    import org.jetbrains.jet.lang.resolve.calls.context.ResolutionContext;
028    import org.jetbrains.jet.lang.resolve.name.Name;
029    import org.jetbrains.jet.lang.resolve.scopes.JetScope;
030    import org.jetbrains.jet.lang.types.JetType;
031    import org.jetbrains.jet.lang.types.JetTypeInfo;
032    import org.jetbrains.jet.lang.types.TypeUtils;
033    import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
034    import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
035    
036    import static org.jetbrains.jet.lang.types.expressions.OperatorConventions.*;
037    
038    public class ConstantUtils {
039    
040        public static void propagateConstantValues(JetQualifiedExpression expression, BindingTrace trace, JetSimpleNameExpression selectorExpression) {
041            JetExpression receiverExpression = expression.getReceiverExpression();
042            CompileTimeConstant<?> receiverValue = trace.getBindingContext().get(BindingContext.COMPILE_TIME_VALUE, receiverExpression);
043            CompileTimeConstant<?> wholeExpressionValue = trace.getBindingContext().get(BindingContext.COMPILE_TIME_VALUE, expression);
044            DeclarationDescriptor declarationDescriptor = trace.getBindingContext().get(BindingContext.REFERENCE_TARGET, selectorExpression);
045            if (wholeExpressionValue == null && receiverValue != null && !(receiverValue instanceof ErrorValue) && receiverValue.getValue() instanceof Number
046                && KotlinBuiltIns.getInstance().getNumber() == declarationDescriptor) {
047                Number value = (Number) receiverValue.getValue();
048                Name referencedName = selectorExpression.getReferencedNameAsName();
049                if (OperatorConventions.NUMBER_CONVERSIONS.contains(referencedName)) {
050                    if (DOUBLE.equals(referencedName)) {
051                        trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new DoubleValue(value.doubleValue()));
052                    }
053                    else if (FLOAT.equals(referencedName)) {
054                        trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new FloatValue(value.floatValue()));
055                    }
056                    else if (LONG.equals(referencedName)) {
057                        trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new LongValue(value.longValue()));
058                    }
059                    else if (SHORT.equals(referencedName)) {
060                        trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new ShortValue(value.shortValue()));
061                    }
062                    else if (BYTE.equals(referencedName)) {
063                        trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new ByteValue(value.byteValue()));
064                    }
065                    else if (INT.equals(referencedName)) {
066                        trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new IntValue(value.intValue()));
067                    }
068                }
069            }
070        }
071    }