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.context; 018 019 import kotlin.collections.CollectionsKt; 020 import org.jetbrains.annotations.NotNull; 021 import org.jetbrains.annotations.Nullable; 022 import org.jetbrains.kotlin.codegen.FieldInfo; 023 import org.jetbrains.kotlin.codegen.OwnerKind; 024 import org.jetbrains.kotlin.codegen.state.GenerationState; 025 import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper; 026 import org.jetbrains.kotlin.descriptors.ClassDescriptor; 027 import org.jetbrains.kotlin.descriptors.ScriptDescriptor; 028 import org.jetbrains.kotlin.psi.KtAnonymousInitializer; 029 import org.jetbrains.kotlin.psi.KtDeclaration; 030 import org.jetbrains.kotlin.psi.KtExpression; 031 import org.jetbrains.kotlin.psi.KtScript; 032 import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils; 033 import org.jetbrains.kotlin.resolve.jvm.AsmTypes; 034 035 import java.util.List; 036 037 public class ScriptContext extends ClassContext { 038 private final ScriptDescriptor scriptDescriptor; 039 private final List<ScriptDescriptor> earlierScripts; 040 private final KtExpression lastStatement; 041 042 public ScriptContext( 043 @NotNull KotlinTypeMapper typeMapper, 044 @NotNull ScriptDescriptor scriptDescriptor, 045 @NotNull List<ScriptDescriptor> earlierScripts, 046 @NotNull ClassDescriptor contextDescriptor, 047 @Nullable CodegenContext parentContext 048 ) { 049 super(typeMapper, contextDescriptor, OwnerKind.IMPLEMENTATION, parentContext, null); 050 this.scriptDescriptor = scriptDescriptor; 051 this.earlierScripts = earlierScripts; 052 KtScript script = (KtScript) DescriptorToSourceUtils.getSourceFromDescriptor(scriptDescriptor); 053 assert script != null : "Declaration should be present for script: " + scriptDescriptor; 054 KtDeclaration lastDeclaration = CollectionsKt.lastOrNull(script.getDeclarations()); 055 if (lastDeclaration instanceof KtAnonymousInitializer) { 056 this.lastStatement = ((KtAnonymousInitializer) lastDeclaration).getBody(); 057 } 058 else { 059 this.lastStatement = null; 060 } 061 } 062 063 @NotNull 064 public ScriptDescriptor getScriptDescriptor() { 065 return scriptDescriptor; 066 } 067 068 @NotNull 069 public FieldInfo getResultFieldInfo() { 070 assert getState().getReplSpecific().getShouldGenerateScriptResultValue() : "Should not be called unless 'scriptResultFieldName' is set"; 071 GenerationState state = getState(); 072 String scriptResultFieldName = state.getReplSpecific().getScriptResultFieldName(); 073 assert scriptResultFieldName != null; 074 return FieldInfo.createForHiddenField(state.getTypeMapper().mapClass(scriptDescriptor), AsmTypes.OBJECT_TYPE, scriptResultFieldName); 075 } 076 077 @NotNull 078 public List<ScriptDescriptor> getEarlierScripts() { 079 return earlierScripts; 080 } 081 082 @NotNull 083 public String getScriptFieldName(@NotNull ScriptDescriptor scriptDescriptor) { 084 int index = earlierScripts.indexOf(scriptDescriptor); 085 if (index < 0) { 086 throw new IllegalStateException("Unregistered script: " + scriptDescriptor); 087 } 088 return "script$" + (index + 1); 089 } 090 091 @Nullable 092 public KtExpression getLastStatement() { 093 return lastStatement; 094 } 095 096 @Override 097 public String toString() { 098 return "Script: " + getContextDescriptor().getName().asString(); 099 } 100 }