mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
By explicitly marking children in the `schema.yml` file, an internal `getAChild` predicate is implemented, that is in turn used in `AstNode` to implement `getParent`. This is yet to be used in the control flow library to replace the hand-rolled implementation. A further, more complex step is to use the same information to fully generate the core implementation of `PrintAst` (including the accessor string). This will be done later. The `parent` tests use the same swift code as the extractor tests, and this is currently enforced by `sync-files.py`. Notice that `qltest.sh` had to be modified to deal with multiple files, which was not working yet.
95 lines
2.1 KiB
Python
95 lines
2.1 KiB
Python
import pathlib
|
|
from dataclasses import dataclass, field
|
|
from typing import List, ClassVar
|
|
|
|
import inflection
|
|
|
|
|
|
@dataclass
|
|
class Param:
|
|
param: str
|
|
first: bool = False
|
|
|
|
|
|
@dataclass
|
|
class Property:
|
|
singular: str
|
|
type: str = None
|
|
tablename: str = None
|
|
tableparams: List[Param] = field(default_factory=list)
|
|
plural: str = None
|
|
first: bool = False
|
|
local_var: str = "x"
|
|
is_optional: bool = False
|
|
is_predicate: bool = False
|
|
is_child: bool = False
|
|
|
|
def __post_init__(self):
|
|
if self.tableparams:
|
|
if self.type_is_class:
|
|
self.tableparams = [x if x != "result" else self.local_var for x in self.tableparams]
|
|
self.tableparams = [Param(x) for x in self.tableparams]
|
|
self.tableparams[0].first = True
|
|
|
|
@property
|
|
def getter(self):
|
|
return f"get{self.singular}" if not self.is_predicate else self.singular
|
|
|
|
@property
|
|
def indefinite_getter(self):
|
|
if self.plural:
|
|
article = "An" if self.singular[0] in "AEIO" else "A"
|
|
return f"get{article}{self.singular}"
|
|
|
|
@property
|
|
def type_is_class(self):
|
|
return bool(self.type) and self.type[0].isupper()
|
|
|
|
@property
|
|
def is_repeated(self):
|
|
return bool(self.plural)
|
|
|
|
|
|
@dataclass
|
|
class Class:
|
|
template: ClassVar = 'ql_class'
|
|
|
|
name: str
|
|
bases: List[str] = field(default_factory=list)
|
|
final: bool = False
|
|
properties: List[Property] = field(default_factory=list)
|
|
dir: pathlib.Path = pathlib.Path()
|
|
imports: List[str] = field(default_factory=list)
|
|
|
|
def __post_init__(self):
|
|
self.bases = sorted(self.bases)
|
|
if self.properties:
|
|
self.properties[0].first = True
|
|
|
|
@property
|
|
def db_id(self):
|
|
return "@" + inflection.underscore(self.name)
|
|
|
|
@property
|
|
def root(self):
|
|
return not self.bases
|
|
|
|
@property
|
|
def path(self):
|
|
return self.dir / self.name
|
|
|
|
|
|
@dataclass
|
|
class Stub:
|
|
template: ClassVar = 'ql_stub'
|
|
|
|
name: str
|
|
base_import: str
|
|
|
|
|
|
@dataclass
|
|
class ImportList:
|
|
template: ClassVar = 'ql_imports'
|
|
|
|
imports: List[str] = field(default_factory=list)
|