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    
017    package org.jetbrains.jet.lang.types;
018    
019    import org.jetbrains.annotations.NotNull;
020    import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
021    import org.jetbrains.jet.lang.resolve.BindingTrace;
022    import org.jetbrains.jet.lang.resolve.scopes.JetScope;
023    import org.jetbrains.jet.util.Box;
024    import org.jetbrains.jet.util.lazy.RecursionIntolerantLazyValue;
025    import org.jetbrains.jet.util.lazy.ReenteringLazyValueComputationException;
026    
027    import java.util.List;
028    
029    import static org.jetbrains.jet.lang.resolve.BindingContext.DEFERRED_TYPE;
030    
031    public 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    }