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