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