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.descriptors.impl;
018    
019    import com.google.common.collect.Sets;
020    import org.jetbrains.annotations.NotNull;
021    import org.jetbrains.annotations.Nullable;
022    import org.jetbrains.jet.lang.descriptors.*;
023    import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
024    import org.jetbrains.jet.lang.resolve.name.Name;
025    import org.jetbrains.jet.lang.types.JetType;
026    import org.jetbrains.jet.lang.types.TypeSubstitutor;
027    
028    import java.util.Collections;
029    import java.util.Set;
030    
031    public class ValueParameterDescriptorImpl extends VariableDescriptorImpl implements ValueParameterDescriptor {
032        private Boolean hasDefaultValue;
033        private final boolean declaresDefaultValue;
034    
035        private final JetType varargElementType;
036        private final int index;
037        private final ValueParameterDescriptor original;
038    
039        private final Set<ValueParameterDescriptor> overriddenDescriptors = Sets.newLinkedHashSet(); // Linked is essential
040        private boolean overriddenDescriptorsLocked = false;
041        private final Set<? extends ValueParameterDescriptor> readOnlyOverriddenDescriptors = Collections.unmodifiableSet(overriddenDescriptors);
042    
043        public ValueParameterDescriptorImpl(
044                @NotNull DeclarationDescriptor containingDeclaration,
045                @Nullable ValueParameterDescriptor original,
046                int index,
047                @NotNull Annotations annotations,
048                @NotNull Name name,
049                @NotNull JetType outType,
050                boolean declaresDefaultValue,
051                @Nullable JetType varargElementType,
052                @NotNull SourceElement source
053        ) {
054            super(containingDeclaration, annotations, name, outType, source);
055            this.original = original == null ? this : original;
056            this.index = index;
057            this.declaresDefaultValue = declaresDefaultValue;
058            this.varargElementType = varargElementType;
059        }
060    
061        public void setType(@NotNull JetType type) {
062            setOutType(type);
063        }
064    
065        @Override
066        public int getIndex() {
067            return index;
068        }
069    
070        @Override
071        public boolean hasDefaultValue() {
072            computeDefaultValuePresence();
073            return hasDefaultValue;
074        }
075    
076        @Override
077        public boolean declaresDefaultValue() {
078            return declaresDefaultValue && ((CallableMemberDescriptor) getContainingDeclaration()).getKind().isReal();
079        }
080    
081        private void computeDefaultValuePresence() {
082            if (hasDefaultValue != null) return;
083            overriddenDescriptorsLocked = true;
084            if (declaresDefaultValue) {
085                hasDefaultValue = true;
086            }
087            else {
088                for (ValueParameterDescriptor descriptor : overriddenDescriptors) {
089                    if (descriptor.hasDefaultValue()) {
090                        hasDefaultValue = true;
091                        return;
092                    }
093                }
094                hasDefaultValue = false;
095            }
096        }
097    
098        @Nullable
099        @Override
100        public JetType getVarargElementType() {
101            return varargElementType;
102        }
103    
104        @NotNull
105        @Override
106        public ValueParameterDescriptor getOriginal() {
107            return original == this ? this : original.getOriginal();
108        }
109    
110        @NotNull
111        @Override
112        public ValueParameterDescriptor substitute(@NotNull TypeSubstitutor substitutor) {
113            throw new UnsupportedOperationException(); // TODO
114        }
115    
116        @Override
117        public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
118            return visitor.visitValueParameterDescriptor(this, data);
119        }
120    
121        @Override
122        public boolean isVar() {
123            return false;
124        }
125    
126        @NotNull
127        @Override
128        public ValueParameterDescriptor copy(@NotNull DeclarationDescriptor newOwner, @NotNull Name newName) {
129            return new ValueParameterDescriptorImpl(newOwner, null, index, getAnnotations(), newName, getType(), declaresDefaultValue(), varargElementType, SourceElement.NO_SOURCE);
130        }
131    
132        @NotNull
133        @Override
134        public Visibility getVisibility() {
135            return Visibilities.LOCAL;
136        }
137    
138        @NotNull
139        @Override
140        public Set<? extends ValueParameterDescriptor> getOverriddenDescriptors() {
141            return readOnlyOverriddenDescriptors;
142        }
143    
144        @Override
145        public void addOverriddenDescriptor(@NotNull ValueParameterDescriptor overridden) {
146            assert !overriddenDescriptorsLocked : "Adding more overridden descriptors is not allowed at this point: " +
147                                                  "the presence of the default value has already been calculated";
148            overriddenDescriptors.add(overridden);
149        }
150    }