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.jet.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 029 @Nullable 030 private final InliningContext parent; 031 032 public final Map<Integer, LambdaInfo> expressionMap; 033 034 public final GenerationState state; 035 036 public final NameGenerator nameGenerator; 037 038 public final Map<String, String> typeMapping; 039 040 public final ReifiedTypeInliner reifedTypeInliner; 041 042 public final boolean isInliningLambda; 043 044 public final boolean classRegeneration; 045 046 protected InliningContext( 047 @Nullable InliningContext parent, 048 @NotNull Map<Integer, LambdaInfo> map, 049 @NotNull GenerationState state, 050 @NotNull NameGenerator nameGenerator, 051 @NotNull Map<String, String> typeMapping, 052 @NotNull ReifiedTypeInliner reifedTypeInliner, 053 boolean isInliningLambda, 054 boolean classRegeneration 055 ) { 056 this.parent = parent; 057 expressionMap = map; 058 this.state = state; 059 this.nameGenerator = nameGenerator; 060 this.typeMapping = typeMapping; 061 this.reifedTypeInliner = reifedTypeInliner; 062 this.isInliningLambda = isInliningLambda; 063 this.classRegeneration = classRegeneration; 064 } 065 066 public InliningContext subInline(NameGenerator generator) { 067 return subInline(generator, Collections.<String, String>emptyMap()); 068 } 069 070 public InliningContext subInlineLambda(LambdaInfo lambdaInfo) { 071 Map<String, String> map = new HashMap<String, String>(); 072 map.put(lambdaInfo.getLambdaClassType().getInternalName(), null); //mark lambda inlined 073 return subInline(nameGenerator.subGenerator("lambda"), map, true); 074 } 075 076 public InliningContext subInline(NameGenerator generator, Map<String, String> additionalTypeMappings) { 077 return subInline(generator, additionalTypeMappings, isInliningLambda); 078 } 079 080 public InliningContext subInlineWithClassRegeneration(@NotNull NameGenerator generator, 081 @NotNull Map<String, String> additionalTypeMappings, 082 @NotNull AnonymousObjectGeneration anonymousObjectGeneration 083 ) { 084 Map<String, String> newTypeMappings = new HashMap<String, String>(typeMapping); 085 newTypeMappings.putAll(additionalTypeMappings); 086 return new RegenetedClassContext(this, expressionMap, state, generator, 087 newTypeMappings, reifedTypeInliner, isInliningLambda, anonymousObjectGeneration); 088 089 } 090 091 public InliningContext subInline(NameGenerator generator, Map<String, String> additionalTypeMappings, boolean isInliningLambda) { 092 return subInline(generator, additionalTypeMappings, isInliningLambda, classRegeneration); 093 } 094 095 private InliningContext subInline( 096 NameGenerator generator, 097 Map<String, String> additionalTypeMappings, 098 boolean isInliningLambda, 099 boolean isRegeneration 100 ) { 101 Map<String, String> newTypeMappings = new HashMap<String, String>(typeMapping); 102 newTypeMappings.putAll(additionalTypeMappings); 103 return new InliningContext(this, expressionMap, state, generator, 104 newTypeMappings, reifedTypeInliner, isInliningLambda, isRegeneration); 105 } 106 107 public boolean isRoot() { 108 return parent == null; 109 } 110 111 @NotNull 112 public RootInliningContext getRoot() { 113 if (isRoot()) { 114 return (RootInliningContext) this; 115 } 116 else { 117 return parent.getRoot(); 118 } 119 } 120 121 @Nullable 122 public InliningContext getParent() { 123 return parent; 124 } 125 126 public boolean isInliningLambdaRootContext() { 127 //noinspection ConstantConditions 128 return isInliningLambda && !getParent().isInliningLambda; 129 } 130 131 public String getClassNameToInline() { 132 assert parent != null : "At least root context should return proper value"; 133 return parent.getClassNameToInline(); 134 } 135 }