Exemple #1
0
function getRuntimeMarkDecl(blockPath) {
  let block = blockPath.node;
  assert.ok(Array.isArray(block.body));

  let info = getMarkInfo(block);
  if (info.decl) {
    return info.decl;
  }

  info.decl = t.variableDeclaration("var", [
    t.variableDeclarator(
      blockPath.scope.generateUidIdentifier("marked"),
      t.callExpression(
        t.memberExpression(
          t.arrayExpression([]),
          t.identifier("map"),
          false
        ),
        [util.runtimeProperty("mark")]
      )
    )
  ]);

  blockPath.unshiftContainer("body", info.decl);

  return info.decl;
}
Exemple #2
0
Ep.getTryLocsList = function() {
  if (this.tryEntries.length === 0) {
    // To avoid adding a needless [] to the majority of runtime.wrap
    // argument lists, force the caller to handle this case specially.
    return null;
  }

  let lastLocValue = 0;

  return t.arrayExpression(
    this.tryEntries.map(function(tryEntry) {
      let thisLocValue = tryEntry.firstLoc.value;
      assert.ok(thisLocValue >= lastLocValue, "try entries out of order");
      lastLocValue = thisLocValue;

      let ce = tryEntry.catchEntry;
      let fe = tryEntry.finallyEntry;

      let locs = [
        tryEntry.firstLoc,
        // The null here makes a hole in the array.
        ce ? ce.firstLoc : null
      ];

      if (fe) {
        locs[2] = fe.firstLoc;
        locs[3] = fe.afterLoc;
      }

      return t.arrayExpression(locs);
    })
  );
};
			it("analyses the body of a callback that has been passed as argument", function () {
				// arrange
				const predicateDeclaration = functionDeclaration(t.identifier("isEven"), t.identifier("x")); // body x % 2 === 0;
				const predicate = new FunctionType(VoidType.create(), [TypeVariable.create()], TypeVariable.create(), predicateDeclaration);
				const x = new Symbol("x", SymbolFlags.Variable);
				program.symbolTable.setSymbol(predicateDeclaration.params[0], x);

				const elementType = TypeVariable.create();
				const predicateExpectedSignature = new FunctionType(VoidType.create(), [elementType], BooleanType.create());
				const filter = new FunctionType(VoidType.create(), [ArrayType.of(elementType), predicateExpectedSignature], ArrayType.of(elementType));
				const callExpression = t.callExpression(t.identifier("filter"), [t.arrayExpression([t.numericLiteral(1), t.numericLiteral(2)]), t.identifier("isEven")]);

				const callContext = context.fresh();
				typeInferenceAnalysis.infer.withArgs(callExpression.callee).returns(filter);
				typeInferenceAnalysis.infer.withArgs(callExpression.arguments[0]).returns(ArrayType.of(NumberType.create()));
				typeInferenceAnalysis.infer.withArgs(callExpression.arguments[1]).returns(predicate);
				sinon.stub(context, "fresh").returns(callContext);
				sinon.stub(context, "unify").returnsArg(0); // return the actual argument type

				// unifying the parameter with the argument type requires that the type variables in the parameter type are substituted
				callContext.unify = (t1, t2) => {
					if (t1 instanceof ArrayType && t1.of instanceof NumberType && t2 instanceof ArrayType && t2.of instanceof TypeVariable) {
						callContext.substitute(t2.of, t1.of);
						return t2;
					}
				};

				// Fake analysis of the predicate function by setting the return type
				callContext.analyse = () => callContext.typeEnvironment = callContext.typeEnvironment.setType(Symbol.RETURN, BooleanType.create());

				// expect
				expect(rule.refine(callExpression, context)).to.be.instanceOf(ArrayType).and.to.have.property("of").that.is.an.instanceOf(NumberType);
			});
export let test = opts => {
    let tests = (prop, valid) => {
        return value => {
            return t.objectExpression([
                t.objectProperty(
                    t.identifier('fixture'),
                    t.stringLiteral(`${prop}: ${value}`)
                ),
                t.objectProperty(
                    t.identifier('valid'),
                    t.identifier(valid ? 'true' : 'false')
                )
            ]);
        };
    };
    
    let program = t.program([
        template('module.exports = EXPORTS;')({
            EXPORTS: t.arrayExpression(flatten(opts.properties.map(prop => {
                const valid   = opts.valid.map(tests(prop, true));
                const invalid = opts.invalid.map(tests(prop, false));
                return valid.concat(invalid);
            })))
        })
    ]);

    return warning() + generate(program).code;
};
Exemple #5
0
export function push(mutatorMap: Object, node: Object, kind: string, file, scope?): Object {
  let 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) {
    let 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);
  }

  let 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;
}
Exemple #6
0
export default opts => {
    const tests = opts.candidates.reduce((list, candidate) => {
        if (candidate.type === 'keyword') {
            list.push(
                createTest(candidate.value),
                createTest(candidate.value.toUpperCase()),
            );
        }
        if (candidate.type === 'data') {
            const camel = camelCase(candidate.value);
            if (fixtures[camel]) { // eslint-disable-line
                const values = fixtures[camel].fixtures; // eslint-disable-line
                list.push.apply(list, values.valid.map(fixture => {
                    return createTest(fixture);
                }));
                list.push.apply(list, values.invalid.map(fixture => {
                    return createTest(fixture, false);
                }));
                if (candidate.min === 1 && candidate.max === false && candidate.separator === ',') {
                    list.push(
                        createTest(`${values.valid[0]}, ${values.valid[0]}`),
                        createTest(`${values.valid[0]}, ${values.valid[0]},`, false),
                        createTest(`var(--foo), var(--bar)`),
                        createTest(`var(--foo), var(--bar),`, false)
                    );
                }
            }
        }
        return list;
    }, [...globals, ...globals.map(val => val.toUpperCase()), 'var(--foo)'].map(ident => createTest(ident)));
    if (opts.properties.length === 1) {
        return generateProgram([
            template(`const property = PROPERTY;`)({
                PROPERTY: t.stringLiteral(opts.properties[0]),
            }),
            template(`export default SUITE;`)({
                SUITE: t.arrayExpression(tests),
            }),
        ]);
    }
    return generateProgram([
        template(`
            export default PROPERTIES.reduce((suite, property) => {
                SUITE;

                return suite;
            }, []);
        `)({
            PROPERTIES: arrayOfStrings(opts.properties),
            SUITE: t.callExpression(
                t.memberExpression(
                    t.identifier('suite'),
                    t.identifier('push')
                ), tests),
        }),
    ]);
};
Exemple #7
0
var formCSSXElement = function (args, pure) {
  return t.callExpression(
    t.memberExpression(
      t.identifier('cssx'),
      t.identifier('push')
    ),
    [t.arrayExpression(args)]
  );
};
Exemple #8
0
export function toComputedObjectFromClass(obj: Object): Object {
  let objExpr = t.arrayExpression([]);

  for (let i = 0; i < obj.properties.length; i++) {
    let prop = obj.properties[i];
    let val = prop.value;
    val.properties.unshift(t.objectProperty(t.identifier("key"), t.toComputedKey(prop)));
    objExpr.elements.push(val);
  }

  return objExpr;
}
export let exportModules = exported => {
    const exportTemplate = template('module.exports = EXPORTS');

    let ast = exportTemplate({
        EXPORTS: t.arrayExpression(exported.map((value, index) => {
            if (index === exported.length - 1) {
                return t.identifier(`\n    ${value}\n`);
            }
            return t.identifier(`\n    ${value}`);
        }))
    });

    return generate(ast).code + '\n';
};
Exemple #10
0
    it("replaces declaration in ExportDefaultDeclaration node", function() {
      traverse(ast, {
        FunctionDeclaration(path) {
          path.replaceWith(t.arrayExpression([
            t.functionExpression(
              path.node.id,
              path.node.params,
              path.node.body,
              path.node.generator,
              path.node.async
            ),
          ]));
        },
      });

      assert(ast.program.body[0].declaration.type == "ArrayExpression");
    });
Exemple #11
0
 processRule = function (rule) {
   propAssignment = t.expressionStatement(
     t.assignmentExpression(
       '=',
       t.memberExpression(
         t.identifier(id),
         rule.key,
         true
       ),
       isArray(rule.value.value) ?
         t.arrayExpression(rule.value.value.map(function (v) {
           return t.stringLiteral(v);
         })) :
         rule.value
     )
   );
   addToContext(propAssignment);
 };
Exemple #12
0
        TemplateLiteral : function(path, state){
            var rawCode = _.trim(this.file.code.substring(path.node.start, path.node.end), '`');

            var defaultOptions = {
                prefix : 'sql:',
                mode:'lodash'
            };

            var options = _.assign({}, defaultOptions, state.opts);

            //如果不命中则直接返回
            if(rawCode.substring(0, options.prefix.length).toLowerCase() != options.prefix.toLowerCase()){
                return;
            }else{
                rawCode = rawCode.substring(options.prefix.length);
            }



            //parse and gen code
            var ast = SQLParser.parse(rawCode);
            ast.yy = SQLParser.yy;
            ast.yy.clear();

            var code = SQLComplile.exec(ast, {
                mode:options.mode,
                rawCode:rawCode
            }, path);


            if(options.debug){
                console.log(rawCode, '==>', code);
            }


            //save the TemplateLiteral expressions
            var preexp = path.node.expressions;
            var replacement = babylon.parse( '(' + code + ')' , {plugins:['objectRestSpread']});
            replacement = replacement.program.body[0].expression;
            //path.replaceWithSourceString(code);
            path.replaceWith(
                t.callExpression(replacement, [t.arrayExpression(preexp)])
            );
        }
Exemple #13
0
    this.tryEntries.map(function(tryEntry) {
      let thisLocValue = tryEntry.firstLoc.value;
      assert.ok(thisLocValue >= lastLocValue, "try entries out of order");
      lastLocValue = thisLocValue;

      let ce = tryEntry.catchEntry;
      let fe = tryEntry.finallyEntry;

      let locs = [
        tryEntry.firstLoc,
        // The null here makes a hole in the array.
        ce ? ce.firstLoc : null
      ];

      if (fe) {
        locs[2] = fe.firstLoc;
        locs[3] = fe.afterLoc;
      }

      return t.arrayExpression(locs);
    })
			it("it throws if the return type of the callback is not a subtype of the expected return type for the callback", function () {
				// arrange
				const predicateDeclaration = functionDeclaration(t.identifier("isEven"), t.identifier("x")); // body return null;
				const predicate = new FunctionType(VoidType.create(), [TypeVariable.create()], TypeVariable.create(), predicateDeclaration);
				const x = new Symbol("x", SymbolFlags.Variable);
				program.symbolTable.setSymbol(predicateDeclaration.params[0], x);

				const elementType = TypeVariable.create();
				const predicateExpectedSignature = new FunctionType(VoidType.create(), [elementType], elementType);
				const filter = new FunctionType(VoidType.create(), [ArrayType.of(elementType), predicateExpectedSignature], ArrayType.of(elementType));
				const callExpression = t.callExpression(t.identifier("map"), [t.arrayExpression([t.numericLiteral(1), t.numericLiteral(2)]), t.identifier("isEven")]);

				const callContext = context.fresh();
				sinon.stub(context, "fresh").returns(callContext);

				// unifying the parameter with the argument type requires that the type variables in the parameter type are substituted
				callContext.unify = (t1, t2) => {
					if (t1 instanceof ArrayType && t1.of instanceof NumberType && t2 instanceof ArrayType && t2.of instanceof TypeVariable) {
						callContext.substitute(t2.of, t1.of);
						return t2;
					}

					if (t1 instanceof NumberType && t2 instanceof NullType) {
						return MaybeType.of(t1);
					}
				};

				typeInferenceAnalysis.infer.withArgs(callExpression.callee).returns(filter);
				typeInferenceAnalysis.infer.withArgs(callExpression.arguments[0]).returns(ArrayType.of(NumberType.create()));
				typeInferenceAnalysis.infer.withArgs(callExpression.arguments[1]).returns(predicate);
				typeInferenceAnalysis.unify.returnsArg(0); // return the actual argument type

				// Fake analysis of the predicate function by setting the return type
				callContext.analyse = () => callContext.typeEnvironment = callContext.typeEnvironment.setType(Symbol.RETURN, NullType.create());

				// expect
				expect(() => rule.refine(callExpression, context)).to.throw("Type inference failure: The return type 'null' of the callback is not a subtype of the return type 'number' of the expected callback.");
			});
function buildUmd(namespace, builder) {
  let body = [];
  body.push(t.variableDeclaration("var", [
    t.variableDeclarator(namespace, t.identifier("global"))
  ]));

  builder(body);

  return t.program([
    buildUmdWrapper({
      FACTORY_PARAMETERS: t.identifier("global"),
      BROWSER_ARGUMENTS:  t.assignmentExpression(
        "=",
        t.memberExpression(t.identifier("root"), namespace),
        t.objectExpression([])
      ),
      COMMON_ARGUMENTS:   t.identifier("exports"),
      AMD_ARGUMENTS:      t.arrayExpression([t.stringLiteral("exports")]),
      FACTORY_BODY:       body,
      UMD_ROOT:           t.identifier("this")
    })
  ]);
}
Exemple #16
0
    rulesRegistration = rulesRegistration.reduce(function (result, current) {
      var name;

      if (current.expression && current.expression.left) {
        name = current.expression.left.property.value;
        if (name && rulesBuffer[name]) {
          if (result[rulesBuffer[name].index].expression.right.type === 'ArrayExpression') {
            result[rulesBuffer[name].index].expression.right.elements.push(
              t.identifier(current.expression.right.name)
            );
          } else {
            result[rulesBuffer[name].index].expression.right = t.arrayExpression([
              t.identifier(rulesBuffer[name].rule.expression.right.name),
              t.identifier(current.expression.right.name)
            ]);
          }
        } else {
          rulesBuffer[name] = { index: result.length, rule: current };
          result.push(current);
        }
      }
      return result;
    }, []);
export let plugin = () => {
    const dependencies = [
        requireModule({
            identifier: 'validators',
            module: `./properties/`
        }),
        requireModule({
            identifier: 'valueParser',
            module: `postcss-value-parser`
        })
    ];
    const tmpl = template(`
    module.exports = function isValid (cssString) {
        var parts = cssString.split(':').map(function (value) {
            return value.trim();
        });
        var parsed = valueParser(parts[1]);
        if (parsed.nodes.length === 1 && ~GLOBALS.indexOf(parsed.nodes[0].value)) {
            return true;
        }
        var invalid = validators.some(function (validator) {
            if (!~validator.properties.indexOf(parts[0])) {
                return;
            }
            return !validator(parsed);
        });
        return !invalid;
    }
    `);
    
    let program = t.program([ tmpl({
        GLOBALS: t.arrayExpression(globals.map(toStringLiteral))
    }) ]);
    
    return warning() + dependencies.join('') + generate(program).code;
};
Exemple #18
0
function setParentCondition(jsx, expr, array = false) {
    const conditionExpr = jsx.findParent(p => p.isConditionalExpression());
    const logicExpr = jsx.findParent(p => p.isLogicalExpression({ operator: '&&' }));
    if (array) {
        const ifAttrSet = new Set([
            adapter_1.Adapter.if,
            adapter_1.Adapter.else
        ]);
        const logicalJSX = jsx.findParent(p => p.isJSXElement() && p.node.openingElement.attributes.some(a => ifAttrSet.has(a.name.name)));
        if (logicalJSX) {
            const attr = logicalJSX.node.openingElement.attributes.find(a => ifAttrSet.has(a.name.name));
            if (attr) {
                if (attr.name.name === adapter_1.Adapter.else) {
                    const prevElement = logicalJSX.getPrevSibling();
                    if (prevElement && prevElement.isJSXElement()) {
                        const attr = prevElement.node.openingElement.attributes.find(a => a.name.name === adapter_1.Adapter.if);
                        if (attr && t.isJSXExpressionContainer(attr.value)) {
                            expr = t.conditionalExpression(reverseBoolean(lodash_1.cloneDeep(attr.value.expression)), expr, t.arrayExpression());
                            return expr;
                        }
                    }
                }
                else if (t.isJSXExpressionContainer(attr.value)) {
                    expr = t.conditionalExpression(lodash_1.cloneDeep(attr.value.expression), expr, t.arrayExpression());
                    return expr;
                }
            }
        }
    }
    if (conditionExpr && conditionExpr.isConditionalExpression()) {
        const consequent = conditionExpr.get('consequent');
        if (consequent === jsx || jsx.findParent(p => p === consequent)) {
            expr = t.conditionalExpression(lodash_1.cloneDeep(conditionExpr.get('test').node), expr, array ? t.arrayExpression([]) : t.nullLiteral());
        }
    }
    if (logicExpr && logicExpr.isLogicalExpression({ operator: '&&' })) {
        const consequent = logicExpr.get('right');
        if (consequent === jsx || jsx.findParent(p => p === consequent)) {
            expr = t.conditionalExpression(lodash_1.cloneDeep(logicExpr.get('left').node), expr, array ? t.arrayExpression([]) : t.nullLiteral());
        }
    }
    return expr;
}
  compile: function(){
    var ast = [];
    if (this.pp) {
      ast.push(t.variableDeclaration('var', [t.variableDeclarator(t.identifier('pug_indent'), t.arrayExpression())]));
    }
    
    push.apply(ast, this.visit(this.node));
    
    if (!this.dynamicMixins) {
      // if there are no dynamic mixins we can remove any un-used mixins
      var mixinNames = Object.keys(this.mixins);
      for (var i = 0; i < mixinNames.length; i++) {
        var mixin = this.mixins[mixinNames[i]];
        if (!mixin.used) {
          for (var x = 0; x < mixin.instances.length; x++) {
            mixin.instances[x].stmt.type = "EmptyStatement";
            delete mixin.instances[x].stmt.expression;
          }
        }
      }
    }

    
    if (this.options.self) {
      ast = [
        t.variableDeclaration('var', [
          t.variableDeclarator(t.identifier('self'), t.logicalExpression('||', t.identifier('locals'), t.objectExpression([])))
        ])
      ].concat(ast);
    } else {
      // transform `ast` into `with(locals || {}) { ast }`
      ast = this.ast_with(ast);
    }


    if (this.debug) {
      if (this.options.includeSources) {
        ast.unshift(t.variableDeclaration('var', [
          t.variableDeclarator(t.identifier('pug_debug_sources'), this.parseExpr(stringify(this.options.includeSources)))
        ]))
      }

 
      var rethrowArgs = [
                t.identifier('err'),
                t.identifier('pug_debug_filename'),
                t.identifier('pug_debug_line')
              ]
      if (this.options.includeSources) {
          rethrowArgs.push(t.memberExpression(t.identifier('pug_debug_sources'), t.identifier('pug_debug_filename'), true))
      } 
      ast = [
        t.variableDeclaration('var', [
          t.variableDeclarator(t.identifier('pug_debug_filename'), null),
          t.variableDeclarator(t.identifier('pug_debug_line'), null)
        ]),
        t.tryStatement(
          t.blockStatement(ast),
          t.catchClause(
            t.identifier('err'),
            t.blockStatement([t.expressionStatement(t.callExpression(
              (this.inlineRuntimeFunctions ? t.identifier('pug_rethrow') : t.memberExpression(t.identifier('pug'), t.identifier('rethrow'))),
              rethrowArgs
            ))])
          )
        )
      ]

    }

    ast = t.functionDeclaration(
      t.identifier(this.options.templateName || 'template'),
      this.templateVars.map(function(v) { return t.identifier(v)}),
      t.blockStatement([this.ast_variableDeclaration()].concat(ast, this.ast_return()))
    )

    ast = this.ast_postprocess(ast);

    return buildRuntime(this.runtimeFunctionsUsed) + gen.default(ast).code;
  },
Exemple #20
0
 function constructCommonModule (moduleBody, deps) {
   return commonModuleTmpl({
     MODULE_BODY: moduleBody,
     DEPS: t.arrayExpression(deps.map(dep => t.stringLiteral(dep.id)))
   });
 }
Exemple #21
0
  exit: function (node, parent, index, context) {
    var rulesRegistration;
    var newStylesheetExpr;
    var createSelfInvoke;
    var funcExpr;
    var funcCallExpr;
    var result;
    var options = this.options;

    var applyResult = function (r) {
      if (isArray(parent)) {
        injectAt(parent, index, r);
      } else {
        parent[index] = r;
      }
    };

    delete context.addToCSSXSelfInvoke;

    if (node.body.length === 0) {
      delete parent[index];
      return;
    }

    // make sure that we keep the stylesheet definitions
    if (checkForStyleDefinition(node)) {
      applyResult(node.body[0]);
      return;
    }

    newStylesheetExpr = t.variableDeclaration(
      'var',
      [
        t.variableDeclarator(
          t.identifier(stylesheetId),
          this.options.format === 'object' ? t.objectExpression([]) : t.arrayExpression()
        )
      ]
    );

    rulesRegistration = node.body.map(function (line) {
      line = updateStyleSheet(line, stylesheetId, options);
      if (line.type === 'CallExpression') {
        line = t.expressionStatement(updateStyleSheet(line, stylesheetId, options));
      }
      return line;
    });

    // styles for only one rule
    if (
      objectLiterals.length >= 1 &&
      (typeof objectLiterals[0].selector === 'object' ?
        objectLiterals[0].selector.value === '' :
        objectLiterals[0].selector === '')
    ) {
      funcLines.push(t.returnStatement(t.identifier(objectLiterals[0].rulesObjVar)));
    } else {
      funcLines.push(newStylesheetExpr);
      funcLines = funcLines.concat(rulesRegistration);
      funcLines.push(t.returnStatement(t.identifier(stylesheetId)));
    }

    createSelfInvoke = function (expr) { return t.parenthesizedExpression(expr); };

    // wrapping up the self-invoke function
    funcExpr = t.functionExpression(null, [], t.blockStatement(funcLines));
    funcCallExpr = t.callExpression(
      t.memberExpression(funcExpr, t.identifier('apply')),
      [t.thisExpression()]
    );

    result = createSelfInvoke(funcCallExpr);

    applyResult(result);
  }
  visitMixin: function(mixin){
    var ast = [];
    var self = this;
    var name = 'pug_mixins[';
    var args = mixin.args || '';
    var block = mixin.block;
    var attrs = mixin.attrs;
    var attrsBlocks = this.attributeBlocks(mixin.attributeBlocks);
    var pp = this.pp;
    var dynamic = mixin.name[0]==='#';
    var key = mixin.name;
    if (dynamic) this.dynamicMixins = true;
    name += (dynamic ? mixin.name.substr(2,mixin.name.length-3):'"'+mixin.name+'"')+']';
    var mixinName = dynamic ? (mixin.astName || this.parseExpr(mixin.name.substr(2,mixin.name.length-3))): t.stringLiteral(mixin.name);
    this.mixins[key] = this.mixins[key] || {used: false, instances: []};

    // mixin invocation
    if (mixin.call) {
      this.mixins[key].used = true;
      if (pp) {
        ast.push(t.expressionStatement(t.callExpression(
          t.memberExpression(t.identifier('pug_indent'), t.identifier('push')),
          [t.stringLiteral(Array(this.indents + 1).join(pp))]
        )))
      }
      if (block || attrs.length || attrsBlocks.length) {

        var astArgs = []
        ast.push(
          t.expressionStatement(this.wrapCallExpression(t.callExpression(
            t.memberExpression(
              t.memberExpression(t.identifier('pug_mixins'), mixinName, true),
              t.identifier("call")
            ),
            astArgs
          )))
        );

        var astObj, astKey;
        if (block || attrsBlocks.length || attrs.length) {
          astKey = [];
          astObj = t.objectExpression(astKey);
          astArgs.push(astObj);
        }

        if (block) {
          var astFunc = [];
        
          // Render block with no indents, dynamically added when rendered
          this.parentIndents++;
          var _indents = this.indents;
          this.indents = 0;
          push.apply(astFunc, this.visit(mixin.block, mixin));
          this.indents = _indents;
          this.parentIndents--;

          astKey.push(t.objectProperty(
            t.identifier('block'),
            t.functionExpression(
              null,
              [],
              t.blockStatement(astFunc),
              this.useGenerators
            )
          ));
 
        }

        if (attrsBlocks.length) {
          if (attrs.length) {
            var val = this.attrs(attrs);
            attrsBlocks.unshift(val);
          }
          if (attrsBlocks.length > 1) {
            astKey.push(t.objectProperty(
              t.identifier('attributes'),
              t.callExpression(
                this.runtime('merge', true),
                attrsBlocks.map(function(b) { return self.parseExpr(b) })
              )
            ));
          } else {
            astKey.push(t.objectProperty(
              t.identifier('attributes'),
              this.parseExpr(attrsBlocks[0])
            ));
          }
        } else if (attrs.length) {
          var val = this.attrs(attrs);
          astKey.push(t.objectProperty(
            t.identifier('attributes'),
            this.parseExpr(val)
          ));
        }

        if (args) { 
          args = args ? args.split(',') : [];
          Array.prototype.push.apply(astArgs, mixin.astArgs || this.parseArgs(args) )
        }

      } else {
        var astArgs = mixin.astArgs || this.parseArgs(args);
        ast.push(t.expressionStatement(this.wrapCallExpression(t.callExpression(
          t.memberExpression(t.identifier('pug_mixins'), mixinName, true),
          astArgs
        ))));
      }
      if (pp) {
        ast.push(t.expressionStatement(t.callExpression(
          t.memberExpression(t.identifier('pug_indent'), t.identifier('pop')),
          []
        )))
 
      }
    }
    // mixin definition
    else {
      args = args ? args.split(',') : [];
      var rest;
      if (args.length && /^\.\.\./.test(args[args.length - 1].trim())) {
        rest = args.pop().trim().replace(/^\.\.\./, '');
      }
      var astArgs = args.map(function(arg) { return t.identifier(arg.trim())})
      // we need use pug_interp here for v8: https://code.google.com/p/v8/issues/detail?id=4165
      // once fixed, use this: this.buf.push(name + ' = function(' + args.join(',') + '){');
      var astMixin = [];

      astMixin.push(
        t.variableDeclaration('var', [
          t.variableDeclarator(
            t.identifier('block'),
            t.logicalExpression('&&', t.thisExpression(), t.memberExpression(t.thisExpression(), t.identifier('block')))
          ),
          t.variableDeclarator(
            t.identifier('attributes'),
            t.logicalExpression('||',
              t.logicalExpression('&&', t.thisExpression(), t.memberExpression(t.thisExpression(), t.identifier('attributes'))),
              t.objectExpression([])
            )
          )
        ])
      )

      if (rest) {
        astMixin.push(
          t.variableDeclaration('var', [
            t.variableDeclarator(
              t.identifier(rest),
              t.arrayExpression([])
            )
          ])
        )
        astMixin.push(
          t.forStatement(
            t.assignmentExpression('=', t.identifier('pug_interp'), t.numericLiteral(args.length)),
            t.binaryExpression('<', t.identifier('pug_interp'), t.memberExpression(t.identifier('arguments'), t.identifier('length'))),
            t.updateExpression('++', t.identifier('pug_interp'), false),
            t.expressionStatement(
              t.callExpression(
                t.memberExpression(t.identifier(rest), t.identifier('push')),
                [t.memberExpression(t.identifier('arguments'), t.identifier('pug_interp'), true)]
              )
            )
          )
        )
      }

      this.parentIndents++;
      push.apply(astMixin, this.visit(block, mixin));
      this.parentIndents--;


      var mixinStmt = 
        t.expressionStatement(
          t.assignmentExpression(
            '=',
            t.memberExpression(t.identifier('pug_mixins'), mixinName, true),
            t.assignmentExpression(
              '=',
              t.identifier('pug_interp'),
              t.functionExpression(
                null,
                astArgs,
                t.blockStatement(astMixin),
                this.useGenerators
              )
            )
          )
        );
      ast.push(mixinStmt);
 


      this.mixins[key].instances.push({stmt: mixinStmt});
    }
    return ast;
  },
Exemple #23
0
Ep.explodeExpression = function(path, ignoreResult) {
  let expr = path.node;
  if (expr) {
    t.assertExpression(expr);
  } else {
    return expr;
  }

  let self = this;
  let result; // Used optionally by several cases below.
  let after;

  function finish(expr) {
    t.assertExpression(expr);
    if (ignoreResult) {
      self.emit(expr);
    } else {
      return expr;
    }
  }

  // If the expression does not contain a leap, then we either emit the
  // expression as a standalone statement or return it whole.
  if (!meta.containsLeap(expr)) {
    return finish(expr);
  }

  // If any child contains a leap (such as a yield or labeled continue or
  // break statement), then any sibling subexpressions will almost
  // certainly have to be exploded in order to maintain the order of their
  // side effects relative to the leaping child(ren).
  let hasLeapingChildren = meta.containsLeap.onlyChildren(expr);

  // In order to save the rest of explodeExpression from a combinatorial
  // trainwreck of special cases, explodeViaTempVar is responsible for
  // deciding when a subexpression needs to be "exploded," which is my
  // very technical term for emitting the subexpression as an assignment
  // to a temporary variable and the substituting the temporary variable
  // for the original subexpression. Think of exploded view diagrams, not
  // Michael Bay movies. The point of exploding subexpressions is to
  // control the precise order in which the generated code realizes the
  // side effects of those subexpressions.
  function explodeViaTempVar(tempVar, childPath, ignoreChildResult) {
    assert.ok(
      !ignoreChildResult || !tempVar,
      "Ignoring the result of a child expression but forcing it to " +
        "be assigned to a temporary variable?"
    );

    let result = self.explodeExpression(childPath, ignoreChildResult);

    if (ignoreChildResult) {
      // Side effects already emitted above.

    } else if (tempVar || (hasLeapingChildren &&
                           !t.isLiteral(result))) {
      // If tempVar was provided, then the result will always be assigned
      // to it, even if the result does not otherwise need to be assigned
      // to a temporary variable.  When no tempVar is provided, we have
      // the flexibility to decide whether a temporary variable is really
      // necessary.  Unfortunately, in general, a temporary variable is
      // required whenever any child contains a yield expression, since it
      // is difficult to prove (at all, let alone efficiently) whether
      // this result would evaluate to the same value before and after the
      // yield (see #206).  One narrow case where we can prove it doesn't
      // matter (and thus we do not need a temporary variable) is when the
      // result in question is a Literal value.
      result = self.emitAssign(
        tempVar || self.makeTempVar(),
        result
      );
    }
    return result;
  }

  // If ignoreResult is true, then we must take full responsibility for
  // emitting the expression with all its side effects, and we should not
  // return a result.

  switch (expr.type) {
  case "MemberExpression":
    return finish(t.memberExpression(
      self.explodeExpression(path.get("object")),
      expr.computed
        ? explodeViaTempVar(null, path.get("property"))
        : expr.property,
      expr.computed
    ));

  case "CallExpression":
    let calleePath = path.get("callee");
    let argsPath = path.get("arguments");

    let newCallee;
    let newArgs = [];

    let hasLeapingArgs = false;
    argsPath.forEach(function(argPath) {
      hasLeapingArgs = hasLeapingArgs ||
        meta.containsLeap(argPath.node);
    });

    if (t.isMemberExpression(calleePath.node)) {
      if (hasLeapingArgs) {
        // If the arguments of the CallExpression contained any yield
        // expressions, then we need to be sure to evaluate the callee
        // before evaluating the arguments, but if the callee was a member
        // expression, then we must be careful that the object of the
        // member expression still gets bound to `this` for the call.

        let newObject = explodeViaTempVar(
          // Assign the exploded callee.object expression to a temporary
          // variable so that we can use it twice without reevaluating it.
          self.makeTempVar(),
          calleePath.get("object")
        );

        let newProperty = calleePath.node.computed
          ? explodeViaTempVar(null, calleePath.get("property"))
          : calleePath.node.property;

        newArgs.unshift(newObject);

        newCallee = t.memberExpression(
          t.memberExpression(
            newObject,
            newProperty,
            calleePath.node.computed
          ),
          t.identifier("call"),
          false
        );

      } else {
        newCallee = self.explodeExpression(calleePath);
      }

    } else {
      newCallee = self.explodeExpression(calleePath);

      if (t.isMemberExpression(newCallee)) {
        // If the callee was not previously a MemberExpression, then the
        // CallExpression was "unqualified," meaning its `this` object
        // should be the global object. If the exploded expression has
        // become a MemberExpression (e.g. a context property, probably a
        // temporary variable), then we need to force it to be unqualified
        // by using the (0, object.property)(...) trick; otherwise, it
        // will receive the object of the MemberExpression as its `this`
        // object.
        newCallee = t.sequenceExpression([
          t.numbericLiteral(0),
          newCallee
        ]);
      }
    }

    argsPath.forEach(function(argPath) {
      newArgs.push(explodeViaTempVar(null, argPath));
    });

    return finish(t.callExpression(
      newCallee,
      newArgs
    ));

  case "NewExpression":
    return finish(t.newExpression(
      explodeViaTempVar(null, path.get("callee")),
      path.get("arguments").map(function(argPath) {
        return explodeViaTempVar(null, argPath);
      })
    ));

  case "ObjectExpression":
    return finish(t.objectExpression(
      path.get("properties").map(function(propPath) {
        if (propPath.isObjectProperty()) {
          return t.objectProperty(
            propPath.node.key,
            explodeViaTempVar(null, propPath.get("value")),
            propPath.node.computed
          );
        } else {
          return propPath.node;
        }
      })
    ));

  case "ArrayExpression":
    return finish(t.arrayExpression(
      path.get("elements").map(function(elemPath) {
        return explodeViaTempVar(null, elemPath);
      })
    ));

  case "SequenceExpression":
    let lastIndex = expr.expressions.length - 1;

    path.get("expressions").forEach(function(exprPath) {
      if (exprPath.key === lastIndex) {
        result = self.explodeExpression(exprPath, ignoreResult);
      } else {
        self.explodeExpression(exprPath, true);
      }
    });

    return result;

  case "LogicalExpression":
    after = loc();

    if (!ignoreResult) {
      result = self.makeTempVar();
    }

    let left = explodeViaTempVar(result, path.get("left"));

    if (expr.operator === "&&") {
      self.jumpIfNot(left, after);
    } else {
      assert.strictEqual(expr.operator, "||");
      self.jumpIf(left, after);
    }

    explodeViaTempVar(result, path.get("right"), ignoreResult);

    self.mark(after);

    return result;

  case "ConditionalExpression":
    let elseLoc = loc();
    after = loc();
    let test = self.explodeExpression(path.get("test"));

    self.jumpIfNot(test, elseLoc);

    if (!ignoreResult) {
      result = self.makeTempVar();
    }

    explodeViaTempVar(result, path.get("consequent"), ignoreResult);
    self.jump(after);

    self.mark(elseLoc);
    explodeViaTempVar(result, path.get("alternate"), ignoreResult);

    self.mark(after);

    return result;

  case "UnaryExpression":
    return finish(t.unaryExpression(
      expr.operator,
      // Can't (and don't need to) break up the syntax of the argument.
      // Think about delete a[b].
      self.explodeExpression(path.get("argument")),
      !!expr.prefix
    ));

  case "BinaryExpression":
    return finish(t.binaryExpression(
      expr.operator,
      explodeViaTempVar(null, path.get("left")),
      explodeViaTempVar(null, path.get("right"))
    ));

  case "AssignmentExpression":
    return finish(t.assignmentExpression(
      expr.operator,
      self.explodeExpression(path.get("left")),
      self.explodeExpression(path.get("right"))
    ));

  case "UpdateExpression":
    return finish(t.updateExpression(
      expr.operator,
      self.explodeExpression(path.get("argument")),
      expr.prefix
    ));

  case "YieldExpression":
    after = loc();
    let arg = expr.argument && self.explodeExpression(path.get("argument"));

    if (arg && expr.delegate) {
      let result = self.makeTempVar();

      self.emit(t.returnStatement(t.callExpression(
        self.contextProperty("delegateYield"), [
          arg,
          t.stringLiteral(result.property.name),
          after
        ]
      )));

      self.mark(after);

      return result;
    }

    self.emitAssign(self.contextProperty("next"), after);
    self.emit(t.returnStatement(arg || null));
    self.mark(after);

    return self.contextProperty("sent");

  default:
    throw new Error(
      "unknown Expression of type " +
        JSON.stringify(expr.type));
  }
};
  compile: function(){
    var ast = [];
    if (this.pp) {
      ast.push(t.variableDeclaration('var', [t.variableDeclarator(t.identifier('pug_indent'), t.arrayExpression())]));
    }
    push.apply(ast, this.visit(this.node));
    if (!this.dynamicMixins) {
      // if there are no dynamic mixins we can remove any un-used mixins
      var mixinNames = Object.keys(this.mixins);
      for (var i = 0; i < mixinNames.length; i++) {
        var mixin = this.mixins[mixinNames[i]];
        if (!mixin.used) {
          for (var x = 0; x < mixin.instances.length; x++) {
            mixin.instances[x].stmt.type = "EmptyStatement";
            delete mixin.instances[x].stmt.expression;
          }
        }
      }
    }

    
    if (this.options.self) {
      ast = [
        t.variableDeclaration('var', [
          t.variableDeclarator(t.identifier('self'), t.logicalExpression('||', t.identifier('locals'), t.objectExpression([])))
        ])
      ].concat(ast);
    } else {
      ast = [t.withStatement(t.identifier('locals'), t.blockStatement(ast))]
    }


    if (this.debug) {
      if (this.options.includeSources) {
        ast.unshift(t.variableDeclaration('var', [
          t.variableDeclarator(t.identifier('pug_debug_sources'), this.parseExpr(stringify(this.options.includeSources)))
        ]))
      }

 
      var rethrowArgs = [
                t.identifier('err'),
                t.identifier('pug_debug_filename'),
                t.identifier('pug_debug_line')
              ]
      if (this.options.includeSources) {
          rethrowArgs.push(t.memberExpression(t.identifier('pug_debug_sources'), t.identifier('pug_debug_filename'), true))
      } 
      ast = [
        t.variableDeclaration('var', [
          t.variableDeclarator(t.identifier('pug_debug_filename'), null),
          t.variableDeclarator(t.identifier('pug_debug_line'), null)
        ]),
        t.tryStatement(
          t.blockStatement(ast),
          t.catchClause(
            t.identifier('err'),
            t.blockStatement([t.expressionStatement(t.callExpression(
              (this.inlineRuntimeFunctions ? t.identifier('pug_rethrow') : t.memberExpression(t.identifier('pug'), t.identifier('rethrow'))),
              rethrowArgs
            ))])
          )
        )
      ]

    }

    ast = t.functionDeclaration(
      t.identifier(this.options.templateName || 'template'),
      this.templateVars.map(function(v) { return t.identifier(v)}),
      t.blockStatement([this.ast_variableDeclaration()].concat(ast, this.ast_return()))
    )


    var plugins = [ babelPluginPugConcat ];
    if (!this.options.self) {
      let globals = this.options.globals ? this.options.globals.concat(INTERNAL_VARIABLES) : INTERNAL_VARIABLES;
      globals.concat(this.runtimeFunctionsUsed.map(function (name) { return 'pug_' + name; }));
      plugins.push([babelPluginTransformWith, { exclude: globals }]);
    }
    var file = babylon.parse('');
    file.program.body = [ast];
    var w = babel.transformFromAst(file, null, {
      code: false,
      plugins: plugins
    });

    return buildRuntime(this.runtimeFunctionsUsed) + gen.default(w.ast).code;
  },
export let property = opts => {
    const tmpl = template(`
    module.exports = function (parsed) {
        var valid = true;
        var count = 0;

        parsed.walk(function (node) {
            WORD
            STRING
            SEPARATOR
        });

        return count > COUNT ? false : valid;
    }
    `);
    
    const properties = template(`module.exports.properties = EXPORTS;`)({
        EXPORTS: t.arrayExpression(opts.properties.map(toStringLiteral))
    });
    
    let config = ['SEPARATOR', 'STRING', 'WORD'].reduce((list, key) => {
        list[key] = t.emptyStatement();
        return list;
    }, {});

    config.COUNT = t.numericLiteral(opts.count);

    let conditions = [];
    let dependencies = [];

    if (opts.values && opts.values.length) {
        if (opts.values.length === 1) {
            conditions.push(template(`node.value !== "${opts.values[0]}"`)().expression);
        } else {
            conditions.push(template(`!~VALUES.indexOf(node.value)`)({
                VALUES: t.arrayExpression(opts.values.map(toStringLiteral))
            }).expression);
        }
    }

    ['length', 'integer', 'percentage', 'number', 'time'].forEach(type => {
        if (!opts[type]) {
            return;
        }
        const camel = 'is' + type[0].toUpperCase() + type.slice(1, type.length);
        conditions.push(template(`!${camel}(node.value)`)().expression);
        dependencies.push(requireModule({
            identifier: camel,
            module: `../../validators/${camel}`
        }));
    });

    if (conditions.length) {
        config.WORD = template(`if (node.type === 'word') { inject; count++; }`)({
            inject: template('if (inject) { valid = false; return false; }')({
                inject: generateConditions.apply(null, conditions)
            })
        });
    }

    if (opts.string) {
        config.STRING = template(`if (node.type === 'string') { count++; }`)();
    }

    if (opts.repeat && opts.repeat.separator) {
        config.SEPARATOR = template(`if (node.type === 'div' && node.value === "${opts.repeat.separator}") { count --; }`)();
    }

    let program = t.program([ tmpl(config), properties ]);

    traverse(program, {
        noScope: true,
        EmptyStatement: function (path) {
            path.remove();
        }
    });

    return warning() + dependencies.join('') + generate(program).code;
};
function makePropType(data) {
  const method = data.type;

  let reactNode = t.callExpression(t.identifier('require'), [makeLiteral('react')]);
  let node = t.memberExpression(reactNode, t.identifier('PropTypes'));
  let isRequired = true;

  if (method === 'any' || method === 'string' || method === 'number' || method === 'bool' || method === 'object' ||
      method === 'array' || method === 'func') {
    node = t.memberExpression(node, t.identifier(method));
  }
  else if (method === 'raw') {
    node = t.identifier(data.value);
    isRequired = false;
  }
  else if (method === 'shape') {
    const shapeObjectProperties = (data.properties || {}).map(({key, value}) => {
      return t.objectProperty(
        t.identifier(key),
        makePropType(value)
      );
    });
    const shapeObjectLiteral = t.objectExpression(shapeObjectProperties);
    node = t.callExpression(
      t.memberExpression(node, t.identifier('shape')),
      [shapeObjectLiteral]
    );
  }
  else if (method === 'arrayOf') {
    node = t.callExpression(
      t.memberExpression(node, t.identifier('arrayOf')),
      [makePropType(data.of)]
    );
  }
  else if (method === 'oneOf') {
    node = t.callExpression(
      t.memberExpression(node, t.identifier('oneOf')),
      [t.arrayExpression(data.options.map(makeLiteral))]
    );
  }
  else if (method === 'oneOfType') {
    node = t.callExpression(
      t.memberExpression(node, t.identifier('oneOfType')),
      [t.arrayExpression(data.options.map(makePropType))]
    );
  }
  else if (method === 'void') {
    node = dontSetTemplate().expression;
  }
  else if (method === 'instanceOf') {
    node = t.callExpression(
      t.memberExpression(node, t.identifier('instanceOf')),
      [t.identifier(data.of)]
    )
  }
  else {
    $debug('Unknown node ' + JSON.stringify(data, null, 2));
    throw new Error(`${PLUGIN_NAME} processing error: This is an internal error that should never happen. ` +
      `Report it immediately with the source file and babel config. Data: ${data}`);
  }

  if (isRequired && data.isRequired && method !== 'void') {
    node = t.memberExpression(node, t.identifier('isRequired'));
  }

  return node;
}
module.exports = function addTestcheck(path, state, fnString) {
  const params = state.get('paramTypes'); // set by decypherParamTypes.js

  // creates `testcheck.check`
  const check = t.memberExpression(
    t.identifier('testcheck'),
    t.identifier('check')
  );

  // creates `testcheck.property`
  const property = t.memberExpression(
    t.identifier('testcheck'),
    t.identifier('property')
  );

  // creates `testcheckResults.push`
  const resultsPush = t.memberExpression(
    t.identifier('testcheckResults'),
    t.identifier('push')
  );

  const testcheckArgs = params.map(p => createGenArgument(p.type));

  // creates
  // ```js
  // testcheck.check(
  //   testcheck.property(
  //     [args],
  //     function() { ... }
  //   )
  // );
  // ```
  const fn = t.callExpression(check, [
    t.callExpression(property, [
      t.arrayExpression(testcheckArgs),
      t.identifier(fnString),
    ]),
  ]);

  // creates
  // ```js
  // {
  //   name: '',
  //   results: fn()
  // }
  const resultObject = t.objectExpression(
    [t.objectProperty(
      t.identifier('name'),
      t.stringLiteral(path.node.id.name)
    ), t.objectProperty(
      t.identifier('results'),
      fn
    )]
  );

  const allTogetherNow = t.callExpression(
    resultsPush,
    [resultObject]
  );

  path.insertAfter(allTogetherNow);
};