function visitStartIfTag(traverse, object, path, state) {
  hasElse = false;

  var attributes = object.attributes;

  if (!attributes || !attributes.length) {
    throw new Error(errors.IF_WITH_NO_CONDITION);
  }

  var condition = _.find(attributes, function (attr) {
    return attr.name.name === 'condition'
  });

  if (!condition) {
    throw new Error(errors.IF_WITH_NO_CONDITION);
  }

  if (shouldWrapCurlyBrackets()) {
    utils.append('{ ', state);
  }

  utils.move(condition.value.expression.range[0], state);
  utils.catchup(condition.value.expression.range[1], state);
  utils.append(' ? (', state);
  utils.move(object.range[1], state);

  inControlStatement = true;
}
Example #2
0
function visitTypedFunction(traverse, node, path, state) {
  var klass = getParentClassDeclaration(path);
  var generics = klass && klass.typeParameters ? toLookup(klass.typeParameters.params.map(getName)) : {};
  if (node.typeParameters) {
    generics = mixin(generics, toLookup(node.typeParameters.params.map(getName)));
  }
  var ctx = new Context(state, generics);
  var rest = node.rest ? ', ' + ctx.getType(node.rest.typeAnnotation.typeAnnotation) : '';
  var types = [];
  var params = [];
  node.params.forEach(function (param) {
    var type = ctx.getType(param.typeAnnotation ? param.typeAnnotation.typeAnnotation : null);
    types.push(param.optional ? ctx.getProperty('optional') + '(' + type + ')' : type);
    params.push(param.name);
  });

  utils.catchup(node.body.range[0] + 1, state);

  if (params.length || rest) {
    utils.append(ctx.getProperty('check') + '(arguments, ' + ctx.getProperty('arguments') + '([' + types.join(', ') + ']' + rest + '));', state);
  }

  if (node.returnType) {
    var returnType = ctx.getType(node.returnType.typeAnnotation);
    utils.append(' var ret = (function (' + params.join(', ') + ') {', state);
    traverse(node.body, path, state);
    utils.catchup(node.body.range[1] - 1, state);
    utils.append('}).apply(this, arguments); return ' + ctx.getProperty('check') + '(ret, ' + returnType + ');', state);
  } else {
    traverse(node.body, path, state);
  }

  return false;
}
Example #3
0
  attributes.forEach(function(attr, index) {
    var isLast = (index === (attributes.length - 1));
    var name = attr.name.name;

    utils.catchup(attr.range[0], state, trimLeft);

    var displayName = name;
    if (name in options.renameAttrs) {
      displayName = options.renameAttrs[name];
    }

    utils.append(quoteJSObjKey(displayName) + ': ', state);

    if (attr.value) {
      utils.move(attr.name.range[1], state);
      utils.catchupNewlines(attr.value.range[0], state);
      if (attr.value.type === Syntax.Literal) {
        renderJSXLiteral(attr.value, isLast, state);
      } else {
        renderJSXExpressionContainer(traverse, attr.value, isLast, path, state);
      }
    } else {
      state.g.buffer += 'true';
      state.g.position = attr.name.range[1];
      if (!isLast) {
        utils.append(', ', state);
      }
    }

    utils.catchup(attr.range[1], state, trimLeft);
  });
function visitStartForTag(traverse, object, path, state) {
  var attributes = object.attributes;

  if (!attributes || !attributes.length) {
    throw new Error(errors.FOR_WITH_NO_ATTRIBUTES);
  }

  var each, of;
  attributes.forEach(function (attr) {
    if (attr.name.name === 'each') {
      each = attr;
    } else if (attr.name.name === 'of') {
      of = attr;
    }
  });

  if (!each || !of) {
    throw new Error(errors.FOR_WITH_NO_ATTRIBUTES);
  }

  if (shouldWrapCurlyBrackets()) {
    utils.append('{ ', state);
  }
  utils.move(of.value.expression.range[0], state);
  utils.catchup(of.value.expression.range[1], state);
  utils.append('.map(function(', state);
  utils.move(each.value.range[0] + 1, state);
  utils.catchup(each.value.range[1] - 1, state);
  utils.append(', $index) { return (', state);

  utils.move(object.range[1], state)
  inControlStatement = true;
}
Example #5
0
// In: x = {class: 2};
// Out: x = {"class": 2};
function visitProperty(traverse, node, path, state) {
    utils.catchup(node.key.range[0], state);
    utils.append('"', state);
    utils.catchup(node.key.range[1], state);
    utils.append('"', state);
    utils.catchup(node.value.range[0], state);
    traverse(node.value, path, state);
    return false;
}
function visitEndForTag(traverse, object, path, state) {
  utils.append(')}, this)', state);
  if (shouldWrapCurlyBrackets()) {
    utils.append('}', state);
  }
  utils.move(object.range[1], state);

  contextStack.pop();
}
Example #7
0
// In: x.class = 3;
// Out: x["class"] = 3;
function visitMemberExpression(traverse, node, path, state) {
    traverse(node.object, path, state);
    utils.catchup(node.object.range[1], state);
    utils.append('[', state);
    utils.catchupWhiteSpace(node.property.range[0], state);
    utils.append('"', state);
    utils.catchup(node.property.range[1], state);
    utils.append('"]', state);
    return false;
}
function visitEndIfTag(traverse, object, path, state) {
  utils.catchup(object.range[0], state);
  utils.append(hasElse ? ')' : ') : \'\'', state);
  if (shouldWrapCurlyBrackets()) {
    utils.append(' }', state);
  }
  utils.move(object.range[1], state);

  contextStack.pop();
}
Example #9
0
function visitTypedVariableDeclarator(traverse, node, path, state) {
  var ctx = new Context(state);
  if (node.init) {
    utils.catchup(node.init.range[0], state);
    utils.append(ctx.getProperty('check') + '(', state);
    traverse(node.init, path, state);
    utils.catchup(node.init.range[1], state);
    utils.append(', ' + ctx.getType(node.id.typeAnnotation.typeAnnotation) + ')', state);
  }
  utils.catchup(node.range[1], state);
  return false;
}
Example #10
0
function visitFunctionBodyWithRestParam(traverse, node, path, state) {
  utils.catchup(node.range[0] + 1, state);
  var parentNode = path[0];
  utils.append(renderRestParamSetup(parentNode), state);
  traverse(node.body, path, state);
  return false;
}
Example #11
0
function addDisplayName(displayName, object, state) {
  if (object &&
      object.type === Syntax.CallExpression &&
      object.callee.type === Syntax.MemberExpression &&
      object.callee.object.type === Syntax.Identifier &&
      object.callee.object.name === 'React' &&
      object.callee.property.type === Syntax.Identifier &&
      object.callee.property.name === 'createClass' &&
      object['arguments'].length === 1 &&
      object['arguments'][0].type === Syntax.ObjectExpression) {
    // Verify that the displayName property isn't already set
    var properties = object['arguments'][0].properties;
    var safe = properties.every(function(property) {
      var value = property.key.type === Syntax.Identifier ?
        property.key.name :
        property.key.value;
      return value !== 'displayName';
    });

    if (safe) {
      utils.catchup(object['arguments'][0].range[0] + 1, state);
      utils.append("displayName: '" + displayName + "',", state);
    }
  }
}
Example #12
0
/**
 * Visit ImportDeclaration.
 *
 * Examples:
 *
 *    import "module"
 *    import name from "module"
 *    import { name, one as other } from "module"
 */
function visitImportDeclaration(traverse, node, path, state) {
  var specifier, name;
  utils.catchup(node.range[0], state);

  switch (node.kind) {

    // import "module"
    case undefined:
      utils.append('require(' + node.source.raw + ');', state);
      break;

    // import name from "module"
    case "default":
      specifier = node.specifiers[0];
      assert(specifier, "default import without specifier: " + node);
      name = specifier.name ? specifier.name.name : specifier.id.name;
      utils.append('var ' + name + ' = require(' + node.source.raw + ');', state);
      break;

    // import {name, one as other} from "module"
    case "named":
      var modID;

      if (node.specifiers.length === 1) {
        modID = 'require(' + node.source.raw + ')';
      } else {
        modID = genID('mod');
        utils.append('var ' + modID + ' = require(' + node.source.raw + ');', state);
      }

      for (var i = 0, len = node.specifiers.length; i < len; i++) {
        specifier = node.specifiers[i];
        utils.catchupNewlines(specifier.range[0], state);
        name = specifier.name ? specifier.name.name : specifier.id.name;
        utils.append('var ' + name + ' = ' + modID + '.' + specifier.id.name + ';', state);
      }

      break;

    default:
      assert(false, "don't know how to transform: " + node.kind);
  }

  utils.catchupNewlines(node.range[1], state);
  utils.move(node.range[1], state);
  return false;
}
Example #13
0
File: xjs.js Project: 0x4139/react
function renderXJSLiteral(object, state) {
  var value = object.raw;

  utils.catchup(object.range[0], state);

  /*
    This can be used to "annotate spaces" inserted by this transformation,
    so that they can be more easily recognized as such in the final code

    {' '}
    {'\\x20'}
    {(' ')}
    {' '||0}
    {' '||AnyTextYouLike}
    {' '||'AnyTextYouLike'}
    {GlobalVariableWithASpace}
  */

  var space = "{' '}";

  /*
    · space
    ¬ newline
    {expr} = <tag>

    Old whitespace rules:
    {1}··Aaa··Bbb··{2}··{3}  →  {1}·Aaa··Bbb·{2}{3}
    {1}¬¬Aaa¬¬Bbb¬¬{2}¬¬{3}  →  {1}·Aaa·Bbb·{2}{3}

    New whitespace rules:
    {1}··Aaa··Bbb··{2}··{3}  →  {1}··Aaa··Bbb··{2}··{3}
    {1}¬¬Aaa¬¬Bbb¬¬{2}¬¬{3}  →  {1}Aaa·Bbb{2}{3}

    Required transformation:
    {1}··{2}       =  {1}··{2}       →  {1}{2}
    {1}··Aaa··{2}  =  {1}··Aaa··{2}  →  {1}·Aaa·{2}
    {1}¬¬Aaa¬¬{2}  =  {1}Aaa{2}      →  {1}·Aaa·{2}
  */

  // {1}··{2}  =  {1}··{2}  →  {1}{2}
  value = value.replace(/^[ \t]+$/, '');

  // {1}··Aaa··{2}  =  {1}··Aaa··{2}  →  {1}·Aaa·{2}
  value = value.replace(/^[ \t]+([^ \t\r\n])/, " $1");
  value = value.replace(/([^ \t\r\n])[ \t]+$/, "$1 ");

  // {1}¬¬Aaa¬¬{2}  =  {1}Aaa{2}  →  {1}·Aaa·{2}
  value = value.replace(/^([ \t]*[\r\n][ \t\r\n]*)([^ \t\r\n].*)/, "$1" + space + "$2");
  value = value.replace(/([^ \t\r\n])([ \t]*[\r\n][ \t\r\n]*)$/, "$1" + space + "$2");

  // Rendered whitespace tabs are replaced with spaces
  value = value.replace(/[^ \t\r\n][ ]*[\t][ \t]*[^ \t\r\n]/, function(match) {
    return match.replace(/\t/g, ' ');
  });

  utils.append(value, state);
  utils.move(object.range[1], state);
}
Example #14
0
File: xjs.js Project: bcen/react
    lines.forEach(function (line, ii) {
      var lastLine = ii === numLines - 1;
      var trimmedLine = safeTrim(line);
      if (trimmedLine === '' && !lastLine) {
        append(line, state);
      } else {
        var preString = '';
        var postString = '';
        var leading = '';

        if (ii === 0) {
          if (hasInitialNewLine) {
            preString = ' ';
            leading = '\n';
          }
          if (trimmedChildValueWithSpace.substring(0, 1) === ' ') {
            // If this is the first line, and the original content starts with
            // whitespace, place a single space at the beginning.
            preString = ' ';
          }
        } else {
          leading = line.match(/^[ \t]*/)[0];
        }
        if (!lastLine || trimmedChildValueWithSpace.substr(
             trimmedChildValueWithSpace.length - 1, 1) === ' ' ||
             hasFinalNewLine
             ) {
          // If either not on the last line, or the original content ends with
          // whitespace, place a single character at the end.
          postString = ' ';
        }

        append(
          leading +
          JSON.stringify(
            preString + trimmedLine + postString
          ) +
          (lastLine ? '' : '+') +
          line.match(/[ \t]*$/)[0],
          state);
      }
      if (!lastLine) {
        append('\n', state);
      }
    });
Example #15
0
function visitProgram(traverse, node, path, state) {
  var ctx = new Context(state);
  var namespace = ctx.namespace;
  // FIXME remove 2nd condition when flowcheck-loader will not use the namespace option
  if (!ctx.skipImport && namespace.indexOf('require') === -1) {
    utils.append('var ' + namespace + ' = require(' + JSON.stringify(ctx.module) + ');', state);
  }
  return true;
}
  var visitor = function visitRequireAssets(traverse, node, p, state) {

    var id = node.arguments[0].value;
    var result = registry.requireAssets(id, basedir);

    utils.catchup(node.range[0], state);
    utils.append(JSON.stringify(result), state);

    utils.move(node.range[1], state);
  };
Example #17
0
    /**
     * 当 visitGlobal.test 判断正确后,进出此逻辑
     *
     * 用来将 global.xxx 换成 window.xxx
     *
     * @param  {Function} traverse  可用来继续处理子节点。
     * @param  {Object} node 当前节点。
     * @param  {Array} path 路径数组,包含进入该节点前的父级节点。
     * @param  {Object} state state 对象,用来保存对 node 修改状态。
     * @return {boolean} false   [description]
     */
    function visitGlobal(traverse, node, path, state) {

        // 如果当前 scope 中存在 global 变量,则忽略。
        if (util.existsVariable(path, node)) {
            return false;
        }

        utils.catchup(node.range[0], state);
        utils.append('window', state);
        utils.move(node.range[1], state);
        return false;
    }
Example #18
0
  function visitProcessEnv(traverse, node, path, state) {
    var key = node.property.name

    for (var i = 0; i < envs.length; i++) {
      var value = envs[i][key]
      if (value !== undefined) {
        utils.catchup(node.range[0], state)
        utils.append(JSON.stringify(value), state)
        utils.move(node.range[1], state)
        return false
      }
    }

    return false
  }
Example #19
0
File: xjs.js Project: bcen/react
function renderXJSExpressionContainer(traverse, object, isLast, path, state) {
  // Plus 1 to skip `{`.
  move(object.range[0] + 1, state);
  traverse(object.expression, path, state);
  if (!isLast && object.expression.type !== Syntax.XJSEmptyExpression) {
    // If we need to append a comma, make sure to do so after the expression.
    catchup(object.expression.range[1], state);
    append(',', state);
  }

  // Minus 1 to skip `}`.
  catchup(object.range[1] - 1, state);
  move(object.range[1], state);
  return false;
}
Example #20
0
		childrenToRender.forEach(function (child, index) {
			utils.catchup(child.range[0], state, trimLeft);

			var isLast = index >= lastRenderableIndex;

			if (child.type === Syntax.Literal) {
				renderXJSLiteral(child, isLast, state);
			} else if (child.type === Syntax.XJSExpressionContainer) {
				renderXJSExpressionContainer(traverse, child, isLast, path, state);
			} else {
				traverse(child, path, state);
				if (!isLast) {
					utils.append(', ', state);
				}
			}

			utils.catchup(child.range[1], state, trimLeft);
		});
Example #21
0
  attributesObject.forEach(function(attr, index) {
    utils.catchup(attr.range[0], state);
    if (attr.name.namespace) {
      throw new Error(
         'Namespace attributes are not supported. ReactJSX is not XML.');
    }
    var name = attr.name.name;
    var isFirst = index === 0;
    var isLast = index === attributesObject.length - 1;

    if (isFirst) {
      utils.append('{', state);
    }

    utils.append(quoteAttrName(name), state);
    utils.append(':', state);

    if (!attr.value) {
      state.g.buffer += 'true';
      state.g.position = attr.name.range[1];
      if (!isLast) {
        utils.append(',', state);
      }
    } else {
      utils.move(attr.name.range[1], state);
      // Use catchupWhiteSpace to skip over the '=' in the attribute
      utils.catchupWhiteSpace(attr.value.range[0], state);
      if (JSX_ATTRIBUTE_TRANSFORMS[attr.name.name]) {
        utils.append(JSX_ATTRIBUTE_TRANSFORMS[attr.name.name](attr), state);
        utils.move(attr.value.range[1], state);
        if (!isLast) {
          utils.append(',', state);
        }
      } else if (attr.value.type === Syntax.Literal) {
        renderXJSLiteral(attr.value, isLast, state);
      } else {
        renderXJSExpressionContainer(traverse, attr.value, isLast, path, state);
      }
    }

    if (isLast) {
      utils.append('}', state);
    }

    utils.catchup(attr.range[1], state);
  });
Example #22
0
    childrenToRender.forEach(function(child, index) {
      utils.catchup(child.range[0], state);

      var isLast = index === childrenToRender.length - 1;

      if (child.type === Syntax.Literal) {
        renderXJSLiteral(child, isLast, state);
      } else if (child.type === Syntax.XJSExpressionContainer) {
        renderXJSExpressionContainer(traverse, child, isLast, path, state);
      } else {
        traverse(child, path, state);
        if (!isLast) {
          utils.append(',', state);
          state.g.buffer = state.g.buffer.replace(/(\s*),$/, ',$1');
        }
      }

      utils.catchup(child.range[1], state);
    });
Example #23
0
File: xjs.js Project: 0x4139/react
function renderXJSExpressionContainer(
  traverse, object,
  isNotAfterLiteral,
  isNotBeforeLiteral,
  path, state)
{
  utils.catchup(object.range[0], state);

  // Unbox the previously required {' '}-workaround
  var raw = object.expression.raw;
  var isSpace = (raw === "' '" || raw === '" "');

  if (isNotAfterLiteral && isNotBeforeLiteral && isSpace) {
    utils.append(' ', state);
    utils.move(object.range[1], state);
  } else {
    utils.catchup(object.range[1], state);
  }

  return false;
}
Example #24
0
  lines.forEach(function (line, index) {
    var isFirstLine = index === 0;
    var isLastLine = index === lines.length - 1;
    var isLastNonEmptyLine = index === lastNonEmptyLine;

    // replace rendered whitespace tabs with spaces
    var trimmedLine = line.replace(/\t/g, ' ');

    // trim whitespace touching a newline
    if (!isFirstLine) {
      trimmedLine = trimmedLine.replace(/^[ ]+/, '');
    }
    if (!isLastLine) {
      trimmedLine = trimmedLine.replace(/[ ]+$/, '');
    }

    if (!isFirstLine) {
      utils.append(line.match(/^[ \t]*/)[0], state);
    }

    if (trimmedLine || isLastNonEmptyLine) {
      utils.append(
        JSON.stringify(trimmedLine) +
        (!isLastNonEmptyLine ? " + ' ' +" : ''),
        state);

      if (isLastNonEmptyLine) {
        if (end) {
          utils.append(end, state);
        }
        if (!isLast) {
          utils.append(', ', state);
        }
      }

      // only restore tail whitespace if line had literals
      if (trimmedLine && !isLastLine) {
        utils.append(line.match(/[ \t]*$/)[0], state);
      }
    }

    if (!isLastLine) {
      utils.append('\n', state);
    }
  });
function visitElseTag(traverse, object, path, state) {
  hasElse = true;
  utils.catchup(object.range[0], state);
  utils.append(') : (', state);
  utils.move(object.range[1], state);
}
Example #26
0
/**
 * Visit tag node and desugar JSX.
 *
 * @see {@link https://github.com/facebook/jstransform}
 * @param {Function} traverse
 * @param {Object} object
 * @param {String} path
 * @param {Object} state
 * @returns {Boolean}
 * @private
 */
function visitNode(traverse, object, path, state) {
  var options = state.g.opts;
  var factory = (options.factory);
  var arrayChildren = options.arrayChildren
  var openingEl = object.openingElement;
  var closingEl = object.closingElement;
  var nameObj = openingEl.name;
  var attributes = openingEl.attributes;
  var spreadFn = options.spreadFn;
  var unknownTagPattern = options.unknownTagPattern;

  if (!options.renameAttrs) {
    options.renameAttrs = {};
  }

  utils.catchup(openingEl.range[0], state, trimLeft);

  var tagName = nameObj.name;
  var isJSXIdentifier = nameObj.type === Syntax.JSXIdentifier;
  var knownTag = tagName[0] !== tagName[0].toUpperCase() && isJSXIdentifier;
  var hasAtLeastOneSpreadAttribute = attributes.some(function (attr) {
    return attr.type === Syntax.JSXSpreadAttribute;
  });
  var secondArg = false;

  if (knownTag) {
    utils.append(factory + "('", state); // DOM('div', ...)
  } else if (options.passUnknownTagsToFactory) {
    if (options.unknownTagsAsString) {
      utils.append(factory + "('", state);
    } else {
      utils.append(factory + '(', state);
    }
  }

  utils.move(nameObj.range[0], state);

  if (knownTag) {
    // DOM('div', ...)
    utils.catchup(nameObj.range[1], state);
    utils.append("'", state);
    secondArg = true
  } else if (options.passUnknownTagsToFactory) {
    // DOM(Component, ...)
    utils.catchup(nameObj.range[1], state);
    if (options.unknownTagsAsString) {
      utils.append("'", state);
    }
    secondArg = true
  } else {
    // Component(...)
    tagName = unknownTagPattern.replace('{tag}', nameObj.name);
    utils.append(tagName, state);
    utils.move(
      nameObj.range[1] + (tagName.length - nameObj.name.length),
      state
    );
    utils.append('(', state);
  }

  if (hasAtLeastOneSpreadAttribute) {
    if (options.passUnknownTagsToFactory || knownTag) {
      utils.append(', ' + spreadFn + '({', state);
    } else {
      utils.append(spreadFn + '({', state);
    }
  } else if (attributes.length) {
    if (secondArg) {
      utils.append(', ', state);
    }
    utils.append('{', state);
  }

  var previousWasSpread = false;

  attributes.forEach(function(attr, index) {
    var isLast = (index === (attributes.length - 1));

    if (attr.type === Syntax.JSXSpreadAttribute) {
      // close the previous or initial object
      if (!previousWasSpread) {
        utils.append('}, ', state);
      }

      // Move to the expression start, ignoring everything except parenthesis
      // and whitespace.
      utils.catchup(attr.range[0], state, stripNonParen);
      // Plus 1 to skip `{`.
      utils.move(attr.range[0] + 1, state);
      utils.catchup(attr.argument.range[0], state, stripNonParen);

      traverse(attr.argument, path, state);

      utils.catchup(attr.argument.range[1], state);

      // Move to the end, ignoring parenthesis and the closing `}`
      utils.catchup(attr.range[1] - 1, state, stripNonParen);

      if (!isLast) {
        utils.append(', ', state);
      }

      utils.move(attr.range[1], state);

      previousWasSpread = true;

      return;
    }

    // If the next attribute is a spread, we're effective last in this object
    if (!isLast) {
      isLast = attributes[index + 1].type === Syntax.JSXSpreadAttribute;
    }

    var name
    if (attr.name.namespace) {
      name = attr.name.namespace.name + ':' + attr.name.name.name
    }
    else {
      name = attr.name.name;
    }

    utils.catchup(attr.range[0], state, trimLeft);

    if (previousWasSpread) {
      utils.append('{', state);
    }

    utils.append(quoteJSObjKey(name) + ': ', state);

    if (attr.value) {
      utils.move(attr.name.range[1], state);
      utils.catchupNewlines(attr.value.range[0], state);
      if (attr.value.type === Syntax.Literal) {
        renderJSXLiteral(attr.value, isLast, state);
      } else {
        renderJSXExpressionContainer(traverse, attr.value, isLast, path, state);
      }
    } else {
      state.g.buffer += 'true';
      state.g.position = attr.name.range[1];
      if (!isLast) {
        utils.append(', ', state);
      }
    }

    utils.catchup(attr.range[1], state, trimLeft);

    previousWasSpread = false;
  });

  if (!openingEl.selfClosing) {
    utils.catchup(openingEl.range[1] - 1, state, trimLeft);
    utils.move(openingEl.range[1], state);
  }

  if (attributes.length && !previousWasSpread) {
    utils.append('}', state);
  }

  if (hasAtLeastOneSpreadAttribute) {
    utils.append(')', state);
  }

  // filter out whitespace
  var children = object.children.filter(function(child) {
    return !(child.type === Syntax.Literal
    && typeof child.value === 'string'
    && child.value.match(/^[ \t]*[\r\n][ \t\r\n]*$/));
  });

  if (children.length) {
    if (!attributes.length) {
      if (secondArg) {
        utils.append(', ', state);
      }
      utils.append('null', state);
    }
    var lastRenderableIndex;

    children.forEach(function(child, index) {
      if (child.type !== Syntax.JSXExpressionContainer ||
        child.expression.type !== Syntax.JSXEmptyExpression) {
        lastRenderableIndex = index;
      }
    });

    if (lastRenderableIndex !== undefined) {
      utils.append(', ', state);
    }

    if (arrayChildren && children.length) {
      utils.append('[', state);
    }

    children.forEach(function(child, index) {
      utils.catchup(child.range[0], state, trimLeft);

      var isFirst = index === 0;
      var isLast = index >= lastRenderableIndex;

      if (child.type === Syntax.Literal) {
        renderJSXLiteral(child, isLast, state);
      } else if (child.type === Syntax.JSXExpressionContainer) {
        renderJSXExpressionContainer(traverse, child, isLast, path, state);
      } else {
        traverse(child, path, state);
        if (!isLast) {
          utils.append(',', state);
        }
      }

      utils.catchup(child.range[1], state, trimLeft);
    });
  }

  if (openingEl.selfClosing) {
    // everything up to />
    utils.catchup(openingEl.range[1] - 2, state, trimLeft);
    utils.move(openingEl.range[1], state);
  } else {
    // everything up to </close>
    utils.catchup(closingEl.range[0], state, trimLeft);
    utils.move(closingEl.range[1], state);
  }

  if (arrayChildren && children.length) {
    utils.append(']', state);
  }

  utils.append(')', state);

  return false;
}
Example #27
0
/**
 * Taken from {@link https://github.com/facebook/react/blob/0.10-stable/vendor/fbtransform/transforms/xjs.js}
 *
 * @param {Object} object
 * @param {Boolean} isLast
 * @param {Object} state
 * @param {Number} start
 * @param {Number} end
 * @private
 */
function renderJSXLiteral(object, isLast, state, start, end) {
  var lines = object.value.split(/\r\n|\n|\r/);

  if (start) {
    utils.append(start, state);
  }

  var lastNonEmptyLine = 0;

  lines.forEach(function (line, index) {
    if (line.match(/[^ \t]/)) {
      lastNonEmptyLine = index;
    }
  });

  lines.forEach(function (line, index) {
    var isFirstLine = index === 0;
    var isLastLine = index === lines.length - 1;
    var isLastNonEmptyLine = index === lastNonEmptyLine;

    // replace rendered whitespace tabs with spaces
    var trimmedLine = line.replace(/\t/g, ' ');

    // trim whitespace touching a newline
    if (!isFirstLine) {
      trimmedLine = trimmedLine.replace(/^[ ]+/, '');
    }
    if (!isLastLine) {
      trimmedLine = trimmedLine.replace(/[ ]+$/, '');
    }

    if (!isFirstLine) {
      utils.append(line.match(/^[ \t]*/)[0], state);
    }

    if (trimmedLine || isLastNonEmptyLine) {
      utils.append(
        JSON.stringify(trimmedLine) +
        (!isLastNonEmptyLine ? " + ' ' +" : ''),
        state);

      if (isLastNonEmptyLine) {
        if (end) {
          utils.append(end, state);
        }
        if (!isLast) {
          utils.append(', ', state);
        }
      }

      // only restore tail whitespace if line had literals
      if (trimmedLine && !isLastLine) {
        utils.append(line.match(/[ \t]*$/)[0], state);
      }
    }

    if (!isLastLine) {
      utils.append('\n', state);
    }
  });

  utils.move(object.range[1], state);
}
Example #28
0
 function replaceEnv(node, state, value) {
   utils.catchup(node.range[0], state);
   utils.append(JSON.stringify(value), state);
   utils.move(node.range[1], state);
 }
Example #29
0
function visitTypeAlias(traverse, node, path, state) {
  var ctx = new Context(state);
  utils.catchup(node.range[1], state);
  utils.append('var ' + node.id.name + ' = ' + ctx.getType(node.right) + ';', state);
  return false;
}
Example #30
0
  attributes.forEach(function(attr, index) {
    var isLast = (index === (attributes.length - 1));

    if (attr.type === Syntax.JSXSpreadAttribute) {
      // close the previous or initial object
      if (!previousWasSpread) {
        utils.append('}, ', state);
      }

      // Move to the expression start, ignoring everything except parenthesis
      // and whitespace.
      utils.catchup(attr.range[0], state, stripNonParen);
      // Plus 1 to skip `{`.
      utils.move(attr.range[0] + 1, state);
      utils.catchup(attr.argument.range[0], state, stripNonParen);

      traverse(attr.argument, path, state);

      utils.catchup(attr.argument.range[1], state);

      // Move to the end, ignoring parenthesis and the closing `}`
      utils.catchup(attr.range[1] - 1, state, stripNonParen);

      if (!isLast) {
        utils.append(', ', state);
      }

      utils.move(attr.range[1], state);

      previousWasSpread = true;

      return;
    }

    // If the next attribute is a spread, we're effective last in this object
    if (!isLast) {
      isLast = attributes[index + 1].type === Syntax.JSXSpreadAttribute;
    }

    var name
    if (attr.name.namespace) {
      name = attr.name.namespace.name + ':' + attr.name.name.name
    }
    else {
      name = attr.name.name;
    }

    utils.catchup(attr.range[0], state, trimLeft);

    if (previousWasSpread) {
      utils.append('{', state);
    }

    utils.append(quoteJSObjKey(name) + ': ', state);

    if (attr.value) {
      utils.move(attr.name.range[1], state);
      utils.catchupNewlines(attr.value.range[0], state);
      if (attr.value.type === Syntax.Literal) {
        renderJSXLiteral(attr.value, isLast, state);
      } else {
        renderJSXExpressionContainer(traverse, attr.value, isLast, path, state);
      }
    } else {
      state.g.buffer += 'true';
      state.g.position = attr.name.range[1];
      if (!isLast) {
        utils.append(', ', state);
      }
    }

    utils.catchup(attr.range[1], state, trimLeft);

    previousWasSpread = false;
  });