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; 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.asm4.commons.Method; 024 import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor; 025 import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; 026 import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; 027 028 import java.util.*; 029 030 public final class MemberMap { 031 private final Map<FunctionDescriptor, Method> methodForFunction = new HashMap<FunctionDescriptor, Method>(); 032 private final Map<PropertyDescriptor, Pair<Type, String>> fieldForProperty = new HashMap<PropertyDescriptor, Pair<Type, String>>(); 033 private final Map<PropertyDescriptor, String> syntheticMethodNameForProperty = new HashMap<PropertyDescriptor, String>(); 034 private final Map<CallableMemberDescriptor, String> srcClassNameForCallable = new HashMap<CallableMemberDescriptor, String>(); 035 private final Set<PropertyDescriptor> staticFieldInOuterClass = new HashSet<PropertyDescriptor>(); 036 037 @NotNull 038 public static MemberMap union(@NotNull Collection<MemberMap> maps) { 039 MemberMap result = new MemberMap(); 040 for (MemberMap map : maps) { 041 for (Map.Entry<FunctionDescriptor, Method> entry : map.methodForFunction.entrySet()) { 042 result.recordMethodOfDescriptor(entry.getKey(), entry.getValue()); 043 } 044 045 for (Map.Entry<PropertyDescriptor, Pair<Type, String>> entry : map.fieldForProperty.entrySet()) { 046 result.recordFieldOfProperty(entry.getKey(), entry.getValue().first, entry.getValue().second); 047 } 048 049 for (Map.Entry<PropertyDescriptor, String> entry : map.syntheticMethodNameForProperty.entrySet()) { 050 result.recordSyntheticMethodNameOfProperty(entry.getKey(), entry.getValue()); 051 } 052 053 for (Map.Entry<CallableMemberDescriptor, String> entry : map.srcClassNameForCallable.entrySet()) { 054 result.recordSrcClassNameForCallable(entry.getKey(), entry.getValue()); 055 } 056 057 for (PropertyDescriptor property : map.staticFieldInOuterClass) { 058 result.recordStaticFieldInOuterClass(property); 059 } 060 } 061 062 return result; 063 } 064 065 public void recordMethodOfDescriptor(@NotNull FunctionDescriptor descriptor, @NotNull Method method) { 066 Method old = methodForFunction.put(descriptor, method); 067 assert old == null : "Duplicate method for callable member: " + descriptor + "; " + old; 068 } 069 070 public void recordFieldOfProperty(@NotNull PropertyDescriptor descriptor, @NotNull Type type, @NotNull String fieldName) { 071 Pair<Type, String> old = fieldForProperty.put(descriptor, Pair.create(type, fieldName)); 072 assert old == null : "Duplicate field for property: " + descriptor + "; " + old; 073 } 074 075 public void recordSyntheticMethodNameOfProperty(@NotNull PropertyDescriptor descriptor, @NotNull String name) { 076 String old = syntheticMethodNameForProperty.put(descriptor, name); 077 assert old == null : "Duplicate synthetic method for property: " + descriptor + "; " + old; 078 } 079 080 public void recordSrcClassNameForCallable(@NotNull CallableMemberDescriptor descriptor, @NotNull String name) { 081 String old = srcClassNameForCallable.put(descriptor, name); 082 assert old == null : "Duplicate src class name for callable: " + descriptor + "; " + old; 083 } 084 085 public void recordStaticFieldInOuterClass(@NotNull PropertyDescriptor property) { 086 boolean added = staticFieldInOuterClass.add(property); 087 assert added : "Duplicate static field in outer class: " + property; 088 } 089 090 @Nullable 091 public Method getMethodOfDescriptor(@NotNull FunctionDescriptor descriptor) { 092 return methodForFunction.get(descriptor); 093 } 094 095 @Nullable 096 public Pair<Type, String> getFieldOfProperty(@NotNull PropertyDescriptor descriptor) { 097 return fieldForProperty.get(descriptor); 098 } 099 100 @Nullable 101 public String getSyntheticMethodNameOfProperty(@NotNull PropertyDescriptor descriptor) { 102 return syntheticMethodNameForProperty.get(descriptor); 103 } 104 105 @Nullable 106 public String getSrcClassNameOfCallable(@NotNull CallableMemberDescriptor descriptor) { 107 return srcClassNameForCallable.get(descriptor); 108 } 109 110 public boolean isStaticFieldInOuterClass(@NotNull PropertyDescriptor property) { 111 return staticFieldInOuterClass.contains(property); 112 } 113 114 @Override 115 public String toString() { 116 return "Functions: " + methodForFunction.size() + 117 ", fields: " + fieldForProperty.size() + 118 ", synthetic methods: " + syntheticMethodNameForProperty.size() + 119 ", src class names: " + srcClassNameForCallable.size(); 120 } 121 }