This patch introduces the basic infrastructure of the code generation
suite and the `dbscheme` generator.

Notice that the checked in `schema.yml` should reflect swift 5.6 but
might need some tweaking.

Closes https://github.com/github/codeql-c-team/issues/979
This commit is contained in:
Paolo Tranquilli 2022-04-13 17:37:53 +02:00
Родитель d094bbc06d
Коммит 91fd83a554
14 изменённых файлов: 3318 добавлений и 5 удалений

Просмотреть файл

@ -4,6 +4,32 @@ The Swift codeql package is an experimental and unsupported work in progress.
## Usage ## Usage
Run `bazel run //swift:create-extractor-pack`, which will install `swift/extractor-pack`. Run
```bash
bazel run //swift:create-extractor-pack
```
which will install `swift/extractor-pack`.
Using `--search-path=swift/extractor-pack` will then pick up the Swift extractor. You can also use Using `--search-path=swift/extractor-pack` will then pick up the Swift extractor. You can also use
`--search-path=swift`, as the extractor pack is mentioned in `swift/.codeqlmanifest.json`. `--search-path=swift`, as the extractor pack is mentioned in `swift/.codeqlmanifest.json`.
Notice you can run `bazel run :create-extractor-pack` if you already are in the `swift` directory.
## Code generation
Make sure to install the [pip requirements](./codegen/requirements.txt) via
```bash
python3 -m pip install -r codegen/requirements.txt
```
Run
```bash
bazel run //swift/codegen
```
to update generated files. This can be shortened to
`bazel run codegen` if you are in the `swift` directory.

Просмотреть файл

@ -0,0 +1,8 @@
py_binary(
name = "codegen",
srcs = glob(["**/*.py"]),
data = glob(["**/*.mustache"]) + [
"schema.yml",
"prefix.dbscheme",
],
)

7
swift/codegen/codegen.py Executable file
Просмотреть файл

@ -0,0 +1,7 @@
#!/usr/bin/env python3
from lib import generator
import dbschemegen
if __name__ == "__main__":
generator.run(dbschemegen.generate)

76
swift/codegen/dbschemegen.py Executable file
Просмотреть файл

@ -0,0 +1,76 @@
#!/usr/bin/env python3
import inflection
from lib.renderer import Renderer
from lib.dbscheme import *
from lib import paths, schema, generator
log = logging.getLogger(__name__)
def dbtype(typename):
if typename[0].isupper():
return "@" + inflection.underscore(typename)
return typename
def cls_to_dbscheme(cls: schema.Class):
if cls.derived:
yield DbUnion(dbtype(cls.name), (dbtype(c) for c in cls.derived))
if not cls.derived or any(f.is_single() for f in cls.fields):
binding = not cls.derived
keyset = DbKeySet(["id"]) if cls.derived else None
yield DbTable(
keyset=keyset,
name=inflection.tableize(cls.name),
columns=[
DbColumn("id", type=dbtype(cls.name), binding=binding),
] + [
DbColumn(f.name, dbtype(f.type)) for f in cls.fields if f.is_single()
]
)
for f in cls.fields:
if f.is_optional():
yield DbTable(
keyset=DbKeySet(["id"]),
name=inflection.tableize(f"{cls.name}_{f.name}"),
columns=[
DbColumn("id", type=dbtype(cls.name)),
DbColumn(f.name, dbtype(f.type)),
],
)
elif f.is_repeated():
yield DbTable(
keyset=DbKeySet(["id", "index"]),
name=inflection.tableize(f"{cls.name}_{f.name}"),
columns=[
DbColumn("id", type=dbtype(cls.name)),
DbColumn("index", type="int"),
DbColumn(inflection.singularize(f.name), dbtype(f.type)),
]
)
def generate(opts):
input = opts.schema.resolve()
out = opts.dbscheme.resolve()
renderer = Renderer(opts.check)
with open(input) as src:
data = schema.load(src)
declarations = [d for cls in data.classes.values() for d in cls_to_dbscheme(cls)]
includes = []
for inc in data.includes:
inc = input.parent / inc
with open(inc) as inclusion:
includes.append({"src": inc.relative_to(paths.swift_dir), "data": inclusion.read()})
renderer.render("dbscheme", out, includes=includes, src=input.relative_to(paths.swift_dir),
declarations=declarations)
return renderer.written
if __name__ == "__main__":
generator.run(generate, tags=["schema", "dbscheme"])

Просмотреть файл

@ -0,0 +1,85 @@
import logging
import re
from dataclasses import dataclass
from typing import ClassVar, List
log = logging.getLogger(__name__)
dbscheme_keywords = {"case", "boolean", "int", "string", "type"}
@dataclass
class DbColumn:
schema_name: str
type: str
binding: bool = False
first: bool = False
def name(self):
if self.schema_name in dbscheme_keywords:
return self.schema_name + "_"
return self.schema_name
def lhstype(self):
if self.type[0] == "@":
return "unique int" if self.binding else "int"
return self.type
def rhstype(self):
if self.type[0] == "@" and self.binding:
return self.type
return self.type + " ref"
@dataclass
class DbKeySetId:
id: str
first: bool = False
@dataclass
class DbKeySet:
ids: List[DbKeySetId]
def __post_init__(self):
assert self.ids
self.ids = [DbKeySetId(x) for x in self.ids]
self.ids[0].first = True
class DbDecl:
is_table = False
is_union = False
@dataclass
class DbTable(DbDecl):
is_table: ClassVar = True
name: str
columns: List[DbColumn]
keyset: DbKeySet = None
def __post_init__(self):
if self.columns:
self.columns[0].first = True
@dataclass
class DbUnionCase:
type: str
first: bool = False
@dataclass
class DbUnion(DbDecl):
is_union: ClassVar = True
lhs: str
rhs: List[DbUnionCase]
def __post_init__(self):
assert self.rhs
self.rhs = [DbUnionCase(x) for x in self.rhs]
self.rhs.sort(key=lambda c: c.type)
self.rhs[0].first = True

Просмотреть файл

@ -0,0 +1,55 @@
import argparse
import collections
import logging
import pathlib
import sys
from . import paths
options = collections.defaultdict(list)
class Option:
def __init__(self, *args, tags=None, **kwargs):
tags = tags or []
self.args = args
self.kwargs = kwargs
if tags:
for t in tags:
options[t].append(self)
else:
options["*"].append(self)
def add_to(self, parser: argparse.ArgumentParser):
parser.add_argument(*self.args, **self.kwargs)
Option("--check", "-c", action="store_true")
Option("--verbose", "-v", action="store_true")
Option("--schema", tags=["schema"], type=pathlib.Path, default=paths.swift_dir / "codegen/schema.yml")
Option("--dbscheme", tags=["dbscheme"], type=pathlib.Path, default=paths.swift_dir / "ql/lib/swift.dbscheme")
def _parse(*tags):
parser = argparse.ArgumentParser()
if not tags:
opts = [o for os in options.values() for o in os]
else:
opts = options["*"]
for t in tags:
opts.extend(options[t])
for opt in opts:
opt.add_to(parser)
ret = parser.parse_args()
log_level = logging.DEBUG if ret.verbose else logging.INFO
logging.basicConfig(format="{levelname} {message}", style='{', level=log_level)
return ret
def run(*generate, tags=()):
opts = _parse(*tags)
done_something = False
for g in generate:
if g(opts):
done_something = True
sys.exit(1 if opts.check and done_something else 0)

Просмотреть файл

@ -0,0 +1,15 @@
import pathlib
import sys
import os
try:
_workspace_dir = pathlib.Path(os.environ['BUILD_WORKSPACE_DIRECTORY'])
swift_dir = _workspace_dir / 'swift'
lib_dir = swift_dir / 'codegen' / 'lib'
except KeyError:
_this_file = pathlib.Path(__file__).resolve()
swift_dir = _this_file.parents[2]
lib_dir = _this_file.parent
exe_file = pathlib.Path(sys.argv[0]).resolve()

Просмотреть файл

@ -0,0 +1,59 @@
import hashlib
import logging
import pystache
from . import paths
log = logging.getLogger(__name__)
def md5(data):
return hashlib.md5(data).digest()
class Renderer:
def __init__(self, check=False):
self.r = pystache.Renderer(search_dirs=str(paths.lib_dir / "templates"), escape=lambda u: u)
self.generator = paths.exe_file.relative_to(paths.swift_dir)
self.check = check
self.written = set()
self.skipped = set()
self.erased = set()
@property
def done_something(self):
return bool(self.written or self.erased)
@property
def rendered(self):
return self.written | self.skipped
def render(self, name, output, **data):
mnemonic, _, _ = name.lower().partition(".")
output.parent.mkdir(parents=True, exist_ok=True)
data["generator"] = self.generator
data = self.r.render_name(name, data)
if output.is_file():
with open(output, "rb") as file:
if md5(data.encode()) == md5(file.read()):
log.debug(f"skipped {output.name}")
self.skipped.add(output)
return
if self.check:
log.error(f"would have generated {mnemonic} {output.name}")
else:
with open(output, "w") as out:
out.write(data)
log.info(f"generated {mnemonic} {output.name}")
self.written.add(output)
def cleanup(self, existing):
for f in existing - self.written - self.skipped:
if f.is_file():
if self.check:
log.error(f"would have removed {f.name}")
else:
f.unlink()
log.info(f"removed {f.name}")
self.erased.add(f)

Просмотреть файл

@ -0,0 +1,98 @@
import pathlib
from dataclasses import dataclass, field
from enum import Enum, auto
from typing import List, Set, Dict
import re
import yaml
class Cardinality(Enum):
ONE = auto()
OPTIONAL = auto()
MANY = auto()
@dataclass
class Field:
name: str
type: str
cardinality: Cardinality = Cardinality.ONE
def is_single(self):
return self.cardinality == Cardinality.ONE
def is_optional(self):
return self.cardinality == Cardinality.OPTIONAL
def is_repeated(self):
return self.cardinality == Cardinality.MANY
@dataclass
class Class:
name: str
bases: Set[str] = field(default_factory=set)
derived: Set[str] = field(default_factory=set)
fields: List[Field] = field(default_factory=list)
dir: pathlib.Path = pathlib.Path()
@dataclass
class Schema:
classes: Dict[str, Class]
includes: Set[str] = field(default_factory=set)
def _parse_field(name, type):
if type.endswith("*"):
cardinality = Cardinality.MANY
type = type[:-1]
elif type.endswith("?"):
cardinality = Cardinality.OPTIONAL
type = type[:-1]
else:
cardinality = Cardinality.ONE
return Field(name, type, cardinality)
root_class_name = "Element"
class DirSelector:
def __init__(self, dir_to_patterns):
self.selector = [(re.compile(p), pathlib.Path(d)) for d, p in dir_to_patterns]
self.selector.append((re.compile(""), pathlib.Path()))
def get(self, name):
return next(d for p, d in self.selector if p.search(name))
def load(file):
data = yaml.load(file, Loader=yaml.SafeLoader)
grouper = DirSelector(data.get("_directories", {}).items())
ret = Schema(classes={cls: Class(cls, dir=grouper.get(cls)) for cls in data if not cls.startswith("_")},
includes=set(data.get("_includes", [])))
assert root_class_name not in ret.classes
ret.classes[root_class_name] = Class(root_class_name)
for name, info in data.items():
if name.startswith("_"):
continue
assert name[0].isupper()
cls = ret.classes[name]
for k, v in info.items():
if not k.startswith("_"):
cls.fields.append(_parse_field(k, v))
elif k == "_extends":
if not isinstance(v, list):
v = [v]
for base in v:
cls.bases.add(base)
ret.classes[base].derived.add(name)
elif k == "_dir":
cls.dir = pathlib.Path(v)
if not cls.bases:
cls.bases.add(root_class_name)
ret.classes[root_class_name].derived.add(name)
return ret

Просмотреть файл

@ -0,0 +1,25 @@
// generated by {{generator}}
{{#includes}}
// from {{src}}
{{data}}
{{/includes}}
// from {{src}}
{{#declarations}}
{{#is_union}}
{{lhs}} =
{{#rhs}}
{{#first}} {{/first}}{{^first}}| {{/first}}{{type}}
{{/rhs}};
{{/is_union}}
{{#is_table}}
{{#keyset}}
#keyset[{{#ids}}{{^first}}, {{/first}}{{id}}{{/ids}}]
{{/keyset}}
{{name}}({{#columns}}{{^first}},{{/first}}
{{lhstype}} {{name}}: {{rhstype}}{{/columns}}
);
{{/is_table}}
{{/declarations}}

Просмотреть файл

@ -0,0 +1,6 @@
/**
* The source location of the snapshot.
*/
sourceLocationPrefix(
string prefix: string ref
);

Просмотреть файл

@ -0,0 +1,3 @@
pystache
pyyaml
inflection

997
swift/codegen/schema.yml Normal file
Просмотреть файл

@ -0,0 +1,997 @@
# add dbscheme files to be added verbatim
_includes:
- prefix.dbscheme
# organize generated class files in subdirectories according to these regexp rules
# a class can override this specifying `_dir`
_directories:
decl: Decl$|Context$
pattern: Pattern$
type: Type$
typerepr: TypeRepr$
expr: Expr$
stmt: Stmt$
File:
name: string
IterableDeclContext:
members: Decl*
Locatable:
location: Location
Location:
file: File
begin_line: int
begin_column: int
end_line: int
end_column: int
Type:
diagnostics_name: string
canonical_type: Type
ExtensionDecl:
_extends:
- GenericContext
- IterableDeclContext
- Decl
NominalTypeDecl:
_extends:
- IterableDeclContext
- GenericTypeDecl
type: Type
AstNode:
_extends: Locatable
ConditionElement:
_extends: Locatable
boolean: Expr?
pattern: Pattern?
initializer: Expr?
_dir: stmt
AnyFunctionType:
_extends: Type
result: Type
param_types: Type*
param_labels: string*
AnyGenericType:
_extends: Type
parent: Type?
declaration: Decl
AnyMetatypeType:
_extends: Type
BuiltinType:
_extends: Type
DependentMemberType:
_extends: Type
DynamicSelfType:
_extends: Type
ErrorType:
_extends: Type
InOutType:
_extends: Type
LValueType:
_extends: Type
object_type: Type
ModuleType:
_extends: Type
PlaceholderType:
_extends: Type
ProtocolCompositionType:
_extends: Type
ExistentialType:
_extends: Type
ReferenceStorageType:
_extends: Type
SilBlockStorageType:
_extends: Type
SilBoxType:
_extends: Type
SilFunctionType:
_extends: Type
SilTokenType:
_extends: Type
SubstitutableType:
_extends: Type
SugarType:
_extends: Type
TupleType:
_extends: Type
TypeVariableType:
_extends: Type
UnknownType:
_extends: Type
name: string
UnresolvedType:
_extends: Type
ClassDecl:
_extends: NominalTypeDecl
EnumDecl:
_extends: NominalTypeDecl
ProtocolDecl:
_extends: NominalTypeDecl
StructDecl:
_extends: NominalTypeDecl
Decl:
_extends: AstNode
Expr:
_extends: AstNode
type: Type?
Pattern:
_extends: AstNode
Stmt:
_extends: AstNode
TypeRepr:
_extends: AstNode
FunctionType:
_extends: AnyFunctionType
GenericFunctionType:
_extends: AnyFunctionType
generic_params: GenericTypeParamType*
NominalOrBoundGenericNominalType:
_extends: AnyGenericType
UnboundGenericType:
_extends: AnyGenericType
ExistentialMetatypeType:
_extends: AnyMetatypeType
MetatypeType:
_extends: AnyMetatypeType
AnyBuiltinIntegerType:
_extends: BuiltinType
BuiltinBridgeObjectType:
_extends: BuiltinType
BuiltinDefaultActorStorageType:
_extends: BuiltinType
BuiltinExecutorType:
_extends: BuiltinType
BuiltinFloatType:
_extends: BuiltinType
BuiltinJobType:
_extends: BuiltinType
BuiltinNativeObjectType:
_extends: BuiltinType
BuiltinRawPointerType:
_extends: BuiltinType
BuiltinRawUnsafeContinuationType:
_extends: BuiltinType
BuiltinUnsafeValueBufferType:
_extends: BuiltinType
BuiltinVectorType:
_extends: BuiltinType
UnmanagedStorageType:
_extends: ReferenceStorageType
UnownedStorageType:
_extends: ReferenceStorageType
WeakStorageType:
_extends: ReferenceStorageType
ArchetypeType:
_extends: SubstitutableType
GenericTypeParamType:
_extends: SubstitutableType
name: string
ParenType:
_extends: SugarType
SyntaxSugarType:
_extends: SugarType
TypeAliasType:
_extends: SugarType
EnumCaseDecl:
_extends: Decl
elements: EnumElementDecl*
IfConfigDecl:
_extends: Decl
ImportDecl:
_extends: Decl
MissingMemberDecl:
_extends: Decl
OperatorDecl:
_extends: Decl
PatternBindingDecl:
_extends: Decl
inits: Expr*
patterns: Pattern*
PoundDiagnosticDecl:
_extends: Decl
PrecedenceGroupDecl:
_extends: Decl
TopLevelCodeDecl:
_extends: Decl
body: BraceStmt
UnknownAstNode:
_extends:
- Decl
- Expr
- Pattern
- Stmt
- TypeRepr
name: string
ValueDecl:
_extends: Decl
interface_type: Type
AbstractClosureExpr:
_extends: Expr
AnyTryExpr:
_extends: Expr
sub_expr: Expr
AppliedPropertyWrapperExpr:
_extends: Expr
Argument:
label: string
expr: Expr
_dir: expr
ApplyExpr:
_extends: Expr
function: Expr
arguments: Argument*
ArrowExpr:
_extends: Expr
AssignExpr:
_extends: Expr
dest: Expr
src: Expr
BindOptionalExpr:
_extends: Expr
CaptureListExpr:
_extends: Expr
CodeCompletionExpr:
_extends: Expr
CollectionExpr:
_extends: Expr
DeclRefExpr:
_extends: Expr
decl: Decl
replacement_types: Type*
DefaultArgumentExpr:
_extends: Expr
param_decl: ParamDecl
param_index: int
caller_side_default: Expr?
DiscardAssignmentExpr:
_extends: Expr
DotSyntaxBaseIgnoredExpr:
_extends: Expr
DynamicTypeExpr:
_extends: Expr
EditorPlaceholderExpr:
_extends: Expr
EnumIsCaseExpr:
_extends: Expr
ErrorExpr:
_extends: Expr
ExplicitCastExpr:
_extends: Expr
sub_expr: Expr
ForceValueExpr:
_extends: Expr
sub_expr: Expr
IdentityExpr:
_extends: Expr
sub_expr: Expr
IfExpr:
_extends: Expr
ImplicitConversionExpr:
_extends: Expr
sub_expr: Expr
InOutExpr:
_extends: Expr
sub_expr: Expr
KeyPathApplicationExpr:
_extends: Expr
KeyPathDotExpr:
_extends: Expr
KeyPathExpr:
_extends: Expr
parsed_root: Expr?
parsed_path: Expr?
LazyInitializerExpr:
_extends: Expr
LiteralExpr:
_extends: Expr
LookupExpr:
_extends: Expr
MakeTemporarilyEscapableExpr:
_extends: Expr
ObjCSelectorExpr:
_extends: Expr
OneWayExpr:
_extends: Expr
OpaqueValueExpr:
_extends: Expr
OpenExistentialExpr:
_extends: Expr
OptionalEvaluationExpr:
_extends: Expr
OtherConstructorDeclRefExpr:
_extends: Expr
OverloadSetRefExpr:
_extends: Expr
PropertyWrapperValuePlaceholderExpr:
_extends: Expr
RebindSelfInConstructorExpr:
_extends: Expr
SequenceExpr:
_extends: Expr
SuperRefExpr:
_extends: Expr
TapExpr:
_extends: Expr
sub_expr: Expr?
var: VarDecl
body: BraceStmt
TupleElementExpr:
_extends: Expr
TupleExpr:
_extends: Expr
elements: Expr*
TypeExpr:
_extends: Expr
type_repr: UnknownAstNode?
UnresolvedDeclRefExpr:
_extends: Expr
UnresolvedDotExpr:
_extends: Expr
UnresolvedMemberExpr:
_extends: Expr
UnresolvedPatternExpr:
_extends: Expr
UnresolvedSpecializeExpr:
_extends: Expr
VarargExpansionExpr:
_extends: Expr
sub_expr: Expr
AnyPattern:
_extends: Pattern
BindingPattern:
_extends: Pattern
sub_pattern: Pattern
BoolPattern:
_extends: Pattern
value: boolean
EnumElementPattern:
_extends: Pattern
element: EnumElementDecl
sub_pattern: Pattern?
ExprPattern:
_extends: Pattern
sub_expr: Expr
IsPattern:
_extends: Pattern
cast_type_repr: TypeRepr
sub_pattern: Pattern?
NamedPattern:
_extends: Pattern
name: string
OptionalSomePattern:
_extends: Pattern
sub_pattern: Pattern
ParenPattern:
_extends: Pattern
sub_pattern: Pattern
TuplePattern:
_extends: Pattern
elements: Pattern*
TypedPattern:
_extends: Pattern
sub_pattern: Pattern
type_repr: TypeRepr?
BraceStmt:
_extends: Stmt
elements: AstNode*
BreakStmt:
_extends: Stmt
target_name: string?
target: Stmt?
CaseStmt:
_extends: Stmt
body: Stmt
labels: CaseLabelItem*
variables: VarDecl*
CaseLabelItem:
_extends: AstNode
pattern: Pattern
guard: Expr?
_dir: stmt
ContinueStmt:
_extends: Stmt
target_name: string?
target: Stmt?
DeferStmt:
_extends: Stmt
body: BraceStmt
FailStmt:
_extends: Stmt
FallthroughStmt:
_extends: Stmt
fallthrough_source: CaseStmt
fallthrough_dest: CaseStmt
LabeledStmt:
_extends: Stmt
label: string?
PoundAssertStmt:
_extends: Stmt
ReturnStmt:
_extends: Stmt
result: Expr?
ThrowStmt:
_extends: Stmt
sub_expr: Expr
YieldStmt:
_extends: Stmt
BoundGenericType:
_extends: NominalOrBoundGenericNominalType
NominalType:
_extends: NominalOrBoundGenericNominalType
BuiltinIntegerLiteralType:
_extends: AnyBuiltinIntegerType
BuiltinIntegerType:
_extends: AnyBuiltinIntegerType
NestedArchetypeType:
_extends: ArchetypeType
SequenceArchetypeType:
_extends: ArchetypeType
OpaqueTypeArchetypeType:
_extends: ArchetypeType
OpenedArchetypeType:
_extends: ArchetypeType
PrimaryArchetypeType:
_extends: ArchetypeType
interface_type: GenericTypeParamType
DictionaryType:
_extends: SyntaxSugarType
UnarySyntaxSugarType:
_extends: SyntaxSugarType
InfixOperatorDecl:
_extends: OperatorDecl
PostfixOperatorDecl:
_extends: OperatorDecl
PrefixOperatorDecl:
_extends: OperatorDecl
AbstractFunctionDecl:
_extends:
- GenericContext
- ValueDecl
name: string
body: BraceStmt?
params: ParamDecl*
AbstractStorageDecl:
_extends: ValueDecl
EnumElementDecl:
_extends: ValueDecl
name: string
params: ParamDecl*
TypeDecl:
_extends: ValueDecl
name: string
AutoClosureExpr:
_extends: AbstractClosureExpr
ClosureExpr:
_extends: AbstractClosureExpr
body: BraceStmt
ForceTryExpr:
_extends: AnyTryExpr
OptionalTryExpr:
_extends: AnyTryExpr
TryExpr:
_extends: AnyTryExpr
BinaryExpr:
_extends: ApplyExpr
CallExpr:
_extends: ApplyExpr
PostfixUnaryExpr:
_extends: ApplyExpr
PrefixUnaryExpr:
_extends: ApplyExpr
SelfApplyExpr:
_extends: ApplyExpr
base: Expr
ArrayExpr:
_extends: CollectionExpr
elements: Expr*
DictionaryExpr:
_extends: CollectionExpr
elements: Expr*
CheckedCastExpr:
_extends: ExplicitCastExpr
CoerceExpr:
_extends: ExplicitCastExpr
AwaitExpr:
_extends: IdentityExpr
DotSelfExpr:
_extends: IdentityExpr
ParenExpr:
_extends: IdentityExpr
UnresolvedMemberChainResultExpr:
_extends: IdentityExpr
AnyHashableErasureExpr:
_extends: ImplicitConversionExpr
ArchetypeToSuperExpr:
_extends: ImplicitConversionExpr
ArrayToPointerExpr:
_extends: ImplicitConversionExpr
BridgeFromObjCExpr:
_extends: ImplicitConversionExpr
BridgeToObjCExpr:
_extends: ImplicitConversionExpr
ClassMetatypeToObjectExpr:
_extends: ImplicitConversionExpr
CollectionUpcastConversionExpr:
_extends: ImplicitConversionExpr
ConditionalBridgeFromObjCExpr:
_extends: ImplicitConversionExpr
CovariantFunctionConversionExpr:
_extends: ImplicitConversionExpr
CovariantReturnConversionExpr:
_extends: ImplicitConversionExpr
DerivedToBaseExpr:
_extends: ImplicitConversionExpr
DestructureTupleExpr:
_extends: ImplicitConversionExpr
DifferentiableFunctionExpr:
_extends: ImplicitConversionExpr
DifferentiableFunctionExtractOriginalExpr:
_extends: ImplicitConversionExpr
ErasureExpr:
_extends: ImplicitConversionExpr
ExistentialMetatypeToObjectExpr:
_extends: ImplicitConversionExpr
ForeignObjectConversionExpr:
_extends: ImplicitConversionExpr
FunctionConversionExpr:
_extends: ImplicitConversionExpr
InOutToPointerExpr:
_extends: ImplicitConversionExpr
InjectIntoOptionalExpr:
_extends: ImplicitConversionExpr
LinearFunctionExpr:
_extends: ImplicitConversionExpr
LinearFunctionExtractOriginalExpr:
_extends: ImplicitConversionExpr
LinearToDifferentiableFunctionExpr:
_extends: ImplicitConversionExpr
LoadExpr:
_extends: ImplicitConversionExpr
MetatypeConversionExpr:
_extends: ImplicitConversionExpr
PointerToPointerExpr:
_extends: ImplicitConversionExpr
ProtocolMetatypeToObjectExpr:
_extends: ImplicitConversionExpr
StringToPointerExpr:
_extends: ImplicitConversionExpr
UnderlyingToOpaqueExpr:
_extends: ImplicitConversionExpr
UnevaluatedInstanceExpr:
_extends: ImplicitConversionExpr
UnresolvedTypeConversionExpr:
_extends: ImplicitConversionExpr
BuiltinLiteralExpr:
_extends: LiteralExpr
InterpolatedStringLiteralExpr:
_extends: LiteralExpr
interpolation_expr: OpaqueValueExpr?
interpolation_count_expr: Expr?
literal_capacity_expr: Expr?
appending_expr: TapExpr?
RegexLiteralExpr:
_extends: LiteralExpr
NilLiteralExpr:
_extends: LiteralExpr
ObjectLiteralExpr:
_extends: LiteralExpr
DynamicLookupExpr:
_extends: LookupExpr
MemberRefExpr:
_extends: LookupExpr
base_expr: Expr
SubscriptExpr:
_extends:
- GenericContext
- LookupExpr
base_expr: Expr
arguments: Argument*
OverloadedDeclRefExpr:
_extends: OverloadSetRefExpr
DoCatchStmt:
_extends: LabeledStmt
body: Stmt
catches: CaseStmt*
DoStmt:
_extends: LabeledStmt
body: BraceStmt
ForEachStmt:
_extends: LabeledStmt
body: BraceStmt
where: Expr?
LabeledConditionalStmt:
_extends: LabeledStmt
condition: StmtCondition
StmtCondition:
_extends: AstNode
elements: ConditionElement*
_dir: stmt
RepeatWhileStmt:
_extends: LabeledStmt
cond: Expr
body: Stmt
SwitchStmt:
_extends: LabeledStmt
subject_expr: Expr
cases: CaseStmt*
BoundGenericClassType:
_extends: BoundGenericType
BoundGenericEnumType:
_extends: BoundGenericType
BoundGenericStructType:
_extends: BoundGenericType
ClassType:
_extends: NominalType
decl: ClassDecl
EnumType:
_extends: NominalType
ProtocolType:
_extends: NominalType
StructType:
_extends: NominalType
decl: StructDecl
ArraySliceType:
_extends: UnarySyntaxSugarType
OptionalType:
_extends: UnarySyntaxSugarType
VariadicSequenceType:
_extends: UnarySyntaxSugarType
ConstructorDecl:
_extends: AbstractFunctionDecl
DestructorDecl:
_extends: AbstractFunctionDecl
FuncDecl:
_extends: AbstractFunctionDecl
SubscriptDecl:
_extends: AbstractStorageDecl
VarDecl:
_extends: AbstractStorageDecl
name: string
type: Type
AbstractTypeParamDecl:
_extends: TypeDecl
GenericContext:
generic_type_params: GenericTypeParamDecl*
GenericTypeDecl:
_extends:
- GenericContext
- TypeDecl
ModuleDecl:
_extends: TypeDecl
ConstructorRefCallExpr:
_extends: SelfApplyExpr
DotSyntaxCallExpr:
_extends: SelfApplyExpr
ConditionalCheckedCastExpr:
_extends: CheckedCastExpr
ForcedCheckedCastExpr:
_extends: CheckedCastExpr
IsExpr:
_extends: CheckedCastExpr
BooleanLiteralExpr:
_extends: BuiltinLiteralExpr
value: boolean
MagicIdentifierLiteralExpr:
_extends: BuiltinLiteralExpr
kind: string
NumberLiteralExpr:
_extends: BuiltinLiteralExpr
StringLiteralExpr:
_extends: BuiltinLiteralExpr
value: string
DynamicMemberRefExpr:
_extends: DynamicLookupExpr
DynamicSubscriptExpr:
_extends: DynamicLookupExpr
GuardStmt:
_extends: LabeledConditionalStmt
body: BraceStmt
IfStmt:
_extends: LabeledConditionalStmt
then: Stmt
else: Stmt?
WhileStmt:
_extends: LabeledConditionalStmt
body: Stmt
AccessorDecl:
_extends: FuncDecl
ConcreteFuncDecl:
_extends: FuncDecl
ConcreteVarDecl:
_extends: VarDecl
introducer_int: int
ParamDecl:
_extends: VarDecl
AssociatedTypeDecl:
_extends: AbstractTypeParamDecl
GenericTypeParamDecl:
_extends: AbstractTypeParamDecl
OpaqueTypeDecl:
_extends: GenericTypeDecl
TypeAliasDecl:
_extends: GenericTypeDecl
FloatLiteralExpr:
_extends: NumberLiteralExpr
string_value: string
IntegerLiteralExpr:
_extends: NumberLiteralExpr
string_value: string

Разница между файлами не показана из-за своего большого размера Загрузить разницу