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.asm4.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 ParametersBuilder addNextParameter(@NotNull Type type, boolean skipped, @Nullable ParameterInfo original) {
047            addParameter(new ParameterInfo(type, skipped, nextIndex, original != null ? original.getIndex() : -1));
048            return this;
049        }
050    
051        @NotNull
052        public CapturedParamInfo addCapturedParam(
053                @NotNull CapturedParamInfo original,
054                @NotNull String newFieldName
055        ) {
056            CapturedParamInfo info = new CapturedParamInfo(original.desc, newFieldName, original.isSkipped, nextCaptured, original.getIndex());
057            info.setLambda(original.getLambda());
058            return addCapturedParameter(info);
059        }
060    
061        @NotNull
062        public CapturedParamInfo addCapturedParam(
063                @NotNull String fieldName,
064                @NotNull Type type,
065                boolean skipped,
066                @Nullable ParameterInfo original,
067                @NotNull CapturedParamOwner containingLambda
068        ) {
069            CapturedParamInfo info =
070                    new CapturedParamInfo(CapturedParamDesc.createDesc(containingLambda, fieldName, type), skipped, nextCaptured,
071                                          original != null ? original.getIndex() : -1);
072            if (original != null) {
073                info.setLambda(original.getLambda());
074            }
075            return addCapturedParameter(info);
076        }
077    
078        private void addParameter(ParameterInfo info) {
079            params.add(info);
080            nextIndex += info.getType().getSize();
081        }
082    
083        private CapturedParamInfo addCapturedParameter(CapturedParamInfo info) {
084            capturedParams.add(info);
085            nextCaptured += info.getType().getSize();
086            return info;
087        }
088    
089        public List<ParameterInfo> build() {
090            return Collections.unmodifiableList(params);
091        }
092    
093        public List<CapturedParamInfo> buildCaptured() {
094            return Collections.unmodifiableList(capturedParams);
095        }
096    
097        public List<ParameterInfo> buildWithStubs() {
098            return Parameters.addStubs(build());
099        }
100    
101        public List<CapturedParamInfo> buildCapturedWithStubs() {
102            return Parameters.shiftAndAddStubs(buildCaptured(), nextIndex);
103        }
104    
105        public Parameters buildParameters() {
106            return new Parameters(buildWithStubs(), buildCapturedWithStubs());
107        }
108    }