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.resolve.constants;
018    
019    import org.jetbrains.annotations.NotNull;
020    import org.jetbrains.annotations.Nullable;
021    import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
022    import org.jetbrains.kotlin.descriptors.annotations.AnnotationArgumentVisitor;
023    import org.jetbrains.kotlin.types.JetType;
024    
025    public abstract class CompileTimeConstant<T> {
026        protected final T value;
027        private final int flags;
028    
029       /*
030        * if is pure is false then constant type cannot be changed
031        * ex1. val a: Long = 1.toInt() (TYPE_MISMATCH error, 1.toInt() isn't pure)
032        * ex2. val b: Int = a (TYPE_MISMATCH error, a isn't pure)
033        *
034        */
035        private static final int IS_PURE_MASK = 1;
036        private static final int CAN_BE_USED_IN_ANNOTATIONS_MASK = 1 << 1;
037        private static final int USES_VARIABLE_AS_CONSTANT_MASK = 1 << 2;
038    
039        protected CompileTimeConstant(T value,
040                                      boolean canBeUsedInAnnotations,
041                                      boolean isPure,
042                                      boolean usesVariableAsConstant) {
043            this.value = value;
044            flags = (isPure ? IS_PURE_MASK : 0) |
045                    (canBeUsedInAnnotations ? CAN_BE_USED_IN_ANNOTATIONS_MASK : 0) |
046                    (usesVariableAsConstant ? USES_VARIABLE_AS_CONSTANT_MASK : 0);
047        }
048    
049        public boolean canBeUsedInAnnotations() {
050            return (flags & CAN_BE_USED_IN_ANNOTATIONS_MASK) != 0;
051        }
052    
053        public boolean isPure() {
054            return (flags & IS_PURE_MASK) != 0;
055        }
056    
057        public boolean usesVariableAsConstant() {
058            return (flags & USES_VARIABLE_AS_CONSTANT_MASK) != 0;
059        }
060    
061        @Nullable
062        public T getValue() {
063            return value;
064        }
065    
066        @NotNull
067        public abstract JetType getType(@NotNull KotlinBuiltIns kotlinBuiltIns);
068    
069        public abstract <R, D> R accept(AnnotationArgumentVisitor<R, D> visitor, D data);
070    }