11package org .parchmentmc .compass .data .validation .impl ;
22
3+ import org .checkerframework .checker .nullness .qual .MonotonicNonNull ;
34import org .checkerframework .checker .nullness .qual .Nullable ;
45import org .parchmentmc .compass .data .validation .Validator ;
6+ import org .parchmentmc .compass .util .DescriptorIndexer ;
57import org .parchmentmc .feather .mapping .MappingDataContainer ;
68import org .parchmentmc .feather .metadata .ClassMetadata ;
79import org .parchmentmc .feather .metadata .FieldMetadata ;
810import org .parchmentmc .feather .metadata .MethodMetadata ;
911import org .parchmentmc .feather .metadata .SourceMetadata ;
1012
13+ import java .util .BitSet ;
14+
1115/**
12- * Validates that classes, fields, and methods exist according to the Blackstone metadata.
16+ * Validates that classes, fields, methods, and parameters exist according to the Blackstone metadata.
17+ *
18+ * @see DescriptorIndexer
1319 */
1420public class MemberExistenceValidator extends Validator {
21+ @ MonotonicNonNull
22+ private DescriptorIndexer indexer ;
23+
1524 public MemberExistenceValidator () {
1625 super ("member existence" );
1726 }
1827
1928 @ Override
2029 public boolean visit (MappingDataContainer container , @ Nullable SourceMetadata metadata ) {
30+ indexer = new DescriptorIndexer ();
2131 return metadata != null ; // Only visit when we have metadata available
2232 }
2333
2434 @ Override
2535 public boolean preVisit (DataType type ) {
26- return DataType .CLASSES .test (type ) || DataType .FIELDS .test (type ) || DataType .METHODS .test (type );
36+ return DataType .CLASSES .test (type )
37+ || DataType .FIELDS .test (type )
38+ || DataType .METHODS .test (type )
39+ || DataType .PARAMETERS .test (type );
2740 }
2841
2942 @ Override
@@ -36,19 +49,33 @@ public boolean visitClass(MappingDataContainer.ClassData classData, @Nullable Cl
3649 }
3750
3851 @ Override
39- public void visitField (MappingDataContainer .ClassData classData , MappingDataContainer .FieldData fieldData ,
52+ public void visitField (MappingDataContainer .ClassData classData , MappingDataContainer .FieldData fieldData ,
4053 @ Nullable ClassMetadata classMetadata , @ Nullable FieldMetadata fieldMetadata ) {
4154 if (fieldMetadata == null ) {
4255 error ("Field does not exist according to metadata" );
4356 }
4457 }
4558
4659 @ Override
47- public boolean visitMethod (MappingDataContainer .ClassData classData , MappingDataContainer .MethodData methodData ,
60+ public boolean visitMethod (MappingDataContainer .ClassData classData , MappingDataContainer .MethodData methodData ,
4861 @ Nullable ClassMetadata classMetadata , @ Nullable MethodMetadata methodMetadata ) {
4962 if (methodMetadata == null ) {
5063 error ("Method does not exist according to metadata" );
64+ return false ;
65+ }
66+ return true ;
67+ }
68+
69+ @ Override
70+ public void visitParameter (MappingDataContainer .ClassData classData , MappingDataContainer .MethodData methodData ,
71+ MappingDataContainer .ParameterData paramData , @ Nullable ClassMetadata classMetadata ,
72+ @ Nullable MethodMetadata methodMetadata ) {
73+ final BitSet indexes = indexer .getIndexes (methodData , methodMetadata );
74+ byte paramIndex = paramData .getIndex ();
75+
76+ if (!indexes .get (paramIndex )) {
77+ // When above is resolved, add special-case for index 0 and non-static method
78+ error ("Parameter does not exist according to descriptor" );
5179 }
52- return false ;
5380 }
5481}
0 commit comments