|
|
|
# SPDX-License-Identifer: Apache-2.0
|
|
|
|
# Copyright 2021 The Meson development team
|
|
|
|
|
|
|
|
from pathlib import Path
|
|
|
|
import json
|
|
|
|
import re
|
|
|
|
|
|
|
|
from .generatorbase import GeneratorBase
|
|
|
|
from . import jsonschema as J
|
|
|
|
from .model import (
|
|
|
|
ReferenceManual,
|
|
|
|
Function,
|
|
|
|
Object,
|
|
|
|
Type,
|
|
|
|
|
|
|
|
PosArg,
|
|
|
|
VarArgs,
|
|
|
|
Kwarg,
|
|
|
|
)
|
|
|
|
|
|
|
|
import typing as T
|
|
|
|
|
|
|
|
class GeneratorJSON(GeneratorBase):
|
|
|
|
def __init__(self, manual: ReferenceManual, out: Path, enable_modules: bool) -> None:
|
|
|
|
super().__init__(manual)
|
|
|
|
self.out = out
|
|
|
|
self.enable_modules = enable_modules
|
|
|
|
|
|
|
|
def _generate_type(self, typ: Type) -> T.List[J.Type]:
|
|
|
|
return [
|
|
|
|
{
|
|
|
|
'obj': x.data_type.name,
|
|
|
|
'holds': self._generate_type(x.holds) if x.holds else [],
|
|
|
|
}
|
|
|
|
for x in typ.resolved
|
|
|
|
]
|
|
|
|
|
|
|
|
def _generate_type_str(self, typ: Type) -> str:
|
|
|
|
# Remove all whitespaces
|
|
|
|
return re.sub(r'[ \n\r\t]', '', typ.raw)
|
|
|
|
|
|
|
|
def _generate_arg(self, arg: T.Union[PosArg, VarArgs, Kwarg], isOptarg: bool = False) -> J.Argument:
|
|
|
|
return {
|
|
|
|
'name': arg.name,
|
|
|
|
'description': arg.description,
|
|
|
|
'since': arg.since if arg.since else None,
|
|
|
|
'deprecated': arg.deprecated if arg.deprecated else None,
|
|
|
|
'type': self._generate_type(arg.type),
|
|
|
|
'type_str': self._generate_type_str(arg.type),
|
|
|
|
'required': arg.required if isinstance(arg, Kwarg) else not isOptarg and not isinstance(arg, VarArgs),
|
|
|
|
'default': arg.default if isinstance(arg, (PosArg, Kwarg)) else None,
|
|
|
|
'min_varargs': arg.min_varargs if isinstance(arg, VarArgs) and arg.min_varargs > 0 else None,
|
|
|
|
'max_varargs': arg.max_varargs if isinstance(arg, VarArgs) and arg.max_varargs > 0 else None,
|
|
|
|
|
|
|
|
# Not yet supported
|
|
|
|
'notes': [],
|
|
|
|
'warnings': [],
|
|
|
|
}
|
|
|
|
|
|
|
|
def _generate_function(self, func: Function) -> J.Function:
|
|
|
|
return {
|
|
|
|
'name': func.name,
|
|
|
|
'description': func.description,
|
|
|
|
'since': func.since if func.since else None,
|
|
|
|
'deprecated': func.deprecated if func.deprecated else None,
|
|
|
|
'notes': func.notes,
|
|
|
|
'warnings': func.warnings,
|
|
|
|
'example': func.example if func.example else None,
|
|
|
|
'returns': self._generate_type(func.returns),
|
|
|
|
'returns_str': self._generate_type_str(func.returns),
|
|
|
|
'posargs': {x.name: self._generate_arg(x) for x in func.posargs},
|
|
|
|
'optargs': {x.name: self._generate_arg(x, True) for x in func.optargs},
|
|
|
|
'kwargs': {x.name: self._generate_arg(x) for x in self.sorted_and_filtered(list(func.kwargs.values()))},
|
|
|
|
'varargs': self._generate_arg(func.varargs) if func.varargs else None,
|
|
|
|
'arg_flattening': func.arg_flattening,
|
|
|
|
}
|
|
|
|
|
|
|
|
def _generate_objects(self, obj: Object) -> J.Object:
|
|
|
|
return {
|
|
|
|
'name': obj.name,
|
|
|
|
'description': obj.description,
|
|
|
|
'since': obj.since if obj.since else None,
|
|
|
|
'deprecated': obj.deprecated if obj.deprecated else None,
|
|
|
|
'notes': obj.notes,
|
|
|
|
'warnings': obj.warnings,
|
|
|
|
'defined_by_module': obj.defined_by_module.name if obj.defined_by_module else None,
|
|
|
|
'object_type': obj.obj_type.name,
|
|
|
|
'is_container': obj.is_container,
|
|
|
|
'example': obj.example if obj.example else None,
|
|
|
|
'extends': obj.extends if obj.extends else None,
|
|
|
|
'returned_by': [x.name for x in self.sorted_and_filtered(obj.returned_by)],
|
|
|
|
'extended_by': [x.name for x in self.sorted_and_filtered(obj.extended_by)],
|
|
|
|
'methods': {x.name: self._generate_function(x) for x in self.sorted_and_filtered(obj.methods)},
|
|
|
|
}
|
|
|
|
|
|
|
|
def generate(self) -> None:
|
|
|
|
data: J.Root = {
|
|
|
|
'version_major': J.VERSION_MAJOR,
|
|
|
|
'version_minor': J.VERSION_MINOR,
|
|
|
|
'meson_version': self._extract_meson_version(),
|
|
|
|
'functions': {x.name: self._generate_function(x) for x in self.sorted_and_filtered(self.functions)},
|
|
|
|
'objects': {x.name: self._generate_objects(x) for x in self.sorted_and_filtered(self.objects)},
|
|
|
|
'objects_by_type': {
|
|
|
|
'elementary': [x.name for x in self.elementary],
|
|
|
|
'builtins': [x.name for x in self.builtins],
|
|
|
|
'returned': [x.name for x in self.returned],
|
|
|
|
'modules': {
|
|
|
|
x.name: [y.name for y in self.sorted_and_filtered(self.extract_returned_by_module(x))]
|
|
|
|
for x in self.modules
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
self.out.write_text(json.dumps(data), encoding='utf-8')
|