react / react-0.13.3 / node_modules / coffee-react / node_modules / coffee-react-transform / lib / parser.js
80758 views// Generated by CoffeeScript 1.9.11var $, BOM, CJSX_ESC_COMMENT, CLOSING_TAG, COMMENT, HEREDOC, HEREGEX, JSTOKEN, OPENING_TAG, PRAGMA, ParseTreeBranchNode, ParseTreeLeafNode, Parser, REGEX, SIMPLESTR, TAG_ATTRIBUTES, TRAILING_SPACES, WHITESPACE, compact, count, invertLiterate, last, ref, repeat, starts, throwSyntaxError;23ref = require('./helpers'), count = ref.count, starts = ref.starts, compact = ref.compact, last = ref.last, repeat = ref.repeat, throwSyntaxError = ref.throwSyntaxError, invertLiterate = ref.invertLiterate;45$ = require('./symbols');67ParseTreeLeafNode = function(type, value) {8if (value == null) {9value = null;10}11return {12type: type,13value: value14};15};1617ParseTreeBranchNode = function(type, value, children) {18if (value == null) {19value = null;20}21if (children == null) {22children = [];23}24return {25type: type,26value: value,27children: children28};29};3031module.exports = Parser = (function() {32function Parser() {}3334Parser.prototype.parse = function(code, opts) {35var consumed, i, message, ref1, ref2;36this.opts = opts != null ? opts : {};37this.parseTree = ParseTreeBranchNode(this.opts.root || $.ROOT);38this.activeStates = [this.parseTree];39this.chunkLine = 0;40this.chunkColumn = 0;41this.cjsxPragmaChecked = false;42code = this.clean(code);43i = 0;44while ((this.chunk = code.slice(i))) {45if (this.activeStates.length === 0) {46break;47}48consumed = ((ref1 = this.currentState()) !== $.CJSX_EL && ref1 !== $.CJSX_ATTRIBUTES ? this.csComment() || this.csHeredoc() || this.csString() || this.csRegex() || this.jsEscaped() : void 0) || this.cjsxStart() || this.cjsxAttribute() || this.cjsxComment() || this.cjsxEscape() || this.cjsxUnescape() || this.cjsxEnd() || this.cjsxText() || this.coffeescriptCode();49ref2 = this.getLineAndColumnFromChunk(consumed), this.chunkLine = ref2[0], this.chunkColumn = ref2[1];50i += consumed;51}52if ((this.activeBranchNode() != null) && this.activeBranchNode() !== this.parseTree) {53message = "Unexpected end of input: unclosed " + (this.currentState());54throwSyntaxError(message, {55first_line: this.chunkLine,56first_column: this.chunkColumn57});58}59this.remainder = code.slice(i);60if (!this.opts.recursive) {61if (this.remainder.length) {62throwSyntaxError("Unexpected return from root state", {63first_line: this.chunkLine,64first_column: this.chunkColumn65});66}67}68return this.parseTree;69};7071Parser.prototype.csComment = function() {72var comment, here, match, pragmaMatch, prefix;73if (!(match = this.chunk.match(COMMENT))) {74return 0;75}76comment = match[0], here = match[1];77if (!this.cjsxPragmaChecked) {78this.cjsxPragmaChecked = true;79if (pragmaMatch = comment.match(PRAGMA)) {80if (pragmaMatch && pragmaMatch[1] && pragmaMatch[1].length) {81prefix = pragmaMatch[1];82} else {83prefix = 'React.DOM';84}85this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.CJSX_PRAGMA, prefix));86return comment.length;87}88}89this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.CS_COMMENT, comment));90return comment.length;91};9293Parser.prototype.csHeredoc = function() {94var heredoc, match;95if (!(match = HEREDOC.exec(this.chunk))) {96return 0;97}98heredoc = match[0];99this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.CS_HEREDOC, heredoc));100return heredoc.length;101};102103Parser.prototype.csString = function() {104var quote, string;105switch (quote = this.chunk.charAt(0)) {106case "'":107string = SIMPLESTR.exec(this.chunk)[0];108break;109case '"':110string = this.balancedString(this.chunk, '"');111}112if (!string) {113return 0;114}115this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.CS_STRING, string));116return string.length;117};118119Parser.prototype.csRegex = function() {120var flags, length, match, ref1, regex;121if (this.chunk.charAt(0) !== '/') {122return 0;123}124if (length = this.csHeregex()) {125return length;126}127if (!(match = REGEX.exec(this.chunk))) {128return 0;129}130ref1 = match, match = ref1[0], regex = ref1[1], flags = ref1[2];131if (regex.indexOf("\n") > -1) {132return 0;133}134if (regex === '//') {135return 0;136}137this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.CS_REGEX, match));138return match.length;139};140141Parser.prototype.csHeregex = function() {142var body, flags, heregex, match;143if (!(match = HEREGEX.exec(this.chunk))) {144return 0;145}146heregex = match[0], body = match[1], flags = match[2];147this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.CS_HEREGEX, heregex));148return heregex.length;149};150151Parser.prototype.jsEscaped = function() {152var match, script;153if (!(this.chunk.charAt(0) === '`' && (match = JSTOKEN.exec(this.chunk)))) {154return 0;155}156script = match[0];157this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.JS_ESC, script));158return script.length;159};160161Parser.prototype.cjsxStart = function() {162var attributesText, input, match, selfClosing, tagName;163if (!(match = OPENING_TAG.exec(this.chunk))) {164return 0;165}166input = match[0], tagName = match[1], attributesText = match[2], selfClosing = match[3];167if (!(selfClosing || this.chunk.indexOf("</" + tagName + ">", input.length) > -1)) {168return 0;169}170this.pushActiveBranchNode(ParseTreeBranchNode($.CJSX_EL, tagName));171this.pushActiveBranchNode(ParseTreeBranchNode($.CJSX_ATTRIBUTES));172return 1 + tagName.length;173};174175Parser.prototype.cjsxAttribute = function() {176var attrName, bareVal, cjsxEscVal, doubleQuotedVal, input, match, singleQuotedVal, spreadAttr, whitespace;177if (this.currentState() !== $.CJSX_ATTRIBUTES) {178return 0;179}180if (this.chunk.charAt(0) === '/') {181if (this.chunk.charAt(1) === '>') {182this.popActiveBranchNode();183this.popActiveBranchNode();184return 2;185} else {186throwSyntaxError("/ without immediately following > in CJSX tag " + (this.peekActiveState(2).value), {187first_line: this.chunkLine,188first_column: this.chunkColumn189});190}191}192if (this.chunk.charAt(0) === '>') {193this.popActiveBranchNode();194return 1;195}196if (!(match = TAG_ATTRIBUTES.exec(this.chunk))) {197return 0;198}199input = match[0], attrName = match[1], doubleQuotedVal = match[2], singleQuotedVal = match[3], cjsxEscVal = match[4], bareVal = match[5], spreadAttr = match[6], whitespace = match[7];200if (attrName) {201if (doubleQuotedVal != null) {202this.addLeafNodeToActiveBranch(ParseTreeBranchNode($.CJSX_ATTR_PAIR, null, [ParseTreeLeafNode($.CJSX_ATTR_KEY, "\"" + attrName + "\""), ParseTreeLeafNode($.CJSX_ATTR_VAL, "\"" + doubleQuotedVal + "\"")]));203return input.length;204} else if (singleQuotedVal != null) {205this.addLeafNodeToActiveBranch(ParseTreeBranchNode($.CJSX_ATTR_PAIR, null, [ParseTreeLeafNode($.CJSX_ATTR_KEY, "\"" + attrName + "\""), ParseTreeLeafNode($.CJSX_ATTR_VAL, "'" + singleQuotedVal + "'")]));206return input.length;207} else if (cjsxEscVal) {208this.pushActiveBranchNode(ParseTreeBranchNode($.CJSX_ATTR_PAIR));209this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.CJSX_ATTR_KEY, "\"" + attrName + "\""));210return input.indexOf('{');211} else if (bareVal) {212this.addLeafNodeToActiveBranch(ParseTreeBranchNode($.CJSX_ATTR_PAIR, null, [ParseTreeLeafNode($.CJSX_ATTR_KEY, "\"" + attrName + "\""), ParseTreeLeafNode($.CJSX_ATTR_VAL, bareVal)]));213return input.length;214} else {215this.addLeafNodeToActiveBranch(ParseTreeBranchNode($.CJSX_ATTR_PAIR, null, [ParseTreeLeafNode($.CJSX_ATTR_KEY, "\"" + attrName + "\""), ParseTreeLeafNode($.CJSX_ATTR_VAL, 'true')]));216return input.length;217}218} else if (spreadAttr) {219this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.CJSX_ATTR_SPREAD, spreadAttr));220return input.length;221} else if (whitespace != null) {222this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.CJSX_WHITESPACE, whitespace));223return input.length;224} else {225return throwSyntaxError("Invalid attribute " + input + " in CJSX tag " + (this.peekActiveState(2).value), {226first_line: this.chunkLine,227first_column: this.chunkColumn228});229}230};231232Parser.prototype.cjsxComment = function() {233var match;234match = this.chunk.match(CJSX_ESC_COMMENT);235if (!match) {236return 0;237}238this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.CJSX_COMMENT, match[1]));239return match[0].length;240};241242Parser.prototype.cjsxEscape = function() {243var ref1;244if (!(this.chunk.charAt(0) === '{' && ((ref1 = this.currentState()) === $.CJSX_EL || ref1 === $.CJSX_ATTR_PAIR))) {245return 0;246}247this.pushActiveBranchNode(ParseTreeBranchNode($.CJSX_ESC));248this.activeBranchNode().stack = 1;249return 1;250};251252Parser.prototype.cjsxUnescape = function() {253var ref1;254if (!(this.currentState() === $.CJSX_ESC && this.chunk.charAt(0) === '}')) {255return 0;256}257if (this.activeBranchNode().stack === 0) {258this.popActiveBranchNode();259if ((ref1 = this.currentState()) === $.CJSX_ATTR_PAIR) {260this.popActiveBranchNode();261}262return 1;263} else {264return 0;265}266};267268Parser.prototype.cjsxEnd = function() {269var input, match, tagName;270if (this.currentState() !== $.CJSX_EL) {271return 0;272}273if (!(match = CLOSING_TAG.exec(this.chunk))) {274return 0;275}276input = match[0], tagName = match[1];277if (tagName !== this.activeBranchNode().value) {278throwSyntaxError("opening CJSX tag " + (this.activeBranchNode().value) + " doesn't match closing CJSX tag " + tagName, {279first_line: this.chunkLine,280first_column: this.chunkColumn281});282}283this.popActiveBranchNode();284return input.length;285};286287Parser.prototype.cjsxText = function() {288if (this.currentState() !== $.CJSX_EL) {289return 0;290}291if (this.newestNode().type !== $.CJSX_TEXT) {292this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.CJSX_TEXT, ''));293}294this.newestNode().value += this.chunk.charAt(0);295return 1;296};297298Parser.prototype.coffeescriptCode = function() {299if (this.currentState() === $.CJSX_ESC) {300if (this.chunk.charAt(0) === '{') {301this.activeBranchNode().stack++;302} else if (this.chunk.charAt(0) === '}') {303this.activeBranchNode().stack--;304if (this.activeBranchNode().stack === 0) {305return 0;306}307}308}309if (this.newestNode().type !== $.CS) {310this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.CS, ''));311}312this.newestNode().value += this.chunk.charAt(0);313return 1;314};315316Parser.prototype.activeBranchNode = function() {317return last(this.activeStates);318};319320Parser.prototype.peekActiveState = function(depth) {321if (depth == null) {322depth = 1;323}324return this.activeStates.slice(-depth)[0];325};326327Parser.prototype.currentState = function() {328return this.activeBranchNode().type;329};330331Parser.prototype.newestNode = function() {332return last(this.activeBranchNode().children) || this.activeBranchNode();333};334335Parser.prototype.pushActiveBranchNode = function(node) {336this.activeBranchNode().children.push(node);337return this.activeStates.push(node);338};339340Parser.prototype.popActiveBranchNode = function() {341return this.activeStates.pop();342};343344Parser.prototype.addLeafNodeToActiveBranch = function(node) {345return this.activeBranchNode().children.push(node);346};347348Parser.prototype.clean = function(code) {349var ref1;350if (code.charCodeAt(0) === BOM) {351code = code.slice(1);352}353code = code.replace(/\r/g, '');354if ((ref1 = this.opts) != null ? ref1.literate : void 0) {355code = invertLiterate(code);356}357return code;358};359360Parser.prototype.getLineAndColumnFromChunk = function(offset) {361var column, lineCount, lines, string;362if (offset === 0) {363return [this.chunkLine, this.chunkColumn];364}365if (offset >= this.chunk.length) {366string = this.chunk;367} else {368string = this.chunk.slice(0, +(offset - 1) + 1 || 9e9);369}370lineCount = count(string, '\n');371column = this.chunkColumn;372if (lineCount > 0) {373lines = string.split('\n');374column = last(lines).length;375} else {376column += string.length;377}378return [this.chunkLine + lineCount, column];379};380381Parser.prototype.balancedString = function(str, end) {382var continueCount, i, j, letter, match, prev, ref1, stack;383continueCount = 0;384stack = [end];385for (i = j = 1, ref1 = str.length; 1 <= ref1 ? j < ref1 : j > ref1; i = 1 <= ref1 ? ++j : --j) {386if (continueCount) {387--continueCount;388continue;389}390switch (letter = str.charAt(i)) {391case '\\':392++continueCount;393continue;394case end:395stack.pop();396if (!stack.length) {397return str.slice(0, +i + 1 || 9e9);398}399end = stack[stack.length - 1];400continue;401}402if (end === '}' && (letter === '"' || letter === "'")) {403stack.push(end = letter);404} else if (end === '}' && letter === '/' && (match = HEREGEX.exec(str.slice(i)) || REGEX.exec(str.slice(i)))) {405continueCount += match[0].length - 1;406} else if (end === '}' && letter === '{') {407stack.push(end = '}');408} else if (end === '"' && prev === '#' && letter === '{') {409stack.push(end = '}');410}411prev = letter;412}413return throwSyntaxError("missing " + (stack.pop()) + ", starting");414};415416return Parser;417418})();419420OPENING_TAG = /^<(@?[-A-Za-z0-9_\.]+)((?:(?:(?:\s+[\w-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|(?:{[\s\S]*?})|[^>\s]+)))|\s+[\w-]+|\s+\{\.\.\.\s*?[^\s{}]+?\s*?\})?)*?\s*)(\/?)>/;421422CLOSING_TAG = /^<\/(@?[-A-Za-z0-9_\.]+)[^>]*>/;423424TAG_ATTRIBUTES = /(?:([-A-Za-z0-9_]+)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|(?:{((?:\\.|[\s\S])*)})|([^>\s]+)))?)|(?:\{\.\.\.(\s*?[^\s{}]+?\s*?)\})|([\s\n]+)/;425426PRAGMA = /^\s*#\s*@cjsx\s+(\S*)/i;427428CJSX_ESC_COMMENT = /^\{#(.*)\}/;429430BOM = 65279;431432WHITESPACE = /^[^\n\S]+/;433434COMMENT = /^###([^#][\s\S]*?)(?:###[^\n\S]*|###$)|^(?:\s*#(?!##[^#]).*)+/;435436TRAILING_SPACES = /\s+$/;437438HEREDOC = /^("""|''')((?:\\[\s\S]|[^\\])*?)(?:\n[^\n\S]*)?\1/;439440SIMPLESTR = /^'[^\\']*(?:\\[\s\S][^\\']*)*'/;441442JSTOKEN = /^`[^\\`]*(?:\\.[^\\`]*)*`/;443444REGEX = /^(\/(?![\s=])[^[\/\n\\]*(?:(?:\\[\s\S]|\[[^\]\n\\]*(?:\\[\s\S][^\]\n\\]*)*])[^[\/\n\\]*)*\/)([imgy]{0,4})(?!\w)/;445446HEREGEX = /^\/{3}((?:\\?[\s\S])+?)\/{3}([imgy]{0,4})(?!\w)/;447448449