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.signature; 018 019 import org.jetbrains.annotations.NotNull; 020 import org.jetbrains.annotations.Nullable; 021 import org.jetbrains.kotlin.name.Name; 022 import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature; 023 import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind; 024 import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature; 025 import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature; 026 import org.jetbrains.kotlin.types.Variance; 027 import org.jetbrains.org.objectweb.asm.Type; 028 import org.jetbrains.org.objectweb.asm.commons.Method; 029 030 import java.util.ArrayList; 031 import java.util.List; 032 033 public class JvmSignatureWriter { 034 035 private final List<JvmMethodParameterSignature> kotlinParameterTypes = new ArrayList<JvmMethodParameterSignature>(); 036 037 private int jvmCurrentTypeArrayLevel; 038 private Type jvmCurrentType; 039 private Type jvmReturnType; 040 041 private JvmMethodParameterKind currentParameterKind; 042 043 private int currentSignatureSize = 0; 044 045 /** 046 * Shortcut 047 */ 048 public void writeAsmType(Type asmType) { 049 switch (asmType.getSort()) { 050 case Type.OBJECT: 051 writeClassBegin(asmType); 052 writeClassEnd(); 053 return; 054 case Type.ARRAY: 055 writeArrayType(); 056 writeAsmType(asmType.getElementType()); 057 writeArrayEnd(); 058 return; 059 default: 060 writeAsmType0(asmType); 061 } 062 } 063 064 private String makeArrayPrefix() { 065 StringBuilder sb = new StringBuilder(); 066 for (int i = 0; i < jvmCurrentTypeArrayLevel; ++i) { 067 sb.append('['); 068 } 069 return sb.toString(); 070 } 071 072 protected void writeAsmType0(Type type) { 073 if (jvmCurrentType == null) { 074 jvmCurrentType = Type.getType(makeArrayPrefix() + type.getDescriptor()); 075 } 076 } 077 078 public void writeClassBegin(Type asmType) { 079 writeAsmType0(asmType); 080 } 081 082 public void writeOuterClassBegin(Type resultingAsmType, String outerInternalName) { 083 writeAsmType0(resultingAsmType); 084 } 085 086 public void writeInnerClass(String name) { 087 } 088 089 public void writeClassEnd() { 090 } 091 092 public void writeArrayType() { 093 if (jvmCurrentType == null) { 094 ++jvmCurrentTypeArrayLevel; 095 } 096 } 097 098 public void writeArrayEnd() { 099 } 100 101 public void writeTypeArgument(@NotNull Variance projectionKind) { 102 } 103 104 public void writeUnboundedWildcard() { 105 } 106 107 public void writeTypeArgumentEnd() { 108 } 109 110 public void writeTypeVariable(Name name, Type asmType) { 111 writeAsmType0(asmType); 112 } 113 114 public void writeFormalTypeParameter(String name) { 115 } 116 117 public void writeClassBound() { 118 } 119 120 public void writeClassBoundEnd() { 121 } 122 123 public void writeInterfaceBound() { 124 } 125 126 public void writeInterfaceBoundEnd() { 127 } 128 129 public void writeParametersStart() { 130 // hacks 131 jvmCurrentType = null; 132 jvmCurrentTypeArrayLevel = 0; 133 } 134 135 public void writeParameterType(JvmMethodParameterKind parameterKind) { 136 currentParameterKind = parameterKind; 137 } 138 139 public void writeParameterTypeEnd() { 140 kotlinParameterTypes.add(new JvmMethodParameterSignature(jvmCurrentType, currentParameterKind)); 141 currentSignatureSize += jvmCurrentType.getSize(); 142 143 currentParameterKind = null; 144 jvmCurrentType = null; 145 jvmCurrentTypeArrayLevel = 0; 146 } 147 148 public void writeReturnType() { 149 } 150 151 public void writeReturnTypeEnd() { 152 jvmReturnType = jvmCurrentType; 153 jvmCurrentType = null; 154 jvmCurrentTypeArrayLevel = 0; 155 } 156 157 public void writeSuperclass() { 158 } 159 160 public void writeSuperclassEnd() { 161 } 162 163 public void writeInterface() { 164 } 165 166 public void writeInterfaceEnd() { 167 } 168 169 @Nullable 170 public String makeJavaGenericSignature() { 171 return null; 172 } 173 174 @NotNull 175 public JvmMethodGenericSignature makeJvmMethodSignature(@NotNull String name) { 176 List<Type> types = new ArrayList<Type>(kotlinParameterTypes.size()); 177 for (JvmMethodParameterSignature parameter : kotlinParameterTypes) { 178 types.add(parameter.getAsmType()); 179 } 180 Method asmMethod = new Method(name, jvmReturnType, types.toArray(new Type[types.size()])); 181 return new JvmMethodGenericSignature(asmMethod, kotlinParameterTypes, makeJavaGenericSignature()); 182 } 183 184 public int getCurrentSignatureSize() { 185 return currentSignatureSize; 186 } 187 188 public boolean skipGenericSignature() { 189 return true; 190 } 191 192 @Override 193 public String toString() { 194 return "empty"; 195 } 196 } 197