All Downloads are FREE. Search and download functionalities are using the official Maven repository.

schemas.base.json Maven / Gradle / Ivy

The newest version!
// Schema for the base code property graph
// Language modules are required to produce graphs adhering to this schema
{

    // Keys for node properties

    "nodeKeys" : [

        { "id": 19, "name" : "LANGUAGE", "comment" : "The programming language this graph originates from", "valueType" : "string", "cardinality" : "one"},
        { "id" : 13, "name": "VERSION", "comment" : "A version, given as a string", "valueType" : "string", "cardinality" : "one"},

        // Properties that indicate where the code can be found

        {"id" : 2, "name": "LINE_NUMBER", "comment": "Line where the code starts", "valueType" : "int", "cardinality" : "zeroOrOne"},
        {"id" : 11, "name": "COLUMN_NUMBER", "comment" : "Column where the code starts", "valueType" : "int", "cardinality" : "zeroOrOne" },
	{"id" : 12, "name": "LINE_NUMBER_END", "comment" : "Line where the code ends", "valueType" : "int", "cardinality" : "zeroOrOne"},
	{"id" : 16, "name": "COLUMN_NUMBER_END", "comment" : "Column where the code ends", "valueType" : "int", "cardinality" : "zeroOrOne"},

        {"id" : 3, "name": "PARSER_TYPE_NAME", "comment": "Type name emitted by parser, only present for logical type UNKNOWN", "valueType" : "string", "cardinality" : "one"},
        {"id" : 4, "name": "ORDER", "comment": "General ordering property, such that the children of each AST-node are typically numbered from 1, ..., N (this is not enforced). The ordering has no technical meaning, but is used for pretty printing and OUGHT TO reflect order in the source code", "valueType" : "int", "cardinality" : "one"},
        {"id" : 40, "name": "ARGUMENT_INDEX", "comment": "AST-children of CALL nodes have an argument index, that is used to match call-site arguments with callee parameters. Explicit parameters are numbered from 1 to N, while index 0 is reserved for implicit self / this parameter. CALLs without implicit parameter therefore have arguments starting with index 1. AST-children of BLOCK nodes may have an argument index as well; in this case, the last argument index determines the return-value of a BLOCK expression", "valueType" : "int", "cardinality" : "one"},

        {"id" : 7, "name": "IS_EXTERNAL", "comment" : "Indicates that the construct (METHOD or TYPE_DECL) is external, that is, it is referenced but not defined in the code (applies both to insular parsing and to library functions where we have header files only)", "valueType" : "boolean", "cardinality" : "one"},

        // String properties for various types of nodes

        {"id" : 5, "name": "NAME", "comment": "Name of represented object, e.g., method name (e.g. \"run\")", "valueType" : "string", "cardinality" : "one"},
        {"id" : 6, "name": "FULL_NAME", "comment" : "Full name of an element, e.g., the class name along, including its package (e.g. \"io.shiftleft.dataflowenging.layers.dataflows.DataFlowRunner.run\"). In theory, the FULL_NAME just needs to be unique and is used for linking references, so a consecutive integer would be valid. In practice, this should be human readable", "valueType" : "string", "cardinality" : "one"},
        {"id": 21, "name": "CODE", "comment": "The code snippet the node represents", "valueType" : "string", "cardinality" : "one"},
        {"id": 22, "name": "SIGNATURE", "comment": "Method signature. The format is defined by the language front-end, and the backend simply compares strings to resolve function overloading, i.e. match call-sites to METHODs. In theory, consecutive integers would be valid, but in practice this should be human readable", "valueType" : "string", "cardinality" : "one"},
        {"id": 26, "name" : "MODIFIER_TYPE", "comment" : "Indicates the modifier which is represented by a MODIFIER node. See modifierTypes", "valueType" : "string", "cardinality" : "one"},

        // Properties to characterize call-sites

        {"id": 25, "name": "DISPATCH_TYPE", "comment": "The dispatch type of a call, which is either static or dynamic. See dispatchTypes", "valueType" : "string", "cardinality" : "one"},
        {"id": 15, "name" : "EVALUATION_STRATEGY", "comment" : "Evaluation strategy for function parameters and return values. One of the values in \"evaluationStrategies\"", "valueType" : "string", "cardinality" : "one"},

        // Properties used to link nodes in the backend
        {"id": 51, "name" : "TYPE_FULL_NAME", "comment" : "The static type of an entity. E.g. expressions, local, parameters etc. This property is matched against the FULL_NAME of TYPE nodes and thus it is required to have at least one TYPE node for each TYPE_FULL_NAME", "valueType" : "string", "cardinality" : "one"},
        {"id": 52, "name" : "TYPE_DECL_FULL_NAME", "comment" : "The static type decl of a TYPE. This property is matched against the FULL_NAME of TYPE_DECL nodes. It is required to have exactly one TYPE_DECL for each different TYPE_DECL_FULL_NAME", "valueType" : "string", "cardinality" : "one"},
        {"id": 53, "name" : "INHERITS_FROM_TYPE_FULL_NAME", "comment" : "The static types a TYPE_DECL inherits from. This property is matched against the FULL_NAME of TYPE nodes and thus it is required to have at least one TYPE node for each TYPE_FULL_NAME", "valueType" : "string", "cardinality" : "list"},
        {"id": 54, "name" : "METHOD_FULL_NAME", "comment" : "The FULL_NAME of a method. Used to link CALL and METHOD nodes. It is required to have exactly one METHOD node for each METHOD_FULL_NAME", "valueType" : "string", "cardinality" : "one"},
        {"id": 55, "name" : "METHOD_INST_FULL_NAME", "comment" : "Deprecated", "valueType" : "string", "cardinality" : "zeroOrOne"},
        {"id": 56, "name" : "AST_PARENT_TYPE", "comment" : "The type of the AST parent. Since this is only used in some parts of the graph the list does not include all possible parents by intention. Possible parents: METHOD, TYPE_DECL, NAMESPACE_BLOCK", "valueType" : "string", "cardinality" : "one"},
        {"id": 57, "name" : "AST_PARENT_FULL_NAME", "comment" : "The FULL_NAME of a the AST parent of an entity", "valueType" : "string", "cardinality" : "one"},
        {"id": 158, "name" : "ALIAS_TYPE_FULL_NAME", "comment" : "Type full name of which a TYPE_DECL is an alias of", "valueType" : "string", "cardinality" : "zeroOrOne"},
        {"id": 1591, "name" : "DYNAMIC_TYPE_HINT_FULL_NAME", "comment" : "Type hint for the dynamic type", "valueType" : "string", "cardinality" : "list"}
    ],

    // Keys for edge properties

    "edgeKeys" : [
      {"id" : 6, "name" : "LOCAL_NAME", "comment" : "Local name of referenced CONTAINED node", "valueType" : "string", "cardinality" : "zeroOrOne"},
      {"id" : 8, "name" : "INDEX", "comment" : "Index of referenced CONTAINED node (0 based) - used together with cardinality=list", "valueType" : "int", "cardinality" : "zeroOrOne"}
    ],

    // Types of nodes

    "nodeTypes" : [
        {
            "id" : 39,
            "name" : "META_DATA",
            "keys" : ["LANGUAGE", "VERSION"],
            "comment" : "Node to save meta data about the graph on its properties. Exactly one node of this type per graph",
            "outEdges" : []
        },
        // Nodes describing program structure

        {"id" : 38,
         "name": "FILE",
         "keys": ["NAME", "ORDER"],
         "comment": "Node representing a source file. Often also the AST root",
         "outEdges": [
             {"edgeName": "AST", "inNodes": ["NAMESPACE_BLOCK"]}
         ],
	 "is" : ["AST_NODE"]
        },

        // Nodes of method declarations

        {"id" : 1, "name" : "METHOD",
         "keys": ["NAME", "FULL_NAME", "IS_EXTERNAL", "SIGNATURE", "AST_PARENT_TYPE", "AST_PARENT_FULL_NAME",
		  "LINE_NUMBER", "COLUMN_NUMBER", "LINE_NUMBER_END", "COLUMN_NUMBER_END", "ORDER"],
         "comment" : "A method/function/procedure",
         "is": ["DECLARATION", "CFG_NODE", "AST_NODE"],
         "outEdges" : [
             {"edgeName": "AST", "inNodes": ["METHOD_RETURN", "METHOD_PARAMETER_IN",
                                             "MODIFIER", "BLOCK", "TYPE_PARAMETER"]},
             {"edgeName": "CFG", "inNodes": ["CALL", "IDENTIFIER", "LITERAL", "METHOD_REF", "RETURN", "BLOCK", "UNKNOWN"]}
         ]
        },

        {"id" : 34, "name" : "METHOD_PARAMETER_IN",
         "keys": ["CODE", "ORDER", "NAME", "EVALUATION_STRATEGY", "TYPE_FULL_NAME", "DYNAMIC_TYPE_HINT_FULL_NAME", "LINE_NUMBER", "COLUMN_NUMBER"],
         "comment" : "This node represents a formal parameter going towards the callee side",
         "is": ["DECLARATION", "LOCAL_LIKE", "TRACKING_POINT", "AST_NODE"]
        },

        {"id" : 3, "name" : "METHOD_RETURN",
         "keys": ["CODE", "EVALUATION_STRATEGY", "TYPE_FULL_NAME", "DYNAMIC_TYPE_HINT_FULL_NAME", "LINE_NUMBER", "COLUMN_NUMBER", "ORDER"],
         "comment" : "A formal method return",
         "is": ["CFG_NODE", "TRACKING_POINT"]
        },
        {"id" : 300, "name" : "MODIFIER",
         "keys" : ["MODIFIER_TYPE", "ORDER"],
         "comment" : "A modifier, e.g., static, public, private",
         "outEdges": [],
	 "is" : ["AST_NODE"]
        },

        // Types

        {"id" : 45, "name" : "TYPE",
         "keys" : ["NAME", "FULL_NAME", "TYPE_DECL_FULL_NAME"],
         "comment" : "A type which always has to reference a type declaration and may have type argument children if the referred to type declaration is a template",
         "outEdges" : [
             {"edgeName": "AST", "inNodes": ["TYPE_ARGUMENT"]}
         ]
        },
        {"id" : 46, "name" : "TYPE_DECL",
         "keys" : ["NAME", "FULL_NAME", "IS_EXTERNAL", "INHERITS_FROM_TYPE_FULL_NAME", "AST_PARENT_TYPE", "AST_PARENT_FULL_NAME", "ALIAS_TYPE_FULL_NAME", "ORDER"],
         "comment" : "A type declaration",
         "outEdges" : [
             {"edgeName": "AST", "inNodes": ["TYPE_PARAMETER", "MEMBER", "MODIFIER"]},
             {"edgeName": "BINDS", "inNodes": ["BINDING"]},
             {"edgeName": "VTABLE", "inNodes": ["METHOD"]}
         ],
	 "is" : ["AST_NODE"]
        },
        {"id" : 146, "name" : "BINDING",
         "keys" : ["NAME", "SIGNATURE"],
         "comment" : "A binding of a METHOD into a TYPE_DECL",
         "outEdges" : [
             {"edgeName": "REF", "inNodes": ["METHOD"]}
         ]
        },
        {"id" : 47, "name" : "TYPE_PARAMETER",
         "keys" : ["NAME", "ORDER"],
         "comment" : "Type parameter of TYPE_DECL or METHOD",
         "outEdges" : [],
	 "is" : ["AST_NODE"]
        },
        {"id" : 48, "name" : "TYPE_ARGUMENT",
         "keys" : ["ORDER"],
         "comment" : "Argument for a TYPE_PARAMETER that belongs to a TYPE. It binds another TYPE to a TYPE_PARAMETER",
         "outEdges" : [
             {"edgeName": "REF", "inNodes": ["TYPE"]},
             {"edgeName": "BINDS_TO", "inNodes": ["TYPE_PARAMETER"]}
         ],
	 "is" : ["AST_NODE"]
        },

        {"id" : 9, "name" : "MEMBER",
         "keys" : [ "CODE", "NAME", "TYPE_FULL_NAME", "DYNAMIC_TYPE_HINT_FULL_NAME", "ORDER"],
         "comment" : "Member of a class struct or union",
         "is": ["DECLARATION", "AST_NODE"]
        },

        {
            "id":41,
            "name": "NAMESPACE_BLOCK",
            "keys": ["NAME", "FULL_NAME", "ORDER"],
            "comment": "A reference to a namespace",
	    "is" : ["AST_NODE"]
        },

        // Nodes that describe method content

        {"id" : 8, "name" : "LITERAL",
         "keys" : ["CODE", "ORDER", "ARGUMENT_INDEX", "TYPE_FULL_NAME", "DYNAMIC_TYPE_HINT_FULL_NAME", "LINE_NUMBER", "COLUMN_NUMBER"],
         "comment" : "Literal/Constant",
         "is": ["EXPRESSION"],
         "outEdges" : [
             {"edgeName": "CFG", "inNodes": ["CALL", "IDENTIFIER", "LITERAL", "METHOD_REF", "RETURN", "BLOCK", "UNKNOWN"]}
         ]
        },
        {"id": 15, "name" : "CALL",
         "keys": ["CODE", "NAME", "ORDER", "METHOD_INST_FULL_NAME", "METHOD_FULL_NAME", "ARGUMENT_INDEX", "DISPATCH_TYPE", "SIGNATURE", "TYPE_FULL_NAME", "DYNAMIC_TYPE_HINT_FULL_NAME", "LINE_NUMBER", "COLUMN_NUMBER"],
         "comment" : "A (method)-call",
         "is": ["EXPRESSION", "CALL_REPR"],
         "outEdges" : [
             {"edgeName": "CFG", "inNodes": ["CALL", "IDENTIFIER", "LITERAL", "METHOD_REF", "RETURN", "BLOCK", "UNKNOWN"]},
             {"edgeName": "AST", "inNodes": ["CALL", "IDENTIFIER", "LITERAL", "METHOD_REF", "RETURN", "BLOCK", "CONTROL_STRUCTURE"]},
             {"edgeName": "RECEIVER", "inNodes": ["CALL", "IDENTIFIER", "LITERAL", "METHOD_REF", "BLOCK", "UNKNOWN"]},
             {"edgeName": "ARGUMENT", "inNodes": ["CALL", "IDENTIFIER", "LITERAL", "METHOD_REF", "BLOCK", "UNKNOWN"]}
         ]
        },
        {"id":23, "name" : "LOCAL",
         "keys": ["CODE", "NAME", "CLOSURE_BINDING_ID", "TYPE_FULL_NAME", "DYNAMIC_TYPE_HINT_FULL_NAME", "LINE_NUMBER", "COLUMN_NUMBER", "ORDER"],
         "comment": "A local variable",
         "is": ["DECLARATION", "LOCAL_LIKE", "AST_NODE"]
        },
        {"id":27, "name": "IDENTIFIER",
         "keys": ["CODE", "NAME", "ORDER", "ARGUMENT_INDEX", "TYPE_FULL_NAME", "DYNAMIC_TYPE_HINT_FULL_NAME", "LINE_NUMBER", "COLUMN_NUMBER"],
         "comment" : "An arbitrary identifier/reference",
         "is": ["EXPRESSION", "LOCAL_LIKE"],
         "outEdges" : [
             {"edgeName": "REF", "inNodes": ["LOCAL", "METHOD_PARAMETER_IN"]},
             {"edgeName": "CFG", "inNodes": ["CALL", "IDENTIFIER", "LITERAL", "METHOD_REF", "RETURN", "BLOCK", "UNKNOWN"]}
         ]
        },
        {"id":30, "name": "RETURN",
         "keys": [ "LINE_NUMBER", "COLUMN_NUMBER", "ORDER", "ARGUMENT_INDEX", "CODE"],
         "comment" : "A return instruction",
         "is": [ "EXPRESSION"],
         "outEdges" : [
             {"edgeName": "AST", "inNodes": ["CALL", "IDENTIFIER", "LITERAL", "METHOD_REF", "RETURN", "BLOCK", "UNKNOWN", "CONTROL_STRUCTURE"]},
             {"edgeName": "CFG", "inNodes": ["METHOD_RETURN"]},
             {"edgeName": "ARGUMENT", "inNodes": ["CALL", "IDENTIFIER", "LITERAL", "METHOD_REF", "RETURN", "BLOCK", "UNKNOWN"]}
         ]
        },
        {"id":31, "name": "BLOCK",
         "keys": [ "CODE", "ORDER", "ARGUMENT_INDEX", "TYPE_FULL_NAME", "DYNAMIC_TYPE_HINT_FULL_NAME", "LINE_NUMBER", "COLUMN_NUMBER"],
         "comment" : "A structuring block in the AST",
         "is": [ "EXPRESSION"],
         "outEdges" : [
             {"edgeName": "AST", "inNodes": ["CALL", "IDENTIFIER", "LITERAL", "METHOD_REF", "RETURN", "BLOCK", "LOCAL", "UNKNOWN", "CONTROL_STRUCTURE"]},
             {"edgeName": "CFG", "inNodes": ["CALL", "IDENTIFIER", "LITERAL", "METHOD_REF", "RETURN", "BLOCK", "UNKNOWN"]}
         ]
        },
        // METHOD_INST is deprecated.
       {"id":32, "name":"METHOD_INST",
         "keys":["NAME", "SIGNATURE", "FULL_NAME", "METHOD_FULL_NAME", "ORDER"],
         "comment":"A method instance which always has to reference a method and may have type argument children if the referred to method is a template",
         "outEdges": [
             {"edgeName": "AST", "inNodes": ["TYPE_ARGUMENT"]}
         ],
	 "is" : ["AST_NODE"]
        },
        {"id" : 14, "name" : "ARRAY_INITIALIZER",
         "keys":[],
         "outEdges": [],
         "comment" : "Initialization construct for arrays",
	 "is" : ["AST_NODE"]
        },

        {"id":333, "name":"METHOD_REF",
          "keys": ["CODE", "ORDER", "ARGUMENT_INDEX", "METHOD_INST_FULL_NAME", "METHOD_FULL_NAME", "LINE_NUMBER", "COLUMN_NUMBER"],
          "comment":"Reference to a method instance",
         "is": ["EXPRESSION"],
          "outEdges": [
            {"edgeName": "CFG", "inNodes": ["CALL", "IDENTIFIER", "LITERAL", "METHOD_REF", "RETURN", "BLOCK", "UNKNOWN"]}
          ]
        },

	{"id" : 339, "name" : "CONTROL_STRUCTURE",
	 "keys" : ["CODE", "COLUMN_NUMBER", "LINE_NUMBER", "ORDER", "PARSER_TYPE_NAME", "ARGUMENT_INDEX"],
	 "comment" : "A control structure such as if, while, or for",
	 "is" : ["EXPRESSION"],
	 "outEdges" : [
             {"edgeName": "AST", "inNodes": ["LITERAL",
                                             "MODIFIER", "ARRAY_INITIALIZER", "CALL", "LOCAL",
                                             "IDENTIFIER", "RETURN", "BLOCK", "UNKNOWN", "CONTROL_STRUCTURE"]},
	     {"edgeName" : "CONDITION", "inNodes" : ["LITERAL", "CALL", "IDENTIFIER", "RETURN", "BLOCK", "METHOD_REF", "CONTROL_STRUCTURE", "UNKNOWN", "ARRAY_INITIALIZER"] }
	 ]
	},

        // This is the "catch-all-others" node type.

        {"id" : 44, "name": "UNKNOWN",
         "keys" : ["CODE", "PARSER_TYPE_NAME", "ORDER", "ARGUMENT_INDEX", "TYPE_FULL_NAME", "DYNAMIC_TYPE_HINT_FULL_NAME", "LINE_NUMBER", "COLUMN_NUMBER"],
         "comment" : "A language-specific node",
         "is": ["EXPRESSION"],
         "outEdges" : [
             {"edgeName": "CFG", "inNodes": ["CALL", "IDENTIFIER", "LITERAL", "RETURN", "METHOD_REF", "BLOCK", "UNKNOWN"]},
             {"edgeName": "AST", "inNodes": ["LITERAL", "MEMBER",
                                             "MODIFIER", "ARRAY_INITIALIZER", "CALL", "LOCAL",
                                             "IDENTIFIER", "RETURN", "BLOCK", "UNKNOWN", "CONTROL_STRUCTURE"]}
         ]
        }
    ],

    // common base traits for nodes
    "nodeBaseTraits" : [
      { "name" : "DECLARATION", "comment" : "", "hasKeys" : ["NAME"]},
      { "name" : "EXPRESSION", "comment" : "Expression as a specialisation of tracking point", "hasKeys" : ["CODE", "ORDER"], "extends" : ["TRACKING_POINT", "CFG_NODE", "AST_NODE"]},
      { "name" : "LOCAL_LIKE", "comment" : "Formal input parameters, locals, and identifiers", "hasKeys" : ["NAME"]},
      { "name" : "CFG_NODE", "comment" : "Any node that can occur as part of a control flow graph", "hasKeys" : ["LINE_NUMBER", "COLUMN_NUMBER"], "extends": ["WITHIN_METHOD", "AST_NODE"]},
      { "name" : "TRACKING_POINT", "comment" : "Any node that can occur in a data flow", "hasKeys" : [], "extends": ["WITHIN_METHOD"]},
      { "name" : "WITHIN_METHOD", "comment" : "Any node that can exist in a method", "hasKeys" : []},
      { "name" : "AST_NODE", "comment": "Any node that can exist in an abstract syntax tree", "hasKeys" : ["ORDER"]},
      { "name" : "CALL_REPR", "comment": "Call representation", "hasKeys" : ["CODE", "NAME", "SIGNATURE"], "extends": ["CFG_NODE"]}
    ],

    "edgeTypes" : [

        {"id" : 3, "name" : "AST", "comment" : "Syntax tree edge" , "keys" : [] },
        {"id" : 19, "name" : "CFG", "comment" : "Control flow edge", "keys" : [] },

        {"id" : 9, "name" : "CONTAINS_NODE", "keys" : ["LOCAL_NAME", "INDEX"], "comment" : "Membership relation for a compound object"},
        {"id" : 41, "name": "CAPTURED_BY", "comment" : "Connection between a captured LOCAL and the corresponding CLOSURE_BINDING", "keys": []},

        // Edges to represent type relations

        {"id" : 22, "name" : "BINDS_TO", "comment" : "Type argument binding to a type parameter", "keys" : [] },
        {"id" : 10, "name" : "REF", "keys" : [], "comment" : "A reference to e.g. a LOCAL" },
        // VTABLE edge is deprecated.
        {"id" : 30, "name": "VTABLE", "comment" : "Indicates that a method is part of the vtable of a certain type declaration", "keys": []},
        {"id" : 55, "name": "RECEIVER", "comment" : "The receiver of a method call which is either an object or a pointer", "keys": []},
        {"id" : 56, "name": "CONDITION", "comment" : "Edge from control structure node to the expression that holds the condition", "keys" : []},
        {"id" : 155, "name": "BINDS", "comment" : "Relation between TYPE_DECL and BINDING node", "keys": []},
        {"id" : 156, "name": "ARGUMENT", "comment" : "Relation between a CALL and its arguments and RETURN and the returned expression", "keys": []}

    ],

    // Enums

    "evaluationStrategies" : [
        {"id" : 1, "name" : "BY_REFERENCE", "comment" : "A parameter or return of a function is passed by reference which means an address is used behind the scenes"},
        {"id" : 2, "name" : "BY_SHARING", "comment" : "Only applicable to object parameter or return values. The pointer to the object is passed by value but the object itself is not copied and changes to it are thus propagated out of the method context"},
        {"id" : 3, "name" : "BY_VALUE", "comment" : "A parameter or return of a function passed by value which means a flat copy is used"}
    ],

    "dispatchTypes" : [
        {"id" : 1, "name" : "STATIC_DISPATCH", "comment": "For statically dispatched calls the call target is known before program execution"},
        {"id" : 2, "name" : "DYNAMIC_DISPATCH", "comment": "For dynamically dispatched calls the target is determined during runtime"}
    ],

    "languages" : [
        {"id" : 1, "name" : "JAVA", "comment" : ""},
        {"id" : 2, "name" : "JAVASCRIPT", "comment" : ""},
        {"id" : 3, "name" : "GOLANG", "comment" : ""},
        {"id" : 4, "name" : "CSHARP", "comment" : ""},
        {"id" : 5, "name" : "C", "comment" : ""},
        {"id" : 6, "name" : "PYTHON", "comment" : ""}
    ],

    "modifierTypes" : [
        {"id" : 1, "name" : "STATIC", "comment" : "The static modifier"},
        {"id" : 2, "name" : "PUBLIC", "comment" : "The public modifier"},
        {"id" : 3, "name" : "PROTECTED", "comment" : "The protected modifier"},
        {"id" : 4, "name" : "PRIVATE", "comment" : "The private modifier"},
        {"id" : 5, "name" : "ABSTRACT", "comment" : "The abstract modifier"},
        {"id" : 6, "name" : "NATIVE", "comment" : "The native modifier"},
        {"id" : 7, "name" : "CONSTRUCTOR", "comment" : "The constructor modifier"},
        {"id" : 8, "name" : "VIRTUAL", "comment" : "The virtual modifier"}
    ],

    // used in extensions
    "frameworks" : [],
    "operatorNames" : []

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy