working on @JetProperty.type
This commit is contained in:
@@ -165,7 +165,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
||||
|
||||
final CodegenContext.ClosureContext closureContext = context.intoClosure(funDescriptor, function, name, this, state.getTypeMapper());
|
||||
FunctionCodegen fc = new FunctionCodegen(closureContext, cv, state);
|
||||
fc.generateMethod(body, new JvmMethodSignature(invokeSignature(funDescriptor), null, null, null, null), funDescriptor);
|
||||
fc.generateMethod(body, new JvmMethodSignature(invokeSignature(funDescriptor), null, null, null, null), null, funDescriptor);
|
||||
return closureContext.outerWasUsed;
|
||||
}
|
||||
|
||||
|
||||
@@ -1097,7 +1097,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
}
|
||||
}
|
||||
if(!(containingDeclaration instanceof JavaNamespaceDescriptor) && !(containingDeclaration instanceof JavaClassDescriptor))
|
||||
getter = typeMapper.mapGetterSignature(propertyDescriptor, OwnerKind.IMPLEMENTATION).getAsmMethod();
|
||||
getter = typeMapper.mapGetterSignature(propertyDescriptor, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod();
|
||||
else
|
||||
getter = null;
|
||||
}
|
||||
@@ -1107,8 +1107,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
}
|
||||
else {
|
||||
if(!(containingDeclaration instanceof JavaNamespaceDescriptor) && !(containingDeclaration instanceof JavaClassDescriptor)) {
|
||||
JvmMethodSignature jvmMethodSignature = typeMapper.mapSetterSignature(propertyDescriptor, OwnerKind.IMPLEMENTATION);
|
||||
setter = jvmMethodSignature != null ? jvmMethodSignature.getAsmMethod() : null;
|
||||
JvmPropertyAccessorSignature jvmMethodSignature = typeMapper.mapSetterSignature(propertyDescriptor, OwnerKind.IMPLEMENTATION);
|
||||
setter = jvmMethodSignature != null ? jvmMethodSignature.getJvmMethodSignature().getAsmMethod() : null;
|
||||
} else {
|
||||
setter = null;
|
||||
}
|
||||
|
||||
@@ -43,18 +43,19 @@ public class FunctionCodegen {
|
||||
final NamedFunctionDescriptor functionDescriptor = state.getBindingContext().get(BindingContext.FUNCTION, f);
|
||||
assert functionDescriptor != null;
|
||||
JvmMethodSignature method = typeMapper.mapToCallableMethod(functionDescriptor, false, owner.getContextKind()).getSignature();
|
||||
generateMethod(f, method, functionDescriptor);
|
||||
generateMethod(f, method, null, functionDescriptor);
|
||||
}
|
||||
|
||||
public void generateMethod(JetDeclarationWithBody f, JvmMethodSignature jvmMethod, FunctionDescriptor functionDescriptor) {
|
||||
public void generateMethod(JetDeclarationWithBody f, JvmMethodSignature jvmMethod, @Nullable String propertyTypeSignature, FunctionDescriptor functionDescriptor) {
|
||||
CodegenContext.MethodContext funContext = owner.intoFunction(functionDescriptor);
|
||||
|
||||
final JetExpression bodyExpression = f.getBodyExpression();
|
||||
generatedMethod(bodyExpression, jvmMethod, funContext, functionDescriptor, f);
|
||||
generatedMethod(bodyExpression, jvmMethod, propertyTypeSignature, funContext, functionDescriptor, f);
|
||||
}
|
||||
|
||||
private void generatedMethod(JetExpression bodyExpressions,
|
||||
JvmMethodSignature jvmSignature,
|
||||
@Nullable String propertyTypeSignature,
|
||||
CodegenContext.MethodContext context,
|
||||
FunctionDescriptor functionDescriptor, JetDeclarationWithBody fun)
|
||||
{
|
||||
@@ -92,9 +93,11 @@ public class FunctionCodegen {
|
||||
int start = 0;
|
||||
if(kind != OwnerKind.TRAIT_IMPL) {
|
||||
if (functionDescriptor instanceof PropertyAccessorDescriptor) {
|
||||
AnnotationVisitor av = mv.visitAnnotation(JvmStdlibNames.JET_PROPERTY.getDescriptor(), true);
|
||||
av.visitEnd();
|
||||
PropertyCodegen.generateJetPropertyAnnotation(mv, propertyTypeSignature);
|
||||
} else if (functionDescriptor instanceof NamedFunctionDescriptor) {
|
||||
if (propertyTypeSignature != null) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
AnnotationVisitor av = mv.visitAnnotation(JvmStdlibNames.JET_METHOD.getDescriptor(), true);
|
||||
if(functionDescriptor.getReturnType().isNullable()) {
|
||||
av.visit(JvmStdlibNames.JET_METHOD_NULLABLE_RETURN_TYPE_FIELD, true);
|
||||
|
||||
@@ -237,50 +237,58 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
PropertyDescriptor bridge = (PropertyDescriptor) entry.getValue();
|
||||
PropertyDescriptor original = (PropertyDescriptor) entry.getKey();
|
||||
|
||||
Method method = typeMapper.mapGetterSignature(bridge, OwnerKind.IMPLEMENTATION).getAsmMethod();
|
||||
Method originalMethod = typeMapper.mapGetterSignature(original, OwnerKind.IMPLEMENTATION).getAsmMethod();
|
||||
MethodVisitor mv = v.newMethod(null, Opcodes.ACC_PUBLIC|Opcodes.ACC_BRIDGE|Opcodes.ACC_FINAL, method.getName(), method.getDescriptor(), null, null);
|
||||
mv.visitAnnotation(JvmStdlibNames.JET_PROPERTY.getDescriptor(), true).visitEnd();
|
||||
InstructionAdapter iv = null;
|
||||
if (v.generateCode()) {
|
||||
mv.visitCode();
|
||||
{
|
||||
Method method = typeMapper.mapGetterSignature(bridge, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod();
|
||||
JvmPropertyAccessorSignature originalSignature = typeMapper.mapGetterSignature(original, OwnerKind.IMPLEMENTATION);
|
||||
Method originalMethod = originalSignature.getJvmMethodSignature().getAsmMethod();
|
||||
MethodVisitor mv = v.newMethod(null, Opcodes.ACC_PUBLIC | Opcodes.ACC_BRIDGE | Opcodes.ACC_FINAL, method.getName(), method.getDescriptor(), null, null);
|
||||
PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature.getPropertyTypeKotlinSignature());
|
||||
mv.visitAnnotation(JvmStdlibNames.JET_PROPERTY.getDescriptor(), true).visitEnd();
|
||||
if (v.generateCode()) {
|
||||
mv.visitCode();
|
||||
|
||||
iv = new InstructionAdapter(mv);
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
|
||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||
if(original.getVisibility() == Visibility.PRIVATE)
|
||||
iv.getfield(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION), original.getName(), originalMethod.getReturnType().getDescriptor());
|
||||
else
|
||||
iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION), originalMethod.getName(), originalMethod.getDescriptor());
|
||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||
if(original.getVisibility() == Visibility.PRIVATE)
|
||||
iv.getfield(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION), original.getName(), originalMethod.getReturnType().getDescriptor());
|
||||
else
|
||||
iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION), originalMethod.getName(), originalMethod.getDescriptor());
|
||||
|
||||
iv.areturn(method.getReturnType());
|
||||
FunctionCodegen.endVisit(iv, "accessor", null);
|
||||
iv.areturn(method.getReturnType());
|
||||
FunctionCodegen.endVisit(iv, "accessor", null);
|
||||
}
|
||||
}
|
||||
|
||||
method = typeMapper.mapSetterSignature(bridge, OwnerKind.IMPLEMENTATION).getAsmMethod();
|
||||
originalMethod = typeMapper.mapSetterSignature(original, OwnerKind.IMPLEMENTATION).getAsmMethod();
|
||||
mv = v.newMethod(null, Opcodes.ACC_PUBLIC|Opcodes.ACC_BRIDGE|Opcodes.ACC_FINAL, method.getName(), method.getDescriptor(), null, null);
|
||||
mv.visitAnnotation(JvmStdlibNames.JET_PROPERTY.getDescriptor(), true).visitEnd();
|
||||
if (v.generateCode()) {
|
||||
mv.visitCode();
|
||||
{
|
||||
|
||||
iv = new InstructionAdapter(mv);
|
||||
Method method = typeMapper.mapSetterSignature(bridge, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod();
|
||||
JvmPropertyAccessorSignature originalSignature2 = typeMapper.mapSetterSignature(original, OwnerKind.IMPLEMENTATION);
|
||||
Method originalMethod = originalSignature2.getJvmMethodSignature().getAsmMethod();
|
||||
MethodVisitor mv = v.newMethod(null, Opcodes.ACC_PUBLIC | Opcodes.ACC_BRIDGE | Opcodes.ACC_FINAL, method.getName(), method.getDescriptor(), null, null);
|
||||
PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature2.getPropertyTypeKotlinSignature());
|
||||
mv.visitAnnotation(JvmStdlibNames.JET_PROPERTY.getDescriptor(), true).visitEnd();
|
||||
if (v.generateCode()) {
|
||||
mv.visitCode();
|
||||
|
||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||
Type[] argTypes = method.getArgumentTypes();
|
||||
for (int i = 0, reg = 1; i < argTypes.length; i++) {
|
||||
Type argType = argTypes[i];
|
||||
iv.load(reg, argType);
|
||||
//noinspection AssignmentToForLoopParameter
|
||||
reg += argType.getSize();
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
|
||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||
Type[] argTypes = method.getArgumentTypes();
|
||||
for (int i = 0, reg = 1; i < argTypes.length; i++) {
|
||||
Type argType = argTypes[i];
|
||||
iv.load(reg, argType);
|
||||
//noinspection AssignmentToForLoopParameter
|
||||
reg += argType.getSize();
|
||||
}
|
||||
if(original.getVisibility() == Visibility.PRIVATE)
|
||||
iv.putfield(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION), original.getName(), originalMethod.getArgumentTypes()[0].getDescriptor());
|
||||
else
|
||||
iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION), originalMethod.getName(), originalMethod.getDescriptor());
|
||||
|
||||
iv.areturn(method.getReturnType());
|
||||
FunctionCodegen.endVisit(iv, "accessor", null);
|
||||
}
|
||||
if(original.getVisibility() == Visibility.PRIVATE)
|
||||
iv.putfield(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION), original.getName(), originalMethod.getArgumentTypes()[0].getDescriptor());
|
||||
else
|
||||
iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION), originalMethod.getName(), originalMethod.getDescriptor());
|
||||
|
||||
iv.areturn(method.getReturnType());
|
||||
FunctionCodegen.endVisit(iv, "accessor", null);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -574,7 +574,7 @@ public class JetTypeMapper {
|
||||
}
|
||||
|
||||
|
||||
public JvmMethodSignature mapGetterSignature(PropertyDescriptor descriptor, OwnerKind kind) {
|
||||
public JvmPropertyAccessorSignature mapGetterSignature(PropertyDescriptor descriptor, OwnerKind kind) {
|
||||
Type returnType = mapType(descriptor.getOutType());
|
||||
String name = PropertyCodegen.getterName(descriptor.getName());
|
||||
ArrayList<Type> params = new ArrayList<Type>();
|
||||
@@ -595,11 +595,13 @@ public class JetTypeMapper {
|
||||
}
|
||||
|
||||
// TODO: proper generic signature
|
||||
return new JvmMethodSignature(new Method(name, returnType, params.toArray(new Type[params.size()])), null, null, null, null);
|
||||
JvmMethodSignature jvmMethodSignature = new JvmMethodSignature(new Method(name, returnType, params.toArray(new Type[params.size()])), null, null, null, null);
|
||||
|
||||
return new JvmPropertyAccessorSignature(jvmMethodSignature, "");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public JvmMethodSignature mapSetterSignature(PropertyDescriptor descriptor, OwnerKind kind) {
|
||||
public JvmPropertyAccessorSignature mapSetterSignature(PropertyDescriptor descriptor, OwnerKind kind) {
|
||||
if (!descriptor.isVar()) {
|
||||
return null;
|
||||
}
|
||||
@@ -627,7 +629,8 @@ public class JetTypeMapper {
|
||||
params.add(mapType(outType));
|
||||
|
||||
// TODO: proper generic signature
|
||||
return new JvmMethodSignature(new Method(name, Type.VOID_TYPE, params.toArray(new Type[params.size()])), null, null, null, null);
|
||||
JvmMethodSignature jvmMethodSignature = new JvmMethodSignature(new Method(name, Type.VOID_TYPE, params.toArray(new Type[params.size()])), null, null, null, null);
|
||||
return new JvmPropertyAccessorSignature(jvmMethodSignature, "");
|
||||
}
|
||||
|
||||
private JvmMethodSignature mapConstructorSignature(ConstructorDescriptor descriptor, List<Type> valueParameterTypes) {
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author Stepan Koltsov
|
||||
*/
|
||||
public class JvmPropertyAccessorSignature {
|
||||
@NotNull
|
||||
private final JvmMethodSignature jvmMethodSignature;
|
||||
@NotNull
|
||||
private final String propertyTypeKotlinSignature;
|
||||
|
||||
public JvmPropertyAccessorSignature(@NotNull JvmMethodSignature jvmMethodSignature, @NotNull String propertyTypeKotlinSignature) {
|
||||
this.jvmMethodSignature = jvmMethodSignature;
|
||||
this.propertyTypeKotlinSignature = propertyTypeKotlinSignature;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JvmMethodSignature getJvmMethodSignature() {
|
||||
return jvmMethodSignature;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getPropertyTypeKotlinSignature() {
|
||||
return propertyTypeKotlinSignature;
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package org.jetbrains.jet.codegen;
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.PropertySetterDescriptor;
|
||||
@@ -12,6 +13,7 @@ import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.Type;
|
||||
@@ -86,7 +88,8 @@ public class PropertyCodegen {
|
||||
final JetPropertyAccessor getter = p.getGetter();
|
||||
if (getter != null) {
|
||||
if (getter.getBodyExpression() != null) {
|
||||
functionCodegen.generateMethod(getter, state.getTypeMapper().mapGetterSignature(propertyDescriptor, kind), propertyDescriptor.getGetter());
|
||||
JvmPropertyAccessorSignature signature = state.getTypeMapper().mapGetterSignature(propertyDescriptor, kind);
|
||||
functionCodegen.generateMethod(getter, signature.getJvmMethodSignature(), signature.getPropertyTypeKotlinSignature(), propertyDescriptor.getGetter());
|
||||
}
|
||||
else if (!getter.hasModifier(JetTokens.PRIVATE_KEYWORD)) {
|
||||
generateDefaultGetter(p, getter);
|
||||
@@ -107,7 +110,8 @@ public class PropertyCodegen {
|
||||
if (setter.getBodyExpression() != null) {
|
||||
final PropertySetterDescriptor setterDescriptor = propertyDescriptor.getSetter();
|
||||
assert setterDescriptor != null;
|
||||
functionCodegen.generateMethod(setter, state.getTypeMapper().mapSetterSignature(propertyDescriptor, kind), setterDescriptor);
|
||||
JvmPropertyAccessorSignature signature = state.getTypeMapper().mapSetterSignature(propertyDescriptor, kind);
|
||||
functionCodegen.generateMethod(setter, signature.getJvmMethodSignature(), signature.getPropertyTypeKotlinSignature(), setterDescriptor);
|
||||
}
|
||||
else if (!p.hasModifier(JetTokens.PRIVATE_KEYWORD)) {
|
||||
generateDefaultSetter(p, setter);
|
||||
@@ -138,10 +142,11 @@ public class PropertyCodegen {
|
||||
if(isTrait && !(kind instanceof OwnerKind.DelegateKind))
|
||||
flags |= Opcodes.ACC_ABSTRACT;
|
||||
|
||||
final String signature = state.getTypeMapper().mapGetterSignature(propertyDescriptor, kind).getAsmMethod().getDescriptor();
|
||||
JvmPropertyAccessorSignature signature = state.getTypeMapper().mapGetterSignature(propertyDescriptor, kind);
|
||||
final String descriptor = signature.getJvmMethodSignature().getAsmMethod().getDescriptor();
|
||||
String getterName = getterName(propertyDescriptor.getName());
|
||||
MethodVisitor mv = v.newMethod(origin, flags, getterName, signature, null, null);
|
||||
mv.visitAnnotation(JvmStdlibNames.JET_PROPERTY.getDescriptor(), true).visitEnd();
|
||||
MethodVisitor mv = v.newMethod(origin, flags, getterName, descriptor, null, null);
|
||||
generateJetPropertyAnnotation(mv, signature.getPropertyTypeKotlinSignature());
|
||||
if (v.generateCode() && (!isTrait || kind instanceof OwnerKind.DelegateKind)) {
|
||||
mv.visitCode();
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
@@ -152,7 +157,7 @@ public class PropertyCodegen {
|
||||
if (kind instanceof OwnerKind.DelegateKind) {
|
||||
OwnerKind.DelegateKind dk = (OwnerKind.DelegateKind) kind;
|
||||
dk.getDelegate().put(JetTypeMapper.TYPE_OBJECT, iv);
|
||||
iv.invokeinterface(dk.getOwnerClass(), getterName, signature);
|
||||
iv.invokeinterface(dk.getOwnerClass(), getterName, descriptor);
|
||||
}
|
||||
else {
|
||||
iv.visitFieldInsn(kind == OwnerKind.NAMESPACE ? Opcodes.GETSTATIC : Opcodes.GETFIELD,
|
||||
@@ -164,6 +169,14 @@ public class PropertyCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
public static void generateJetPropertyAnnotation(MethodVisitor mv, @NotNull String kotlinType) {
|
||||
AnnotationVisitor annotationVisitor = mv.visitAnnotation(JvmStdlibNames.JET_PROPERTY.getDescriptor(), true);
|
||||
if (kotlinType.length() > 0) {
|
||||
annotationVisitor.visit(JvmStdlibNames.JET_PROPERTY_TYPE_FIELD, kotlinType);
|
||||
}
|
||||
annotationVisitor.visitEnd();
|
||||
}
|
||||
|
||||
private void generateDefaultSetter(JetProperty p, JetDeclaration declaration) {
|
||||
final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, p);
|
||||
int flags = JetTypeMapper.getAccessModifiers(declaration, Opcodes.ACC_PUBLIC);
|
||||
@@ -184,9 +197,10 @@ public class PropertyCodegen {
|
||||
if(isTrait && !(kind instanceof OwnerKind.DelegateKind))
|
||||
flags |= Opcodes.ACC_ABSTRACT;
|
||||
|
||||
final String signature = state.getTypeMapper().mapSetterSignature(propertyDescriptor, kind).getAsmMethod().getDescriptor();
|
||||
MethodVisitor mv = v.newMethod(origin, flags, setterName(propertyDescriptor.getName()), signature, null, null);
|
||||
mv.visitAnnotation(JvmStdlibNames.JET_PROPERTY.getDescriptor(), true).visitEnd();
|
||||
JvmPropertyAccessorSignature signature = state.getTypeMapper().mapSetterSignature(propertyDescriptor, kind);
|
||||
final String descriptor = signature.getJvmMethodSignature().getAsmMethod().getDescriptor();
|
||||
MethodVisitor mv = v.newMethod(origin, flags, setterName(propertyDescriptor.getName()), descriptor, null, null);
|
||||
generateJetPropertyAnnotation(mv, signature.getPropertyTypeKotlinSignature());
|
||||
if (v.generateCode() && (!isTrait || kind instanceof OwnerKind.DelegateKind)) {
|
||||
mv.visitCode();
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
@@ -203,7 +217,7 @@ public class PropertyCodegen {
|
||||
dk.getDelegate().put(JetTypeMapper.TYPE_OBJECT, iv);
|
||||
|
||||
iv.load(paramCode, type);
|
||||
iv.invokeinterface(dk.getOwnerClass(), setterName(propertyDescriptor.getName()), signature);
|
||||
iv.invokeinterface(dk.getOwnerClass(), setterName(propertyDescriptor.getName()), descriptor);
|
||||
}
|
||||
else {
|
||||
iv.load(paramCode, type);
|
||||
|
||||
@@ -30,6 +30,8 @@ public class JvmStdlibNames {
|
||||
|
||||
public static final JvmClassName JET_PROPERTY = new JvmClassName("jet.runtime.typeinfo.JetProperty");
|
||||
|
||||
public static final String JET_PROPERTY_TYPE_FIELD = "type";
|
||||
|
||||
public static final JvmClassName JET_CONSTRUCTOR = new JvmClassName("jet.runtime.typeinfo.JetConstructor");
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package test
|
||||
|
||||
import java.lang.CharSequence
|
||||
|
||||
val Int.ggg: CharSequence
|
||||
get() = throw Exception()
|
||||
@@ -0,0 +1,6 @@
|
||||
package test
|
||||
|
||||
import java.lang.CharSequence
|
||||
|
||||
val Int.ggg: CharSequence?
|
||||
get() = throw Exception()
|
||||
@@ -11,4 +11,5 @@ import java.lang.annotation.Target;
|
||||
@Target({ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface JetProperty {
|
||||
String type() default "";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user