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        ) {
053            super(containingDeclaration, annotations, name, outType);
054            this.original = original == null ? this : original;
055            this.index = index;
056            this.declaresDefaultValue = declaresDefaultValue;
057            this.varargElementType = varargElementType;
058        }
059    
060        public void setType(@NotNull JetType type) {
061            setOutType(type);
062        }
063    
064        @Override
065        public int getIndex() {
066            return index;
067        }
068    
069        @Override
070        public boolean hasDefaultValue() {
071            computeDefaultValuePresence();
072            return hasDefaultValue;
073        }
074    
075        @Override
076        public boolean declaresDefaultValue() {
077            return declaresDefaultValue && ((CallableMemberDescriptor) getContainingDeclaration()).getKind().isReal();
078        }
079    
080        private void computeDefaultValuePresence() {
081            if (hasDefaultValue != null) return;
082            overriddenDescriptorsLocked = true;
083            if (declaresDefaultValue) {
084                hasDefaultValue = true;
085            }
086            else {
087                for (ValueParameterDescriptor descriptor : overriddenDescriptors) {
088                    if (descriptor.hasDefaultValue()) {
089                        hasDefaultValue = true;
090                        return;
091                    }
092                }
093                hasDefaultValue = false;
094            }
095        }
096    
097        @Nullable
098        @Override
099        public JetType getVarargElementType() {
100            return varargElementType;
101        }
102    
103        @NotNull
104        @Override
105        public ValueParameterDescriptor getOriginal() {
106            return original == this ? this : original.getOriginal();
107        }
108    
109        @NotNull
110        @Override
111        public ValueParameterDescriptor substitute(@NotNull TypeSubstitutor substitutor) {
112            throw new UnsupportedOperationException(); // TODO
113        }
114    
115        @Override
116        public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
117            return visitor.visitValueParameterDescriptor(this, data);
118        }
119    
120        @Override
121        public boolean isVar() {
122            return false;
123        }
124    
125        @NotNull
126        @Override
127        public ValueParameterDescriptor copy(@NotNull DeclarationDescriptor newOwner, @NotNull Name newName) {
128            return new ValueParameterDescriptorImpl(newOwner, null, index, getAnnotations(), newName, getType(), declaresDefaultValue(), varargElementType);
129        }
130    
131        @NotNull
132        @Override
133        public Visibility getVisibility() {
134            return Visibilities.LOCAL;
135        }
136    
137        @NotNull
138        @Override
139        public Set<? extends ValueParameterDescriptor> getOverriddenDescriptors() {
140            return readOnlyOverriddenDescriptors;
141        }
142    
143        @Override
144        public void addOverriddenDescriptor(@NotNull ValueParameterDescriptor overridden) {
145            assert !overriddenDescriptorsLocked : "Adding more overridden descriptors is not allowed at this point: " +
146                                                  "the presence of the default value has already been calculated";
147            overriddenDescriptors.add(overridden);
148        }
149    }