summaryrefslogtreecommitdiffstats
path: root/generator/plugins/dotnet/dotnet_special_classes.py
blob: a656b6dbe7a9893383a324c57fb5bc55a3c71a9d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

from typing import Dict, List, Union

from generator import model

from .dotnet_commons import TypeData
from .dotnet_constants import NAMESPACE
from .dotnet_helpers import class_wrapper, get_usings, namespace_wrapper

SPECIAL_CLASSES = [
    "LSPObject",
    "LSPAny",
    "LSPArray",
    "ChangeAnnotationIdentifier",
    "Pattern",
    "DocumentSelector",
    "InitializedParams",
]


def generate_special_classes(spec: model.LSPModel, types: TypeData) -> None:
    """Generate code for special classes in LSP."""
    for special_class in SPECIAL_CLASSES:
        for class_def in spec.structures + spec.typeAliases:
            if class_def.name == special_class:
                generate_special_class(class_def, spec, types)


def generate_special_class(
    type_def: Union[model.Structure, model.TypeAlias],
    spec: model.LSPModel,
    types: TypeData,
) -> Dict[str, str]:
    """Generate code for a special class."""
    lines: List[str] = []

    if type_def.name == "LSPObject":
        lines = namespace_wrapper(
            NAMESPACE,
            get_usings(["Dictionary", "DataContract", "JsonConverter"]),
            class_wrapper(
                type_def,
                ["public LSPObject(Dictionary<string, object?> value):base(value){}"],
                "Dictionary<string, object?>",
                ["[JsonConverter(typeof(CustomObjectConverter<LSPObject>))]"],
                is_record=False,
            ),
        )
    if type_def.name == "InitializedParams":
        lines = namespace_wrapper(
            NAMESPACE,
            get_usings(["Dictionary", "DataContract", "JsonConverter"]),
            class_wrapper(
                type_def,
                [
                    "public InitializedParams(Dictionary<string, object?> value):base(value){}"
                ],
                "Dictionary<string, object?>",
                ["[JsonConverter(typeof(CustomObjectConverter<InitializedParams>))]"],
                is_record=False,
            ),
        )
    if type_def.name == "LSPAny":
        lines = namespace_wrapper(
            NAMESPACE,
            get_usings(["DataContract", "JsonConverter"]),
            class_wrapper(
                type_def,
                [
                    "public LSPAny(object? value){this.Value = value;}",
                    "public object? Value { get; set; }",
                ],
                "object",
                ["[JsonConverter(typeof(LSPAnyConverter))]"],
            ),
        )
    if type_def.name == "LSPArray":
        lines = namespace_wrapper(
            NAMESPACE,
            get_usings(["DataContract", "List"]),
            class_wrapper(
                type_def,
                ["public LSPArray(List<object> value):base(value){}"],
                "List<object>",
                is_record=False,
            ),
        )

    if type_def.name == "Pattern":
        inner = [
            "private string pattern;",
            "public Pattern(string value){pattern = value;}",
            "public static implicit operator Pattern(string value) => new Pattern(value);",
            "public static implicit operator string(Pattern pattern) => pattern.pattern;",
            "public override string ToString() => pattern;",
        ]
        lines = namespace_wrapper(
            NAMESPACE,
            get_usings(["JsonConverter", "DataContract"]),
            class_wrapper(
                type_def,
                inner,
                None,
                [f"[JsonConverter(typeof(CustomStringConverter<{type_def.name}>))]"],
            ),
        )

    if type_def.name == "ChangeAnnotationIdentifier":
        inner = [
            "private string identifier;",
            "public ChangeAnnotationIdentifier(string value){identifier = value;}",
            "public static implicit operator ChangeAnnotationIdentifier(string value) => new ChangeAnnotationIdentifier(value);",
            "public static implicit operator string(ChangeAnnotationIdentifier identifier) => identifier.identifier;",
            "public override string ToString() => identifier;",
        ]
        lines = namespace_wrapper(
            NAMESPACE,
            get_usings(["JsonConverter", "DataContract"]),
            class_wrapper(
                type_def,
                inner,
                None,
                [f"[JsonConverter(typeof(CustomStringConverter<{type_def.name}>))]"],
            ),
        )

    if type_def.name == "DocumentSelector":
        inner = [
            "private DocumentFilter[] Filters { get; set; }",
            "public DocumentSelector(params DocumentFilter[] filters)",
            "{",
            "    Filters = filters ?? Array.Empty<DocumentFilter>();",
            "}",
            "public DocumentFilter this[int index]",
            "{",
            "    get { return Filters[index]; }",
            "    set { Filters[index] = value; }",
            "}",
            "public int Length => Filters.Length;",
            "public static implicit operator DocumentSelector(DocumentFilter[] filters) => new(filters);",
            "public static implicit operator DocumentFilter[](DocumentSelector selector) => selector.Filters;",
            "public IEnumerator<DocumentFilter> GetEnumerator() => ((IEnumerable<DocumentFilter>)Filters).GetEnumerator();",
            "System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => Filters.GetEnumerator();",
        ]
        lines = namespace_wrapper(
            NAMESPACE,
            get_usings(["JsonConverter", "DataContract"]),
            class_wrapper(
                type_def,
                inner,
                "IEnumerable<DocumentFilter>",
                [f"[JsonConverter(typeof(DocumentSelectorConverter))]"],
            ),
        )

    types.add_type_info(type_def, type_def.name, lines)