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 }