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.inline; 018 019 import org.jetbrains.annotations.NotNull; 020 import org.jetbrains.annotations.Nullable; 021 import org.jetbrains.kotlin.codegen.StackValue; 022 import org.jetbrains.org.objectweb.asm.Type; 023 024 import java.util.ArrayList; 025 import java.util.Collections; 026 import java.util.List; 027 028 public class ParametersBuilder { 029 030 private final List<ParameterInfo> params = new ArrayList<ParameterInfo>(); 031 private final List<CapturedParamInfo> capturedParams = new ArrayList<CapturedParamInfo>(); 032 033 private int nextIndex = 0; 034 private int nextCaptured = 0; 035 036 @NotNull 037 public static ParametersBuilder newBuilder() { 038 return new ParametersBuilder(); 039 } 040 041 @NotNull 042 public ParameterInfo addThis(@NotNull Type type, boolean skipped) { 043 ParameterInfo info = new ParameterInfo(type, skipped, nextIndex, -1); 044 addParameter(info); 045 return info; 046 } 047 048 @NotNull 049 public ParameterInfo addNextParameter(@NotNull Type type, boolean skipped, @Nullable StackValue remapValue) { 050 return addParameter(new ParameterInfo(type, skipped, nextIndex, remapValue)); 051 } 052 053 @NotNull 054 public CapturedParamInfo addCapturedParam( 055 @NotNull CapturedParamInfo original, 056 @NotNull String newFieldName 057 ) { 058 CapturedParamInfo info = new CapturedParamInfo(original.desc, newFieldName, original.isSkipped, nextCaptured, original.getIndex()); 059 info.setLambda(original.getLambda()); 060 return addCapturedParameter(info); 061 } 062 063 @NotNull 064 public CapturedParamInfo addCapturedParam( 065 @NotNull CapturedParamDesc desc, 066 @NotNull String newFieldName 067 ) { 068 CapturedParamInfo info = new CapturedParamInfo(desc, newFieldName, false, nextCaptured, null); 069 return addCapturedParameter(info); 070 } 071 072 @NotNull 073 public CapturedParamInfo addCapturedParamCopy( 074 @NotNull CapturedParamInfo copyFrom 075 ) { 076 CapturedParamInfo info = copyFrom.newIndex(nextCaptured); 077 return addCapturedParameter(info); 078 } 079 080 @NotNull 081 public CapturedParamInfo addCapturedParam( 082 @NotNull CapturedParamOwner containingLambda, 083 @NotNull String fieldName, 084 @NotNull Type type, 085 boolean skipped, 086 @Nullable ParameterInfo original 087 ) { 088 CapturedParamInfo info = 089 new CapturedParamInfo(CapturedParamDesc.createDesc(containingLambda, fieldName, type), skipped, nextCaptured, 090 original != null ? original.getIndex() : -1); 091 if (original != null) { 092 info.setLambda(original.getLambda()); 093 } 094 return addCapturedParameter(info); 095 } 096 097 @NotNull 098 private ParameterInfo addParameter(ParameterInfo info) { 099 params.add(info); 100 nextIndex += info.getType().getSize(); 101 return info; 102 } 103 104 @NotNull 105 private CapturedParamInfo addCapturedParameter(CapturedParamInfo info) { 106 capturedParams.add(info); 107 nextCaptured += info.getType().getSize(); 108 return info; 109 } 110 111 @NotNull 112 public List<ParameterInfo> listNotCaptured() { 113 return Collections.unmodifiableList(params); 114 } 115 116 @NotNull 117 public List<CapturedParamInfo> listCaptured() { 118 return Collections.unmodifiableList(capturedParams); 119 } 120 121 @NotNull 122 public List<ParameterInfo> listAllParams() { 123 List<ParameterInfo> list = new ArrayList<ParameterInfo>(params); 124 list.addAll(capturedParams); 125 return list; 126 } 127 128 @NotNull 129 private List<ParameterInfo> buildWithStubs() { 130 return Parameters.addStubs(listNotCaptured()); 131 } 132 133 private List<CapturedParamInfo> buildCapturedWithStubs() { 134 return Parameters.shiftAndAddStubs(listCaptured(), nextIndex); 135 } 136 137 public Parameters buildParameters() { 138 return new Parameters(buildWithStubs(), buildCapturedWithStubs()); 139 } 140 141 public int getNextValueParameterIndex() { 142 return nextIndex; 143 } 144 }