Better main function recognition and tests

This commit is contained in:
Sergey Mashkov
2015-07-23 21:12:14 +03:00
parent 273e69c02c
commit 8457b53f8b
14 changed files with 217 additions and 58 deletions
@@ -30,8 +30,6 @@ import org.jetbrains.kotlin.codegen.binding.PsiCodegenPredictor;
import org.jetbrains.kotlin.codegen.context.CodegenContext;
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotated;
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor;
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor;
@@ -54,8 +52,6 @@ import org.jetbrains.kotlin.resolve.annotations.AnnotationsPackage;
import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.resolve.constants.StringValue;
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
import org.jetbrains.kotlin.resolve.jvm.JvmClassName;
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType;
@@ -71,7 +67,6 @@ import org.jetbrains.org.objectweb.asm.commons.Method;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isUnit;
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
@@ -716,20 +711,6 @@ public class JetTypeMapper {
}
}
@Nullable
private static String getPlatformName(@NotNull Annotated descriptor) {
AnnotationDescriptor platformNameAnnotation = descriptor.getAnnotations().findAnnotation(new FqName("kotlin.platform.platformName"));
if (platformNameAnnotation == null) return null;
Map<ValueParameterDescriptor, ConstantValue<?>> arguments = platformNameAnnotation.getAllValueArguments();
if (arguments.isEmpty()) return null;
ConstantValue<?> name = arguments.values().iterator().next();
if (!(name instanceof StringValue)) return null;
return ((StringValue) name).getValue();
}
@NotNull
public JvmMethodSignature mapSignature(@NotNull FunctionDescriptor descriptor) {
return mapSignature(descriptor, OwnerKind.IMPLEMENTATION);
@@ -29,13 +29,11 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.annotations.AnnotationsPackage;
import org.jetbrains.kotlin.types.JetType;
import org.jetbrains.kotlin.types.TypeProjection;
import org.jetbrains.kotlin.types.checker.JetTypeChecker;
import org.jetbrains.kotlin.types.Variance;
import java.util.Collection;
import java.util.List;
import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage.getBuiltIns;
public class MainFunctionDetector {
private final NotNullFunction<JetNamedFunction, FunctionDescriptor> getFunctionDescriptor;
@@ -63,9 +61,15 @@ public class MainFunctionDetector {
}
public boolean isMain(@NotNull JetNamedFunction function) {
if (!"main".equals(function.getName())) return false;
if (!"main".equals(function.getName()) && function.getAnnotationEntries().isEmpty()) {
return false;
}
FunctionDescriptor functionDescriptor = getFunctionDescriptor.fun(function);
if (!getJVMFunctionName(functionDescriptor).equals("main")) {
return false;
}
List<ValueParameterDescriptor> parameters = functionDescriptor.getValueParameters();
if (parameters.size() != 1) return false;
@@ -77,7 +81,12 @@ public class MainFunctionDetector {
if (typeArguments.size() != 1) return false;
JetType typeArgument = typeArguments.get(0).getType();
if (!JetTypeChecker.DEFAULT.equalTypes(typeArgument, getBuiltIns(functionDescriptor).getStringType())) return false;
if (!KotlinBuiltIns.isString(typeArgument)) {
return false;
}
if (typeArguments.get(0).getProjectionKind() != Variance.INVARIANT) {
return false;
}
if (DescriptorUtils.isTopLevelDeclaration(functionDescriptor)) return true;
@@ -110,4 +119,14 @@ public class MainFunctionDetector {
}
return null;
}
@NotNull
private static String getJVMFunctionName(FunctionDescriptor functionDescriptor) {
String platformName = DescriptorUtils.getPlatformName(functionDescriptor);
if (platformName != null) {
return platformName;
}
return functionDescriptor.getName().asString();
}
}