getting rid of TypeInfo
This commit is contained in:
@@ -43,16 +43,22 @@ public abstract class AnnotationCodegen {
|
||||
|
||||
for (AnnotationDescriptor annotationDescriptor : annotations) {
|
||||
List<CompileTimeConstant<?>> valueArguments = annotationDescriptor.getValueArguments();
|
||||
if(!valueArguments.isEmpty()) {
|
||||
throw new UnsupportedOperationException("Only annotations without values are supported by backend so far");
|
||||
}
|
||||
|
||||
JetType type = annotationDescriptor.getType();
|
||||
ClassifierDescriptor classifierDescriptor = type.getConstructor().getDeclarationDescriptor();
|
||||
RetentionPolicy rp = getRetentionPolicy(classifierDescriptor, typeMapper);
|
||||
if(rp != RetentionPolicy.SOURCE) {
|
||||
String internalName = typeMapper.mapType(type).getDescriptor();
|
||||
AnnotationVisitor annotationVisitor = visitAnnotation(internalName, rp == RetentionPolicy.RUNTIME);
|
||||
|
||||
if(!valueArguments.isEmpty()) {
|
||||
// todo: temporary hack for intrinsics in stdlib
|
||||
if(valueArguments.size()==1 && "intrinsic".equals(annotationDescriptor.getType().getConstructor().getDeclarationDescriptor().getName())) {
|
||||
annotationVisitor.visit("value", valueArguments.get(0).getValue());
|
||||
}
|
||||
else
|
||||
throw new UnsupportedOperationException("Only annotations without values are supported by backend so far");
|
||||
}
|
||||
|
||||
annotationVisitor.visitEnd();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -366,12 +366,6 @@ public class BothSignatureWriter {
|
||||
transitionState(State.PARAMETER, State.PARAMETERS);
|
||||
}
|
||||
|
||||
public void writeTypeInfoParameter() {
|
||||
writeParameterType(JvmMethodParameterKind.TYPE_INFO);
|
||||
writeAsmType(JetTypeMapper.TYPE_TYPEINFO, false);
|
||||
writeParameterTypeEnd();
|
||||
}
|
||||
|
||||
public void writeReturnType() {
|
||||
transitionState(State.PARAMETERS, State.RETURN_TYPE);
|
||||
|
||||
|
||||
@@ -296,9 +296,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
|
||||
iv.load(0, Type.getObjectType(funClass));
|
||||
// expressionCodegen.generateTypeInfo(new ProjectionErasingJetType(returnType));
|
||||
iv.aconst(null); // @todo
|
||||
iv.invokespecial(funClass, "<init>", "(Ljet/TypeInfo;)V");
|
||||
iv.invokespecial(funClass, "<init>", "()V");
|
||||
|
||||
i = 1;
|
||||
for (Type type : argTypes) {
|
||||
|
||||
@@ -74,34 +74,6 @@ public class CodegenUtil {
|
||||
return (ClassDescriptor) outerDescriptor;
|
||||
}
|
||||
|
||||
public static boolean hasDerivedTypeInfoField(JetType type) {
|
||||
for (JetType jetType : type.getConstructor().getSupertypes()) {
|
||||
if(hasTypeInfoField(jetType))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean requireTypeInfoConstructorArg(JetType type) {
|
||||
for (TypeParameterDescriptor parameter : type.getConstructor().getParameters()) {
|
||||
if(parameter.isReified())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean hasTypeInfoField(JetType type) {
|
||||
if(isInterface(type))
|
||||
return false;
|
||||
|
||||
if(requireTypeInfoConstructorArg(type))
|
||||
return true;
|
||||
|
||||
return hasDerivedTypeInfoField(type);
|
||||
}
|
||||
|
||||
public static NamedFunctionDescriptor createInvoke(FunctionDescriptor fd) {
|
||||
int arity = fd.getValueParameters().size();
|
||||
NamedFunctionDescriptorImpl invokeDescriptor = new NamedFunctionDescriptorImpl(
|
||||
|
||||
@@ -41,12 +41,6 @@ public class ConstructorFrameMap extends FrameMap {
|
||||
}
|
||||
}
|
||||
|
||||
if (classDescriptor != null) {
|
||||
if (CodegenUtil.requireTypeInfoConstructorArg(classDescriptor.getDefaultType())) {
|
||||
myTypeInfoIndex = enterTemp();
|
||||
}
|
||||
}
|
||||
|
||||
List<Type> explicitArgTypes = callableMethod.getValueParameterTypes();
|
||||
|
||||
List<ValueParameterDescriptor> paramDescrs = descriptor != null
|
||||
|
||||
@@ -1037,8 +1037,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
}
|
||||
final StackValue.Property iValue = intermediateValueForProperty(propertyDescriptor, directToField, isSuper ? (JetSuperExpression)r : null);
|
||||
if(!directToField && resolvedCall != null && !isSuper) {
|
||||
receiver.put(propertyDescriptor.getReceiverParameter().exists() || isStatic? receiver.type : Type.getObjectType(iValue.methodOwner), v);
|
||||
pushTypeArguments(resolvedCall);
|
||||
receiver.put(propertyDescriptor.getReceiverParameter().exists() || isStatic
|
||||
? receiver.type
|
||||
: Type.getObjectType(iValue.methodOwner), v);
|
||||
}
|
||||
else {
|
||||
if (!isStatic) {
|
||||
@@ -1090,7 +1091,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
|
||||
if (descriptor instanceof TypeParameterDescriptor) {
|
||||
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) descriptor;
|
||||
loadTypeParameterTypeInfo(typeParameterDescriptor, null);
|
||||
v.invokevirtual("jet/TypeInfo", "getClassObject", "()Ljava/lang/Object;");
|
||||
v.checkcast(asmType(typeParameterDescriptor.getClassObjectType()));
|
||||
|
||||
@@ -1355,7 +1355,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
}
|
||||
}
|
||||
|
||||
pushTypeArguments(resolvedCall);
|
||||
int mask = pushMethodArguments(expression, callableMethod.getValueParameterTypes());
|
||||
if(mask == 0)
|
||||
callableMethod.invoke(v);
|
||||
@@ -2000,7 +1999,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
receiver.put(receiver.type, v);
|
||||
}
|
||||
|
||||
pushTypeArguments(resolvedCall);
|
||||
pushMethodArguments(resolvedCall, callable.getValueParameterTypes());
|
||||
callable.invoke(v);
|
||||
if (keepReturnValue) {
|
||||
@@ -2095,7 +2093,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference());
|
||||
assert resolvedCall != null;
|
||||
genThisAndReceiverFromResolvedCall(StackValue.none(), resolvedCall, callable);
|
||||
pushTypeArguments(resolvedCall);
|
||||
pushMethodArguments(resolvedCall, callable.getValueParameterTypes());
|
||||
callable.invoke(v);
|
||||
return returnValueAsStackValue(op, callable.getSignature().getAsmMethod().getReturnType());
|
||||
@@ -2270,36 +2267,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
return StackValue.onStack(type);
|
||||
}
|
||||
|
||||
private void pushTypeArguments(ResolvedCall<? extends CallableDescriptor> resolvedCall) {
|
||||
if(resolvedCall != null) {
|
||||
if(resolvedCall.getResultingDescriptor() instanceof ConstructorDescriptor) {
|
||||
ConstructorDescriptor constructorDescriptor = (ConstructorDescriptor) resolvedCall.getResultingDescriptor();
|
||||
ClassDescriptor containingDeclaration = constructorDescriptor.getContainingDeclaration();
|
||||
if(CodegenUtil.requireTypeInfoConstructorArg(containingDeclaration.getDefaultType())) {
|
||||
generateTypeInfo(containingDeclaration.getDefaultType(), resolvedCall.getTypeArguments());
|
||||
}
|
||||
}
|
||||
else {
|
||||
Map<TypeParameterDescriptor, JetType> typeArguments = resolvedCall.getTypeArguments();
|
||||
CallableDescriptor resultingDescriptor = resolvedCall.getCandidateDescriptor();
|
||||
for (TypeParameterDescriptor typeParameterDescriptor : resultingDescriptor.getTypeParameters()) {
|
||||
if(typeParameterDescriptor.isReified()) {
|
||||
JetType jetType = typeArguments.get(typeParameterDescriptor);
|
||||
generateTypeInfo(jetType, typeArguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
public void pushTypeArgument(JetTypeProjection jetTypeArgument) {
|
||||
JetType typeArgument = bindingContext.get(BindingContext.TYPE, jetTypeArgument.getTypeReference());
|
||||
generateTypeInfo(typeArgument, null);
|
||||
}
|
||||
|
||||
private Type generateJavaConstructorCall(JetCallExpression expression) {
|
||||
JetExpression callee = expression.getCalleeExpression();
|
||||
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, callee);
|
||||
@@ -2337,6 +2304,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
}
|
||||
|
||||
if(isArray) {
|
||||
gen(args.get(0), Type.INT_TYPE);
|
||||
v.newarray(boxType(asmType(arrayType.getArguments().get(0).getType())));
|
||||
/*
|
||||
JetType elementType = typeMapper.getGenericsElementType(arrayType);
|
||||
if(elementType != null) {
|
||||
generateTypeInfo(elementType, null);
|
||||
@@ -2347,6 +2317,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
gen(args.get(0), Type.INT_TYPE);
|
||||
v.newarray(boxType(asmType(arrayType.getArguments().get(0).getType())));
|
||||
}
|
||||
*/
|
||||
}
|
||||
else {
|
||||
Type type = typeMapper.mapType(arrayType, OwnerKind.IMPLEMENTATION);
|
||||
@@ -2441,12 +2412,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
if(getterDescriptor.getReceiverParameter().exists()) {
|
||||
index++;
|
||||
}
|
||||
for (TypeParameterDescriptor typeParameterDescriptor : resolvedGetCall.getCandidateDescriptor().getTypeParameters()) {
|
||||
if(typeParameterDescriptor.isReified()) {
|
||||
generateTypeInfo(resolvedGetCall.getTypeArguments().get(typeParameterDescriptor), null);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
asmType = accessor.getSignature().getAsmMethod().getReturnType();
|
||||
}
|
||||
else {
|
||||
@@ -2461,12 +2426,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
if(setterDescriptor.getReceiverParameter().exists()) {
|
||||
index++;
|
||||
}
|
||||
for (TypeParameterDescriptor typeParameterDescriptor : setterDescriptor.getOriginal().getTypeParameters()) {
|
||||
if(typeParameterDescriptor.isReified()) {
|
||||
generateTypeInfo(resolvedSetCall.getTypeArguments().get(typeParameterDescriptor), null);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
asmType = argumentTypes[argumentTypes.length-1];
|
||||
}
|
||||
|
||||
@@ -2712,183 +2671,30 @@ If finally block is present, its last expression is the value of try expression.
|
||||
return StackValue.onStack(Type.BOOLEAN_TYPE);
|
||||
}
|
||||
|
||||
public boolean hasTypeInfoForInstanceOf(JetType type) {
|
||||
DeclarationDescriptor declarationDescriptor = type.getConstructor().getDeclarationDescriptor();
|
||||
if(declarationDescriptor instanceof TypeParameterDescriptor)
|
||||
return true;
|
||||
|
||||
assert declarationDescriptor != null;
|
||||
ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor.getOriginal();
|
||||
if(classDescriptor.equals(state.getStandardLibrary().getArray())) {
|
||||
return hasTypeInfoForInstanceOf(type.getArguments().get(0).getType());
|
||||
}
|
||||
|
||||
for (int i = 0; i < type.getArguments().size(); i++) {
|
||||
TypeParameterDescriptor typeParameterDescriptor = classDescriptor.getTypeConstructor().getParameters().get(i);
|
||||
if(typeParameterDescriptor.isReified()) {
|
||||
TypeProjection typeProjection = type.getArguments().get(i);
|
||||
if( !typeProjection.getType().equals(typeParameterDescriptor.getUpperBoundsAsType())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void generateInstanceOf(StackValue expressionToGen, JetType jetType, boolean leaveExpressionOnStack) {
|
||||
if (!hasTypeInfoForInstanceOf(jetType)) {
|
||||
expressionToGen.put(TYPE_OBJECT, v);
|
||||
if (leaveExpressionOnStack) {
|
||||
v.dup();
|
||||
}
|
||||
Type type = boxType(asmType(jetType));
|
||||
if(jetType.isNullable()) {
|
||||
Label nope = new Label();
|
||||
Label end = new Label();
|
||||
expressionToGen.put(TYPE_OBJECT, v);
|
||||
if (leaveExpressionOnStack) {
|
||||
v.dup();
|
||||
}
|
||||
Type type = boxType(asmType(jetType));
|
||||
if(jetType.isNullable()) {
|
||||
Label nope = new Label();
|
||||
Label end = new Label();
|
||||
|
||||
v.dup();
|
||||
v.ifnull(nope);
|
||||
v.instanceOf(type);
|
||||
v.goTo(end);
|
||||
v.mark(nope);
|
||||
v.pop();
|
||||
v.iconst(1);
|
||||
v.mark(end);
|
||||
}
|
||||
else {
|
||||
v.instanceOf(type);
|
||||
}
|
||||
v.dup();
|
||||
v.ifnull(nope);
|
||||
v.instanceOf(type);
|
||||
v.goTo(end);
|
||||
v.mark(nope);
|
||||
v.pop();
|
||||
v.iconst(1);
|
||||
v.mark(end);
|
||||
}
|
||||
else {
|
||||
generateTypeInfo(jetType, null);
|
||||
expressionToGen.put(TYPE_OBJECT, v);
|
||||
if (leaveExpressionOnStack) {
|
||||
v.dupX1();
|
||||
}
|
||||
v.invokevirtual("jet/TypeInfo", "isInstance", "(Ljava/lang/Object;)Z");
|
||||
v.instanceOf(type);
|
||||
}
|
||||
}
|
||||
|
||||
public void generateTypeInfo(JetType jetType, Map<TypeParameterDescriptor, JetType> typeArguments) {
|
||||
String knownTypeInfo = typeMapper.isKnownTypeInfo(jetType);
|
||||
if(knownTypeInfo != null) {
|
||||
v.getstatic("jet/TypeInfo", knownTypeInfo, "Ljet/TypeInfo;");
|
||||
return;
|
||||
}
|
||||
|
||||
DeclarationDescriptor declarationDescriptor = jetType.getConstructor().getDeclarationDescriptor();
|
||||
if (declarationDescriptor instanceof TypeParameterDescriptor) {
|
||||
loadTypeParameterTypeInfo((TypeParameterDescriptor) declarationDescriptor, typeArguments);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!CodegenUtil.hasTypeInfoField(jetType) && !(bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, jetType.getConstructor().getDeclarationDescriptor()) instanceof PsiClass)) {
|
||||
// TODO: we need some better checks here
|
||||
v.getstatic(typeMapper.mapType(jetType, OwnerKind.IMPLEMENTATION).getInternalName(), "$staticTypeInfo", "Ljet/TypeInfo;");
|
||||
return;
|
||||
}
|
||||
|
||||
boolean hasUnsubstituted = TypeUtils.hasUnsubstitutedTypeParameters(jetType);
|
||||
if(!hasUnsubstituted) {
|
||||
int typeInfoConstantIndex = context.getTypeInfoConstantIndex(jetType);
|
||||
v.invokestatic(context.getNamespaceClassName(), "$getCachedTypeInfo$" + typeInfoConstantIndex, "()Ljet/TypeInfo;");
|
||||
return;
|
||||
}
|
||||
|
||||
final Type jvmType = asmType(jetType);
|
||||
|
||||
v.aconst(jvmType);
|
||||
v.iconst(jetType.isNullable()?1:0);
|
||||
List<TypeProjection> arguments = jetType.getArguments();
|
||||
if (arguments.size() > 0) {
|
||||
v.iconst(arguments.size());
|
||||
v.newarray(TYPE_TYPEINFOPROJECTION);
|
||||
|
||||
for (int i = 0, argumentsSize = arguments.size(); i < argumentsSize; i++) {
|
||||
TypeProjection argument = arguments.get(i);
|
||||
v.dup();
|
||||
v.iconst(i);
|
||||
generateTypeInfo(argument.getType(), typeArguments);
|
||||
genTypeInfoToProjection(v, argument.getProjectionKind());
|
||||
v.astore(TYPE_OBJECT);
|
||||
}
|
||||
v.invokestatic("jet/TypeInfo", JvmStdlibNames.JET_OBJECT_GET_TYPEINFO_METHOD, "(Ljava/lang/Class;Z[Ljet/typeinfo/TypeInfoProjection;)Ljet/TypeInfo;");
|
||||
}
|
||||
else {
|
||||
v.invokestatic("jet/TypeInfo", JvmStdlibNames.JET_OBJECT_GET_TYPEINFO_METHOD, "(Ljava/lang/Class;Z)Ljet/TypeInfo;");
|
||||
}
|
||||
}
|
||||
|
||||
public static void genTypeInfoToProjection(InstructionAdapter v, Variance variance) {
|
||||
if(variance == Variance.INVARIANT)
|
||||
v.checkcast(TYPE_TYPEINFOPROJECTION);
|
||||
else if(variance == Variance.IN_VARIANCE)
|
||||
v.invokestatic("jet/TypeInfo", "inProjection", "(Ljet/TypeInfo;)Ljet/typeinfo/TypeInfoProjection;");
|
||||
else if(variance == Variance.OUT_VARIANCE)
|
||||
v.invokestatic("jet/TypeInfo", "outProjection", "(Ljet/TypeInfo;)Ljet/typeinfo/TypeInfoProjection;");
|
||||
else
|
||||
throw new UnsupportedOperationException(variance.toString());
|
||||
}
|
||||
|
||||
private void loadTypeParameterTypeInfo(TypeParameterDescriptor typeParameterDescriptor, @Nullable Map<TypeParameterDescriptor, JetType> typeArguments) {
|
||||
final StackValue value = typeParameterExpressions.get(typeParameterDescriptor);
|
||||
if (value != null) {
|
||||
value.put(TYPE_TYPEINFO, v);
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeArguments != null) {
|
||||
JetType jetType = typeArguments.get(typeParameterDescriptor);
|
||||
if(jetType != null && !jetType.equals(typeParameterDescriptor.getDefaultType())) {
|
||||
generateTypeInfo(jetType, typeArguments);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DeclarationDescriptor containingDeclaration = typeParameterDescriptor.getContainingDeclaration();
|
||||
if (context.getThisDescriptor() != null) {
|
||||
ClassDescriptor descriptor = context.getThisDescriptor();
|
||||
assert containingDeclaration != null;
|
||||
JetType defaultType = ((ClassDescriptor)containingDeclaration).getDefaultType();
|
||||
Type ownerType = asmType(defaultType);
|
||||
ownerType = boxType(ownerType);
|
||||
if (containingDeclaration == context.getThisDescriptor()) {
|
||||
if(!CodegenUtil.isInterface(descriptor)) {
|
||||
if (CodegenUtil.hasTypeInfoField(defaultType)) {
|
||||
if(!(context instanceof CodegenContext.ConstructorContext)) {
|
||||
v.load(0, TYPE_OBJECT);
|
||||
v.getfield(ownerType.getInternalName(), JvmAbi.TYPE_INFO_FIELD, "Ljet/TypeInfo;");
|
||||
}
|
||||
else {
|
||||
v.load(((ConstructorFrameMap)myFrameMap).getTypeInfoIndex(), TYPE_OBJECT);
|
||||
}
|
||||
}
|
||||
else {
|
||||
v.getstatic(ownerType.getInternalName(), JvmAbi.TYPE_INFO_FIELD, "Ljet/TypeInfo;");
|
||||
}
|
||||
}
|
||||
else {
|
||||
v.load(0, TYPE_OBJECT);
|
||||
v.invokeinterface(TYPE_JET_OBJECT.getInternalName(), JvmStdlibNames.JET_OBJECT_GET_TYPEINFO_METHOD, "()Ljet/TypeInfo;");
|
||||
}
|
||||
}
|
||||
else {
|
||||
v.load(0, TYPE_OBJECT);
|
||||
while(descriptor != containingDeclaration) {
|
||||
descriptor = CodegenUtil.getOuterClassDescriptor(descriptor);
|
||||
v.invokeinterface(TYPE_JET_OBJECT.getInternalName(), JvmStdlibNames.JET_OBJECT_GET_OUTER_OBJECT_METHOD, "()Ljet/JetObject;");
|
||||
}
|
||||
v.invokeinterface(TYPE_JET_OBJECT.getInternalName(), JvmStdlibNames.JET_OBJECT_GET_TYPEINFO_METHOD, "()Ljet/TypeInfo;");
|
||||
}
|
||||
v.aconst(ownerType);
|
||||
v.iconst(typeParameterDescriptor.getIndex());
|
||||
v.invokevirtual("jet/TypeInfo", "getArgumentType", "(Ljava/lang/Class;I)Ljet/TypeInfo;");
|
||||
return;
|
||||
}
|
||||
throw new UnsupportedOperationException("don't know what this type parameter resolves to");
|
||||
}
|
||||
|
||||
@Override
|
||||
public StackValue visitWhenExpression(JetWhenExpression expression, StackValue receiver) {
|
||||
JetExpression expr = expression.getSubjectExpression();
|
||||
@@ -3012,7 +2818,7 @@ If finally block is present, its last expression is the value of try expression.
|
||||
|
||||
final String className = "jet/Tuple" + entries.size();
|
||||
Type tupleType = Type.getObjectType(className);
|
||||
StringBuilder signature = new StringBuilder("(Ljet/TypeInfo;");
|
||||
StringBuilder signature = new StringBuilder("(");
|
||||
for (int i = 0; i != entries.size(); ++i) {
|
||||
signature.append("Ljava/lang/Object;");
|
||||
}
|
||||
@@ -3020,7 +2826,6 @@ If finally block is present, its last expression is the value of try expression.
|
||||
|
||||
v.anew(tupleType);
|
||||
v.dup();
|
||||
generateTypeInfo(new ProjectionErasingJetType(bindingContext.get(BindingContext.EXPRESSION_TYPE, expression)), null);
|
||||
for (JetExpression entry : entries) {
|
||||
gen(entry, TYPE_OBJECT);
|
||||
}
|
||||
|
||||
@@ -146,14 +146,6 @@ public class FunctionCodegen {
|
||||
}
|
||||
av.visitEnd();
|
||||
}
|
||||
for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
|
||||
if (!typeParameterDescriptor.isReified()) {
|
||||
continue;
|
||||
}
|
||||
AnnotationVisitor av = mv.visitParameterAnnotation(start++, JvmStdlibNames.JET_TYPE_PARAMETER.getDescriptor(), true);
|
||||
av.visit(JvmStdlibNames.JET_TYPE_PARAMETER_NAME_FIELD, typeParameterDescriptor.getName());
|
||||
av.visitEnd();
|
||||
}
|
||||
for(int i = 0; i != paramDescrs.size(); ++i) {
|
||||
AnnotationVisitor av = mv.visitParameterAnnotation(i + start, JvmStdlibNames.JET_VALUE_PARAMETER.getDescriptor(), true);
|
||||
ValueParameterDescriptor parameterDescriptor = paramDescrs.get(i);
|
||||
@@ -192,15 +184,6 @@ public class FunctionCodegen {
|
||||
if(receiverParameter.exists())
|
||||
add++;
|
||||
|
||||
for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
|
||||
if (!typeParameterDescriptor.isReified()) {
|
||||
continue;
|
||||
}
|
||||
int slot = frameMap.enterTemp();
|
||||
add++;
|
||||
codegen.addTypeParameter(typeParameterDescriptor, StackValue.local(slot, JetTypeMapper.TYPE_TYPEINFO));
|
||||
}
|
||||
|
||||
for (int i = 0; i < paramDescrs.size(); i++) {
|
||||
ValueParameterDescriptor parameter = paramDescrs.get(i);
|
||||
frameMap.enter(parameter, argTypes[i+add].getSize());
|
||||
@@ -255,10 +238,6 @@ public class FunctionCodegen {
|
||||
k += type.getSize();
|
||||
}
|
||||
|
||||
for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
|
||||
mv.visitLocalVariable(typeParameterDescriptor.getName(), JetTypeMapper.TYPE_TYPEINFO.getDescriptor(), null, methodBegin, methodEnd, k++);
|
||||
}
|
||||
|
||||
for (ValueParameterDescriptor parameter : paramDescrs) {
|
||||
Type type = typeMapper.mapType(parameter.getOutType());
|
||||
// TODO: specify signature
|
||||
@@ -361,13 +340,6 @@ public class FunctionCodegen {
|
||||
var += receiverType.getSize();
|
||||
}
|
||||
|
||||
List<TypeParameterDescriptor> typeParameters = functionDescriptor.getTypeParameters();
|
||||
for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
|
||||
if(typeParameterDescriptor.isReified()) {
|
||||
codegen.addTypeParameter(typeParameterDescriptor, StackValue.local(var++, JetTypeMapper.TYPE_TYPEINFO));
|
||||
}
|
||||
}
|
||||
|
||||
Type[] argTypes = jvmSignature.getArgumentTypes();
|
||||
List<ValueParameterDescriptor> paramDescrs = functionDescriptor.getValueParameters();
|
||||
for (int i = 0; i < paramDescrs.size(); i++) {
|
||||
@@ -388,12 +360,6 @@ public class FunctionCodegen {
|
||||
}
|
||||
|
||||
int extra = hasReceiver ? 1 : 0;
|
||||
for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
|
||||
if(typeParameterDescriptor.isReified()) {
|
||||
iv.load(var++, JetTypeMapper.TYPE_OBJECT);
|
||||
extra++;
|
||||
}
|
||||
}
|
||||
|
||||
Type[] argumentTypes = jvmSignature.getArgumentTypes();
|
||||
for (int index = 0; index < paramDescrs.size(); index++) {
|
||||
|
||||
@@ -233,8 +233,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
@Override
|
||||
protected void generateSyntheticParts() {
|
||||
generateGetTypeInfo();
|
||||
|
||||
generateFieldForObjectInstance();
|
||||
generateFieldForClassObject();
|
||||
|
||||
@@ -414,10 +412,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
signatureWriter.writeParameterTypeEnd();
|
||||
}
|
||||
|
||||
if (CodegenUtil.requireTypeInfoConstructorArg(descriptor.getDefaultType())) {
|
||||
signatureWriter.writeTypeInfoParameter();
|
||||
}
|
||||
|
||||
signatureWriter.writeParametersEnd();
|
||||
|
||||
signatureWriter.writeVoidReturn();
|
||||
@@ -499,12 +493,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
i++;
|
||||
}
|
||||
|
||||
if (CodegenUtil.requireTypeInfoConstructorArg(descriptor.getDefaultType())) {
|
||||
AnnotationVisitor jetTypeParameterAnnotation =
|
||||
mv.visitParameterAnnotation(i++, JvmStdlibNames.JET_TYPE_PARAMETER.getDescriptor(), true);
|
||||
jetTypeParameterAnnotation.visitEnd();
|
||||
}
|
||||
|
||||
for (ValueParameterDescriptor valueParameter : constructorDescriptor.getValueParameters()) {
|
||||
AnnotationVisitor jetValueParameterAnnotation =
|
||||
mv.visitParameterAnnotation(i++, JvmStdlibNames.JET_VALUE_PARAMETER.getDescriptor(), true);
|
||||
@@ -559,10 +547,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
iv.load(1, JetTypeMapper.TYPE_OBJECT);
|
||||
parameterTypes.add(typeMapper.mapType(CodegenUtil.getOuterClassDescriptor(descriptor).getDefaultType(), OwnerKind.IMPLEMENTATION));
|
||||
}
|
||||
for(TypeProjection typeParameterDescriptor : superType.getArguments()) {
|
||||
codegen.generateTypeInfo(typeParameterDescriptor.getType(), null);
|
||||
parameterTypes.add(JetTypeMapper.TYPE_TYPEINFO);
|
||||
}
|
||||
Method superCallMethod = new Method("<init>", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()]));
|
||||
iv.invokespecial(typeMapper.mapType(superClassDescriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), "<init>", superCallMethod.getDescriptor());
|
||||
}
|
||||
@@ -616,12 +600,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
FunctionCodegen.endVisit(outer, JvmStdlibNames.JET_OBJECT_GET_OUTER_OBJECT_METHOD, myClass);
|
||||
}
|
||||
|
||||
if (CodegenUtil.requireTypeInfoConstructorArg(descriptor.getDefaultType()) && kind == OwnerKind.IMPLEMENTATION) {
|
||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||
iv.load(frameMap.getTypeInfoIndex(), JetTypeMapper.TYPE_OBJECT);
|
||||
iv.invokevirtual(typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), JvmAbi.SET_TYPE_INFO_METHOD, "(Ljet/TypeInfo;)V");
|
||||
}
|
||||
|
||||
if(closure != null) {
|
||||
int k = outerDescriptor != null && outerDescriptor.getKind() != ClassKind.OBJECT ? 2 : 1;
|
||||
if(closure.captureReceiver != null) {
|
||||
@@ -959,60 +937,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
return myClass instanceof JetClass ? ((JetClass) myClass).getClassObject() : null;
|
||||
}
|
||||
|
||||
private void generateGetTypeInfo() {
|
||||
JetType defaultType = descriptor.getDefaultType();
|
||||
if(CodegenUtil.requireTypeInfoConstructorArg(defaultType)) {
|
||||
if(myClass instanceof JetClass && ((JetClass)myClass).isTrait())
|
||||
return;
|
||||
|
||||
if(!CodegenUtil.hasDerivedTypeInfoField(defaultType)) {
|
||||
v.newField(myClass, ACC_PROTECTED, JvmAbi.TYPE_INFO_FIELD, "Ljet/TypeInfo;", null, null);
|
||||
|
||||
MethodVisitor mv = v.newMethod(myClass, ACC_PUBLIC, JvmStdlibNames.JET_OBJECT_GET_TYPEINFO_METHOD, "()Ljet/TypeInfo;", null, null);
|
||||
if (v.generateCode()) {
|
||||
mv.visitCode();
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
String owner = typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName();
|
||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||
iv.getfield(owner, JvmAbi.TYPE_INFO_FIELD, "Ljet/TypeInfo;");
|
||||
iv.areturn(JetTypeMapper.TYPE_TYPEINFO);
|
||||
FunctionCodegen.endVisit(iv, JvmStdlibNames.JET_OBJECT_GET_TYPEINFO_METHOD, myClass);
|
||||
}
|
||||
|
||||
mv = v.newMethod(myClass, ACC_PROTECTED | ACC_FINAL, JvmAbi.SET_TYPE_INFO_METHOD, "(Ljet/TypeInfo;)V", null, null);
|
||||
if (v.generateCode()) {
|
||||
mv.visitCode();
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
String owner = typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName();
|
||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||
iv.load(1, JetTypeMapper.TYPE_OBJECT);
|
||||
iv.putfield(owner, JvmAbi.TYPE_INFO_FIELD, "Ljet/TypeInfo;");
|
||||
mv.visitInsn(RETURN);
|
||||
FunctionCodegen.endVisit(iv, JvmAbi.SET_TYPE_INFO_METHOD, myClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!(myClass instanceof JetClass) || !((JetClass) myClass).isTrait()) {
|
||||
genGetStaticGetTypeInfoMethod();
|
||||
}
|
||||
|
||||
staticTypeInfoField();
|
||||
}
|
||||
}
|
||||
|
||||
private void genGetStaticGetTypeInfoMethod() {
|
||||
final MethodVisitor mv = v.newMethod(myClass, ACC_PUBLIC, JvmStdlibNames.JET_OBJECT_GET_TYPEINFO_METHOD, "()Ljet/TypeInfo;", null, null);
|
||||
if (v.generateCode()) {
|
||||
mv.visitCode();
|
||||
InstructionAdapter v = new InstructionAdapter(mv);
|
||||
String owner = typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName();
|
||||
v.getstatic(owner, "$staticTypeInfo", "Ljet/TypeInfo;");
|
||||
v.areturn(JetTypeMapper.TYPE_TYPEINFO);
|
||||
FunctionCodegen.endVisit(v, JvmStdlibNames.JET_OBJECT_GET_TYPEINFO_METHOD, myClass);
|
||||
}
|
||||
}
|
||||
|
||||
private void staticTypeInfoField() {
|
||||
v.newField(myClass, ACC_PUBLIC | ACC_FINAL | ACC_STATIC, "$staticTypeInfo", "Ljet/TypeInfo;", null, null);
|
||||
staticInitializerChunks.add(new CodeChunk() {
|
||||
|
||||
@@ -19,8 +19,6 @@ package org.jetbrains.jet.codegen;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import jet.JetObject;
|
||||
import jet.TypeInfo;
|
||||
import jet.typeinfo.TypeInfoProjection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
@@ -44,8 +42,6 @@ import static org.objectweb.asm.Opcodes.*;
|
||||
public class JetTypeMapper {
|
||||
public static final Type TYPE_OBJECT = Type.getObjectType("java/lang/Object");
|
||||
public static final Type TYPE_THROWABLE = Type.getObjectType("java/lang/Throwable");
|
||||
public static final Type TYPE_TYPEINFO = Type.getType(TypeInfo.class);
|
||||
public static final Type TYPE_TYPEINFOPROJECTION = Type.getType(TypeInfoProjection.class);
|
||||
public static final Type TYPE_JET_OBJECT = Type.getType(JetObject.class);
|
||||
public static final Type TYPE_NOTHING = Type.getObjectType("jet/Nothing");
|
||||
public static final Type JL_NUMBER_TYPE = Type.getObjectType("java/lang/Number");
|
||||
@@ -492,11 +488,6 @@ public class JetTypeMapper {
|
||||
signatureVisitor.writeParameterTypeEnd();
|
||||
}
|
||||
|
||||
for (TypeParameterDescriptor parameterDescriptor : f.getTypeParameters()) {
|
||||
if(parameterDescriptor.isReified()) {
|
||||
signatureVisitor.writeTypeInfoParameter();
|
||||
}
|
||||
}
|
||||
for (ValueParameterDescriptor parameter : parameters) {
|
||||
signatureVisitor.writeParameterType(JvmMethodParameterKind.VALUE);
|
||||
mapType(parameter.getOutType(), signatureVisitor);
|
||||
@@ -625,12 +616,6 @@ public class JetTypeMapper {
|
||||
signatureWriter.writeParameterTypeEnd();
|
||||
}
|
||||
|
||||
for (TypeParameterDescriptor typeParameterDescriptor : descriptor.getTypeParameters()) {
|
||||
if(typeParameterDescriptor.isReified()) {
|
||||
signatureWriter.writeTypeInfoParameter();
|
||||
}
|
||||
}
|
||||
|
||||
signatureWriter.writeParametersEnd();
|
||||
|
||||
signatureWriter.writeReturnType();
|
||||
@@ -672,12 +657,6 @@ public class JetTypeMapper {
|
||||
signatureWriter.writeParameterTypeEnd();
|
||||
}
|
||||
|
||||
for (TypeParameterDescriptor typeParameterDescriptor : descriptor.getTypeParameters()) {
|
||||
if(typeParameterDescriptor.isReified()) {
|
||||
signatureWriter.writeTypeInfoParameter();
|
||||
}
|
||||
}
|
||||
|
||||
signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE);
|
||||
mapType(outType, signatureWriter);
|
||||
signatureWriter.writeParameterTypeEnd();
|
||||
@@ -708,10 +687,6 @@ public class JetTypeMapper {
|
||||
signatureWriter.writeParameterTypeEnd();
|
||||
}
|
||||
|
||||
if (CodegenUtil.requireTypeInfoConstructorArg(classDescriptor.getDefaultType())) {
|
||||
signatureWriter.writeTypeInfoParameter();
|
||||
}
|
||||
|
||||
for (ValueParameterDescriptor parameter : parameters) {
|
||||
signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE);
|
||||
mapType(parameter.getOutType(), signatureWriter);
|
||||
|
||||
@@ -98,13 +98,10 @@ public class NamespaceCodegen {
|
||||
if (hasNonConstantPropertyInitializers(file)) {
|
||||
generateStaticInitializers(file);
|
||||
}
|
||||
|
||||
generateTypeInfoFields(file, context);
|
||||
}
|
||||
|
||||
private void generateStaticInitializers(JetFile namespace) {
|
||||
MethodVisitor mv = v.newMethod(namespace, ACC_PUBLIC | ACC_STATIC,
|
||||
"<clinit>", "()V", null, null);
|
||||
MethodVisitor mv = v.newMethod(namespace, ACC_PUBLIC | ACC_STATIC, "<clinit>", "()V", null, null);
|
||||
if (v.generateCode()) {
|
||||
mv.visitCode();
|
||||
|
||||
@@ -132,78 +129,6 @@ public class NamespaceCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
private void generateTypeInfoFields(JetFile file, CodegenContext context) {
|
||||
if(context.typeInfoConstants != null) {
|
||||
String jvmClassName = getJVMClassName(JetPsiUtil.getFQName(file), true);
|
||||
for(int index = 0; index != context.typeInfoConstantsCount; index++) {
|
||||
JetType type = context.reverseTypeInfoConstants.get(index);
|
||||
String fieldName = "$typeInfoCache$" + index;
|
||||
v.newField(null, ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC, fieldName, "Ljet/TypeInfo;", null, null);
|
||||
|
||||
MethodVisitor mmv = v.newMethod(null, ACC_PUBLIC | ACC_STATIC | ACC_SYNTHETIC, "$getCachedTypeInfo$" + index, "()Ljet/TypeInfo;", null, null);
|
||||
InstructionAdapter v = new InstructionAdapter(mmv);
|
||||
v.visitFieldInsn(GETSTATIC, jvmClassName, fieldName, "Ljet/TypeInfo;");
|
||||
v.visitInsn(DUP);
|
||||
Label end = new Label();
|
||||
v.visitJumpInsn(IFNONNULL, end);
|
||||
|
||||
v.pop();
|
||||
generateTypeInfo(context, v, type, state.getTypeMapper(), type);
|
||||
v.dup();
|
||||
|
||||
v.visitFieldInsn(PUTSTATIC, jvmClassName, fieldName, "Ljet/TypeInfo;");
|
||||
v.visitLabel(end);
|
||||
v.visitInsn(ARETURN);
|
||||
FunctionCodegen.endVisit(v, "type info method", file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void generateTypeInfo(CodegenContext context, InstructionAdapter v, JetType jetType, JetTypeMapper typeMapper, JetType root) {
|
||||
String knownTypeInfo = typeMapper.isKnownTypeInfo(jetType);
|
||||
if(knownTypeInfo != null) {
|
||||
v.getstatic("jet/TypeInfo", knownTypeInfo, "Ljet/TypeInfo;");
|
||||
return;
|
||||
}
|
||||
|
||||
DeclarationDescriptor declarationDescriptor = jetType.getConstructor().getDeclarationDescriptor();
|
||||
if(!jetType.equals(root) && jetType.getArguments().size() == 0 && !JetStandardClasses.getAny().equals(declarationDescriptor)) {
|
||||
// TODO: we need some better checks here
|
||||
v.getstatic(typeMapper.mapType(jetType, OwnerKind.IMPLEMENTATION).getInternalName(), JvmAbi.TYPE_INFO_FIELD, "Ljet/TypeInfo;");
|
||||
return;
|
||||
}
|
||||
|
||||
boolean hasUnsubstituted = TypeUtils.hasUnsubstitutedTypeParameters(jetType);
|
||||
if(!jetType.equals(root) && !hasUnsubstituted) {
|
||||
int typeInfoConstantIndex = context.getTypeInfoConstantIndex(jetType);
|
||||
v.invokestatic(context.getNamespaceClassName(), "$getCachedTypeInfo$" + typeInfoConstantIndex, "()Ljet/TypeInfo;");
|
||||
return;
|
||||
}
|
||||
|
||||
final Type jvmType = typeMapper.mapType(jetType);
|
||||
|
||||
v.aconst(jvmType);
|
||||
v.iconst(jetType.isNullable() ? 1 : 0);
|
||||
List<TypeProjection> arguments = jetType.getArguments();
|
||||
if (arguments.size() > 0 && !(jvmType.getSort() == Type.ARRAY && JetTypeMapper.correctElementType(jvmType).getSort() != Type.OBJECT)) {
|
||||
v.iconst(arguments.size());
|
||||
v.newarray(JetTypeMapper.TYPE_TYPEINFOPROJECTION);
|
||||
|
||||
for (int i = 0, argumentsSize = arguments.size(); i < argumentsSize; i++) {
|
||||
TypeProjection argument = arguments.get(i);
|
||||
v.dup();
|
||||
v.iconst(i);
|
||||
generateTypeInfo(context, v, argument.getType(), typeMapper, root);
|
||||
ExpressionCodegen.genTypeInfoToProjection(v, argument.getProjectionKind());
|
||||
v.astore(JetTypeMapper.TYPE_OBJECT);
|
||||
}
|
||||
v.invokestatic("jet/TypeInfo", JvmStdlibNames.JET_OBJECT_GET_TYPEINFO_METHOD, "(Ljava/lang/Class;Z[Ljet/typeinfo/TypeInfoProjection;)Ljet/TypeInfo;");
|
||||
}
|
||||
else {
|
||||
v.invokestatic("jet/TypeInfo", JvmStdlibNames.JET_OBJECT_GET_TYPEINFO_METHOD, "(Ljava/lang/Class;Z)Ljet/TypeInfo;");
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean hasNonConstantPropertyInitializers(JetFile namespace) {
|
||||
for (JetDeclaration declaration : namespace.getDeclarations()) {
|
||||
if (declaration instanceof JetProperty) {
|
||||
|
||||
@@ -671,12 +671,6 @@ public abstract class StackValue {
|
||||
}
|
||||
}
|
||||
|
||||
for (TypeParameterDescriptor typeParameterDescriptor : setterDescriptor.getOriginal().getTypeParameters()) {
|
||||
if(typeParameterDescriptor.isReified()) {
|
||||
codegen.generateTypeInfo(resolvedSetCall.getTypeArguments().get(typeParameterDescriptor), null);
|
||||
}
|
||||
}
|
||||
|
||||
int index = firstParamIndex;
|
||||
for(int i = 0; i != valueParameters.size(); ++i) {
|
||||
Type type = codegen.typeMapper.mapType(valueParameters.get(i).getOutType());
|
||||
|
||||
@@ -46,8 +46,7 @@ public class ArrayIterator implements IntrinsicMethod {
|
||||
ClassDescriptor containingDeclaration = (ClassDescriptor) funDescriptor.getContainingDeclaration().getOriginal();
|
||||
JetStandardLibrary standardLibrary = codegen.getState().getStandardLibrary();
|
||||
if(containingDeclaration.equals(standardLibrary.getArray())) {
|
||||
codegen.generateTypeInfo(funDescriptor.getReturnType().getArguments().get(0).getType(), null);
|
||||
v.invokestatic("jet/runtime/ArrayIterator", "iterator", "([Ljava/lang/Object;Ljet/TypeInfo;)Ljet/Iterator;");
|
||||
v.invokestatic("jet/runtime/ArrayIterator", "iterator", "([Ljava/lang/Object;)Ljet/Iterator;");
|
||||
return StackValue.onStack(JetTypeMapper.TYPE_ITERATOR);
|
||||
} else {
|
||||
for (JvmPrimitiveType jvmPrimitiveType : JvmPrimitiveType.values()) {
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.search.DelegatingGlobalSearchScope;
|
||||
import com.intellij.psi.search.ProjectScope;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
||||
@@ -46,8 +47,6 @@ public class IntrinsicMethods {
|
||||
private static final IntrinsicMethod UNARY_PLUS = new UnaryPlus();
|
||||
private static final IntrinsicMethod NUMBER_CAST = new NumberCast();
|
||||
private static final IntrinsicMethod INV = new Inv();
|
||||
private static final IntrinsicMethod TYPEINFO = new TypeInfo();
|
||||
private static final IntrinsicMethod VALUE_TYPEINFO = new ValueTypeInfo();
|
||||
private static final IntrinsicMethod UP_TO = new UpTo(true);
|
||||
private static final IntrinsicMethod DOWN_TO = new UpTo(false);
|
||||
private static final IntrinsicMethod INC = new Increment(1);
|
||||
@@ -66,11 +65,15 @@ public class IntrinsicMethods {
|
||||
private final Project myProject;
|
||||
private final JetStandardLibrary myStdLib;
|
||||
private final Map<DeclarationDescriptor, IntrinsicMethod> myMethods = new HashMap<DeclarationDescriptor, IntrinsicMethod>();
|
||||
private final Map<String, IntrinsicMethod> namedMethods = new HashMap<String, IntrinsicMethod>();
|
||||
private static final IntrinsicMethod ARRAY_ITERATOR = new ArrayIterator();
|
||||
|
||||
public IntrinsicMethods(Project project, JetStandardLibrary stdlib) {
|
||||
myProject = project;
|
||||
myStdLib = stdlib;
|
||||
|
||||
namedMethods.put("std.javaClass.property", new JavaClassProperty());
|
||||
|
||||
List<String> primitiveCastMethods = OperatorConventions.NUMBER_CONVERSIONS.asList();
|
||||
for (String method : primitiveCastMethods) {
|
||||
declareIntrinsicProperty("Number", method, NUMBER_CAST);
|
||||
@@ -91,8 +94,6 @@ public class IntrinsicMethods {
|
||||
}
|
||||
|
||||
final Set<FunctionDescriptor> typeInfoFunctionGroup = stdlib.getTypeInfoFunctions();
|
||||
declareOverload(typeInfoFunctionGroup, 0, TYPEINFO);
|
||||
declareOverload(typeInfoFunctionGroup, 1, VALUE_TYPEINFO);
|
||||
|
||||
declareBinaryOp("plus", Opcodes.IADD);
|
||||
declareBinaryOp("minus", Opcodes.ISUB);
|
||||
@@ -238,7 +239,18 @@ public class IntrinsicMethods {
|
||||
}
|
||||
|
||||
public IntrinsicMethod getIntrinsic(DeclarationDescriptor descriptor) {
|
||||
return myMethods.get(descriptor.getOriginal());
|
||||
IntrinsicMethod intrinsicMethod = myMethods.get(descriptor.getOriginal());
|
||||
if(intrinsicMethod == null) {
|
||||
List<AnnotationDescriptor> annotations = descriptor.getAnnotations();
|
||||
if (annotations != null) {
|
||||
for (AnnotationDescriptor annotation : annotations) {
|
||||
if("intrinsic".equals(annotation.getType().getConstructor().getDeclarationDescriptor().getName())) {
|
||||
intrinsicMethod = namedMethods.get(annotation.getValueArguments().get(0).getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return intrinsicMethod;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+6
-13
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,28 +17,21 @@
|
||||
package org.jetbrains.jet.codegen.intrinsics;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.codegen.ExpressionCodegen;
|
||||
import org.jetbrains.jet.codegen.JetTypeMapper;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
import org.jetbrains.jet.lang.psi.JetCallExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetTypeProjection;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
* @author alex.tkachman
|
||||
*/
|
||||
public class TypeInfo implements IntrinsicMethod {
|
||||
public class JavaClassProperty implements IntrinsicMethod {
|
||||
@Override
|
||||
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) {
|
||||
final List<JetTypeProjection> typeArguments = ((JetCallExpression) element).getTypeArguments();
|
||||
if (typeArguments.size() != 1) {
|
||||
throw new UnsupportedOperationException("one type argument expected");
|
||||
}
|
||||
codegen.pushTypeArgument(typeArguments.get(0));
|
||||
return StackValue.onStack(JetTypeMapper.TYPE_TYPEINFO);
|
||||
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, @Nullable PsiElement element, @Nullable List<JetExpression> arguments, StackValue receiver) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.codegen.intrinsics;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.jet.codegen.ExpressionCodegen;
|
||||
import org.jetbrains.jet.codegen.JetTypeMapper;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class ValueTypeInfo implements IntrinsicMethod {
|
||||
@Override
|
||||
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) {
|
||||
JetExpression expr = arguments.get(0);
|
||||
BindingContext bindingContext = codegen.getBindingContext();
|
||||
JetType jetType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expr);
|
||||
DeclarationDescriptor declarationDescriptor = jetType.getConstructor().getDeclarationDescriptor();
|
||||
PsiElement psiElement = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, declarationDescriptor.getOriginal());
|
||||
if(psiElement instanceof JetClassOrObject) {
|
||||
codegen.gen(expr, JetTypeMapper.TYPE_JET_OBJECT);
|
||||
v.invokeinterface(JetTypeMapper.TYPE_JET_OBJECT.getInternalName(), JvmStdlibNames.JET_OBJECT_GET_TYPEINFO_METHOD, "()Ljet/TypeInfo;");
|
||||
}
|
||||
else {
|
||||
codegen.gen(expr, JetTypeMapper.TYPE_OBJECT);
|
||||
v.invokevirtual("java/lang/Object", "getClass", "()Ljava/lang/Class;");
|
||||
v.iconst(jetType.isNullable() ? 1 : 0);
|
||||
v.invokestatic("jet/TypeInfo", "getTypeInfo", "(Ljava/lang/Class;Z)Ljet/TypeInfo;");
|
||||
}
|
||||
return StackValue.onStack(JetTypeMapper.TYPE_TYPEINFO);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user