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 DefaultCallMask 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 DefaultCallMask masks = super.generate(valueArgumentsByIndex, valueArgs); 061 this.codegen.setShouldMarkLineNumbers(shouldMarkLineNumbers); 062 return masks; 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 ValueParameterDescriptor parameter = valueParameters.get(i); 079 Type type = valueParameterTypes.get(i); 080 pushDefaultValueOnStack(type, codegen.v); 081 callGenerator.afterParameterPut(type, null, parameter, i); 082 } 083 084 @Override 085 protected void generateVararg(int i, @NotNull VarargValueArgument argument) { 086 ValueParameterDescriptor parameter = valueParameters.get(i); 087 Type type = valueParameterTypes.get(i); 088 codegen.genVarargs(argument, parameter.getType()); 089 callGenerator.afterParameterPut(type, null, parameter, i); 090 } 091 092 @Override 093 protected void reorderArgumentsIfNeeded(@NotNull List<ArgumentAndDeclIndex> actualArgsWithDeclIndex) { 094 callGenerator.reorderArgumentsIfNeeded(actualArgsWithDeclIndex, valueParameterTypes); 095 } 096 }