-
Notifications
You must be signed in to change notification settings - Fork 753
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for field annotations in local records and tuples #38488
Changes from all commits
9593c36
9dd1884
d1e1e7c
1f2b606
8069fe1
5696819
347ed0f
ebc4c18
d66a17c
e084377
b88ddd0
5429015
097c3eb
8b62528
b34390d
fd46e70
482b160
7b3fd03
49c5772
788a8ac
ecbcd6e
30617b3
3bcf5c2
c3b7bc1
b619783
604f118
144b904
f00c676
84b1b8b
28bf26d
c15e4a9
ba469c5
6c66c1d
dd11149
a5accff
0a93d03
65b7432
85a4717
04d0403
ffa50c3
b4798a6
294bcc7
bf4915b
e14d9f1
ca112e1
e1da96f
b9b862e
01f2595
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,5 +26,4 @@ | |
* @since 1.3.0 | ||
*/ | ||
public interface TypedescValue extends RefValue, BTypedesc { | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,6 +25,7 @@ | |
import io.ballerina.runtime.api.values.BMapInitialValueEntry; | ||
import io.ballerina.runtime.api.values.BTypedesc; | ||
import io.ballerina.runtime.internal.scheduling.Strand; | ||
import io.ballerina.runtime.internal.types.BAnnotatableType; | ||
import io.ballerina.runtime.internal.types.BTypedescType; | ||
import io.ballerina.runtime.internal.util.exceptions.BallerinaException; | ||
|
||
|
@@ -52,6 +53,7 @@ public class TypedescValueImpl implements TypedescValue { | |
final Type type; | ||
final Type describingType; // Type of the value describe by this typedesc. | ||
public MapValue[] closures; | ||
public MapValue annotations; | ||
|
||
@Deprecated | ||
public TypedescValueImpl(Type describingType) { | ||
|
@@ -66,6 +68,11 @@ public TypedescValueImpl(Type describingType, MapValue[] closures) { | |
this.closures = closures; | ||
} | ||
|
||
public TypedescValueImpl(Type describingType, MapValue[] closures, MapValue annotations) { | ||
this(describingType, closures); | ||
this.annotations = annotations; | ||
((BAnnotatableType) describingType).setAnnotations(annotations); | ||
} | ||
|
||
chiranSachintha marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/** | ||
* Returns the {@code BType} of the value describe by this type descriptor. | ||
|
@@ -84,13 +91,17 @@ public Object instantiate(Strand s) { | |
return instantiate(s, new BInitialValueEntry[0]); | ||
} | ||
|
||
public MapValue getAnnotations() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed in chiranSachintha#8 |
||
return annotations; | ||
} | ||
|
||
@Override | ||
public Object instantiate(Strand s, BInitialValueEntry[] initialValues) { | ||
Type referredType = getReferredType(this.describingType); | ||
if (referredType.getTag() == TypeTags.MAP_TAG) { | ||
return new MapValueImpl(this.describingType, (BMapInitialValueEntry[]) initialValues); | ||
} else if (referredType.getTag() == TypeTags.TUPLE_TAG) { | ||
return new TupleValueImpl(this.describingType, (BListInitialValueEntry[]) initialValues); | ||
return new TupleValueImpl(this.describingType, (BListInitialValueEntry[]) initialValues, this); | ||
} | ||
// This method will be overridden for user-defined types, therefor this line shouldn't be reached. | ||
throw new BallerinaException("Given type can't be instantiated at runtime : " + this.describingType); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1608,7 +1608,8 @@ public void visit(BLangTypeConversionExpr astTypeConversionExpr) { | |
@Override | ||
public void visit(BLangStructLiteral astStructLiteralExpr) { | ||
List<BIROperand> varDcls = mapToVarDcls(astStructLiteralExpr.enclMapSymbols); | ||
visitTypedesc(astStructLiteralExpr.pos, astStructLiteralExpr.getBType(), varDcls); | ||
BType type = astStructLiteralExpr.getBType(); | ||
visitTypedesc(astStructLiteralExpr.pos, type, varDcls, getAnnotations(type.tsymbol, this.env)); | ||
|
||
BIRVariableDcl tempVarDcl = new BIRVariableDcl(astStructLiteralExpr.getBType(), | ||
this.env.nextLocalVarId(names), VarScope.FUNCTION, VarKind.TEMP); | ||
|
@@ -1671,17 +1672,33 @@ public void visit(BLangSimpleVarRef.BLangFieldVarRef fieldVarRef) { | |
public void visit(BLangArrayLiteral astArrayLiteralExpr) { | ||
BType bType = astArrayLiteralExpr.getBType(); | ||
if (bType.tag == TypeTags.TUPLE) { | ||
visitTypedesc(astArrayLiteralExpr.pos, bType, Collections.emptyList()); | ||
visitTypedesc(astArrayLiteralExpr.pos, bType, Collections.emptyList(), | ||
getAnnotations(bType.tsymbol, this.env)); | ||
} | ||
generateListConstructorExpr(astArrayLiteralExpr); | ||
} | ||
|
||
@Override | ||
public void visit(BLangTupleLiteral tupleLiteral) { | ||
visitTypedesc(tupleLiteral.pos, tupleLiteral.getBType(), Collections.emptyList()); | ||
BType type = tupleLiteral.getBType(); | ||
visitTypedesc(tupleLiteral.pos, type, Collections.emptyList(), getAnnotations(type.tsymbol, this.env)); | ||
generateListConstructorExpr(tupleLiteral); | ||
} | ||
|
||
private BIROperand getAnnotations(BTypeSymbol typeSymbol, BIRGenEnv env) { | ||
if (typeSymbol == null || typeSymbol.annotations == null) { | ||
return null; | ||
} | ||
return new BIROperand(getAnnotations(typeSymbol.annotations, env)); | ||
} | ||
|
||
private BIRVariableDcl getAnnotations(BVarSymbol annotations, BIRGenEnv env) { | ||
if (env.symbolVarMap.containsKey(annotations)) { | ||
return env.symbolVarMap.get(annotations); | ||
} | ||
return globalVarMap.get(annotations); | ||
} | ||
Comment on lines
+1688
to
+1700
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Move private function to the bottom. |
||
|
||
@Override | ||
public void visit(BLangGroupExpr groupExpr) { | ||
groupExpr.expression.accept(this); | ||
|
@@ -1691,7 +1708,8 @@ public void visit(BLangGroupExpr groupExpr) { | |
public void visit(BLangJSONArrayLiteral jsonArrayLiteralExpr) { | ||
BType bType = jsonArrayLiteralExpr.getBType(); | ||
if (bType.tag == TypeTags.TUPLE) { | ||
visitTypedesc(jsonArrayLiteralExpr.pos, bType, Collections.emptyList()); | ||
visitTypedesc(jsonArrayLiteralExpr.pos, bType, Collections.emptyList(), | ||
getAnnotations(bType.tsymbol, this.env)); | ||
} | ||
generateListConstructorExpr(jsonArrayLiteralExpr); | ||
} | ||
|
@@ -2195,7 +2213,7 @@ public void visit(BLangTypedescExpr accessExpr) { | |
this.env.enclFunc.localVars.add(tempVarDcl); | ||
BIROperand toVarRef = new BIROperand(tempVarDcl); | ||
setScopeAndEmit(new BIRNonTerminator.NewTypeDesc(accessExpr.pos, toVarRef, accessExpr.resolvedType, | ||
Collections.emptyList())); | ||
Collections.emptyList())); | ||
this.env.targetOperand = toVarRef; | ||
} | ||
|
||
|
@@ -2249,11 +2267,19 @@ public void visit(BLangSimpleVarRef.BLangTypeLoad typeLoad) { | |
} | ||
|
||
private void visitTypedesc(Location pos, BType type, List<BIROperand> varDcls) { | ||
BIRVariableDcl tempVarDcl = | ||
new BIRVariableDcl(symTable.typeDesc, this.env.nextLocalVarId(names), VarScope.FUNCTION, VarKind | ||
.TEMP); | ||
visitTypedesc(pos, type, varDcls, null); | ||
} | ||
|
||
private void visitTypedesc(Location pos, BType type, List<BIROperand> varDcls, BIROperand annotations) { | ||
Comment on lines
+2270
to
+2273
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need a separate method? |
||
BIRVariableDcl tempVarDcl = new BIRVariableDcl(symTable.typeDesc, this.env.nextLocalVarId(names), | ||
VarScope.FUNCTION, VarKind.TEMP); | ||
this.env.enclFunc.localVars.add(tempVarDcl); | ||
BIROperand toVarRef = new BIROperand(tempVarDcl); | ||
if (annotations != null) { | ||
setScopeAndEmit(new BIRNonTerminator.NewTypeDesc(pos, toVarRef, type, varDcls, annotations)); | ||
this.env.targetOperand = toVarRef; | ||
return; | ||
} | ||
setScopeAndEmit(new BIRNonTerminator.NewTypeDesc(pos, toVarRef, type, varDcls)); | ||
this.env.targetOperand = toVarRef; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -86,6 +86,7 @@ | |
import static org.objectweb.asm.Opcodes.V1_8; | ||
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmCodeGenUtil.toNameString; | ||
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.ABSTRACT_OBJECT_VALUE; | ||
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.ANNOTATIONS_FIELD; | ||
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.BAL_OPTIONAL; | ||
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.B_OBJECT; | ||
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.JVM_INIT_METHOD; | ||
|
@@ -108,13 +109,15 @@ | |
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmPackageGen.computeLockNameFromString; | ||
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.CAST_B_MAPPING_INITIAL_VALUE_ENTRY; | ||
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_MAP_ARRAY; | ||
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_MAP_VALUE; | ||
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.INIT_TYPEDESC; | ||
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.INSTANTIATE; | ||
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.OBJECT_TYPE_IMPL_INIT; | ||
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.POPULATE_INITIAL_VALUES; | ||
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.RECORD_INIT_WRAPPER; | ||
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.RECORD_VALUE_CLASS; | ||
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.TYPE_DESC_CONSTRUCTOR; | ||
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.TYPE_DESC_CONSTRUCTOR_WITH_ANNOTATIONS; | ||
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.TYPE_PARAMETER; | ||
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.VALUE_CLASS_INIT; | ||
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmTypeGen.getTypeDesc; | ||
|
@@ -249,7 +252,11 @@ private byte[] createRecordTypeDescClass(BRecordType recordType, String classNam | |
} | ||
cw.visit(V1_8, ACC_PUBLIC + ACC_SUPER, className, null, TYPEDESC_VALUE_IMPL, new String[]{TYPEDESC_VALUE}); | ||
|
||
FieldVisitor fv = cw.visitField(0, ANNOTATIONS_FIELD, GET_MAP_VALUE, null, null); | ||
fv.visitEnd(); | ||
|
||
this.createTypeDescConstructor(cw); | ||
this.createTypeDescConstructorWithAnnotations(cw, className); | ||
this.createInstantiateMethod(cw, recordType, typeDef); | ||
|
||
cw.visitEnd(); | ||
|
@@ -429,6 +436,32 @@ private void createTypeDescConstructor(ClassWriter cw) { | |
mv.visitEnd(); | ||
} | ||
|
||
private void createTypeDescConstructorWithAnnotations(ClassWriter cw, String name) { | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lets remove these new lines in the method. Better to remove with separate PR. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated(#39349) |
||
String descriptor = TYPE_DESC_CONSTRUCTOR_WITH_ANNOTATIONS; | ||
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, JVM_INIT_METHOD, descriptor, null, null); | ||
mv.visitCode(); | ||
|
||
mv.visitVarInsn(ALOAD, 0); | ||
mv.visitVarInsn(ALOAD, 3); | ||
mv.visitFieldInsn(PUTFIELD, name, ANNOTATIONS_FIELD, GET_MAP_VALUE); | ||
// load super | ||
mv.visitVarInsn(ALOAD, 0); | ||
// load type | ||
mv.visitVarInsn(ALOAD, 1); | ||
// load closures | ||
mv.visitVarInsn(ALOAD, 2); | ||
// load annotations | ||
mv.visitVarInsn(ALOAD, 3); | ||
// invoke `super(type)`; | ||
mv.visitMethodInsn(INVOKESPECIAL, TYPEDESC_VALUE_IMPL, JVM_INIT_METHOD, TYPE_DESC_CONSTRUCTOR_WITH_ANNOTATIONS, | ||
false); | ||
|
||
mv.visitInsn(RETURN); | ||
mv.visitMaxs(0, 0); | ||
mv.visitEnd(); | ||
} | ||
|
||
private void createRecordConstructor(ClassWriter cw, String argumentClass) { | ||
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, JVM_INIT_METHOD, argumentClass, null, null); | ||
mv.visitCode(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if someone tries to retrieve the annotations via the type now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you provide an example of this? Is it possible to access annotations from a type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In Java code.
io.ballerina.runtime.internal.types.BAnnotatableType#getAnnotations
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This returns a null value. And also this is an internal method and can not be utilized by external parties. Right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
io.ballerina.runtime.api.types.AnnotatableType#getAnnotations
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even if it was only used within lang, should be consistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we set the same annotations to the type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed the issue by setting the annotation to the type and utilizing the type to retrieve the annotations(Except using annotations in the typedesc)