001    /*
002     * Copyright 2010-2015 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.kotlin.codegen;
018    
019    import org.jetbrains.annotations.NotNull;
020    import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument;
021    import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument;
022    import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument;
023    import org.jetbrains.kotlin.resolve.calls.model.VarargValueArgument;
024    
025    import java.util.ArrayList;
026    import java.util.Collections;
027    import java.util.List;
028    
029    public abstract class ArgumentGenerator {
030        /**
031         * @return a {@code List} of bit masks of default arguments that should be passed as last arguments to $default method, if there were
032         * any default arguments, or an empty {@code List} if there were none
033         */
034        @NotNull
035        public List<Integer> generate(@NotNull List<ResolvedValueArgument> valueArguments) {
036            List<Integer> masks = new ArrayList<Integer>(1);
037            boolean maskIsNeeded = false;
038            int mask = 0;
039            int n = valueArguments.size();
040            for (int i = 0; i < n; i++) {
041                if (i != 0 && i % Integer.SIZE == 0) {
042                    masks.add(mask);
043                    mask = 0;
044                }
045                ResolvedValueArgument argument = valueArguments.get(i);
046                if (argument instanceof ExpressionValueArgument) {
047                    generateExpression(i, (ExpressionValueArgument) argument);
048                }
049                else if (argument instanceof DefaultValueArgument) {
050                    maskIsNeeded = true;
051                    mask |= 1 << (i % Integer.SIZE);
052                    generateDefault(i, (DefaultValueArgument) argument);
053                }
054                else if (argument instanceof VarargValueArgument) {
055                    generateVararg(i, (VarargValueArgument) argument);
056                }
057                else {
058                    generateOther(i, argument);
059                }
060            }
061    
062            if (!maskIsNeeded) {
063                return Collections.emptyList();
064            }
065    
066            masks.add(mask);
067            return masks;
068        }
069    
070        protected void generateExpression(int i, @NotNull ExpressionValueArgument argument) {
071            throw new UnsupportedOperationException("Unsupported expression value argument #" + i + ": " + argument);
072        }
073    
074        protected void generateDefault(int i, @NotNull DefaultValueArgument argument) {
075            throw new UnsupportedOperationException("Unsupported default value argument #" + i + ": " + argument);
076        }
077    
078        protected void generateVararg(int i, @NotNull VarargValueArgument argument) {
079            throw new UnsupportedOperationException("Unsupported vararg value argument #" + i + ": " + argument);
080        }
081    
082        @SuppressWarnings("MethodMayBeStatic") // is supposed to be overridden
083        protected void generateOther(int i, @NotNull ResolvedValueArgument argument) {
084            throw new UnsupportedOperationException("Unsupported value argument #" + i + ": " + argument);
085        }
086    }