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 }