Skip to content

Commit 4a2808f

Browse files
committed
improved enum and enum constant pretty printing
1 parent 4fc0ce9 commit 4a2808f

11 files changed

Lines changed: 105 additions & 66 deletions

File tree

lsif-java/src/main/scala/com/sourcegraph/lsif_java/commands/SnapshotLsifCommand.scala

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,10 +129,7 @@ object SnapshotLsifCommand {
129129
hoverId <- lsif.hoverEdges.get(resultSetId)
130130
hover <- lsif.hoverVertexes.get(hoverId)
131131
} yield hover
132-
).get.getContentsList.asScala.map { h =>
133-
println(h.getLanguage)
134-
h
135-
}.find { h => h.getLanguage != Language.UNKNOWN_LANGUAGE.toString.toLowerCase }.get.getValue
132+
).get.getContentsList.asScala.find { h => h.getLanguage != Language.UNKNOWN_LANGUAGE.toString.toLowerCase }.get.getValue
136133
val symInfo = SymbolInformation
137134
.newBuilder()
138135
// we cheese it a bit here, as this is less work than trying to reconstruct

lsif-semanticdb/src/main/java/com/sourcegraph/lsif_semanticdb/SignatureFormatter.java

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -106,10 +106,24 @@ private void formatMethodSignature(MethodSignature methodSignature) {
106106
}
107107

108108
private void formatValueSignature(ValueSignature valueSignature) {
109-
printKeyword(formatAccess());
110-
printKeyword(formatModifiers());
111-
printKeyword(formatType(valueSignature.getTpe()));
112-
s.append(symbolInformation.getDisplayName());
109+
if (isEnumConstant()) {
110+
String ownerSym = SymbolDescriptor.parseFromSymbol(symbolInformation.getSymbol()).owner;
111+
SymbolInformation ownerInfo = symtab.symbols.get(ownerSym);
112+
List<SymbolInformation> enumConstants =
113+
getSymlinks(ownerInfo.getSignature().getClassSignature().getDeclarations()).stream()
114+
.filter(Objects::nonNull)
115+
.filter(this::isEnumConstant)
116+
.collect(Collectors.toList());
117+
int ordinal = enumConstants.indexOf(symbolInformation);
118+
s.append(ownerInfo.getDisplayName()).append('.');
119+
s.append(this.symbolInformation.getDisplayName());
120+
s.append(" /* ordinal ").append(ordinal).append(" */");
121+
} else {
122+
printKeyword(formatAccess());
123+
printKeyword(formatModifiers());
124+
printKeyword(formatType(valueSignature.getTpe()));
125+
s.append(symbolInformation.getDisplayName());
126+
}
113127
}
114128

115129
private void formatTypeParameterSignature(TypeSignature typeSignature) {
@@ -222,8 +236,29 @@ private void printKeyword(String keyword) {
222236
s.append(keyword).append(' ');
223237
}
224238

239+
private boolean isEnumConstant(SymbolInformation symInfo) {
240+
if (!(has(Property.ENUM, symInfo)
241+
&& has(Property.FINAL, symInfo)
242+
&& has(Property.STATIC, symInfo)
243+
&& symInfo.getAccess().hasPublicAccess())) {
244+
return false;
245+
}
246+
SymbolInformation owner =
247+
symtab.symbols.get(SymbolDescriptor.parseFromSymbol(symInfo.getSymbol()).owner);
248+
if (owner == null) return false;
249+
return owner.getKind() == SymbolInformation.Kind.CLASS && has(Property.ENUM, owner);
250+
}
251+
252+
private boolean isEnumConstant() {
253+
return isEnumConstant(symbolInformation);
254+
}
255+
256+
private boolean has(Property property, SymbolInformation symInfo) {
257+
return (symInfo.getProperties() & property.getNumber()) > 0;
258+
}
259+
225260
private boolean has(Property property) {
226-
return (symbolInformation.getProperties() & property.getNumber()) > 0;
261+
return has(property, symbolInformation);
227262
}
228263

229264
/**

semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbVisitor.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import com.sourcegraph.semanticdb_javac.Semanticdb.SymbolInformation.Property;
1414
import com.sourcegraph.semanticdb_javac.Semanticdb.SymbolOccurrence.Role;
1515

16-
import javax.lang.model.element.Element;
16+
import javax.lang.model.element.ElementKind;
1717
import javax.lang.model.util.Elements;
1818
import java.io.IOException;
1919
import java.nio.file.Path;
@@ -22,6 +22,7 @@
2222
import java.util.ArrayList;
2323
import java.util.Iterator;
2424
import java.util.Optional;
25+
import java.util.stream.Collectors;
2526

2627
/** Walks the AST of a typechecked compilation unit and generates a SemanticDB TextDocument. */
2728
public class SemanticdbVisitor extends TreePathScanner<Void, Void> {
@@ -69,17 +70,17 @@ public Semanticdb.TextDocument buildTextDocument(CompilationUnitTree tree) {
6970
.build();
7071
}
7172

72-
private void emitSymbolOccurrence(
73-
Symbol sym, JCDiagnostic.DiagnosticPosition pos, Role role, CompilerRange kind) {
74-
Optional<Semanticdb.SymbolOccurrence> occ = semanticdbOccurrence(sym, pos, kind, role);
73+
private <T extends JCTree & JCDiagnostic.DiagnosticPosition> void emitSymbolOccurrence(
74+
Symbol sym, T posTree, Role role, CompilerRange kind) {
75+
Optional<Semanticdb.SymbolOccurrence> occ = semanticdbOccurrence(sym, posTree, kind, role);
7576
occ.ifPresent(occurrences::add);
7677
if (role == Role.DEFINITION) {
7778
// Only emit SymbolInformation for symbols that are defined in this compilation unit.
78-
emitSymbolInformation(sym);
79+
emitSymbolInformation(sym, posTree);
7980
}
8081
}
8182

82-
private void emitSymbolInformation(Symbol sym) {
83+
private void emitSymbolInformation(Symbol sym, JCTree tree) {
8384
Semanticdb.SymbolInformation.Builder builder =
8485
Semanticdb.SymbolInformation.newBuilder().setSymbol(semanticdbSymbol(sym));
8586
Semanticdb.Documentation documentation = semanticdbDocumentation(sym);
@@ -109,6 +110,11 @@ private void emitSymbolInformation(Symbol sym) {
109110
case TYPE_PARAMETER:
110111
builder.setKind(Kind.TYPE_PARAMETER);
111112
break;
113+
case ENUM_CONSTANT: // overwrite previous value here
114+
String args =
115+
((JCTree.JCNewClass) ((JCTree.JCVariableDecl) tree).init)
116+
.args.stream().map(JCTree::toString).collect(Collectors.joining(", "));
117+
if (!args.isEmpty()) builder.setDisplayName(sym.name.toString() + "(" + args + ")");
112118
}
113119

114120
Semanticdb.SymbolInformation info = builder.build();

tests/minimized/src/main/java/minimized/Enums.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
import java.util.Arrays;
44

5-
public enum Enums {
6-
A("A"),
7-
B("B"),
8-
C("C");
5+
enum Enums {
6+
A("A", 420),
7+
B("B", 1),
8+
C("C", 5);
99
public String value;
1010

11-
Enums(String value) {
11+
Enums(String value, int a) {
1212
this.value = value;
1313
}
1414

tests/snapshots/src/main/generated/com/airbnb/epoxy/Carousel.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -783,14 +783,14 @@ public static class Padding {
783783
// ^^^^^^^^^^^ definition com/airbnb/epoxy/Carousel#Padding#paddingType. public final PaddingType paddingType
784784

785785
enum PaddingType {
786-
// ^^^^^^^^^^^ definition com/airbnb/epoxy/Carousel#Padding#PaddingType# static final enum PaddingType extends Enum<PaddingType>
786+
// ^^^^^^^^^^^ definition com/airbnb/epoxy/Carousel#Padding#PaddingType# enum PaddingType
787787
// ^^^^^^^^^^^ definition com/airbnb/epoxy/Carousel#Padding#PaddingType#`<init>`(). private <init>()
788788
PX,
789-
// ^^ definition com/airbnb/epoxy/Carousel#Padding#PaddingType#PX. public static final PaddingType PX
789+
// ^^ definition com/airbnb/epoxy/Carousel#Padding#PaddingType#PX. PaddingType.PX /* ordinal 0 */
790790
DP,
791-
// ^^ definition com/airbnb/epoxy/Carousel#Padding#PaddingType#DP. public static final PaddingType DP
791+
// ^^ definition com/airbnb/epoxy/Carousel#Padding#PaddingType#DP. PaddingType.DP /* ordinal 1 */
792792
RESOURCE
793-
// ^^^^^^^^ definition com/airbnb/epoxy/Carousel#Padding#PaddingType#RESOURCE. public static final PaddingType RESOURCE
793+
// ^^^^^^^^ definition com/airbnb/epoxy/Carousel#Padding#PaddingType#RESOURCE. PaddingType.RESOURCE /* ordinal 2 */
794794
}
795795

796796
/**

tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyAttribute.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,20 +41,20 @@
4141
* created.
4242
*/
4343
enum Option {
44-
// ^^^^^^ definition com/airbnb/epoxy/EpoxyAttribute#Option# public static final enum Option extends Enum<Option>
44+
// ^^^^^^ definition com/airbnb/epoxy/EpoxyAttribute#Option# public enum Option
4545
// ^^^^^^ definition com/airbnb/epoxy/EpoxyAttribute#Option#`<init>`(). private <init>()
4646
/**
4747
* A getter is generated for this attribute by default. Add this option to prevent a getter from
4848
* being generated.
4949
*/
5050
NoGetter,
51-
// ^^^^^^^^ definition com/airbnb/epoxy/EpoxyAttribute#Option#NoGetter. public static final Option NoGetter
51+
// ^^^^^^^^ definition com/airbnb/epoxy/EpoxyAttribute#Option#NoGetter. Option.NoGetter /* ordinal 0 */
5252
/**
5353
* A setter is generated for this attribute by default. Add this option to prevent a setter from
5454
* being generated.
5555
*/
5656
NoSetter,
57-
// ^^^^^^^^ definition com/airbnb/epoxy/EpoxyAttribute#Option#NoSetter. public static final Option NoSetter
57+
// ^^^^^^^^ definition com/airbnb/epoxy/EpoxyAttribute#Option#NoSetter. Option.NoSetter /* ordinal 1 */
5858
/**
5959
* By default every attribute's hashCode and equals method is called when determining the
6060
* model's state. This option can be used to exclude an attribute's hashCode/equals from
@@ -71,7 +71,7 @@ enum Option {
7171
* then you can use this to prevent the rebind.
7272
*/
7373
DoNotHash,
74-
// ^^^^^^^^^ definition com/airbnb/epoxy/EpoxyAttribute#Option#DoNotHash. public static final Option DoNotHash
74+
// ^^^^^^^^^ definition com/airbnb/epoxy/EpoxyAttribute#Option#DoNotHash. Option.DoNotHash /* ordinal 2 */
7575
/**
7676
* This is meant to be used in conjunction with {@link PackageEpoxyConfig#requireHashCode()}.
7777
* When that is enabled every attribute must implement hashCode/equals. However, there are some
@@ -87,13 +87,13 @@ enum Option {
8787
* contribute to model state you should use {@link Option#DoNotHash} instead.
8888
*/
8989
IgnoreRequireHashCode,
90-
// ^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyAttribute#Option#IgnoreRequireHashCode. public static final Option IgnoreRequireHashCode
90+
// ^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyAttribute#Option#IgnoreRequireHashCode. Option.IgnoreRequireHashCode /* ordinal 3 */
9191
/**
9292
* This attribute is used in {@link Object#toString()} implementation by default.
9393
* Add this option to prevent this attribute being used in {@link Object#toString()}.
9494
*/
9595
DoNotUseInToString
96-
// ^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyAttribute#Option#DoNotUseInToString. public static final Option DoNotUseInToString
96+
// ^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyAttribute#Option#DoNotUseInToString. Option.DoNotUseInToString /* ordinal 4 */
9797
}
9898

9999
/** Specify any {@link Option} values that should be used when generating the model class. */

tests/snapshots/src/main/generated/com/airbnb/epoxy/ModelProp.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
// ^^^^^^^^^ definition com/airbnb/epoxy/ModelProp# public abstract ModelProp extends Annotation
5252

5353
enum Option {
54-
// ^^^^^^ definition com/airbnb/epoxy/ModelProp#Option# public static final enum Option extends Enum<Option>
54+
// ^^^^^^ definition com/airbnb/epoxy/ModelProp#Option# public enum Option
5555
// ^^^^^^ definition com/airbnb/epoxy/ModelProp#Option#`<init>`(). private <init>()
5656
/**
5757
* By default every prop's hashCode and equals method is called when determining the
@@ -69,7 +69,7 @@ enum Option {
6969
* then you can use this to prevent the rebind.
7070
*/
7171
DoNotHash,
72-
// ^^^^^^^^^ definition com/airbnb/epoxy/ModelProp#Option#DoNotHash. public static final Option DoNotHash
72+
// ^^^^^^^^^ definition com/airbnb/epoxy/ModelProp#Option#DoNotHash. Option.DoNotHash /* ordinal 0 */
7373
/**
7474
* This is meant to be used in conjunction with {@link PackageEpoxyConfig#requireHashCode()}.
7575
* When that is enabled every prop must implement hashCode/equals. However, there are some
@@ -85,20 +85,20 @@ enum Option {
8585
* contribute to model state you should use {@link Option#DoNotHash} instead.
8686
*/
8787
IgnoreRequireHashCode,
88-
// ^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/ModelProp#Option#IgnoreRequireHashCode. public static final Option IgnoreRequireHashCode
88+
// ^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/ModelProp#Option#IgnoreRequireHashCode. Option.IgnoreRequireHashCode /* ordinal 1 */
8989
/**
9090
* Setters with a type of {@link CharSequence} can add this option to have {@link
9191
* androidx.annotation.StringRes} and {@link androidx.annotation.PluralsRes}
9292
* overload methods generated on the model, so users can set the string via a resource.
9393
*/
9494
GenerateStringOverloads,
95-
// ^^^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/ModelProp#Option#GenerateStringOverloads. public static final Option GenerateStringOverloads
95+
// ^^^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/ModelProp#Option#GenerateStringOverloads. Option.GenerateStringOverloads /* ordinal 2 */
9696
/**
9797
* Setters with a param annotated with @Nullable can use this to have null set when the view is
9898
* recycled.
9999
*/
100100
NullOnRecycle
101-
// ^^^^^^^^^^^^^ definition com/airbnb/epoxy/ModelProp#Option#NullOnRecycle. public static final Option NullOnRecycle
101+
// ^^^^^^^^^^^^^ definition com/airbnb/epoxy/ModelProp#Option#NullOnRecycle. Option.NullOnRecycle /* ordinal 3 */
102102
}
103103

104104
/** Specify any {@link Option} values that should be used when generating the model class. */

tests/snapshots/src/main/generated/com/airbnb/epoxy/ModelView.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,18 @@
4949
* layout_width} and {@code layout_height}.
5050
*/
5151
enum Size {
52-
// ^^^^ definition com/airbnb/epoxy/ModelView#Size# public static final enum Size extends Enum<Size>
52+
// ^^^^ definition com/airbnb/epoxy/ModelView#Size# public enum Size
5353
// ^^^^ definition com/airbnb/epoxy/ModelView#Size#`<init>`(). private <init>()
5454
NONE,
55-
// ^^^^ definition com/airbnb/epoxy/ModelView#Size#NONE. public static final Size NONE
55+
// ^^^^ definition com/airbnb/epoxy/ModelView#Size#NONE. Size.NONE /* ordinal 0 */
5656
WRAP_WIDTH_WRAP_HEIGHT,
57-
// ^^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/ModelView#Size#WRAP_WIDTH_WRAP_HEIGHT. public static final Size WRAP_WIDTH_WRAP_HEIGHT
57+
// ^^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/ModelView#Size#WRAP_WIDTH_WRAP_HEIGHT. Size.WRAP_WIDTH_WRAP_HEIGHT /* ordinal 1 */
5858
WRAP_WIDTH_MATCH_HEIGHT,
59-
// ^^^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/ModelView#Size#WRAP_WIDTH_MATCH_HEIGHT. public static final Size WRAP_WIDTH_MATCH_HEIGHT
59+
// ^^^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/ModelView#Size#WRAP_WIDTH_MATCH_HEIGHT. Size.WRAP_WIDTH_MATCH_HEIGHT /* ordinal 2 */
6060
MATCH_WIDTH_WRAP_HEIGHT,
61-
// ^^^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/ModelView#Size#MATCH_WIDTH_WRAP_HEIGHT. public static final Size MATCH_WIDTH_WRAP_HEIGHT
61+
// ^^^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/ModelView#Size#MATCH_WIDTH_WRAP_HEIGHT. Size.MATCH_WIDTH_WRAP_HEIGHT /* ordinal 3 */
6262
MATCH_WIDTH_MATCH_HEIGHT
63-
// ^^^^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/ModelView#Size#MATCH_WIDTH_MATCH_HEIGHT. public static final Size MATCH_WIDTH_MATCH_HEIGHT
63+
// ^^^^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/ModelView#Size#MATCH_WIDTH_MATCH_HEIGHT. Size.MATCH_WIDTH_MATCH_HEIGHT /* ordinal 4 */
6464
}
6565

6666
/**

tests/snapshots/src/main/generated/com/airbnb/epoxy/PackageModelViewConfig.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,13 +130,13 @@
130130
* Enable or Disable an option, or inherit the default.
131131
*/
132132
enum Option {
133-
// ^^^^^^ definition com/airbnb/epoxy/PackageModelViewConfig#Option# public static final enum Option extends Enum<Option>
133+
// ^^^^^^ definition com/airbnb/epoxy/PackageModelViewConfig#Option# public enum Option
134134
// ^^^^^^ definition com/airbnb/epoxy/PackageModelViewConfig#Option#`<init>`(). private <init>()
135135
Default,
136-
// ^^^^^^^ definition com/airbnb/epoxy/PackageModelViewConfig#Option#Default. public static final Option Default
136+
// ^^^^^^^ definition com/airbnb/epoxy/PackageModelViewConfig#Option#Default. Option.Default /* ordinal 0 */
137137
Enabled,
138-
// ^^^^^^^ definition com/airbnb/epoxy/PackageModelViewConfig#Option#Enabled. public static final Option Enabled
138+
// ^^^^^^^ definition com/airbnb/epoxy/PackageModelViewConfig#Option#Enabled. Option.Enabled /* ordinal 1 */
139139
Disabled
140-
// ^^^^^^^^ definition com/airbnb/epoxy/PackageModelViewConfig#Option#Disabled. public static final Option Disabled
140+
// ^^^^^^^^ definition com/airbnb/epoxy/PackageModelViewConfig#Option#Disabled. Option.Disabled /* ordinal 2 */
141141
}
142142
}

tests/snapshots/src/main/generated/minimized/Enums.java

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,26 @@
66
// ^^^^ reference java/util/
77
// ^^^^^^ reference java/util/Arrays#
88

9-
public enum Enums {
10-
// ^^^^^ definition minimized/Enums# public final enum Enums extends Enum<Enums>
11-
A("A"),
12-
//^ definition minimized/Enums#A. public static final Enums A
13-
// ^^^^^ reference minimized/Enums#`<init>`().
14-
B("B"),
15-
//^ definition minimized/Enums#B. public static final Enums B
16-
// ^^^^^ reference minimized/Enums#`<init>`().
17-
C("C");
18-
//^ definition minimized/Enums#C. public static final Enums C
19-
// ^^^^^ reference minimized/Enums#`<init>`().
9+
enum Enums {
10+
// ^^^^^ definition minimized/Enums# enum Enums
11+
A("A", 420),
12+
//^ definition minimized/Enums#A. Enums.A("A", 420) /* ordinal 0 */
13+
// ^^^^^^^^^^ reference minimized/Enums#`<init>`().
14+
B("B", 1),
15+
//^ definition minimized/Enums#B. Enums.B("B", 1) /* ordinal 1 */
16+
// ^^^^^^^^ reference minimized/Enums#`<init>`().
17+
C("C", 5);
18+
//^ definition minimized/Enums#C. Enums.C("C", 5) /* ordinal 2 */
19+
// ^^^^^^^^ reference minimized/Enums#`<init>`().
2020
public String value;
2121
// ^^^^^^ reference java/lang/String#
2222
// ^^^^^ definition minimized/Enums#value. public String value
2323

24-
Enums(String value) {
25-
//^^^^^^ definition minimized/Enums#`<init>`(). private <init>(String value)
24+
Enums(String value, int a) {
25+
//^^^^^^ definition minimized/Enums#`<init>`(). private <init>(String value, int a)
2626
// ^^^^^^ reference java/lang/String#
2727
// ^^^^^ definition local0 String value
28+
// ^ definition local1 int a
2829
this.value = value;
2930
// ^^^^ reference minimized/Enums#this.
3031
// ^^^^^ reference minimized/Enums#value.
@@ -36,20 +37,20 @@ public static String app() {
3637
// ^^^ definition minimized/Enums#app(). public static String app()
3738
String all = Arrays.stream(values()).map(e -> e.value).map(Enums::valueOf).toString();
3839
// ^^^^^^ reference java/lang/String#
39-
// ^^^ definition local1 String all
40+
// ^^^ definition local2 String all
4041
// ^^^^^^ reference java/util/Arrays#
4142
// ^^^^^^ reference java/util/Arrays#stream().
4243
// ^^^^^^ reference minimized/Enums#values().
4344
// ^^^ reference java/util/stream/Stream#map().
44-
// ^ definition local2 Enums e
45-
// ^ reference local2
45+
// ^ definition local3 Enums e
46+
// ^ reference local3
4647
// ^^^^^ reference minimized/Enums#value.
4748
// ^^^ reference java/util/stream/Stream#map().
4849
// ^^^^^ reference minimized/Enums#
4950
// ^^^^^^^^^^^^^^ reference minimized/Enums#valueOf().
5051
// ^^^^^^^^ reference java/lang/Object#toString().
5152
return all + A.value + B.value + C.value;
52-
// ^^^ reference local1
53+
// ^^^ reference local2
5354
// ^ reference minimized/Enums#A.
5455
// ^^^^^ reference minimized/Enums#value.
5556
// ^ reference minimized/Enums#B.

0 commit comments

Comments
 (0)