# Copyright (c) Meta Platforms, Inc. and affiliates. schema codemarkup.flow.2 { import src import code.flow import codemarkup.types import flow # Resolving locations to entities predicate FlowResolveLocation: { location: codemarkup.types.Location, entity: code.flow.Entity, } { { NameStr, File, { span = Span }, nothing }, Entity } where ( { decl = Decl } = Entity; flow.FileDeclaration { File, Decl }; flow.DeclarationNameSpan { Decl, Name, Span }; Name = flow.Name NameStr ) | ( flow.ModuleLocationByFile { File, Mod, Span, NameStr }; { module_ = Mod } = Entity ) # Finding entities' locations predicate FlowEntityLocation: { entity: code.flow.Entity, location: codemarkup.types.Location, } { Entity, { NameStr, File, { span = Span }, nothing } } where ( { decl = D } = Entity; flow.DeclarationLocation { decl = D, file = File, span = Span }; flow.DeclarationNameSpan { decl = D, name = Name }; Name = flow.Name NameStr; ) | ( { module_ = Mod } = Entity; flow.ModuleLocation { Mod, File, Span, NameStr } ) predicate FlowFileEntityXRefLocations: { file: src.File, xref: codemarkup.types.XRefLocation, entity: code.flow.Entity, } { File, XRef, Entity } where FlowFileReferenceEntityXRefLocations { File, XRef, Entity } | FlowFileImportDeclEntityXRefLocations { File, XRef, Entity } # Flow cross-references from occurrences. # # References in the Flow index point to the local import declaration # in the file. To resolve these to the remote reference: # # * For each reference in the file (flow.FileXRef) # * emit a DirectXRef to its target # * also, if the target is a flow.ImportDeclaration # * find the source of the import, and emit a DirectXRef to that # # And do the same for type declarations. # # This will result in two DirectXRefs for each non-local reference, # one pointing to the import declaration and another to the non-local # target. The client can decide which one(s) it wants. # predicate FlowFileReferenceEntityXRefLocations: { file: src.File, xref: codemarkup.types.XRefLocation, entity: code.flow.Entity, } { File, {Location, { span = Src }}, Entity } where flow.FileXRef { file = File, ref = XRef }; flow.FlowXRefDeclInfo { XRef, SrcLoc, Name, TargetLoc, D }; Name = flow.Name Str; { span = Src } = SrcLoc; ( # TODO: should be able to inline M, but the optimiser got it wrong { module = M, span = TargetSpan } = TargetLoc; { file = TargetFile } = M; { decl = D } = Entity; ) | ( { localRef = { declaration = LocalD } } = XRef; flow.FlowImportXRef { LocalD, Entity, TargetFile, TargetSpan }; ) | ( { typeRef = { typeDeclaration = T } } = XRef; flow.FlowTypeImportXRef { T, Entity, TargetFile, TargetSpan }; ); Location = codemarkup.types.Location { Str, TargetFile, { span = TargetSpan }, nothing } # Flow cross-references from import declarations. # # We want to hyperlink the identifiers in an import declaration to the # source of the import: # # * For each declaration in the file (flow.FileDeclaration) # * If it is an import declaraiton, find the source (reusing FlowImportXRef) # # and do the same for type declarations (FlowTypeImportXRef). # predicate FlowFileImportDeclEntityXRefLocations: { file: src.File, xref: codemarkup.types.XRefLocation, entity: code.flow.Entity, } { File, { Location, { span = Src } }, Entity } where flow.FileDeclaration { File, D }; ( { localDecl = LocalD } = D; flow.FlowImportXRef { LocalD, Entity, TargetFile, TargetSpan }; { name = Name, loc = SrcLoc } = LocalD; ) | ( { typeDecl = TypeD } = D; flow.FlowTypeImportXRef { TypeD, Entity, TargetFile, TargetSpan }; { name = Name, loc = SrcLoc } = TypeD; ); Location = codemarkup.types.Location { Str, TargetFile, { span = TargetSpan }, nothing }; Name = flow.Name Str; { span = Src } = SrcLoc; # # Language entity uses # predicate FlowEntityUses: { target: code.flow.Entity, file: src.File, span: src.ByteSpan, } { Entity, File, Span } where flow.FlowEntityUsesAll { Entity, File, Span }; # # relations # predicate FlowContainsParentEntity : { child: code.flow.Entity, parent: code.flow.Entity } { { decl = Child }, { module_ = Parent } } where ( { localDecl = Decl } = Child; { loc = { module = Parent } } = Decl; ) | ( { memberDecl = Decl } = Child; { loc = { module = Parent } } = Decl; ) | ( { typeDecl = Decl } = Child; { loc = { module = Parent } } = Decl; ) predicate FlowContainsChildEntity : { parent: code.flow.Entity, child: code.flow.Entity } { { module_ = Parent }, { decl = Child } } where flow.ModuleContains { Parent, Child } # kinds and symbol info predicate FlowEntityKind: { entity: code.flow.Entity, kind: codemarkup.types.SymbolKind } { Entity, Kind} where ( { decl = Decl } = Entity; ( { localDecl = _ } = Decl; Object_ = Kind # not true ) | ( { memberDecl = _ } = Decl; Property = Kind # not true either ) | ( { typeDecl = _ } = Decl; Type = Kind ) ) | ( { module_ = _ } = Entity; Module = Kind ) # documentation spans in flow are attached to declarations only predicate FlowEntityDocumentation : { entity : code.flow.Entity, file : src.File, span : src.ByteSpan } { Entity, File, Span } where ( { decl = Decl } = Entity; FlowDeclarationDocumentation { Decl, File, Span } ) | ( { module_ = Module } = Entity; flow.ModuleComments { Module, File, Span } ) predicate FlowDeclarationDocumentation : { decl : flow.SomeDeclaration, file : src.File, span : src.ByteSpan } { Decl, File, Span } where ( { localDecl = D } = Decl; flow.DeclarationInfo { D, _, { just = Docs }, _ } ) | ( { memberDecl = D } = Decl; flow.MemberDeclarationInfo { D, _, { just = Docs }, _ } ) | ( { typeDecl = D } = Decl; flow.TypeDeclarationInfo { D, _, { just = Docs }, _ } ); FlowDocumentationSpan { Docs, File, Span } predicate FlowDocumentationSpan : { doc : flow.Documentation, file : src.File, span : src.ByteSpan } { Docs, File, Span } where { module = M , span = Span } = Docs; ( { file = File } = M ) | ( { string_ = Str } = M; flow.StringToFileModule { Str , File } ) predicate FlowEntityModuleName : { entity : code.flow.Entity, name : string } { { module_ = Module }, Name } where flow.ModuleLocation { module_ = Module, name = Name }; }