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.state.GenerationState;
022
023 import java.util.Collections;
024 import java.util.HashMap;
025 import java.util.Map;
026
027 public class InliningContext {
028 @Nullable
029 private final InliningContext parent;
030
031 private final Map<Integer, LambdaInfo> expressionMap;
032 public final GenerationState state;
033 public final NameGenerator nameGenerator;
034 public final TypeRemapper typeRemapper;
035 public final ReifiedTypeInliner reifiedTypeInliner;
036 public final boolean isInliningLambda;
037 public final boolean classRegeneration;
038
039 public InliningContext(
040 @Nullable InliningContext parent,
041 @NotNull Map<Integer, LambdaInfo> expressionMap,
042 @NotNull GenerationState state,
043 @NotNull NameGenerator nameGenerator,
044 @NotNull TypeRemapper typeRemapper,
045 @NotNull ReifiedTypeInliner reifiedTypeInliner,
046 boolean isInliningLambda,
047 boolean classRegeneration
048 ) {
049 this.parent = parent;
050 this.expressionMap = expressionMap;
051 this.state = state;
052 this.nameGenerator = nameGenerator;
053 this.typeRemapper = typeRemapper;
054 this.reifiedTypeInliner = reifiedTypeInliner;
055 this.isInliningLambda = isInliningLambda;
056 this.classRegeneration = classRegeneration;
057 }
058
059 @NotNull
060 public InliningContext subInline(@NotNull NameGenerator generator) {
061 return subInline(generator, Collections.<String, String>emptyMap(), isInliningLambda);
062 }
063
064 @NotNull
065 public InliningContext subInlineLambda(@NotNull LambdaInfo lambdaInfo) {
066 Map<String, String> map = new HashMap<String, String>();
067 map.put(lambdaInfo.getLambdaClassType().getInternalName(), null); //mark lambda inlined
068 return subInline(nameGenerator.subGenerator("lambda"), map, true);
069 }
070
071 @NotNull
072 public InliningContext subInlineWithClassRegeneration(
073 @NotNull NameGenerator generator,
074 @NotNull Map<String, String> newTypeMappings,
075 @NotNull InlineCallSiteInfo callSiteInfo
076 ) {
077 return new RegeneratedClassContext(
078 this, expressionMap, state, generator, TypeRemapper.createFrom(typeRemapper, newTypeMappings),
079 reifiedTypeInliner, isInliningLambda, callSiteInfo
080 );
081 }
082
083 @NotNull
084 private InliningContext subInline(
085 @NotNull NameGenerator generator, @NotNull Map<String, String> additionalTypeMappings, boolean isInliningLambda
086 ) {
087 //isInliningLambda && !this.isInliningLambda for root inline lambda
088 return new InliningContext(
089 this, expressionMap, state, generator,
090 TypeRemapper.createFrom(
091 typeRemapper,
092 additionalTypeMappings,
093 //root inline lambda
094 isInliningLambda && !this.isInliningLambda
095 ),
096 reifiedTypeInliner, isInliningLambda, classRegeneration
097 );
098 }
099
100 public boolean isRoot() {
101 return parent == null;
102 }
103
104 @NotNull
105 public RootInliningContext getRoot() {
106 //noinspection ConstantConditions
107 return isRoot() ? (RootInliningContext) this : parent.getRoot();
108 }
109
110 @Nullable
111 public InliningContext getParent() {
112 return parent;
113 }
114
115 @NotNull
116 public InlineCallSiteInfo getCallSiteInfo() {
117 assert parent != null : "At least root context should return proper value";
118 return parent.getCallSiteInfo();
119 }
120 }