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.results; 018 019import java.util.EnumSet; 020 021public enum ResolutionStatus { 022 UNKNOWN_STATUS, 023 UNSAFE_CALL_ERROR, 024 OTHER_ERROR, 025 // '1.foo()' shouldn't be resolved to 'fun String.foo()' 026 // candidates with such error are treated specially 027 // (are mentioned in 'unresolved' error, if there are no other options) 028 RECEIVER_TYPE_ERROR, 029 // 'a.foo()' shouldn't be resolved to package level non-extension 'fun foo()' 030 // candidates with such error are thrown away completely 031 RECEIVER_PRESENCE_ERROR, 032 INCOMPLETE_TYPE_INFERENCE, 033 SUCCESS(true); 034 035 @SuppressWarnings("unchecked") 036 public static final EnumSet<ResolutionStatus>[] SEVERITY_LEVELS = new EnumSet[] { 037 EnumSet.of(UNSAFE_CALL_ERROR), // weakest 038 EnumSet.of(OTHER_ERROR), 039 EnumSet.of(RECEIVER_TYPE_ERROR), 040 EnumSet.of(RECEIVER_PRESENCE_ERROR), // most severe 041 }; 042 043 private final boolean success; 044 private int severityIndex = -1; 045 046 private ResolutionStatus(boolean success) { 047 this.success = success; 048 } 049 050 private ResolutionStatus() { 051 this(false); 052 } 053 054 public boolean isSuccess() { 055 return success; 056 } 057 058 public ResolutionStatus combine(ResolutionStatus other) { 059 if (this == UNKNOWN_STATUS) return other; 060 if (SUCCESS.among(this, other)) { 061 return SUCCESS.chooseDifferent(this, other); 062 } 063 if (INCOMPLETE_TYPE_INFERENCE.among(this, other)) { 064 return INCOMPLETE_TYPE_INFERENCE.chooseDifferent(this, other); 065 } 066 if (this.getSeverityIndex() < other.getSeverityIndex()) return other; 067 return this; 068 } 069 070 private boolean among(ResolutionStatus first, ResolutionStatus second) { 071 return this == first || this == second; 072 } 073 074 private ResolutionStatus chooseDifferent(ResolutionStatus first, ResolutionStatus second) { 075 assert among(first, second); 076 return this == first ? second : first; 077 } 078 079 private int getSeverityIndex() { 080 if (severityIndex == -1) { 081 for (int i = 0; i < SEVERITY_LEVELS.length; i++) { 082 if (SEVERITY_LEVELS[i].contains(this)) { 083 severityIndex = i; 084 break; 085 } 086 } 087 } 088 assert severityIndex >= 0; 089 090 return severityIndex; 091 } 092}