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.types;
018
019import org.jetbrains.annotations.NotNull;
020import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
021import org.jetbrains.jet.lang.resolve.BindingTrace;
022import org.jetbrains.jet.lang.resolve.scopes.JetScope;
023import org.jetbrains.jet.util.Box;
024import org.jetbrains.jet.util.lazy.RecursionIntolerantLazyValue;
025import org.jetbrains.jet.util.lazy.ReenteringLazyValueComputationException;
026
027import java.util.List;
028
029import static org.jetbrains.jet.lang.resolve.BindingContext.DEFERRED_TYPE;
030
031public class DeferredType implements JetType {
032    
033    public static DeferredType create(BindingTrace trace, RecursionIntolerantLazyValue<JetType> lazyValue) {
034        DeferredType deferredType = new DeferredType(lazyValue);
035        trace.record(DEFERRED_TYPE, new Box<DeferredType>(deferredType));
036        return deferredType;
037    }
038    
039    private final RecursionIntolerantLazyValue<JetType> lazyValue;
040
041    private DeferredType(RecursionIntolerantLazyValue<JetType> lazyValue) {
042        this.lazyValue = lazyValue;
043    }
044
045    public boolean isComputed() {
046        return lazyValue.isComputed();
047    }
048
049    @NotNull
050    public JetType getActualType() {
051        return lazyValue.get();
052    }
053
054    @Override
055    @NotNull
056    public JetScope getMemberScope() {
057        return getActualType().getMemberScope();
058    }
059
060    @Override
061    @NotNull
062    public TypeConstructor getConstructor() {
063        return getActualType().getConstructor();
064    }
065
066    @Override
067    @NotNull
068    public List<TypeProjection> getArguments() {
069        return getActualType().getArguments();
070    }
071
072    @Override
073    public boolean isNullable() {
074        return getActualType().isNullable();
075    }
076
077    @Override
078    public List<AnnotationDescriptor> getAnnotations() {
079        return getActualType().getAnnotations();
080    }
081
082    @Override
083    public String toString() {
084        try {
085            if (lazyValue.isComputed()) {
086                return getActualType().toString();
087            }
088            else {
089                return "<Not computed yet>";
090            }
091        }
092        catch (ReenteringLazyValueComputationException e) {
093            return "<Failed to compute this type>";
094        }
095    }
096
097    @Override
098    public boolean equals(Object obj) {
099        return getActualType().equals(obj);
100    }
101
102    @Override
103    public int hashCode() {
104        return getActualType().hashCode();
105    }
106}