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 }