Codebase list node-ast-types / upstream/0.15.1 def / babel-core.ts
upstream/0.15.1

Tree @upstream/0.15.1 (Download .tar.gz)

babel-core.ts @upstream/0.15.1raw · history · blame

import { Fork } from "../types";
import esProposalsDef from "./es-proposals";
import typesPlugin from "../lib/types";
import sharedPlugin from "../lib/shared";
import { namedTypes as N } from "../gen/namedTypes";

export default function (fork: Fork) {
  fork.use(esProposalsDef);

  var types = fork.use(typesPlugin);
  var defaults = fork.use(sharedPlugin).defaults;
  var def = types.Type.def;
  var or = types.Type.or;

  def("Noop")
    .bases("Statement")
    .build();

  def("DoExpression")
    .bases("Expression")
    .build("body")
    .field("body", [def("Statement")]);

  def("BindExpression")
    .bases("Expression")
    .build("object", "callee")
    .field("object", or(def("Expression"), null))
    .field("callee", def("Expression"));

  def("ParenthesizedExpression")
    .bases("Expression")
    .build("expression")
    .field("expression", def("Expression"));

  def("ExportNamespaceSpecifier")
    .bases("Specifier")
    .build("exported")
    .field("exported", def("Identifier"));

  def("ExportDefaultSpecifier")
    .bases("Specifier")
    .build("exported")
    .field("exported", def("Identifier"));

  def("CommentBlock")
    .bases("Comment")
    .build("value", /*optional:*/ "leading", "trailing");

  def("CommentLine")
    .bases("Comment")
    .build("value", /*optional:*/ "leading", "trailing");

  def("Directive")
    .bases("Node")
    .build("value")
    .field("value", def("DirectiveLiteral"));

  def("DirectiveLiteral")
    .bases("Node", "Expression")
    .build("value")
    .field("value", String, defaults["use strict"]);

  def("InterpreterDirective")
    .bases("Node")
    .build("value")
    .field("value", String);

  def("BlockStatement")
    .bases("Statement")
    .build("body")
    .field("body", [def("Statement")])
    .field("directives", [def("Directive")], defaults.emptyArray);

  def("Program")
    .bases("Node")
    .build("body")
    .field("body", [def("Statement")])
    .field("directives", [def("Directive")], defaults.emptyArray)
    .field("interpreter", or(def("InterpreterDirective"), null), defaults["null"]);

  // Split Literal
  def("StringLiteral")
    .bases("Literal")
    .build("value")
    .field("value", String);

  def("NumericLiteral")
    .bases("Literal")
    .build("value")
    .field("value", Number)
    .field("raw", or(String, null), defaults["null"])
    .field("extra", {
      rawValue: Number,
      raw: String
    }, function getDefault(this: N.NumericLiteral) {
      return {
        rawValue: this.value,
        raw: this.value + ""
      }
    });

  def("BigIntLiteral")
    .bases("Literal")
    .build("value")
    // Only String really seems appropriate here, since BigInt values
    // often exceed the limits of JS numbers.
    .field("value", or(String, Number))
    .field("extra", {
      rawValue: String,
      raw: String
    }, function getDefault(this: N.BigIntLiteral) {
      return {
        rawValue: String(this.value),
        raw: this.value + "n",
      };
    });

  // https://github.com/tc39/proposal-decimal
  // https://github.com/babel/babel/pull/11640
  def("DecimalLiteral")
    .bases("Literal")
    .build("value")
    .field("value", String)
    .field("extra", {
      rawValue: String,
      raw: String
    }, function getDefault(this: N.DecimalLiteral) {
      return {
        rawValue: String(this.value),
        raw: this.value + "m",
      };
    });

  def("NullLiteral")
    .bases("Literal")
    .build()
    .field("value", null, defaults["null"]);

  def("BooleanLiteral")
    .bases("Literal")
    .build("value")
    .field("value", Boolean);

  def("RegExpLiteral")
    .bases("Literal")
    .build("pattern", "flags")
    .field("pattern", String)
    .field("flags", String)
    .field("value", RegExp, function (this: N.RegExpLiteral) {
      return new RegExp(this.pattern, this.flags);
    });

  var ObjectExpressionProperty = or(
    def("Property"),
    def("ObjectMethod"),
    def("ObjectProperty"),
    def("SpreadProperty"),
    def("SpreadElement")
  );

  // Split Property -> ObjectProperty and ObjectMethod
  def("ObjectExpression")
    .bases("Expression")
    .build("properties")
    .field("properties", [ObjectExpressionProperty]);

  // ObjectMethod hoist .value properties to own properties
  def("ObjectMethod")
    .bases("Node", "Function")
    .build("kind", "key", "params", "body", "computed")
    .field("kind", or("method", "get", "set"))
    .field("key", or(def("Literal"), def("Identifier"), def("Expression")))
    .field("params", [def("Pattern")])
    .field("body", def("BlockStatement"))
    .field("computed", Boolean, defaults["false"])
    .field("generator", Boolean, defaults["false"])
    .field("async", Boolean, defaults["false"])
    .field("accessibility", // TypeScript
           or(def("Literal"), null),
           defaults["null"])
    .field("decorators",
           or([def("Decorator")], null),
           defaults["null"]);

  def("ObjectProperty")
    .bases("Node")
    .build("key", "value")
    .field("key", or(def("Literal"), def("Identifier"), def("Expression")))
    .field("value", or(def("Expression"), def("Pattern")))
    .field("accessibility", // TypeScript
           or(def("Literal"), null),
           defaults["null"])
    .field("computed", Boolean, defaults["false"]);

  var ClassBodyElement = or(
    def("MethodDefinition"),
    def("VariableDeclarator"),
    def("ClassPropertyDefinition"),
    def("ClassProperty"),
    def("ClassPrivateProperty"),
    def("ClassMethod"),
    def("ClassPrivateMethod"),
  );

  // MethodDefinition -> ClassMethod
  def("ClassBody")
    .bases("Declaration")
    .build("body")
    .field("body", [ClassBodyElement]);

  def("ClassMethod")
    .bases("Declaration", "Function")
    .build("kind", "key", "params", "body", "computed", "static")
    .field("key", or(def("Literal"), def("Identifier"), def("Expression")));

  def("ClassPrivateMethod")
    .bases("Declaration", "Function")
    .build("key", "params", "body", "kind", "computed", "static")
    .field("key", def("PrivateName"));

  ["ClassMethod",
   "ClassPrivateMethod",
  ].forEach(typeName => {
    def(typeName)
      .field("kind", or("get", "set", "method", "constructor"), () => "method")
      .field("body", def("BlockStatement"))
      .field("computed", Boolean, defaults["false"])
      .field("static", or(Boolean, null), defaults["null"])
      .field("abstract", or(Boolean, null), defaults["null"])
      .field("access", or("public", "private", "protected", null), defaults["null"])
      .field("accessibility", or("public", "private", "protected", null), defaults["null"])
      .field("decorators", or([def("Decorator")], null), defaults["null"])
      .field("optional", or(Boolean, null), defaults["null"]);
  });

  var ObjectPatternProperty = or(
    def("Property"),
    def("PropertyPattern"),
    def("SpreadPropertyPattern"),
    def("SpreadProperty"), // Used by Esprima
    def("ObjectProperty"), // Babel 6
    def("RestProperty") // Babel 6
  );

  // Split into RestProperty and SpreadProperty
  def("ObjectPattern")
    .bases("Pattern")
    .build("properties")
    .field("properties", [ObjectPatternProperty])
    .field("decorators",
           or([def("Decorator")], null),
           defaults["null"]);

  def("SpreadProperty")
    .bases("Node")
    .build("argument")
    .field("argument", def("Expression"));

  def("RestProperty")
    .bases("Node")
    .build("argument")
    .field("argument", def("Expression"));

  def("ForAwaitStatement")
    .bases("Statement")
    .build("left", "right", "body")
    .field("left", or(
      def("VariableDeclaration"),
      def("Expression")))
    .field("right", def("Expression"))
    .field("body", def("Statement"));

  // The callee node of a dynamic import(...) expression.
  def("Import")
    .bases("Expression")
    .build();
};