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