packages feed

glean-0.1.0.0: glean/schema/source/java.alpha.angle

#
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
#
# Schema for Java that interops with Kotlin.
# Intentionally a breaking change from java.6
#
schema java.alpha.1 {
  import src
  import javakotlin.alpha

type Modifier =
  enum {
    abstract_ |
    default_ |
    final_ |
    native_ |
    private_ |
    protected_ |
    public_ |
    static_ |
    strictfp_ |
    synchronized_ |
    transient_ |
    volatile_ |
  }

predicate PrimitiveType :
  {
    type : string,
  }

predicate TypeVar :
  {
    type : javakotlin.alpha.Name,
    span : src.ByteSpan,
  }

predicate ObjectType :
  {
    type : javakotlin.alpha.QName,
    span : src.ByteSpan,
  }

predicate ArrayType :
  {
    contents : Type,
    span : src.ByteSpan,
  }

# Giving a type structure
type BaseType =
  {
    object : ObjectType |
    primitive : PrimitiveType |
    variable : TypeVar |
    array : ArrayType |
  }

predicate Type :
  {
    baseType : BaseType,
    typeArgs : [TypeArg],
    interopType : javakotlin.alpha.Type,
    span : src.ByteSpan,
  }

predicate TypeArg :
  {
    type: Type |
    wildcard: Wildcard |
  }

# https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.5.1
type Wildcard =
  {
    extends_: Type |
    super_: Type |
    unbounded: bool |
  }

predicate TypeParam :
  {
    name: javakotlin.alpha.Name,
    extends_: [Type],
    span : src.ByteSpan,
  }

predicate Annotation :
  {
    name : javakotlin.alpha.QName,
    constructor : javakotlin.alpha.MethodName,
    constant : maybe string,
    span : src.ByteSpan,
  }

predicate ParameterDeclaration :
  {
    name: javakotlin.alpha.QName,
    type: Type,
    annotations: [Annotation],
    modifier : [Modifier],
    span : src.ByteSpan,
  }

# A local variable, not parameter
predicate LocalDeclaration :
  {
    name: javakotlin.alpha.QName,
    type: Type,
    annotations : [Annotation],
    # Maybe get a restricted set here
    modifier : [Modifier],
    container : ExecutableDefinition,
    span : src.ByteSpan,
  }

predicate FieldDeclaration :
  {
    name: javakotlin.alpha.QName,
    type : Type,
    annotations : [Annotation],
    modifiers : [Modifier],
    container : Definition,
    span : src.ByteSpan,
  }

# Will add a type combining Local and Field later

# A constructor declaration
predicate ConstructorDeclaration :
  {
    name: javakotlin.alpha.MethodName,
    parameters : [ParameterDeclaration],
    annotations : [Annotation],
    modifiers : [Modifier],
    typeParams: [TypeParam],
    throws_ : [Type],
    container : Definition,
    span : src.ByteSpan,
  }

# A method declaration
predicate MethodDeclaration :
  {
    name : javakotlin.alpha.MethodName,
    parameters : [ParameterDeclaration],
    returnType : Type,
    annotations : [Annotation],
    modifiers : [Modifier],
    typeParams: [TypeParam],
    throws_ : [Type],
    container : Definition,
    span : src.ByteSpan,
  }

# An interface declaration
predicate InterfaceDeclaration :
  {
    name: javakotlin.alpha.QName,
    annotations : [Annotation],
    modifiers : [Modifier],
    extends_ : [Type],
    container : maybe Definition,
    typeParams: [TypeParam],
    span : src.ByteSpan,
    file : src.File,
  }

# A class declaration
predicate ClassDeclaration :
  {
    name : javakotlin.alpha.QName,
    modifiers : [Modifier],
    extends_ : maybe Type,
    implements_ : [Type],
    annotations : [Annotation],
    container : maybe Definition,
    typeParams: [TypeParam],
    span : src.ByteSpan,
    file : src.File,
  }

predicate EnumDeclaration :
  {
    name: javakotlin.alpha.QName,
    annotations : [Annotation],
    modifiers : [Modifier],
    implements_ : [Type],
    container : maybe Definition,
    span : src.ByteSpan,
    file : src.File,
  }

# just container definitions
type Definition =
  {
    class_ : ClassDeclaration |
    interface_ : InterfaceDeclaration |
    enum_ : EnumDeclaration |
  }

type ExecutableDefinition =
  {
    constructor : ConstructorDeclaration |
    method : MethodDeclaration |
  }

# helper for unwrapping the container Definition type
predicate DeclOfDefn:
  {
    defn: Definition,
    decl: Declaration
  }
  { Defn, Decl } where
    ( { class_ = CDecl } = Defn; { class_ = CDecl } = Decl ) |
    ( { enum_ = CDecl } = Defn; { enum_ = CDecl } = Decl ) |
    ( { interface_ = CDecl } = Defn; { interface_ = CDecl } = Decl );

# helper for unwrapping the container ExecutableDefinition type
predicate DeclOfExecutableDefn:
  {
    defn: ExecutableDefinition,
    decl: Declaration
  }
  { Defn, Decl } where
    ( { constructor = CDecl } = Defn; { ctor = CDecl } = Decl ) |
    ( { method = MDecl } = Defn; { method = MDecl } = Decl );

# An import, whether specific, an entire package, or static
predicate ImportDeclaration :
  {
    name : javakotlin.alpha.Name,
    import_on_demand : bool,
    static_member : maybe string,
    path : javakotlin.alpha.Path,
    location: src.ByteSpan,
  }

# The package specification for a file
predicate PackageDeclaration :
  {
    name : javakotlin.alpha.Name,
    annotation: [Annotation],
    # Path is not required in a package
    path : maybe javakotlin.alpha.Path,
    location : src.ByteSpan,
  }

#
# Handling xrefs and uses
#

# Code that is referenced elsewhere, including by an import
# Note: params and locals aren't yet xref-able
# These are the unique QName/MethodName compoennt of a Declaration.
type XRefTarget =
  {
    definition_: javakotlin.alpha.QName |
    ctor_: javakotlin.alpha.MethodName |
    method_: javakotlin.alpha.MethodName |
    field_: javakotlin.alpha.QName |
  }

# Lookup the xref entity by its qname and kind
predicate XRefTargetDeclaration:
  {
    xref: XRefTarget,
    decl : Declaration
  }
  { XRef, Decl } where
    ( { definition_ = QName } = XRef;
      QNameToDefinition { QName, Decl }
    ) | (
      { ctor_ = MName } = XRef;
      CDecl = ConstructorDeclaration { name = MName };
      { ctor = CDecl } = Decl
    ) | (
      { method_ = MName } = XRef;
      MDecl = MethodDeclaration { name = MName };
      { method = MDecl } = Decl
    ) | (
      { field_ = QName } = XRef;
      FDecl = FieldDeclaration { name = QName };
      { field = FDecl } = Decl
    )

# Given a declaration extract its XRefTarget key
# Reverses the XRefTargetDeclaration mapping
predicate DeclarationXRefTarget:
  {
    decl : Declaration,
    xref: XRefTarget
  }
  { Decl, XRef } where
    ( { field = { name = QName }} = Decl;
      { field_ = QName } = XRef ) |
    ( { ctor = { name = MName } } = Decl;
      { ctor_ = MName } = XRef ) |
    ( { method = { name = MName }  } = Decl;
      { method_ = MName } = XRef ) |
    ( { interface_ = { name = QName } } = Decl;
      { definition_ = QName } = XRef ) |
    ( { enum_ = { name = QName } } = Decl;
      { definition_ = QName } = XRef ) |
    ( { class_ = { name = QName } } = Decl;
      { definition_ = QName } = XRef );

predicate QNameToDefinition:
  {
    name : javakotlin.alpha.QName,
    defn : java.alpha.Declaration
  }
  { QName, Decl } where
    ( CDecl = ClassDeclaration { name = QName };
      { class_ = CDecl } = Decl
    ) | (
      IDecl = InterfaceDeclaration { name = QName };
      { interface_ = IDecl } = Decl
    ) | (
      EDecl = EnumDeclaration { name = QName };
      { enum_ = EDecl } = Decl
    );

# References to target code
predicate XRef :
  {
    target: XRefTarget,
    ranges: [src.ByteSpan],
  }

# Cross-references to a target within a file
predicate FileXRefs :
  {
    file : src.File,
    xrefs : [XRef],
  }

predicate XRefFile :
  {
    xref: XRef,
    file: src.File,
  }
    stored {Xref, File} where
      FileXRefs {file = File, xrefs = Xs};
      Xref = Xs[..];

#
# Extracting xref uses and targets from type signature components
#
predicate XRefOfType:
  {
    type: Type,
    decl: Declaration,
    use: src.ByteSpan,
  }
  { Type, Decl, Span } where
    { baseType = Base, typeArgs = _ } = Type;
    { object = ObjType } = Base;
    { type = QName , span = Span } = ObjType;
    QNameToDefinition { QName, Decl }

# If you have a Type, it may also have types contained.
# Extract all the types in a typeArgs
predicate TypeOfTypeArgs:
  {
    typeWithArgs : Type,
    type: Type
  }
  { TypeWithArgs, Type } where
     { typeArgs = Tys } = TypeWithArgs;
     ArgTy = Tys[..];
     ( { type = Type } = ArgTy ) |
       ( { wildcard = Wild } = ArgTy;
       ( { extends_ = Type } ) | ( { super_ = Type } ) = Wild;
     );

#
# Extract type components of declarations. These are all uses (i.e. xrefs)
#
predicate DeclarationType:
  {
    decl: Declaration,
    type: Type
  }
  { Decl, Type } where
    ( { param = PDecl } = Decl;
      { type = Ty } = PDecl;
      ( Ty = Type ) | ( TypeOfTypeArgs { Ty, Type } )
    ) | (
      { local = LDecl } = Decl;
      { type = Ty } = LDecl;
      ( Ty = Type ) | ( TypeOfTypeArgs { Ty, Type } )
    ) | (
      { field = FDecl } = Decl;
      { type = Ty } = FDecl;
      ( Ty = Type ) | ( TypeOfTypeArgs { Ty, Type } )
    ) | (
      { ctor = CDecl } = Decl;
      { parameters = PDecls, throws_ = TTypes } = CDecl;
      Ty = ( { type = T } = PDecls[..]; T ) | ( T = TTypes[..]; T );
      ( Ty = Type ) | ( TypeOfTypeArgs { Ty, Type } );
    ) | (
      { method = MDecl } = Decl;
      { parameters = PDecls, returnType = RType, throws_ = TTypes } = MDecl;
      Ty = ( { type = T } = PDecls[..]; T) | ( RType ) | ( T = TTypes[..]; T );
      ( Ty = Type ) | ( TypeOfTypeArgs { Ty, Type } );
    ) | (
      { interface_ = IDecl } = Decl;
      { extends_ = Types } = IDecl;
      Ty = Types[..];
      ( Ty = Type ) | ( TypeOfTypeArgs { Ty, Type } );
    ) | (
      { class_ = CDecl } = Decl;
      { extends_ =  { just = ETy }, implements_ = ITys } = CDecl;
      Ty = ( ETy ) | ( ITys[..] );
      ( Ty = Type ) | ( TypeOfTypeArgs { Ty, Type } );
    ) | (
      { enum_ = EDecl } = Decl;
      { implements_ = ITys } = EDecl;
      Ty = ITys[..];
      ( Ty = Type ) | ( TypeOfTypeArgs { Ty, Type } );
    );

# Uses
predicate DeclarationUses :
  {
    target : Declaration,
    file : src.File,
    uses : [src.ByteSpan],
  }
  { Decl, File, Spans } where
    DeclarationXRefTarget { Decl, XRefTarget };
    XRef = XRef { XRefTarget, Spans }; # all xrefs that mention this target
    XRefFile { XRef, File };

predicate AnnotatedClass :
  {
    annotation : Annotation,
    class_ : ClassDeclaration,
  } stored { Annotation, Class_ } where
      Class_ = ClassDeclaration { annotations = As };
      Annotation = As[..]

# base type has subclass
predicate Inheritance :
  {
    base: Type,
    subclass: ClassDeclaration,
  }
  stored { Base, Subclass } where
    Subclass = ClassDeclaration { extends_ = { just = Base } }

# interface type has these implemented classes
predicate InterfaceInheritance :
  {
    interface_name: Type,
    subclass: ClassDeclaration,
  }
  stored { InterfaceName, Subclass } where
    Subclass = ClassDeclaration { implements_ = Implements_ };
    InterfaceName = Implements_[..];

# generic scope "contains" relationship.
# e.g. a class contains methods or inner clases
predicate ContainsDeclaration:
  {
    container: Declaration,
    member: Declaration
  } stored { Container, Member } where
    ( { method = { container = Defn } } ) |
    ( { ctor = { container = Defn } } ) |
    ( { field = { container = Defn } } ) |
    ( { interface_ = { container = { just = Defn } } } ) |
    ( { enum_ = { container = { just = Defn } } } ) |
    ( { class_ = { container = { just = Defn } } } ) = Member;
    DeclOfDefn { Defn, Container }

#
# codemarkup/glass APIs
#

# All entities that we expose to navigation or search
type Declaration =
  {
    param : ParameterDeclaration |
    local : LocalDeclaration |
    field : FieldDeclaration |
    ctor : ConstructorDeclaration |
    method : MethodDeclaration |
    interface_ : InterfaceDeclaration |
    class_ : ClassDeclaration |
    enum_ : EnumDeclaration
  }

predicate DeclarationAnnotations:
  {
    decl : java.alpha.Declaration,
    annotations : [Annotation]
  }
  { Decl, Anns } where
    ( { param = PDecl } = Decl; { annotations = Anns } = PDecl ) |
    ( { local = LDecl } = Decl; { annotations = Anns } = LDecl ) |
    ( { field = FDecl } = Decl; { annotations = Anns } = FDecl ) |
    ( { ctor = CDecl } = Decl; { annotations = Anns } = CDecl ) |
    ( { method = MDecl } = Decl; { annotations = Anns } = MDecl ) |
    ( { interface_ = IDecl } = Decl; { annotations = Anns } = IDecl ) |
    ( { class_ = CDecl } = Decl; { annotations = Anns } = CDecl ) |
    ( { enum_ = EDecl } = Decl; { annotations = Anns } = EDecl );

predicate DefinitionLocation:
  {
    defn : Definition,
    name : string,
    file : src.File,
    span : src.ByteSpan
  }
  { Defn, NameStr, File, Span } where
    ( { interface_ = IDecl } = Defn;
      { name = QName, span = Span, file = File } = IDecl;
    ) | (
      { class_ = CDecl } = Defn;
      { name = QName, span = Span, file = File } = CDecl;
    ) | (
      { enum_ = EDecl } = Defn;
      { name = QName, span = Span, file = File } = EDecl;
    );
    { name = javakotlin.alpha.Name NameStr } = QName;

# Comment(s) that appears at the first of a Declaration
predicate DeclarationComment:
  {
    declaration : Declaration,
    file : src.File,
    span : src.ByteSpan,
  }

predicate DeclarationLocation:
  {
    decl : Declaration,
    name : string,
    file : src.File,
    span : src.ByteSpan,
  } { Decl, NameStr, File, Span } where
    ( (
        { interface_ = IDecl } = Decl;
        DefinitionLocation { { interface_ = IDecl }, NameStr, File, Span }
      ) | (
        { class_ = CDecl } = Decl;
        DefinitionLocation { { class_ = CDecl }, NameStr, File, Span }
      ) | (
        { enum_ = EDecl } = Decl;
        DefinitionLocation { { enum_ = EDecl }, NameStr, File, Span }
      )
    ) | (
      ( { method = MDecl } = Decl;
        Defn = ExecutableDefinition { method = MDecl };
      ) | (
        { ctor = CDecl } = Decl;
        Defn = ExecutableDefinition { constructor = CDecl };
      );
      ExecutableDefnLocation { Defn, NameStr, File, Span }

    ) | (
      { local = LDecl } = Decl;
      { name = QName, container = EDefn, span = Span } = LDecl;
      { name = javakotlin.alpha.Name NameStr } = QName;
      ExecutableDefnLocation { defn = EDefn, file = File }
    ) | (
      { field = FDecl } = Decl;
      { name = QName, container = Defn, span = Span } = FDecl;
      { name = javakotlin.alpha.Name NameStr } = QName;
      DefinitionLocation { defn = Defn, file = File }
    )

# src.File of a method or constructor is the src.File of its parent container
predicate ExecutableDefnLocation:
  {
    defn : ExecutableDefinition,
    name : string,
    file : src.File,
    span : src.ByteSpan
  }
  { EDefn, NameStr, File, Span } where
    ( { method = MDecl } = EDefn;
      { name = MName, span = Span, container = Defn } = MDecl;
    ) | (
      { constructor = CDecl } = EDefn;
      { name = MName, span = Span, container = Defn } = CDecl;
    );
    DefinitionLocation { defn = Defn, file = File };
    javakotlin.alpha.MethodName { name = QName } = MName;
    { name = javakotlin.alpha.Name NameStr } = QName

# decls keyed by file (i.e. file entities)
predicate FileDeclarations:
  {
    file : src.File,
    decl : Declaration
  } stored { File, Decl } where DeclarationLocation { decl = Decl, file = File }

#
# container relationships
#

# Container parent (by scope)
predicate ParentDeclaration:
  {
    child: Declaration,
    parent: Declaration
  }
  { Child, Parent } where
    # can't do param parents yet
    ( { local = LDecl } = Child;
      { container = Defn } = LDecl;
      DeclOfExecutableDefn { Defn, Parent }
    ) | (
      ( ( { field = FDecl } = Child; { container = Defn } = FDecl ) |
        ( { ctor = CDecl } = Child; { container = Defn } = CDecl ) |
        ( { method = MDecl } = Child; { container = Defn } = MDecl ) |
        ( { class_ = CDecl } = Child; { container = { just = Defn }} = CDecl) |
        ( { enum_ = CDecl } = Child; { container = { just = Defn }} = CDecl ) |
        ( { interface_ = CDecl} = Child; { container = { just = Defn}} = CDecl);
      );
      DeclOfDefn { Defn, Parent }
    )

# extends parent (by inheritance)
predicate ExtendsDeclaration:
  {
    child: Declaration,
    parent: Declaration
  }
  { Child, Parent } where
    ( { class_ = CDecl } = Child;
      ( { extends_ = { just = T } } = CDecl ) |
      ( { implements_ = Ts } = CDecl; T = Ts[..]);
    ) | (
      { interface_ = IDecl } = Child;
      ( { extends_ = Ts } = IDecl; T = Ts[..]);
    ) | (
      { enum_ = EDecl } = Child;
      ( { implements_ = Ts } = EDecl; T = Ts[..]);
    );
    Type { baseType = { object = { type = QName } } } = T;
    QNameToDefinition { QName, Parent }

# extended by child (inheritance)
predicate ExtendedByDeclaration:
  {
    parent: Declaration,
    child: Declaration
  }
  { Parent, Child } where
    ( { class_ = { name = QName } } = Parent;
    ) | (
      { interface_ = { name = QName } } = Parent;
    ) | (
      { enum_ = { name = QName } } = Parent;
    );
    T = Type { baseType = { object = { type = QName } } };
    Inheritance { base = T, subclass = CDecl } |
    InterfaceInheritance { interface_name = T, subclass = CDecl };
    { class_ = CDecl } = Child

} # schema