Skip to content

Add virtual reference to a used store #142

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 95 additions & 37 deletions src/parser/analyze-scope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,30 +90,65 @@ export function analyzeReactiveScope(scopeManager: ScopeManager): void {
* Analyze store scope. e.g. $count
*/
export function analyzeStoreScope(scopeManager: ScopeManager): void {
const moduleScope = scopeManager.scopes.find(
(scope) => scope.type === "module",
)
if (!moduleScope) {
return
}
const toBeMarkAsUsedReferences: Reference[] = []

for (const reference of [...scopeManager.globalScope.through]) {
if (reference.identifier.name.startsWith("$")) {
const realName = reference.identifier.name.slice(1)
const moduleScope = scopeManager.scopes.find(
(scope) => scope.type === "module",
)
if (moduleScope) {
const variable = moduleScope?.set.get(realName)
if (variable) {
// It does not write directly to the original variable.
// Therefore, this variable is always a reference.
reference.isWrite = () => false
reference.isWriteOnly = () => false
reference.isReadWrite = () => false
reference.isReadOnly = () => true
reference.isRead = () => true

variable.references.push(reference)
reference.resolved = variable
removeReferenceFromThrough(reference, moduleScope)
const variable = moduleScope.set.get(realName)
if (variable) {
if (reference.isWriteOnly()) {
// Need mark as used
toBeMarkAsUsedReferences.push(reference)
}

// It does not write directly to the original variable.
// Therefore, this variable is always a reference.
reference.isWrite = () => false
reference.isWriteOnly = () => false
reference.isReadWrite = () => false
reference.isReadOnly = () => true
reference.isRead = () => true

variable.references.push(reference)
reference.resolved = variable
removeReferenceFromThrough(reference, moduleScope)
}
}
}

for (const variable of new Set(
toBeMarkAsUsedReferences.map((ref) => ref.resolved!),
)) {
if (
variable.references.some(
(ref) =>
!toBeMarkAsUsedReferences.includes(ref) &&
ref.identifier !== variable.identifiers[0],
)
) {
// It is already used.
continue
}

// Add the virtual reference for reading.
;(
addVirtualReference(
variable.identifiers[0],
variable,
moduleScope,
{
read: true,
},
) as any
).svelteMarkAsUsed = true
}
}

/** Transform props exports */
Expand Down Expand Up @@ -163,27 +198,25 @@ export function analyzePropsScope(
}

// Add the virtual reference for writing.
const reference = new Reference()
;(reference as any).sveltePropReference = true
reference.from = scope
reference.identifier = {
...node,
// @ts-expect-error -- ignore
parent: body,
loc: {
start: { ...node.loc!.start },
end: { ...node.loc!.end },
const reference = addVirtualReference(
{
...node,
// @ts-expect-error -- ignore
parent: body,
loc: {
start: { ...node.loc!.start },
end: { ...node.loc!.end },
},
range: [...node.range!],
},
range: [...node.range!],
}
reference.isWrite = () => true
reference.isWriteOnly = () => false
reference.isRead = () => true
reference.isReadOnly = () => false
reference.isReadWrite = () => true

variable.references.push(reference)
reference.resolved = variable
variable,
scope,
{
write: true,
read: true,
},
)
;(reference as any).sveltePropReference = true
}
}
}
Expand All @@ -210,6 +243,31 @@ function removeReferenceFromThrough(reference: Reference, baseScope: Scope) {
}
}

/**
* Add the virtual reference.
*/
function addVirtualReference(
node: ESTree.Identifier,
variable: Variable,
scope: Scope,
readWrite: { read?: boolean; write?: boolean },
) {
const reference = new Reference()
;(reference as any).svelteVirtualReference = true
reference.from = scope
reference.identifier = node
reference.isWrite = () => Boolean(readWrite.write)
reference.isWriteOnly = () => Boolean(readWrite.write) && !readWrite.read
reference.isRead = () => Boolean(readWrite.read)
reference.isReadOnly = () => Boolean(readWrite.read) && !readWrite.write
reference.isReadWrite = () => Boolean(readWrite.read && readWrite.write)

variable.references.push(reference)
reference.resolved = variable

return reference
}

/** Get parent node */
function getParent(node: ESTree.Node): ESTree.Node | null {
return (node as any).parent
Expand Down
8 changes: 0 additions & 8 deletions tests/fixtures/parser/ast/$var-no-unused-vars-result.json

This file was deleted.

40 changes: 40 additions & 0 deletions tests/fixtures/parser/ast/$var-scope-output.json
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,46 @@
}
}
}
},
{
"identifier": {
"type": "Identifier",
"name": "a",
"range": [
20,
21
],
"loc": {
"start": {
"line": 2,
"column": 11
},
"end": {
"line": 2,
"column": 12
}
}
},
"from": "module",
"init": null,
"resolved": {
"type": "Identifier",
"name": "a",
"range": [
20,
21
],
"loc": {
"start": {
"line": 2,
"column": 11
},
"end": {
"line": 2,
"column": 12
}
}
}
}
]
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,46 @@
}
}
}
},
{
"identifier": {
"type": "Identifier",
"name": "imported",
"range": [
19,
27
],
"loc": {
"start": {
"line": 2,
"column": 10
},
"end": {
"line": 2,
"column": 18
}
}
},
"from": "module",
"init": null,
"resolved": {
"type": "Identifier",
"name": "imported",
"range": [
19,
27
],
"loc": {
"start": {
"line": 2,
"column": 10
},
"end": {
"line": 2,
"column": 18
}
}
}
}
]
},
Expand Down Expand Up @@ -624,6 +664,46 @@
}
}
}
},
{
"identifier": {
"type": "Identifier",
"name": "writeOnly",
"range": [
69,
78
],
"loc": {
"start": {
"line": 3,
"column": 7
},
"end": {
"line": 3,
"column": 16
}
}
},
"from": "module",
"init": null,
"resolved": {
"type": "Identifier",
"name": "writeOnly",
"range": [
69,
78
],
"loc": {
"start": {
"line": 3,
"column": 7
},
"end": {
"line": 3,
"column": 16
}
}
}
}
]
},
Expand Down