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.binding; 018 019 import com.intellij.openapi.util.Pair; 020 import org.jetbrains.annotations.NotNull; 021 import org.jetbrains.annotations.Nullable; 022 import org.jetbrains.asm4.Type; 023 import org.jetbrains.jet.codegen.context.EnclosedValueDescriptor; 024 import org.jetbrains.jet.lang.descriptors.CallableDescriptor; 025 import org.jetbrains.jet.lang.descriptors.ClassDescriptor; 026 import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; 027 import org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor; 028 import org.jetbrains.jet.lang.psi.JetDelegatorToSuperCall; 029 import org.jetbrains.jet.lang.types.JetType; 030 031 import java.util.*; 032 033 public final class MutableClosure implements CalculatedClosure { 034 private final JetDelegatorToSuperCall superCall; 035 036 private final ClassDescriptor enclosingClass; 037 private final CallableDescriptor enclosingReceiverDescriptor; 038 039 private boolean captureThis; 040 private boolean captureReceiver; 041 042 private Map<DeclarationDescriptor, EnclosedValueDescriptor> captureVariables; 043 private List<Pair<String, Type>> recordedFields; 044 045 MutableClosure( 046 JetDelegatorToSuperCall superCall, 047 ClassDescriptor enclosingClass, 048 CallableDescriptor enclosingReceiverDescriptor 049 ) { 050 this.superCall = superCall; 051 this.enclosingClass = enclosingClass; 052 this.enclosingReceiverDescriptor = enclosingReceiverDescriptor; 053 } 054 055 @Nullable 056 @Override 057 public ClassDescriptor getEnclosingClass() { 058 return enclosingClass; 059 } 060 061 @Override 062 public JetDelegatorToSuperCall getSuperCall() { 063 return superCall; 064 } 065 066 @Override 067 public ClassDescriptor getCaptureThis() { 068 return captureThis ? enclosingClass : null; 069 } 070 071 public void setCaptureThis() { 072 this.captureThis = true; 073 } 074 075 @Override 076 public JetType getCaptureReceiverType() { 077 if (captureReceiver) { 078 ReceiverParameterDescriptor parameter = enclosingReceiverDescriptor.getReceiverParameter(); 079 assert parameter != null : "Receiver parameter should exist in " + enclosingReceiverDescriptor; 080 return parameter.getType(); 081 } 082 083 return null; 084 } 085 086 public void setCaptureReceiver() { 087 if (enclosingReceiverDescriptor == null) { 088 throw new IllegalStateException(); 089 } 090 this.captureReceiver = true; 091 } 092 093 @NotNull 094 @Override 095 public Map<DeclarationDescriptor, EnclosedValueDescriptor> getCaptureVariables() { 096 return captureVariables != null ? captureVariables : Collections.<DeclarationDescriptor, EnclosedValueDescriptor>emptyMap(); 097 } 098 099 @NotNull 100 @Override 101 public List<Pair<String, Type>> getRecordedFields() { 102 return recordedFields != null ? recordedFields : Collections.<Pair<String, Type>>emptyList(); 103 } 104 105 public void recordField(String name, Type type) { 106 if (recordedFields == null) { 107 recordedFields = new LinkedList<Pair<String, Type>>(); 108 } 109 recordedFields.add(new Pair<String, Type>(name, type)); 110 } 111 112 public void captureVariable(EnclosedValueDescriptor value) { 113 if (captureVariables == null) { 114 captureVariables = new HashMap<DeclarationDescriptor, EnclosedValueDescriptor>(); 115 } 116 captureVariables.put(value.getDescriptor(), value); 117 } 118 119 public CallableDescriptor getEnclosingReceiverDescriptor() { 120 return enclosingReceiverDescriptor; 121 } 122 }