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