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