Files
ada_language_server/scripts/io_gen.py
Anthony Leonardo Gracio ed859b18bb Add support for setTrace notification
In order to not raise an exception when VS Code sends it.

We don't handle it for now since VS Code already outputs a lot
of useful information (resquests being sent, results...) when
the trace setting is set to 'messages' or 'verbose'.

This could be used in the future if we want to have more debug
traces in the ALS.

closes eng/ide/ada_language_server#1116
2023-03-22 17:08:30 +00:00

648 lines
18 KiB
Python

import libadalang as lal
# The list of types to generate Write procedures:
types_to_print = {
# 'Message',
'RequestMessage',
# 'ResponseMessage',
'NotificationMessage',
'CancelParams',
'Position',
'Span',
'CodeActionKind',
'AlsReferenceKind',
'AlsDisplayMethodAncestryOnNavigationPolicy',
# 'AlsReferenceKind_Array',
# 'AlsReferenceKind_Set',
'Location',
'LocationLink',
# 'Location_Or_Link_Kind',
# 'Location_Or_Link_Vector',
'DiagnosticSeverity',
'DiagnosticTag',
'CodeDescription',
'DiagnosticRelatedInformation',
'Diagnostic',
# 'Command',
'TextEdit',
'AnnotatedTextEdit',
'TextDocumentIdentifier',
'VersionedTextDocumentIdentifier',
'OptionalVersionedTextDocumentIdentifier',
'TextDocumentEdit',
'FileResourceChangeKind',
'CreateFileOptions',
'CreateFile',
'RenameFileOptions',
'RenameFile',
'DeleteFileOptions',
'DeleteFile',
# 'Document_Change_Kind',
# 'Document_Change',
# 'WorkspaceEdit',
'ChangeAnnotation',
'TextDocumentItem',
'TextDocumentPositionParams',
# 'DocumentFilter',
# 'DocumentSelector',
'dynamicRegistration',
'ResourceOperationKind',
'FailureHandlingKind',
'AnnotationSupport',
'WorkspaceEditClientCapabilities',
'SymbolKind',
'symbolKindCapabilities',
'Als_Visibility',
'WorkspaceSymbolClientCapabilities',
'WorkspaceClientCapabilities',
'MarkupKind',
'MarkupContent',
# 'String_Or_MarkupContent',
'SaveOptions',
'TextDocumentSyncClientCapabilities',
'CompletionItemTag',
'CompletionItemTagSupport',
'resolveSupportCapability',
'InsertTextMode',
'insertTextModeSupportCapability',
'completionItemCapability',
'CompletionItemKind',
'CompletionItemKindSetCapabilities',
'CompletionClientCapabilities',
'HoverClientCapabilities',
'parameterInformation_Capability',
'signatureInformation_Capability',
'SignatureHelpClientCapabilities',
'DocumentSymbolClientCapabilities',
'DeclarationClientCapabilities',
'codeActionKindCapability',
'codeActionLiteralSupport_Capability',
'CodeActionClientCapabilities',
'DocumentLinkClientCapabilities',
'PrepareSupportDefaultBehavior',
'RenameClientCapabilities',
'DiagnosticTagSupport',
'PublishDiagnosticsClientCapabilities',
'FoldingRangeClientCapabilities',
'SemanticTokensFullCapabilities',
'SemanticTokensRequestCapabilities',
'TokenFormat',
'SemanticTokensClientCapabilities',
'TextDocumentClientCapabilities',
'ShowDocumentClientCapabilities',
'MessageActionItemCapabilities',
'ShowMessageRequestClientCapabilities',
'WindowClientCapabilities',
'MarkdownClientCapabilities',
'RegularExpressionsClientCapabilities',
'GeneralClientCapabilities',
'fileOperationsClientCapabilities',
'ClientCapabilities',
'WorkspaceFolder',
# 'ProgressParam',
'WorkDoneProgressCreateParams',
# 'WorkDoneProgressParams',
# 'PartialResultParams',
# 'Progress_Partial_Params',
# 'Text_Progress_Partial_Params',
'Text_Progress_Params',
'ProgramInfo',
'TraceValue',
'InitializeParams',
# 'WorkDoneProgressOptions',
'TextDocumentSyncKind',
'TextDocumentSyncOptions',
# 'Optional_TextDocumentSyncOptions',
'CompletionOptions',
'SignatureHelpOptions',
'TextDocumentRegistrationOptions',
'TSW_RegistrationOptions',
# 'Provider_Options',
'DocumentSymbolOptions',
'CodeActionOptions',
'CodeLensOptions',
'DocumentOnTypeFormattingOptions',
'RenameOptions',
'DocumentLinkOptions',
'ExecuteCommandOptions',
'WorkspaceFoldersServerCapabilities',
'FileOperationPatternKind',
'FileOperationPatternOptions',
'FileOperationPattern',
'FileOperationFilter',
'FileOperationRegistrationOptions',
'FileOperationsServerCapabilities',
'workspace_Options',
'SemanticTokenTypes',
'SemanticTokenModifiers',
'SemanticTokensLegend',
'SemanticTokensOptions',
'ServerCapabilities',
'InitializeResult',
'InitializedParams',
'LogTraceParams',
'SetTraceParams',
# 'InitializeError',
'MessageType',
'ShowMessageParams',
'ShowMessageRequestParams',
'LogMessageParams',
'TextDocumentChangeRegistrationOptions',
'TextDocumentSaveRegistrationOptions',
'CompletionRegistrationOptions',
'SignatureHelpRegistrationOptions',
'CodeLensRegistrationOptions',
'CodeLensWorkspaceClientCapabilities',
'FileOperationsClientCapabilities',
'DocumentLinkRegistrationOptions',
'DocumentOnTypeFormattingRegistrationOptions',
'ExecuteCommandRegistrationOptions',
# 'Registration_Option',
'Registration',
'RegistrationParams',
'Unregistration',
'UnregistrationParams',
'DidChangeConfigurationParams',
'DidOpenTextDocumentParams',
'TextDocumentContentChangeEvent',
'DidChangeTextDocumentParams',
'TextDocumentSaveReason',
# 'WillSaveTextDocumentParams',
'DidSaveTextDocumentParams',
'DidCloseTextDocumentParams',
'FileChangeType',
'FileEvent',
'DidChangeWatchedFilesParams',
'PublishDiagnosticsParams',
'InsertTextFormat',
'InsertReplaceEdit',
'CompletionItem',
'CompletionList',
# 'MarkedString',
# 'MarkupContent_Or_MarkedString_Vector',
'Hover',
# 'Parameter_Label',
'ParameterInformation',
'SignatureInformation',
'SignatureHelp',
'ReferenceContext',
'ReferenceParams',
'DocumentHighlightKind',
'DocumentHighlight',
'DocumentSymbolParams',
'SymbolTag',
'tagSupportCapability',
# 'DocumentSymbol',
# 'DocumentSymbol_Tree',
'SymbolInformation',
# 'Symbol_Vector',
'WorkspaceSymbolParams',
'CodeActionContext',
'CodeActionParams',
# 'CodeLensParams',
# 'CodeLens',
# 'DocumentLinkParams',
# 'DocumentLink',
'FormattingOptions',
'DocumentFormattingParams',
'DocumentRangeFormattingParams',
'DocumentOnTypeFormattingParams',
'RenameParams',
# 'ExecuteCommandParams',
'ApplyWorkspaceEditParams',
'ApplyWorkspaceEditResult',
'WorkDoneProgressBegin',
'WorkDoneProgressReport',
'WorkDoneProgressEnd',
# 'Progress_Kind',
# 'Progress_Params',
'WorkspaceFoldersChangeEvent',
'DidChangeWorkspaceFoldersParams',
'ConfigurationItem',
'ConfigurationParams',
# 'WatchKind',
# 'WatchKind_Set',
'FileSystemWatcher',
'DidChangeWatchedFilesRegistrationOptions',
'CompletionTriggerKind',
'CompletionContext',
'CompletionParams',
'Disable_Reason',
# 'CodeAction',
'CodeActionRegistrationOptions',
'RGBA_Color',
'ColorInformation',
'ColorPresentationParams',
'ColorPresentation',
'RenameRegistrationOptions',
'FoldingRangeParams',
'FoldingRange',
'DocumentColorParams',
# 'HoverParams',
'SignatureHelpTriggerKind',
'SignatureHelpContext',
'SignatureHelpParams',
# 'DeclarationParams',
'NavigationRequestParams',
# 'DefinitionParams',
# 'TypeDefinitionParams',
# 'ImplementationParams',
# 'DocumentHighlightParams',
'SelectionRangeParams',
'SelectionRange',
'LinkedEditingRanges',
'CallHierarchyItem',
'CallHierarchyIncomingCallsParams',
'CallHierarchyIncomingCall',
'CallHierarchyOutgoingCall',
'SemanticTokensParams',
'SemanticTokens',
'SemanticTokensPartialResult',
'SemanticTokensDeltaParams',
'SemanticTokensEdit',
'SemanticTokensDelta',
'SemanticTokensDeltaPartialResult',
'SemanticTokensRangeParams',
'SemanticTokensWorkspaceClientCapabilities',
'UniquenessLevel',
'MonikerKind',
'Moniker',
'ShowDocumentParams',
'ShowDocumentResult',
'CreateFilesParams',
'FileCreate',
'RenameFilesParams',
'FileRename',
'DeleteFilesParams',
'FileDelete',
'ALS_Subprogram_And_References',
'ALS_ShowDependenciesKind',
'ALS_Unit_Description',
'ALS_ShowDependenciesParams',
'ALS_Source_Dir_Description',
# 'ALS_Debug_Kinds',
# 'ALSDebugParams',
'Search_Kind',
# 'ALS_Check_Syntax_Params',
# 'ALS_Check_Syntax_Result',
}
spec_header = """-- Automatically generated, do not edit.
with Ada.Streams;
with LSP.Messages;
package LSP.Message_IO is
"""
body_header = """-- Automatically generated, do not edit.
with Interfaces;
with VSS.Strings.Conversions;
with LSP.JSON_Streams;
with LSP.Messages; use LSP.Messages;
with LSP.Types; use LSP.Types;
package body LSP.Message_IO is
pragma Style_Checks ("M175");
use type Interfaces.Integer_64;
use type VSS.Strings.Virtual_String;
"""
file_footer = """
end LSP.Message_IO;
"""
io_spec = """
procedure {kind}_{type}
(S : access Ada.Streams.Root_Stream_Type'Class;
V : {out}LSP.Messages.{type});
"""
io_header = """
procedure {kind}_{type}
(S : access Ada.Streams.Root_Stream_Type'Class;
V : {out}{type})
is
{unref} JS : LSP.JSON_Streams.JSON_Stream'Class renames
LSP.JSON_Streams.JSON_Stream'Class (S.all);
"""
io_footer = """\
end {kind}_{type};
"""
write_component = {
"VSS.Strings.Virtual_String": """\
JS.Key ("{key}");
LSP.Types.Write_String (S, V.{name});
""",
"VSS.String_Vectors.Virtual_String_Vector": """\
JS.Key ("{key}");
LSP.Types.Write_String_Vector (S, V.{name});
""",
"LSP_String": """\
JS.Key ("{key}");
LSP.Types.Write (S, V.{name});
""",
"DocumentUri": """\
JS.Key ("{key}");
LSP.Types.Write_LSP_URI (S, V.{name});
""",
"Boolean": """\
{kind}_Boolean (JS, "{key}", V.{name});
""",
"UTF_16_Index": """\
JS.Key ("{key}");
LSP.Types.Write_UTF16_Code_Unit_Count (JS, V.{name});
""",
"": """\
JS.Key ("{key}");
{type}'{kind} (S, V.{name});
"""
}
read_component = {
"VSS.Strings.Virtual_String": """if Key = "{key}" then
LSP.Types.Read_String (S, V.{name});
els""",
"VSS.String_Vectors.Virtual_String_Vector": """if Key = "{key}" then
LSP.Types.Read_String_Vector (S, V.{name});
els""",
"LSP_String": """if Key = "{key}" then
LSP.Types.Read (S, V.{name});
els""",
"DocumentUri": """if Key = "{key}" then
LSP.Types.Read_LSP_URI (S, V.{name});
els""",
"Boolean": """if Key = "{key}" then
LSP.Types.Read_Boolean (JS, V.{name});
els""",
"UTF_16_Index": """if Key = "{key}" then
LSP.Types.Read_UTF16_Code_Unit_Count (JS, V.{name});
els""",
"": """if Key = "{key}" then
{type}'Read (S, V.{name});
els"""
}
io_component = {'Read': read_component, 'Write': write_component}
io_pos_enum = {
'Read': """\
V := {type}'Val (JS.R.Number_Value.Integer_Value - {offset});
JS.R.Read_Next;
""",
'Write': """\
JS.Write_Integer (({type}'Pos (V)) + {offset});
"""
}
io_string_enum_header = {
'Read': """
Text : constant Standard.String :=
VSS.Strings.Conversions.To_UTF_8_String (JS.R.String_Value);
begin
JS.R.Read_Next;
""",
'Write': """
function To_Virtual_String
(Value : {type})
return VSS.Strings.Virtual_String;
function To_Virtual_String
(Value : {type})
return VSS.Strings.Virtual_String is
begin
case Value is
"""
}
io_string_enum_case = {
'Read': """if Text = "{key}" then
V := {name};
els""",
'Write': """\
when {name} =>
return "{key}";
"""
}
io_string_enum_footer = {
'Read': """e
V := {type}'First;
end if;
""",
'Write': """\
end case;
end To_Virtual_String;
begin
JS.Write_String (To_Virtual_String (V));
"""
}
read_prolog = {
'Read': """ begin
pragma Assert (JS.R.Is_Start_Object);
JS.R.Read_Next;
while not JS.R.Is_End_Object loop
pragma Assert (JS.R.Is_Key_Name);
declare
Key : constant VSS.Strings.Virtual_String := JS.R.Key_Name;
begin
JS.R.Read_Next;
""",
'Write': """ begin
JS.Start_Object;
"""
}
read_epilog = {
'Read': """e
JS.Skip_Value;
end if;
end;
end loop;
JS.R.Read_Next;
""",
'Write': """ JS.End_Object;
"""
}
# The list of enumeration type represented as strings
enum_as_string = [
'AlsReferenceKind',
'AlsDisplayMethodAncestryOnNavigationPolicy',
'CodeActionKind',
'FileResourceChangeKind',
'ResourceOperationKind',
'FailureHandlingKind',
'MarkupKind',
'TokenFormat',
'SemanticTokenTypes',
'SemanticTokenModifiers',
'UniquenessLevel',
'MonikerKind',
'FileOperationPatternKind',
'TraceValue']
# The map to substitute words reserved in Ada:
reserver_named = \
{
"abortapplying": "abort",
"access_ref": "access",
"first": "start",
"last": "end",
"loc": "location", # for ALS_Subprogram_And_References
"span": "range",
"a_type": "type",
"simple": "reference", # For AlsReferenceKind
"write": "write",
"static_call": "call",
"dispatching_call": "dispatching call",
"overriding_decl": "overriding",
"parent": "parent",
"child": "child",
"empty": "", # For CodeActionKind
"quickfix": "quickfix",
"refactor": "refactor",
"refactorextract": "refactor.extract",
"refactorinline": "refactor.inline",
"refactorrewrite": "refactor.rewrite",
"source": "source",
"sourceorganizeimports": "source.organizeImports",
"messages_trace": "messages", # for TraceValue
"diff": "delta", # for SemanticTokens
"an_abstract": "abstract", # for SemanticTokenTypes
"an_interface": "interface",
"a_function": "function",
"a_string": "string",
}
def get_key(field):
lower = field.lower()
if lower in reserver_named:
return reserver_named[lower]
else:
return field
def write_format(type, kind):
if type in io_component[kind]:
return io_component[kind][type]
else:
return io_component[kind][""]
def filter(x):
return isinstance(x, lal.TypeDecl) \
and not isinstance(x, lal.AnonymousTypeDecl) \
and x.p_defining_name.token_start.text in types_to_print
def print_spec(file, node):
name = node.p_defining_name.token_start.text
print(name)
file.write(io_spec.format(type=name, kind='Read', out='out ').encode(encoding='utf-8'))
file.write(io_spec.format(type=name, kind='Write', out='').encode(encoding='utf-8'))
def get_components(node):
if isinstance(node, lal.DerivedTypeDef):
parent = node.f_subtype_indication.p_designated_type_decl
result = get_components(parent.f_type_def)
else:
result = []
result += list(node.finditer(lal.ComponentDecl))
return result
def print_components(file, kind, node, no_components):
file.write(read_prolog[kind].encode(encoding='utf-8'))
if kind == 'Read' and no_components:
# Write something compilable
file.write("""if Key = "" then
null;
els""".encode(encoding='utf-8'))
for x in get_components(node):
name = x.p_defining_name.token_start.text
tp = x.f_component_def.f_type_expr.f_name.text
txt = write_format(tp, kind).format(key=get_key(name),
kind=kind,
name=name,
type=tp)
file.write(txt.encode(encoding='utf-8'))
file.write(read_epilog[kind].encode(encoding='utf-8'))
def print_enums(file, kind, type, node):
if type not in enum_as_string:
offset = 0 if type == 'TextDocumentSyncKind' else 1
file.write(' begin\n'.encode(encoding='utf-8'))
txt = io_pos_enum[kind].format(type=type, offset=offset)
else:
txt = io_string_enum_header[kind].format(type=type)
for x in node.finditer(lal.EnumLiteralDecl):
name = x.p_defining_name.token_start.text
txt += io_string_enum_case[kind].format(name=name,
key=get_key(name))
txt += io_string_enum_footer[kind].format(type=type)
file.write(txt.encode(encoding='utf-8'))
def print_body(file, node):
name = node.p_defining_name.token_start.text
unref = ' pragma Unreferenced (V);\n\n' if \
len(list(node.finditer(lal.NullRecordDef))) else ''
def print_decls_and_statements(kind):
file.write(io_header.format(type=name,
kind=kind,
out='' if kind == 'Write' else 'out ',
unref=unref).encode(encoding='utf-8'))
if isinstance(node.f_type_def, lal.EnumTypeDef):
print_enums(file, kind, name, node.f_type_def)
else:
print_components(file, kind, node.f_type_def, unref)
file.write(io_footer.format(type=node.p_defining_name.token_start.text,
kind=kind).encode(encoding='utf-8'))
print_decls_and_statements('Read')
print_decls_and_statements('Write')
def print_io():
up = lal.UnitProvider.for_project("gnat/lsp.gpr")
ctx = lal.AnalysisContext(unit_provider=up)
unit = ctx.get_from_file("source/protocol/lsp-messages.ads")
ads = open("source/protocol/generated/lsp-message_io.ads", 'wb')
ads.write(spec_header.encode(encoding='utf-8'))
adb = open("source/protocol/generated/lsp-message_io.adb", 'wb')
adb.write(body_header.encode(encoding='utf-8'))
for x in unit.root.finditer(filter):
print_spec(ads, x)
print_body(adb, x)
ads.write(file_footer.encode(encoding='utf-8'))
adb.write(file_footer.encode(encoding='utf-8'))
if __name__ == '__main__':
print_io()