123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- 'use strict'
- const { findVariable } = require('eslint-utils')
- const utils = require('../utils')
- function getCalleeMemberNode(node) {
- const callee = utils.skipChainExpression(node.callee)
- if (callee.type === 'MemberExpression') {
- const name = utils.getStaticPropertyName(callee)
- if (name) {
- return { name, member: callee }
- }
- }
- return null
- }
- module.exports = {
- meta: {
- type: 'problem',
- docs: {
- description: 'disallow asynchronously registered `expose`',
- categories: undefined,
-
- url: 'https://eslint.vuejs.org/rules/no-expose-after-await.html'
- },
- fixable: null,
- schema: [],
- messages: {
- forbidden: 'The `expose` after `await` expression are forbidden.'
- }
- },
-
- create(context) {
-
-
-
- const setupScopes = new Map()
-
- let scopeStack = null
- return utils.defineVueVisitor(context, {
- onSetupFunctionEnter(node) {
- const contextParam = node.params[1]
- if (!contextParam) {
-
- return
- }
- if (contextParam.type === 'RestElement') {
-
- return
- }
- if (contextParam.type === 'ArrayPattern') {
-
- return
- }
-
- const contextReferenceIds = new Set()
-
- const exposeReferenceIds = new Set()
- if (contextParam.type === 'ObjectPattern') {
- const exposeProperty = utils.findAssignmentProperty(
- contextParam,
- 'expose'
- )
- if (!exposeProperty) {
- return
- }
- const exposeParam = exposeProperty.value
-
- const variable =
- exposeParam.type === 'Identifier'
- ? findVariable(context.getScope(), exposeParam)
- : null
- if (!variable) {
- return
- }
- for (const reference of variable.references) {
- if (!reference.isRead()) {
- continue
- }
- exposeReferenceIds.add(reference.identifier)
- }
- } else if (contextParam.type === 'Identifier') {
-
- const variable = findVariable(context.getScope(), contextParam)
- if (!variable) {
- return
- }
- for (const reference of variable.references) {
- if (!reference.isRead()) {
- continue
- }
- contextReferenceIds.add(reference.identifier)
- }
- }
- setupScopes.set(node, {
- afterAwait: false,
- range: node.range,
- exposeReferenceIds,
- contextReferenceIds
- })
- },
-
- ':function'(node) {
- scopeStack = {
- upper: scopeStack,
- scopeNode: node
- }
- },
- ':function:exit'() {
- scopeStack = scopeStack && scopeStack.upper
- },
-
- AwaitExpression(node) {
- if (!scopeStack) {
- return
- }
- const setupScope = setupScopes.get(scopeStack.scopeNode)
- if (!setupScope || !utils.inRange(setupScope.range, node)) {
- return
- }
- setupScope.afterAwait = true
- },
-
- CallExpression(node) {
- if (!scopeStack) {
- return
- }
- const setupScope = setupScopes.get(scopeStack.scopeNode)
- if (
- !setupScope ||
- !setupScope.afterAwait ||
- !utils.inRange(setupScope.range, node)
- ) {
- return
- }
- const { contextReferenceIds, exposeReferenceIds } = setupScope
- if (
- node.callee.type === 'Identifier' &&
- exposeReferenceIds.has(node.callee)
- ) {
-
- context.report({
- node,
- messageId: 'forbidden'
- })
- } else {
- const expose = getCalleeMemberNode(node)
- if (
- expose &&
- expose.name === 'expose' &&
- expose.member.object.type === 'Identifier' &&
- contextReferenceIds.has(expose.member.object)
- ) {
-
- context.report({
- node,
- messageId: 'forbidden'
- })
- }
- }
- },
- onSetupFunctionExit(node) {
- setupScopes.delete(node)
- }
- })
- }
- }
|