Esempio n. 1
0
function getVariableDeclarators(node: Object): Object[] | Object {
  if (t.isIdentifier(node)) {
    return t.variableDeclarator(t.identifier(node.name));
  }

  if (t.isObjectProperty(node)) {
    return getVariableDeclarators(node.value);
  }
  if (t.isRestElement(node)) {
    return getVariableDeclarators(node.argument);
  }

  if (t.isAssignmentPattern(node)) {
    return getVariableDeclarators(node.left);
  }

  if (t.isArrayPattern(node)) {
    return node.elements.reduce(
      (acc, element) => acc.concat(getVariableDeclarators(element)),
      []
    );
  }
  if (t.isObjectPattern(node)) {
    return node.properties.reduce(
      (acc, property) => acc.concat(getVariableDeclarators(property)),
      []
    );
  }
  return [];
}
Esempio n. 2
0
export function isObjectShorthand(parent: Node): boolean {
  return (
    t.isObjectProperty(parent) &&
    parent.value &&
    parent.key.start == parent.value.start &&
    parent.key.loc.identifierName === parent.value.loc.identifierName
  );
}
Esempio n. 3
0
function isSimpleObjectExpression(node: Node) {
  if (!t.isObjectExpression(node)) {
    return false;
  }
  for (let property of node.properties) {
    if (!t.isObjectProperty(property) ||
        !t.isIdentifier(property.key) ||
        !t.isIdentifier(property.value)) {
      return false;
    }
  }
  return true;
}
Esempio n. 4
0
  generateUidBasedOnNode(parent: Object, defaultName?: String) {
    let node = parent;

    if (t.isAssignmentExpression(parent)) {
      node = parent.left;
    } else if (t.isVariableDeclarator(parent)) {
      node = parent.id;
    } else if (t.isObjectProperty(node) || t.isObjectMethod(node)) {
      node = node.key;
    }

    const parts = [];
    gatherNodeParts(node, parts);

    let id = parts.join("$");
    id = id.replace(/^_/, "") || defaultName || "ref";

    return this.generateUid(id.slice(0, 20));
  }
/**
 * Create a ScannedProperty object from an estree Property AST node.
 */
function toScannedPolymerProperty(node, sourceRange, document) {
    const parsedJsdoc = jsdoc.parseJsdoc(esutil_1.getAttachedComment(node) || '');
    const description = parsedJsdoc.description.trim();
    const maybeName = esutil_1.getPropertyName(node);
    const warnings = [];
    if (!maybeName) {
        warnings.push(new model_1.Warning({
            code: 'unknown-prop-name',
            message: `Could not determine name of property from expression of type: ` +
                `${node.key.type}`,
            sourceRange: sourceRange,
            severity: model_1.Severity.WARNING,
            parsedDocument: document
        }));
        return;
    }
    const value = babel.isObjectProperty(node) ? node.value : node;
    const typeResult = esutil_1.getClosureType(value, parsedJsdoc, sourceRange, document);
    let type;
    if (typeResult.successful) {
        type = typeResult.value;
    }
    else {
        warnings.push(typeResult.error);
        type = 'Object';
    }
    const name = maybeName || '';
    const result = {
        name,
        type,
        description,
        sourceRange,
        warnings,
        astNode: { node, language: 'js', containingDocument: document },
        isConfiguration: esutil_1.configurationProperties.has(name),
        jsdoc: parsedJsdoc,
        privacy: esutil_1.getOrInferPrivacy(name, parsedJsdoc)
    };
    return result;
}
Esempio n. 6
0
export function isPropertyWithKey(property, identifierName) {
  return isObjectProperty(property) && isIdentifier(property.key, { name: identifierName });
}
Esempio n. 7
0
function getSnippet(
  path: SimplePath | null,
  prevPath?: SimplePath,
  expression?: string = ""
): string {
  if (!path) {
    return expression;
  }

  if (t.isVariableDeclaration(path)) {
    const node = path.node.declarations[0];
    const name = node.id.name;
    return extendSnippet(name, expression, path, prevPath);
  }

  if (t.isVariableDeclarator(path)) {
    const node = path.node.id;
    if (t.isObjectPattern(node)) {
      return expression;
    }

    const name = node.name;
    const prop = extendSnippet(name, expression, path, prevPath);
    return prop;
  }

  if (t.isAssignmentExpression(path)) {
    const node = path.node.left;
    const name = t.isMemberExpression(node)
      ? getMemberSnippet(node)
      : node.name;

    const prop = extendSnippet(name, expression, path, prevPath);
    return prop;
  }

  if (isFunction(path)) {
    return expression;
  }

  if (t.isIdentifier(path)) {
    const node = path.node;
    return `${node.name}.${expression}`;
  }

  if (t.isObjectProperty(path)) {
    return getObjectSnippet(path, prevPath, expression);
  }

  if (t.isObjectExpression(path)) {
    const parentPath = prevPath && prevPath.parentPath;
    return getObjectSnippet(parentPath, prevPath, expression);
  }

  if (t.isMemberExpression(path)) {
    return getMemberSnippet(path.node, expression);
  }

  if (t.isArrayExpression(path)) {
    if (!prevPath) {
      throw new Error("Assertion failure - path should exist");
    }

    return getArraySnippet(path, prevPath, expression);
  }

  return "";
}
Esempio n. 8
0
/* eslint-disable complexity */
function extractSymbol(path: SimplePath, symbols, state) {
  if (isFunction(path)) {
    const name = getFunctionName(path.node, path.parent);

    if (!state.fnCounts[name]) {
      state.fnCounts[name] = 0;
    }
    const index = state.fnCounts[name]++;

    symbols.functions.push({
      name,
      klass: inferClassName(path),
      location: path.node.loc,
      parameterNames: getFunctionParameterNames(path),
      identifier: path.node.id,
      // indicates the occurence of the function in a file
      // e.g { name: foo, ... index: 4 } is the 4th foo function
      // in the file
      index
    });
  }

  if (t.isJSXElement(path)) {
    symbols.hasJsx = true;
  }

  if (t.isGenericTypeAnnotation(path)) {
    symbols.hasTypes = true;
  }

  if (t.isClassDeclaration(path)) {
    const { loc, superClass } = path.node;
    symbols.classes.push({
      name: path.node.id.name,
      parent: superClass
        ? {
            name: t.isMemberExpression(superClass)
              ? getCode(superClass)
              : superClass.name,
            location: superClass.loc
          }
        : null,
      location: loc
    });
  }

  if (t.isImportDeclaration(path)) {
    symbols.imports.push({
      source: path.node.source.value,
      location: path.node.loc,
      specifiers: getSpecifiers(path.node.specifiers)
    });
  }

  if (t.isObjectProperty(path)) {
    const { start, end, identifierName } = path.node.key.loc;
    symbols.objectProperties.push({
      name: identifierName,
      location: { start, end },
      expression: getSnippet(path)
    });
  }

  if (t.isMemberExpression(path)) {
    const { start, end } = path.node.property.loc;
    symbols.memberExpressions.push({
      name: path.node.property.name,
      location: { start, end },
      expression: getSnippet(path),
      computed: path.node.computed
    });
  }

  if (
    (t.isStringLiteral(path) || t.isNumericLiteral(path)) &&
    t.isMemberExpression(path.parentPath)
  ) {
    // We only need literals that are part of computed memeber expressions
    const { start, end } = path.node.loc;
    symbols.literals.push({
      name: path.node.value,
      location: { start, end },
      expression: getSnippet(path.parentPath)
    });
  }

  if (t.isCallExpression(path)) {
    const callee = path.node.callee;
    const args = path.node.arguments;
    if (t.isMemberExpression(callee)) {
      const {
        property: { name, loc }
      } = callee;
      symbols.callExpressions.push({
        name: name,
        values: args.filter(arg => arg.value).map(arg => arg.value),
        location: loc
      });
    } else {
      const { start, end, identifierName } = callee.loc;
      symbols.callExpressions.push({
        name: identifierName,
        values: args.filter(arg => arg.value).map(arg => arg.value),
        location: { start, end }
      });
    }
  }

  if (t.isStringLiteral(path) && t.isProperty(path.parentPath)) {
    const { start, end } = path.node.loc;
    return symbols.identifiers.push({
      name: path.node.value,
      expression: getObjectExpressionValue(path.parent),
      location: { start, end }
    });
  }

  if (t.isIdentifier(path) && !t.isGenericTypeAnnotation(path.parent)) {
    let { start, end } = path.node.loc;

    // We want to include function params, but exclude the function name
    if (t.isClassMethod(path.parent) && !path.inList) {
      return;
    }

    if (t.isProperty(path.parentPath) && !isObjectShorthand(path.parent)) {
      return symbols.identifiers.push({
        name: path.node.name,
        expression: getObjectExpressionValue(path.parent),
        location: { start, end }
      });
    }

    if (path.node.typeAnnotation) {
      const column = path.node.typeAnnotation.loc.start.column;
      end = { ...end, column };
    }

    symbols.identifiers.push({
      name: path.node.name,
      expression: path.node.name,
      location: { start, end }
    });
  }

  if (t.isThisExpression(path.node)) {
    const { start, end } = path.node.loc;
    symbols.identifiers.push({
      name: "this",
      location: { start, end },
      expression: "this"
    });
  }

  if (t.isVariableDeclarator(path)) {
    const nodeId = path.node.id;

    symbols.identifiers.push(...getPatternIdentifiers(nodeId));
  }
}
Esempio n. 9
0
export function push(
  mutatorMap: Object,
  node: Object,
  kind: string,
  file,
  scope?,
): Object {
  const alias = t.toKeyAlias(node);

  //

  let map = {};
  if (has(mutatorMap, alias)) map = mutatorMap[alias];
  mutatorMap[alias] = map;

  //

  map._inherits = map._inherits || [];
  map._inherits.push(node);

  map._key = node.key;

  if (node.computed) {
    map._computed = true;
  }

  if (node.decorators) {
    const decorators = (map.decorators =
      map.decorators || t.arrayExpression([]));
    decorators.elements = decorators.elements.concat(
      node.decorators.map(dec => dec.expression).reverse(),
    );
  }

  if (map.value || map.initializer) {
    throw file.buildCodeFrameError(node, "Key conflict with sibling node");
  }

  let key, value;

  // save the key so we can possibly do function name inferences
  if (
    t.isObjectProperty(node) ||
    t.isObjectMethod(node) ||
    t.isClassMethod(node)
  ) {
    key = t.toComputedKey(node, node.key);
  }

  if (t.isObjectProperty(node) || t.isClassProperty(node)) {
    value = node.value;
  } else if (t.isObjectMethod(node) || t.isClassMethod(node)) {
    value = t.functionExpression(
      null,
      node.params,
      node.body,
      node.generator,
      node.async,
    );
    value.returnType = node.returnType;
  }

  const inheritedKind = toKind(node);
  if (!kind || inheritedKind !== "value") {
    kind = inheritedKind;
  }

  // infer function name
  if (
    scope &&
    t.isStringLiteral(key) &&
    (kind === "value" || kind === "initializer") &&
    t.isFunctionExpression(value)
  ) {
    value = nameFunction({ id: key, node: value, scope });
  }

  if (value) {
    t.inheritsComments(value, node);
    map[kind] = value;
  }

  return map;
}