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 import java.util.Map; 029 030 public abstract class ArgumentGenerator { 031 /** 032 * @return a {@code List} of bit masks of default arguments that should be passed as last arguments to $default method, if there were 033 * any default arguments, or an empty {@code List} if there were none 034 * @see kotlin.reflect.jvm.internal.KCallableImpl#callBy(Map...) 035 */ 036 @NotNull 037 public List<Integer> generate(@NotNull List<ResolvedValueArgument> valueArguments) { 038 List<Integer> masks = new ArrayList<Integer>(1); 039 int mask = 0; 040 int n = valueArguments.size(); 041 for (int i = 0; i < n; i++) { 042 if (i != 0 && i % Integer.SIZE == 0) { 043 masks.add(mask); 044 mask = 0; 045 } 046 ResolvedValueArgument argument = valueArguments.get(i); 047 if (argument instanceof ExpressionValueArgument) { 048 generateExpression(i, (ExpressionValueArgument) argument); 049 } 050 else if (argument instanceof DefaultValueArgument) { 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 (mask == 0 && masks.isEmpty()) { 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 }