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