StackGenVis: Alignment of Data, Algorithms, and Models for Stacking Ensemble Learning Using Performance Metrics https://doi.org/10.1109/TVCG.2020.3030352
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
StackGenVis/frontend/node_modules/babel-plugin-jsx-v-model/index.js

482 lines
16 KiB

'use strict'
var allowedModifiers = ['trim', 'number', 'lazy']
var RANGE_TOKEN = '__r'
var CHECKBOX_RADIO_TOKEN = '__c'
var htmlTags = require('html-tags')
var svgTags = require('svg-tags')
var isReservedTag = function isReservedTag(tag) {
return ~htmlTags.indexOf(tag) || ~svgTags.indexOf(tag)
}
var getExpression = function getExpression(t, path) {
return t.isStringLiteral(path.node.value) ? path.node.value : path.node.value.expression
}
var genValue = function genValue(t, model) {
return t.jSXAttribute(t.jSXIdentifier('domPropsValue'), t.jSXExpressionContainer(model))
}
var genAssignmentCode = function genAssignmentCode(t, model, assignment) {
if (model.computed) {
var object = model.object,
property = model.property
return t.ExpressionStatement(
t.CallExpression(t.MemberExpression(t.ThisExpression(), t.Identifier('$set')), [object, property, assignment])
)
} else {
return t.ExpressionStatement(t.AssignmentExpression('=', model, assignment))
}
}
var genListener = function genListener(t, event, body) {
return t.jSXAttribute(
t.jSXIdentifier('on' + event),
t.jSXExpressionContainer(t.ArrowFunctionExpression([t.Identifier('$event')], t.BlockStatement(body)))
)
}
var genSelectModel = function genSelectModel(t, modelAttribute, model, modifier) {
if (modifier && modifier !== 'number') {
throw modelAttribute.get('name').get('name').buildCodeFrameError('you can only use number modifier with <select/ >')
}
var number = modifier === 'number'
var valueGetter = t.ConditionalExpression(
t.BinaryExpression('in', t.StringLiteral('_value'), t.Identifier('o')),
t.MemberExpression(t.Identifier('o'), t.Identifier('_value')),
t.MemberExpression(t.Identifier('o'), t.Identifier('value'))
)
var selectedVal = t.CallExpression(
t.MemberExpression(
t.CallExpression(
t.MemberExpression(
t.MemberExpression(
t.MemberExpression(t.Identifier('Array'), t.Identifier('prototype')),
t.Identifier('filter')
),
t.Identifier('call')
),
[
t.MemberExpression(
t.MemberExpression(t.Identifier('$event'), t.Identifier('target')),
t.Identifier('options')
),
t.ArrowFunctionExpression(
[t.Identifier('o')],
t.MemberExpression(t.Identifier('o'), t.Identifier('selected'))
)
]
),
t.Identifier('map')
),
[
t.ArrowFunctionExpression(
[t.Identifier('o')],
number
? t.CallExpression(t.MemberExpression(t.ThisExpression(), t.Identifier('_n')), [valueGetter])
: valueGetter
)
]
)
var assignment = t.ConditionalExpression(
t.MemberExpression(t.MemberExpression(t.Identifier('$event'), t.Identifier('target')), t.Identifier('multiple')),
t.Identifier('$$selectedVal'),
t.MemberExpression(t.Identifier('$$selectedVal'), t.NumericLiteral(0), true)
)
var code = t.VariableDeclaration('const', [t.VariableDeclarator(t.Identifier('$$selectedVal'), selectedVal)])
return [genValue(t, model), genListener(t, 'Change', [code, genAssignmentCode(t, model, assignment)])]
}
var genCheckboxModel = function genCheckboxModel(t, modelAttribute, model, modifier, path) {
if (modifier && modifier !== 'number') {
throw modelAttribute
.get('name')
.get('name')
.buildCodeFrameError('you can only use number modifier with input[type="checkbox"]')
}
var value = t.NullLiteral()
var trueValue = t.BooleanLiteral(true)
var falseValue = t.BooleanLiteral(false)
path.get('attributes').forEach(function(path) {
if (!path.node.name) {
return
}
if (path.node.name.name === 'value') {
value = getExpression(t, path)
path.remove()
} else if (path.node.name.name === 'true-value') {
trueValue = getExpression(t, path)
path.remove()
} else if (path.node.name.name === 'false-value') {
falseValue = getExpression(t, path)
path.remove()
}
})
var checkedProp = t.JSXAttribute(
t.JSXIdentifier('checked'),
t.JSXExpressionContainer(
t.ConditionalExpression(
t.CallExpression(t.MemberExpression(t.Identifier('Array'), t.Identifier('isArray')), [model]),
t.BinaryExpression(
'>',
t.CallExpression(t.MemberExpression(t.ThisExpression(), t.Identifier('_i')), [model, value]),
t.UnaryExpression('-', t.NumericLiteral(1))
),
t.isBooleanLiteral(trueValue) && trueValue.value === true
? model
: t.CallExpression(t.MemberExpression(t.ThisExpression(), t.Identifier('_q')), [model, trueValue])
)
)
)
var handlerProp = t.JSXAttribute(
t.JSXIdentifier('on' + CHECKBOX_RADIO_TOKEN),
t.JSXExpressionContainer(
t.ArrowFunctionExpression(
[t.Identifier('$event')],
t.BlockStatement([
t.VariableDeclaration('const', [
t.VariableDeclarator(t.Identifier('$$a'), model),
t.VariableDeclarator(
t.Identifier('$$el'),
t.MemberExpression(t.Identifier('$event'), t.Identifier('target'))
),
t.VariableDeclarator(
t.Identifier('$$c'),
t.ConditionalExpression(
t.MemberExpression(t.Identifier('$$el'), t.Identifier('checked')),
trueValue,
falseValue
)
)
]),
t.IfStatement(
t.CallExpression(t.MemberExpression(t.Identifier('Array'), t.Identifier('isArray')), [t.Identifier('$$a')]),
t.BlockStatement([
t.VariableDeclaration('const', [
t.VariableDeclarator(
t.Identifier('$$v'),
modifier === 'number'
? t.CallExpression(t.MemberExpression(t.ThisExpression(), t.Identifier('_n')), [value])
: value
),
t.VariableDeclarator(
t.Identifier('$$i'),
t.CallExpression(t.MemberExpression(t.ThisExpression(), t.Identifier('_i')), [
t.Identifier('$$a'),
t.Identifier('$$v')
])
)
]),
t.IfStatement(
t.MemberExpression(t.Identifier('$$el'), t.Identifier('checked')),
t.BlockStatement([
t.ExpressionStatement(
t.LogicalExpression(
'&&',
t.BinaryExpression('<', t.Identifier('$$i'), t.NumericLiteral(0)),
t.AssignmentExpression(
'=',
model,
t.CallExpression(t.MemberExpression(t.Identifier('$$a'), t.Identifier('concat')), [
t.Identifier('$$v')
])
)
)
)
]),
t.BlockStatement([
t.ExpressionStatement(
t.LogicalExpression(
'&&',
t.BinaryExpression('>', t.Identifier('$$i'), t.UnaryExpression('-', t.NumericLiteral(1))),
t.AssignmentExpression(
'=',
model,
t.CallExpression(
t.MemberExpression(
t.CallExpression(t.MemberExpression(t.Identifier('$$a'), t.Identifier('slice')), [
t.NumericLiteral(0),
t.Identifier('$$i')
]),
t.Identifier('concat')
),
[
t.CallExpression(t.MemberExpression(t.Identifier('$$a'), t.Identifier('slice')), [
t.BinaryExpression('+', t.Identifier('$$i'), t.NumericLiteral(1))
])
]
)
)
)
)
])
)
]),
t.BlockStatement([genAssignmentCode(t, model, t.Identifier('$$c'))])
)
])
)
)
)
return [checkedProp, handlerProp]
}
var genRadioModel = function genRadioModel(t, modelAttribute, model, modifier, path) {
if (modifier && modifier !== 'number') {
throw modelAttribute
.get('name')
.get('name')
.buildCodeFrameError('you can only use number modifier with input[type="radio"]')
}
var value = t.BooleanLiteral(true)
path.get('attributes').forEach(function(path) {
if (!path.node.name) {
return
}
if (path.node.name.name === 'value') {
value = getExpression(t, path)
path.remove()
}
})
var checkedProp = t.JSXAttribute(
t.JSXIdentifier('checked'),
t.JSXExpressionContainer(
t.CallExpression(t.MemberExpression(t.ThisExpression(), t.Identifier('_q')), [model, value])
)
)
var handlerProp = t.JSXAttribute(
t.JSXIdentifier('on' + CHECKBOX_RADIO_TOKEN),
t.JSXExpressionContainer(
t.ArrowFunctionExpression(
[t.Identifier('$event')],
t.BlockStatement([
genAssignmentCode(
t,
model,
modifier === 'number'
? t.CallExpression(t.MemberExpression(t.ThisExpression(), t.Identifier('_n')), [value])
: value
)
])
)
)
)
return [checkedProp, handlerProp]
}
var genDefaultModel = function genDefaultModel(t, modelAttribute, model, modifier, path, type) {
var needCompositionGuard = modifier !== 'lazy' && type !== 'range'
var event = modifier === 'lazy' ? 'Change' : type === 'range' ? RANGE_TOKEN : 'Input'
var valueExpression = t.MemberExpression(
t.MemberExpression(t.Identifier('$event'), t.Identifier('target')),
t.Identifier('value')
)
if (modifier === 'trim') {
valueExpression = t.CallExpression(t.MemberExpression(valueExpression, t.Identifier('trim')), [])
} else if (modifier === 'number') {
valueExpression = t.CallExpression(t.MemberExpression(t.ThisExpression(), t.Identifier('_n')), [valueExpression])
}
var code = genAssignmentCode(t, model, valueExpression)
if (needCompositionGuard) {
code = t.BlockStatement([
t.IfStatement(
t.MemberExpression(
t.MemberExpression(t.Identifier('$event'), t.Identifier('target')),
t.Identifier('composing')
),
t.ReturnStatement(null)
),
code
])
} else {
code = t.BlockStatement([code])
}
var valueProp = t.JSXAttribute(t.jSXIdentifier('domPropsValue'), t.JSXExpressionContainer(model))
var handlerProp = t.JSXAttribute(
t.JSXIdentifier('on' + event),
t.JSXExpressionContainer(t.ArrowFunctionExpression([t.Identifier('$event')], code))
)
var props = [valueProp, handlerProp]
if (modifier === 'trim' || modifier === 'number') {
props.push(
t.JSXAttribute(
t.JSXIdentifier('onBlur'),
t.JSXExpressionContainer(
t.ArrowFunctionExpression(
[],
t.CallExpression(t.MemberExpression(t.ThisExpression(), t.Identifier('$forceUpdate')), [])
)
)
)
)
}
return props
}
var genComponentModel = function genComponentModel(t, modelAttribute, model, modifier, path, type) {
var baseValueExpression = t.Identifier('$$v')
var valueExpression = baseValueExpression
if (modifier === 'trim') {
valueExpression = t.CallExpression(t.MemberExpression(valueExpression, t.Identifier('trim')), [])
} else if (modifier === 'number') {
valueExpression = t.CallExpression(t.MemberExpression(t.ThisExpression(), t.Identifier('_n')), [valueExpression])
}
var assignment = genAssignmentCode(t, model, valueExpression)
var valueProp = t.JSXAttribute(t.jSXIdentifier('value'), t.JSXExpressionContainer(model))
var handlerProp = t.JSXAttribute(
t.JSXIdentifier('onInput'),
t.JSXExpressionContainer(t.ArrowFunctionExpression([baseValueExpression], t.BlockStatement([assignment])))
)
return [valueProp, handlerProp]
}
module.exports = function(babel) {
var t = babel.types
return {
inherits: require('babel-plugin-syntax-jsx'),
visitor: {
JSXOpeningElement: function JSXOpeningElement(path) {
var model = null
var modifier = null
var modelAttribute = null
var type = null
var typePath = null
path.get('attributes').forEach(function(path) {
if (!path.node.name) {
return
}
if (path.node.name.name === 'type') {
type = path.node.value.value
typePath = path.get('value')
}
/* istanbul ignore else */
if (t.isJSXIdentifier(path.node.name)) {
if (path.node.name.name !== 'v-model') {
return
}
} else if (t.isJSXNamespacedName(path.node.name)) {
if (path.node.name.namespace.name !== 'v-model') {
return
}
if (!~allowedModifiers.indexOf(path.node.name.name.name)) {
throw path
.get('name')
.get('name')
.buildCodeFrameError('v-model does not support "' + path.node.name.name.name + '" modifier')
}
modifier = path.node.name.name.name
} else {
return
}
modelAttribute = path
if (model) {
throw path.buildCodeFrameError('you can not have multiple v-model directives on a single element')
}
if (!t.isJSXExpressionContainer(path.node.value)) {
throw path.get('value').buildCodeFrameError('you should use JSX Expression with v-model')
}
if (!t.isMemberExpression(path.node.value.expression)) {
throw path
.get('value')
.get('expression')
.buildCodeFrameError('you should use MemberExpression with v-model')
}
model = path.node.value.expression
})
if (!model) {
return
}
var tag = path.node.name.name
if (tag === 'input' && typePath && t.isJSXExpressionContainer(typePath.node)) {
throw typePath.buildCodeFrameError('you can not use dynamic type with v-model')
}
if (tag === 'input' && type === 'file') {
throw typePath.buildCodeFrameError('you can not use "file" type with v-model')
}
var replacement = null
if (tag === 'select') {
replacement = genSelectModel(t, modelAttribute, model, modifier)
} else if (tag === 'input' && type === 'checkbox') {
replacement = genCheckboxModel(t, modelAttribute, model, modifier, path)
} else if (tag === 'input' && type === 'radio') {
replacement = genRadioModel(t, modelAttribute, model, modifier, path)
} else if (tag === 'input' || tag === 'textarea') {
replacement = genDefaultModel(t, modelAttribute, model, modifier, path, type)
} else if (!isReservedTag(tag)) {
replacement = genComponentModel(t, modelAttribute, model, modifier, path)
} else {
throw path.buildCodeFrameError('you can not use "' + tag + '" with v-model')
}
modelAttribute.replaceWithMultiple([
...replacement,
t.JSXSpreadAttribute(
t.ObjectExpression([
t.ObjectProperty(
t.Identifier('directives'),
t.ArrayExpression([
t.ObjectExpression([
t.ObjectProperty(t.Identifier('name'), t.StringLiteral('model')),
t.ObjectProperty(t.Identifier('value'), model)
])
])
)
])
)
])
}
}
}
}