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.descriptors.ValueParameterDescriptor; 021 import org.jetbrains.kotlin.psi.KtExpression; 022 import org.jetbrains.kotlin.psi.ValueArgument; 023 import org.jetbrains.kotlin.resolve.calls.model.*; 024 import org.jetbrains.org.objectweb.asm.Type; 025 026 import java.util.List; 027 028 import static org.jetbrains.kotlin.codegen.AsmUtil.pushDefaultValueOnStack; 029 030 public class CallBasedArgumentGenerator extends ArgumentGenerator { 031 private final ExpressionCodegen codegen; 032 private final CallGenerator callGenerator; 033 private final List<ValueParameterDescriptor> valueParameters; 034 private final List<Type> valueParameterTypes; 035 036 public CallBasedArgumentGenerator( 037 @NotNull ExpressionCodegen codegen, 038 @NotNull CallGenerator callGenerator, 039 @NotNull List<ValueParameterDescriptor> valueParameters, 040 @NotNull List<Type> valueParameterTypes 041 ) { 042 this.codegen = codegen; 043 this.callGenerator = callGenerator; 044 this.valueParameters = valueParameters; 045 this.valueParameterTypes = valueParameterTypes; 046 047 assert valueParameters.size() == valueParameterTypes.size() : 048 "Value parameters and their types mismatch in sizes: " + valueParameters.size() + " != " + valueParameterTypes.size(); 049 } 050 051 052 @NotNull 053 @Override 054 public DefaultCallArgs generate( 055 @NotNull List<? extends ResolvedValueArgument> valueArgumentsByIndex, 056 @NotNull List<? extends ResolvedValueArgument> valueArgs 057 ) { 058 boolean shouldMarkLineNumbers = this.codegen.isShouldMarkLineNumbers(); 059 this.codegen.setShouldMarkLineNumbers(false); 060 DefaultCallArgs defaultArgs = super.generate(valueArgumentsByIndex, valueArgs); 061 this.codegen.setShouldMarkLineNumbers(shouldMarkLineNumbers); 062 return defaultArgs; 063 } 064 065 @Override 066 protected void generateExpression(int i, @NotNull ExpressionValueArgument argument) { 067 ValueParameterDescriptor parameter = valueParameters.get(i); 068 Type type = valueParameterTypes.get(i); 069 ValueArgument valueArgument = argument.getValueArgument(); 070 assert valueArgument != null; 071 KtExpression argumentExpression = valueArgument.getArgumentExpression(); 072 assert argumentExpression != null : valueArgument.asElement().getText(); 073 callGenerator.genValueAndPut(parameter, argumentExpression, type, i); 074 } 075 076 @Override 077 protected void generateDefault(int i, @NotNull DefaultValueArgument argument) { 078 Type type = valueParameterTypes.get(i); 079 pushDefaultValueOnStack(type, codegen.v); 080 callGenerator.afterParameterPut(type, null, i); 081 } 082 083 @Override 084 protected void generateVararg(int i, @NotNull VarargValueArgument argument) { 085 ValueParameterDescriptor parameter = valueParameters.get(i); 086 Type type = valueParameterTypes.get(i); 087 codegen.genVarargs(argument, parameter.getType()); 088 callGenerator.afterParameterPut(type, null, i); 089 } 090 091 @Override 092 protected void reorderArgumentsIfNeeded(@NotNull List<ArgumentAndDeclIndex> actualArgsWithDeclIndex) { 093 callGenerator.reorderArgumentsIfNeeded(actualArgsWithDeclIndex, valueParameterTypes); 094 } 095 }