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 017package org.jetbrains.jet.lang.resolve.calls.autocasts; 018 019import org.jetbrains.annotations.NotNull; 020 021public enum Nullability { 022 NULL(true, false), 023 NOT_NULL(false, true), 024 UNKNOWN(true, true), 025 IMPOSSIBLE(false, false); 026 027 @NotNull 028 public static Nullability fromFlags(boolean canBeNull, boolean canBeNonNull) { 029 if (!canBeNull && !canBeNonNull) return IMPOSSIBLE; 030 if (!canBeNull && canBeNonNull) return NOT_NULL; 031 if (canBeNull && !canBeNonNull) return NULL; 032 return UNKNOWN; 033 } 034 035 private final boolean canBeNull; 036 private final boolean canBeNonNull; 037 038 Nullability(boolean canBeNull, boolean canBeNonNull) { 039 this.canBeNull = canBeNull; 040 this.canBeNonNull = canBeNonNull; 041 } 042 043 public boolean canBeNull() { 044 return canBeNull; 045 } 046 047 public boolean canBeNonNull() { 048 return canBeNonNull; 049 } 050 051 @NotNull 052 public Nullability refine(@NotNull Nullability other) { 053 switch (this) { 054 case UNKNOWN: 055 return other; 056 case IMPOSSIBLE: 057 return other; 058 case NULL: 059 switch (other) { 060 case NOT_NULL: return NOT_NULL; 061 default: return NULL; 062 } 063 case NOT_NULL: 064 switch (other) { 065 case NULL: return NOT_NULL; 066 default: return NOT_NULL; 067 } 068 } 069 throw new IllegalStateException(); 070 } 071 072 @NotNull 073 public Nullability invert() { 074 switch (this) { 075 case NULL: 076 return NOT_NULL; 077 case NOT_NULL: 078 return UNKNOWN; 079 case UNKNOWN: 080 return UNKNOWN; 081 case IMPOSSIBLE: 082 return UNKNOWN; 083 } 084 throw new IllegalStateException(); 085 } 086 087 @NotNull 088 public Nullability and(@NotNull Nullability other) { 089 return fromFlags(this.canBeNull && other.canBeNull, this.canBeNonNull && other.canBeNonNull); 090 } 091 092 @NotNull 093 public Nullability or(@NotNull Nullability other) { 094 return fromFlags(this.canBeNull || other.canBeNull, this.canBeNonNull || other.canBeNonNull); 095 } 096}