3a3de571b5ee1830d3826f4913cb670ef2587baa
[idea/community.git] / jps / jps-builders / src / org / jetbrains / jps / builders / java / dependencyView / UsageRepr.java
1 // Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
2 package org.jetbrains.jps.builders.java.dependencyView;
3
4 import com.intellij.util.io.DataExternalizer;
5 import com.intellij.util.io.DataInputOutputUtil;
6 import gnu.trove.TIntHashSet;
7 import org.jetbrains.annotations.NotNull;
8 import org.jetbrains.jps.builders.storage.BuildDataCorruptedException;
9 import org.jetbrains.org.objectweb.asm.Type;
10
11 import java.io.DataInput;
12 import java.io.DataOutput;
13 import java.io.IOException;
14 import java.io.PrintStream;
15 import java.util.*;
16
17 /**
18  * @author: db
19  */
20 class UsageRepr {
21   private static final byte FIELD_USAGE = 0x0;
22   private static final byte FIELD_ASSIGN_USAGE = 0x1;
23   private static final byte METHOD_USAGE = 0x2;
24   private static final byte CLASS_USAGE = 0x3;
25   private static final byte CLASS_EXTENDS_USAGE = 0x4;
26   private static final byte CLASS_NEW_USAGE = 0x5;
27   private static final byte ANNOTATION_USAGE = 0x6;
28   private static final byte METAMETHOD_USAGE = 0x7;
29   private static final byte CLASS_AS_GENERIC_BOUND_USAGE = 0x8;
30   private static final byte MODULE_USAGE = 0x9;
31   private static final byte IMPORT_STATIC_MEMBER_USAGE = 0xa;
32   private static final byte IMPORT_STATIC_ON_DEMAND_USAGE = 0xb;
33
34   private static final int DEFAULT_SET_CAPACITY = 32;
35   private static final float DEFAULT_SET_LOAD_FACTOR = 0.98f;
36
37   private UsageRepr() {
38
39   }
40
41   public static abstract class Usage implements RW.Savable, Streamable {
42     public abstract int getOwner();
43   }
44
45   public static abstract class FMUsage extends Usage {
46     public final int myName;
47     public final int myOwner;
48
49     abstract void kindToStream (PrintStream stream);
50
51     @Override
52     public void toStream(final DependencyContext context, final PrintStream stream) {
53       kindToStream(stream);
54       stream.println("          Name : " + context.getValue(myName));
55       stream.println("          Owner: " + context.getValue(myOwner));
56     }
57
58     @Override
59     public int getOwner() {
60       return myOwner;
61     }
62
63     private FMUsage(final int name, final int owner) {
64       this.myName = name;
65       this.myOwner = owner;
66     }
67
68     private FMUsage(final DataInput in) {
69       try {
70         myName = DataInputOutputUtil.readINT(in);
71         myOwner = DataInputOutputUtil.readINT(in);
72       }
73       catch (IOException e) {
74         throw new BuildDataCorruptedException(e);
75       }
76     }
77
78     protected final void save(final byte tag, final DataOutput out) {
79       try {
80         out.writeByte(tag);
81         DataInputOutputUtil.writeINT(out, myName);
82         DataInputOutputUtil.writeINT(out, myOwner);
83       }
84       catch (IOException e) {
85         throw new BuildDataCorruptedException(e);
86       }
87     }
88
89     @Override
90     public boolean equals(final Object o) {
91       if (this == o) return true;
92       if (o == null || getClass() != o.getClass()) return false;
93
94       FMUsage fmUsage = (FMUsage)o;
95
96       if (myName != fmUsage.myName) return false;
97       if (myOwner != fmUsage.myOwner) return false;
98
99       return true;
100     }
101
102     @Override
103     public int hashCode() {
104       return 31 * myName + myOwner;
105     }
106   }
107
108   public static class FieldUsage extends FMUsage {
109     public final TypeRepr.AbstractType myType;
110
111     private FieldUsage(final DependencyContext context, final int name, final int owner, final int descriptor) {
112       super(name, owner);
113       myType = TypeRepr.getType(context, descriptor);
114     }
115
116     private FieldUsage(final DependencyContext context, final DataInput in) {
117       super(in);
118       try {
119         myType = TypeRepr.externalizer(context).read(in);
120       }
121       catch (IOException e) {
122         throw new BuildDataCorruptedException(e);
123       }
124     }
125
126     @Override
127     protected void kindToStream(final PrintStream stream) {
128       stream.println("FieldUsage:");
129     }
130
131     @Override
132     public void toStream(final DependencyContext context, final PrintStream stream) {
133       super.toStream(context, stream);
134       stream.println("          Type: " + myType.getDescr(context));
135     }
136
137     @Override
138     public void save(final DataOutput out) {
139       save(FIELD_USAGE, out);
140       myType.save(out);
141     }
142
143     @Override
144     public boolean equals(Object o) {
145       if (this == o) return true;
146       if (o == null || getClass() != o.getClass()) return false;
147
148       final FieldUsage that = (FieldUsage)o;
149
150       return myType.equals(that.myType) && myName == that.myName && myOwner == that.myOwner;
151     }
152
153     @Override
154     public int hashCode() {
155       return 31 * (31 * myType.hashCode() + myName) + myOwner;
156     }
157   }
158
159   public static class FieldAssignUsage extends FieldUsage {
160     private FieldAssignUsage(final DependencyContext context, final int n, final int o, final int d) {
161       super(context, n, o, d);
162     }
163
164     private FieldAssignUsage(final DependencyContext context, final DataInput in) {
165       super(context, in);
166     }
167
168     @Override
169     protected void kindToStream(final PrintStream stream) {
170       stream.println("FieldAssignUsage:");
171     }
172
173     @Override
174     public void save(final DataOutput out) {
175       save(FIELD_ASSIGN_USAGE, out);
176       myType.save(out);
177     }
178
179     @Override
180     public boolean equals(Object o) {
181       if (this == o) return true;
182       if (o == null || getClass() != o.getClass()) return false;
183
184       final FieldAssignUsage that = (FieldAssignUsage)o;
185
186       return myType.equals(that.myType) && myName == that.myName && myOwner == that.myOwner;
187     }
188
189     @Override
190     public int hashCode() {
191       return super.hashCode() + 1;
192     }
193   }
194
195   public static class MethodUsage extends FMUsage {
196     public final TypeRepr.AbstractType[] myArgumentTypes;
197     public final TypeRepr.AbstractType myReturnType;
198
199     private MethodUsage(final DependencyContext context, final int name, final int owner, final String descriptor) {
200       super(name, owner);
201       myArgumentTypes = TypeRepr.getType(context, Type.getArgumentTypes(descriptor));
202       myReturnType = TypeRepr.getType(context, Type.getReturnType(descriptor));
203     }
204
205     private MethodUsage(final DependencyContext context, final DataInput in) {
206       super(in);
207       try {
208         final DataExternalizer<TypeRepr.AbstractType> externalizer = TypeRepr.externalizer(context);
209         int argumentTypes = DataInputOutputUtil.readINT(in);
210         myArgumentTypes = RW.read(externalizer, in, argumentTypes != 0 ? new TypeRepr.AbstractType[argumentTypes]: TypeRepr.AbstractType.EMPTY_TYPE_ARRAY);
211         myReturnType = externalizer.read(in);
212       }
213       catch (IOException e) {
214         throw new BuildDataCorruptedException(e);
215       }
216     }
217
218     @Override
219     public void save(final DataOutput out) {
220       save(METHOD_USAGE, out);
221       RW.save(myArgumentTypes, out);
222       myReturnType.save(out);
223     }
224
225     @Override
226     public boolean equals(Object o) {
227       if (this == o) return true;
228       if (o == null || getClass() != o.getClass()) return false;
229
230       final MethodUsage that = (MethodUsage)o;
231
232       if (myReturnType != null ? !myReturnType.equals(that.myReturnType) : that.myReturnType != null) return false;
233       if (myName != that.myName) return false;
234       if (myOwner != that.myOwner) return false;
235
236       return Arrays.equals(myArgumentTypes, that.myArgumentTypes);
237     }
238
239     @Override
240     public int hashCode() {
241       return ((31 * Arrays.hashCode(myArgumentTypes) + (myReturnType.hashCode())) * 31 + (myName)) * 31 + (myOwner);
242     }
243
244     @Override
245     void kindToStream(final PrintStream stream) {
246       stream.println("MethodUsage:");
247     }
248
249     @Override
250     public void toStream(DependencyContext context, PrintStream stream) {
251       super.toStream(context, stream);
252
253       stream.println("          Arguments:");
254
255       for (final TypeRepr.AbstractType at : myArgumentTypes) {
256         stream.println("            " + at.getDescr(context));
257       }
258
259       stream.println("          Return type:");
260       stream.println("            " + myReturnType.getDescr(context));
261     }
262   }
263
264   public static class MetaMethodUsage extends FMUsage {
265
266     public MetaMethodUsage(final int n, final int o) {
267       super(n, o);
268     }
269
270     public MetaMethodUsage(final DataInput in) {
271       super(in);
272     }
273
274     @Override
275     public void save(final DataOutput out) {
276       save(METAMETHOD_USAGE, out);
277     }
278
279     @Override
280     void kindToStream(final PrintStream stream) {
281       stream.println("MetaMethodUsage:");
282     }
283
284     @Override
285     public void toStream(DependencyContext context, PrintStream stream) {
286       super.toStream(context, stream);
287     }
288   }
289
290   public static class ImportStaticMemberUsage extends FMUsage {
291
292     public ImportStaticMemberUsage(final int n, final int o) {
293       super(n, o);
294     }
295
296     public ImportStaticMemberUsage(final DataInput in) {
297       super(in);
298     }
299
300     @Override
301     public void save(final DataOutput out) {
302       save(IMPORT_STATIC_MEMBER_USAGE, out);
303     }
304
305     @Override
306     void kindToStream(final PrintStream stream) {
307       stream.println("ImportStaticMemberUsage:");
308     }
309
310     @Override
311     public void toStream(DependencyContext context, PrintStream stream) {
312       super.toStream(context, stream);
313     }
314   }
315
316   public static class ClassUsage extends Usage {
317     final int myClassName;
318
319     @Override
320     public int getOwner() {
321       return myClassName;
322     }
323
324     private ClassUsage(final int className) {
325       this.myClassName = className;
326     }
327
328     private ClassUsage(final DataInput in) {
329       try {
330         myClassName = DataInputOutputUtil.readINT(in);
331       }
332       catch (IOException e) {
333         throw new BuildDataCorruptedException(e);
334       }
335     }
336
337     @Override
338     public void save(final DataOutput out) {
339       try {
340         out.writeByte(CLASS_USAGE);
341         DataInputOutputUtil.writeINT(out, myClassName);
342       }
343       catch (IOException e) {
344         throw new BuildDataCorruptedException(e);
345       }
346     }
347
348     @Override
349     public boolean equals(Object o) {
350       if (this == o) return true;
351       if (o == null || getClass() != o.getClass()) return false;
352
353       final ClassUsage that = (ClassUsage)o;
354
355       return myClassName == that.myClassName;
356     }
357
358     @Override
359     public int hashCode() {
360       return myClassName;
361     }
362
363     @Override
364     public void toStream(final DependencyContext context, final PrintStream stream) {
365       stream.println("ClassUsage: " + context.getValue(myClassName));
366     }
367   }
368
369   public static class ModuleUsage extends Usage {
370     final int myModuleName;
371
372     @Override
373     public int getOwner() {
374       return myModuleName;
375     }
376
377     private ModuleUsage(final int moduleName) {
378       this.myModuleName = moduleName;
379     }
380
381     private ModuleUsage(final DataInput in) {
382       try {
383         myModuleName = DataInputOutputUtil.readINT(in);
384       }
385       catch (IOException e) {
386         throw new BuildDataCorruptedException(e);
387       }
388     }
389
390     @Override
391     public void save(final DataOutput out) {
392       try {
393         out.writeByte(MODULE_USAGE);
394         DataInputOutputUtil.writeINT(out, myModuleName);
395       }
396       catch (IOException e) {
397         throw new BuildDataCorruptedException(e);
398       }
399     }
400
401     @Override
402     public boolean equals(Object o) {
403       if (this == o) return true;
404       if (o == null || getClass() != o.getClass()) return false;
405
406       final ModuleUsage that = (ModuleUsage)o;
407
408       return myModuleName == that.myModuleName;
409     }
410
411     @Override
412     public int hashCode() {
413       return myModuleName;
414     }
415
416     @Override
417     public void toStream(final DependencyContext context, final PrintStream stream) {
418       stream.println("ModuleUsage: " + context.getValue(myModuleName));
419     }
420   }
421
422   public static class ImportStaticOnDemandUsage extends Usage {
423     final int myOwner; // owner class
424
425     @Override
426     public int getOwner() {
427       return myOwner;
428     }
429
430     private ImportStaticOnDemandUsage(final int owner) {
431       this.myOwner = owner;
432     }
433
434     private ImportStaticOnDemandUsage(final DataInput in) {
435       try {
436         myOwner = DataInputOutputUtil.readINT(in);
437       }
438       catch (IOException e) {
439         throw new BuildDataCorruptedException(e);
440       }
441     }
442
443     @Override
444     public void save(final DataOutput out) {
445       try {
446         out.writeByte(IMPORT_STATIC_ON_DEMAND_USAGE);
447         DataInputOutputUtil.writeINT(out, myOwner);
448       }
449       catch (IOException e) {
450         throw new BuildDataCorruptedException(e);
451       }
452     }
453
454     @Override
455     public boolean equals(Object o) {
456       if (this == o) return true;
457       if (o == null || getClass() != o.getClass()) return false;
458
459       final ImportStaticOnDemandUsage that = (ImportStaticOnDemandUsage)o;
460
461       return myOwner == that.myOwner;
462     }
463
464     @Override
465     public int hashCode() {
466       return myOwner;
467     }
468
469     @Override
470     public void toStream(final DependencyContext context, final PrintStream stream) {
471       stream.println("ImportStaticOnDemandUsage: " + context.getValue(myOwner));
472     }
473   }
474
475   public static class ClassAsGenericBoundUsage extends ClassUsage {
476     public ClassAsGenericBoundUsage(int className) {
477       super(className);
478     }
479
480     public ClassAsGenericBoundUsage(DataInput in) {
481       super(in);
482     }
483
484     @Override
485     public int hashCode() {
486       return super.hashCode() + 3;
487     }
488
489     @Override
490     public void save(final DataOutput out) {
491       try {
492         out.writeByte(CLASS_AS_GENERIC_BOUND_USAGE);
493         DataInputOutputUtil.writeINT(out, myClassName);
494       }
495       catch (IOException e) {
496         throw new BuildDataCorruptedException(e);
497       }
498     }
499
500     @Override
501     public void toStream(final DependencyContext context, final PrintStream stream) {
502       stream.println("ClassAsGenericBoundUsage: " + context.getValue(myClassName));
503     }
504   }
505
506   public static class ClassExtendsUsage extends Usage {
507     protected final int myClassName;
508
509     @Override
510     public int getOwner() {
511       return myClassName;
512     }
513
514     private ClassExtendsUsage(final int className) {
515       this.myClassName = className;
516     }
517
518     private ClassExtendsUsage(final DataInput in) {
519       try {
520         myClassName = DataInputOutputUtil.readINT(in);
521       }
522       catch (IOException e) {
523         throw new BuildDataCorruptedException(e);
524       }
525     }
526
527     @Override
528     public void save(final DataOutput out) {
529       try {
530         out.writeByte(CLASS_EXTENDS_USAGE);
531         DataInputOutputUtil.writeINT(out, myClassName);
532       }
533       catch (IOException e) {
534         throw new BuildDataCorruptedException(e);
535       }
536     }
537
538     @Override
539     public int hashCode() {
540       return myClassName + 1;
541     }
542
543     @Override
544     public boolean equals(Object o) {
545       if (this == o) return true;
546       if (o == null || getClass() != o.getClass()) return false;
547
548       ClassExtendsUsage that = (ClassExtendsUsage)o;
549
550       if (myClassName != that.myClassName) return false;
551
552       return true;
553     }
554
555     @Override
556     public void toStream(final DependencyContext context, final PrintStream stream) {
557       stream.println("ClassExtendsUsage: " + context.getValue(myClassName));
558     }
559   }
560
561   public static class ClassNewUsage extends ClassExtendsUsage {
562     public ClassNewUsage(int className) {
563       super(className);
564     }
565
566     private ClassNewUsage(final DataInput in) {
567       super(in);
568     }
569
570     @Override
571     public void save(final DataOutput out) {
572       try {
573         out.writeByte(CLASS_NEW_USAGE);
574         DataInputOutputUtil.writeINT(out, myClassName);
575       }
576       catch (IOException e) {
577         throw new BuildDataCorruptedException(e);
578       }
579     }
580
581     @Override
582     public int hashCode() {
583       return myClassName + 2;
584     }
585
586     @Override
587     public void toStream(final DependencyContext context, final PrintStream stream) {
588       stream.println("ClassNewUsage: " + context.getValue(myClassName));
589     }
590   }
591
592   public static class AnnotationUsage extends Usage {
593     public static final DataExternalizer<ElemType> elementTypeExternalizer = new DataExternalizer<ElemType>() {
594       @Override
595       public void save(@NotNull final DataOutput out, final ElemType value) throws IOException {
596         DataInputOutputUtil.writeINT(out, value.ordinal());
597       }
598
599       @Override
600       public ElemType read(@NotNull final DataInput in) throws IOException {
601         final int ordinal = DataInputOutputUtil.readINT(in);
602         for (ElemType value : ElemType.values()) {
603           if (value.ordinal() == ordinal) {
604             return value;
605           }
606         }
607         throw new IOException("Error reading ElementType enum value; unknown ordinal: " + ordinal);
608       }
609     };
610
611     final TypeRepr.ClassType myType;
612     final TIntHashSet myUsedArguments;
613     final Set<ElemType> myUsedTargets;
614
615     public boolean satisfies(final AnnotationUsage annotationUsage) {
616       if (!myType.equals(annotationUsage.myType)) {
617         return false;
618       }
619
620       boolean argumentsSatisfy = false;
621
622       if (myUsedArguments != null) {
623         final TIntHashSet arguments = new TIntHashSet(myUsedArguments.toArray());
624
625         arguments.removeAll(annotationUsage.myUsedArguments.toArray());
626
627         argumentsSatisfy = !arguments.isEmpty();
628       }
629
630       boolean targetsSatisfy = false;
631
632       if (myUsedTargets != null) {
633         final Collection<ElemType> targets = EnumSet.copyOf(myUsedTargets);
634
635         targets.retainAll(annotationUsage.myUsedTargets);
636
637         targetsSatisfy = !targets.isEmpty();
638       }
639
640       return argumentsSatisfy || targetsSatisfy;
641     }
642
643     private AnnotationUsage(final TypeRepr.ClassType type, final TIntHashSet usedArguments, final Set<ElemType> targets) {
644       this.myType = type;
645       this.myUsedArguments = usedArguments;
646       this.myUsedTargets = targets;
647     }
648
649     private AnnotationUsage(final DependencyContext context, final DataInput in) {
650       final DataExternalizer<TypeRepr.AbstractType> externalizer = TypeRepr.externalizer(context);
651
652       try {
653         myType = (TypeRepr.ClassType)externalizer.read(in);
654         myUsedArguments = RW.read(new TIntHashSet(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR), in);
655         myUsedTargets = RW.read(elementTypeExternalizer, EnumSet.noneOf(ElemType.class), in);
656       }
657       catch (IOException e) {
658         throw new BuildDataCorruptedException(e);
659       }
660     }
661
662     @Override
663     public void save(final DataOutput out) {
664       try {
665         out.writeByte(ANNOTATION_USAGE);
666         myType.save(out);
667         RW.save(myUsedArguments, out);
668         RW.save(myUsedTargets, elementTypeExternalizer, out);
669       }
670       catch (IOException e) {
671         throw new BuildDataCorruptedException(e);
672       }
673     }
674
675     @Override
676     public int getOwner() {
677       return myType.className;
678     }
679
680     @Override
681     public boolean equals(final Object o) {
682       if (this == o) return true;
683       if (o == null || getClass() != o.getClass()) return false;
684
685       AnnotationUsage that = (AnnotationUsage)o;
686
687       if (myUsedArguments != null ? !myUsedArguments.equals(that.myUsedArguments) : that.myUsedArguments != null) return false;
688       if (myUsedTargets != null ? !myUsedTargets.equals(that.myUsedTargets) : that.myUsedTargets != null) return false;
689       if (myType != null ? !myType.equals(that.myType) : that.myType != null) return false;
690
691       return true;
692     }
693
694     @Override
695     public int hashCode() {
696       int result = myType != null ? myType.hashCode() : 0;
697       result = 31 * result + (myUsedArguments != null ? myUsedArguments.hashCode() : 0);
698       result = 31 * result + (myUsedTargets != null ? myUsedTargets.hashCode() : 0);
699       return result;
700     }
701
702     @Override
703     public void toStream(final DependencyContext context, final PrintStream stream) {
704       stream.println("    AnnotationUsage:");
705       stream.println("      Type     : " + myType.getDescr(context));
706
707       final List<String> arguments = new LinkedList<>();
708
709       if (myUsedArguments != null) {
710         myUsedArguments.forEach(value -> {
711           arguments.add(context.getValue(value));
712           return true;
713         });
714       }
715
716       Collections.sort(arguments);
717
718       final List<String> targets = new LinkedList<>();
719
720       if (myUsedTargets != null) {
721         for (final ElemType e : myUsedTargets) {
722           targets.add(e.toString());
723         }
724       }
725
726       Collections.sort(targets);
727
728       stream.println("      Arguments:");
729
730       for (final String s : arguments) {
731         stream.println("        " + s);
732       }
733
734       stream.println("      Targets  :");
735
736       for (final String s : targets) {
737         stream.println("        " + s);
738       }
739     }
740   }
741
742   public static Usage createFieldUsage(final DependencyContext context, final int name, final int owner, final int descr) {
743     return context.getUsage(new FieldUsage(context, name, owner, descr));
744   }
745
746   public static Usage createFieldAssignUsage(final DependencyContext context, final int name, final int owner, final int descr) {
747     return context.getUsage(new FieldAssignUsage(context, name, owner, descr));
748   }
749
750   public static Usage createMethodUsage(final DependencyContext context, final int name, final int owner, final String descr) {
751     return context.getUsage(new MethodUsage(context, name, owner, descr));
752   }
753
754   public static Usage createMetaMethodUsage(final DependencyContext context, final int name, final int owner) {
755     return context.getUsage(new MetaMethodUsage(name, owner));
756   }
757
758   public static Usage createImportStaticMemberUsage(final DependencyContext context, final int name, final int owner) {
759     return context.getUsage(new ImportStaticMemberUsage(name, owner));
760   }
761
762   public static Usage createImportStaticOnDemandUsage(final DependencyContext context, final int owner) {
763     return context.getUsage(new ImportStaticOnDemandUsage(owner));
764   }
765
766   public static Usage createClassUsage(final DependencyContext context, final int name) {
767     return context.getUsage(new ClassUsage(name));
768   }
769
770   public static Usage createClassAsGenericBoundUsage(final DependencyContext context, final int name) {
771     return context.getUsage(new ClassAsGenericBoundUsage(name));
772   }
773
774   public static Usage createClassNewUsage(final DependencyContext context, final int name) {
775     return context.getUsage(new ClassNewUsage(name));
776   }
777
778   public static Usage createAnnotationUsage(final DependencyContext context,
779                                             final TypeRepr.ClassType type,
780                                             final TIntHashSet usedArguments,
781                                             final Set<ElemType> targets) {
782     return context.getUsage(new AnnotationUsage(type, usedArguments, targets));
783   }
784
785   public static Usage createModuleUsage(final DependencyContext context, final int name) {
786     return context.getUsage(new ModuleUsage(name));
787   }
788
789   public static DataExternalizer<Usage> externalizer(final DependencyContext context) {
790     return new DataExternalizer<Usage>() {
791       @Override
792       public void save(@NotNull final DataOutput out, final Usage value) throws IOException {
793         value.save(out);
794       }
795
796       @Override
797       public Usage read(@NotNull DataInput in) throws IOException {
798         final byte tag = in.readByte();
799         switch (tag) {
800           case CLASS_USAGE:
801             return context.getUsage(new ClassUsage(in));
802
803           case CLASS_AS_GENERIC_BOUND_USAGE:
804             return context.getUsage(new ClassAsGenericBoundUsage(in));
805
806           case CLASS_EXTENDS_USAGE:
807             return context.getUsage(new ClassExtendsUsage(in));
808
809           case CLASS_NEW_USAGE:
810             return context.getUsage(new ClassNewUsage(in));
811
812           case FIELD_USAGE:
813             return context.getUsage(new FieldUsage(context, in));
814
815           case FIELD_ASSIGN_USAGE:
816             return context.getUsage(new FieldAssignUsage(context, in));
817
818           case METHOD_USAGE:
819             return context.getUsage(new MethodUsage(context, in));
820
821           case ANNOTATION_USAGE:
822             return context.getUsage(new AnnotationUsage(context, in));
823
824           case METAMETHOD_USAGE:
825             return context.getUsage(new MetaMethodUsage(in));
826
827           case MODULE_USAGE:
828             return context.getUsage(new ModuleUsage(in));
829
830           case IMPORT_STATIC_MEMBER_USAGE:
831             return context.getUsage(new ImportStaticMemberUsage(in));
832
833           case IMPORT_STATIC_ON_DEMAND_USAGE:
834             return context.getUsage(new ImportStaticOnDemandUsage(in));
835         }
836
837         assert (false);
838
839         return null;
840       }
841     };
842   }
843 }