babel-helper-decorate-react
Version:
Babel Helper for custom decorator for React Component
147 lines (146 loc) • 5.49 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RangesEater = exports.DisableRange = exports.EnableRange = exports.Range = void 0;
const escape = require("escape-string-regexp");
function createCommentRegExps(prefix) {
prefix = escape(prefix);
return {
DISABLE_SCOPE: new RegExp(`^ ${prefix}-disable(?:$| (.*)$)`),
ENABLE_SCOPE: new RegExp(`^ ${prefix}-enable(?:$| (.*)$)`),
ENABLE_NEXT_LINE: new RegExp(`^ ${prefix}-enable-next-line(?:$| (.*)$)`),
ENABLE_THIS_LINE: new RegExp(`^ ${prefix}-enable-line(?:$| (.*)$)`),
DISABLE_NEXT_LINE: new RegExp(`^ ${prefix}-disable-next-line(?:$| (.*)$)`),
DISABLE_THIS_LINE: new RegExp(`^ ${prefix}-disable-line(?:$| (.*)$)`)
};
}
class Range {
constructor(start, end, data) {
this.start = start;
this.end = end;
this.data = data;
}
has(pos) {
return this.start <= pos && this.end >= pos;
}
clone() {
// @ts-ignore
return new this.constructor(this.start, this.end, this.data);
}
}
exports.Range = Range;
class EnableRange extends Range {
constructor() {
super(...arguments);
this.type = 'enable';
}
}
exports.EnableRange = EnableRange;
class DisableRange extends Range {
constructor() {
super(...arguments);
this.type = 'disable';
}
}
exports.DisableRange = DisableRange;
class RangesEater {
constructor(opts) {
this.ranges = [];
this.regexps = createCommentRegExps(opts.prefix);
this.opts = Object.assign({ composeData: (a, b) => [].concat(a).concat(b) }, opts);
}
get lastRange() {
return this.ranges[this.ranges.length - 1];
}
parseArgument(value, reg) {
const result = value.match(reg);
const ruleText = ((result && result[1]) || '').trim();
if (this.opts.parseArgument) {
return this.opts.parseArgument(ruleText);
}
return ruleText;
}
eatBlock(value, location) {
if (this.regexps.DISABLE_SCOPE.test(value)) {
const data = this.parseArgument(value, this.regexps.DISABLE_SCOPE);
const last = this.lastRange;
if (!last || last.end !== Infinity) {
this.ranges.push(new DisableRange(location.start.line, Infinity, data));
}
else {
last.end = location.start.line - 1;
if (last.type === 'enable') {
this.ranges.push(new DisableRange(location.start.line, Infinity, data));
}
else {
last.data = this.opts.composeData(last.data, data);
}
}
}
else if (this.regexps.ENABLE_SCOPE.test(value)) {
const data = this.parseArgument(value, this.regexps.ENABLE_SCOPE);
const last = this.lastRange;
if (!last || last.end !== Infinity) {
this.ranges.push(new EnableRange(location.start.line, Infinity, data));
}
else {
last.end = location.start.line - 1;
if (last.type === 'disable') {
this.ranges.push(new EnableRange(location.start.line, Infinity, data));
}
else {
last.data = this.opts.composeData(last.data, data);
}
}
}
}
eatLine(value, location) {
const handleLine = (delta, data, RangeClass) => {
const last = this.lastRange;
if (!last || last.end !== Infinity) {
this.ranges.push(new RangeClass(location.start.line + delta, location.end.line + delta, data));
}
else {
let newData;
if (RangeClass === last.constructor) {
newData = this.opts.composeData(last.data, data);
}
else {
newData = data;
}
const newLast = last.clone();
last.end = location.start.line;
this.ranges.push(new RangeClass(location.start.line + delta, location.end.line + delta, newData), newLast);
}
};
if (this.regexps.DISABLE_THIS_LINE.test(value)) {
const data = this.parseArgument(value, this.regexps.DISABLE_THIS_LINE);
handleLine(0, data, DisableRange);
}
else if (this.regexps.DISABLE_NEXT_LINE.test(value)) {
const data = this.parseArgument(value, this.regexps.DISABLE_NEXT_LINE);
handleLine(1, data, DisableRange);
}
else if (this.regexps.ENABLE_THIS_LINE.test(value)) {
const data = this.parseArgument(value, this.regexps.ENABLE_THIS_LINE);
handleLine(0, data, EnableRange);
}
else if (this.regexps.ENABLE_NEXT_LINE.test(value)) {
const data = this.parseArgument(value, this.regexps.ENABLE_NEXT_LINE);
handleLine(1, data, EnableRange);
}
}
}
exports.RangesEater = RangesEater;
function parseCommentsRanges(comments, options) {
const eater = new RangesEater(options);
comments.forEach(({ loc, value, type }) => {
if (type === 'CommentBlock') {
eater.eatBlock(value, loc);
}
else if (type === 'CommentLine') {
eater.eatLine(value, loc);
}
});
return eater.ranges;
}
exports.default = parseCommentsRanges;