Skip to content

Commit daab4a8

Browse files
committed
fix scope for import as
1 parent e8378c0 commit daab4a8

File tree

4 files changed

+38
-10
lines changed

4 files changed

+38
-10
lines changed

src/utils/scope.ts

+24-8
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,40 @@ import { ContractDefinition, SourceUnit } from "solidity-ast";
22
import { findAll, isNodeType } from "solidity-ast/utils";
33
import { DocItemWithContext } from "../site";
44
import { filterValues, mapValues } from './map-values';
5+
import { mapKeys } from './map-keys';
6+
7+
type Definition = SourceUnit['nodes'][number] & { name: string };
8+
type Scope = { [name in string]: () => { namespace: Scope } | { definition: Definition } };
59

610
export function getContractsInScope(item: DocItemWithContext) {
7-
const cache = new WeakMap<SourceUnit, Record<string, () => Definition>>();
11+
const cache = new WeakMap<SourceUnit, Scope>();
812

913
return filterValues(
10-
mapValues(run(item.__item_context.file), getDef => getDef()),
14+
flattenScope(run(item.__item_context.file)),
1115
isNodeType('ContractDefinition'),
1216
);
1317

14-
type Definition = SourceUnit['nodes'][number] & { name: string };
15-
16-
function run(file: SourceUnit): Record<string, () => Definition> {
18+
function run(file: SourceUnit): Scope {
1719
if (cache.has(file)) {
1820
return cache.get(file)!;
1921
}
2022

21-
const scope: Record<string, () => Definition> = {};
23+
const scope: Scope = {};
2224

2325
cache.set(file, scope);
2426

2527
for (const c of file.nodes) {
2628
if ('name' in c) {
27-
scope[c.name] = () => c;
29+
scope[c.name] = () => ({ definition: c });
2830
}
2931
}
3032

3133
for (const i of findAll('ImportDirective', file)) {
3234
const importedFile = item.__item_context.build.deref('SourceUnit', i.sourceUnit);
3335
const importedScope = run(importedFile);
34-
if (i.symbolAliases.length === 0) {
36+
if (i.unitAlias) {
37+
scope[i.unitAlias] = () => ({ namespace: importedScope });
38+
} else if (i.symbolAliases.length === 0) {
3539
Object.assign(scope, importedScope);
3640
} else {
3741
for (const a of i.symbolAliases) {
@@ -45,3 +49,15 @@ export function getContractsInScope(item: DocItemWithContext) {
4549
}
4650
}
4751

52+
function flattenScope(scope: Scope): Record<string, Definition> {
53+
return Object.fromEntries(
54+
Object.entries(scope).flatMap(([k, fn]) => {
55+
const v = fn();
56+
if ('definition' in v) {
57+
return [[k, v.definition] as const];
58+
} else {
59+
return Object.entries(mapKeys(flattenScope(v.namespace), k2 => k + '.' + k2));
60+
}
61+
}),
62+
);
63+
}

test-contracts/S08_C.sol

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
// SPDX-License-Identifier: MIT
22
pragma solidity ^0.8.11;
33

4-
import {I as J, E} from './S08_I.sol';
4+
import {I as J, E, k} from './S08_I.sol';
55

6-
contract C is J {
6+
contract C is J, k.K {
77
/// @inheritdoc J
88
function foo() external override {}
9+
10+
/// @inheritdoc k.K
11+
function bar() external override{}
912
}

test-contracts/S08_I.sol

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// SPDX-License-Identifier: MIT
22
pragma solidity ^0.8.11;
33

4+
import './S08_K.sol' as k;
5+
46
error E();
57

68
contract I {

test-contracts/S08_K.sol

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.11;
3+
4+
contract K {
5+
/// a function goes into a bar
6+
function bar() external virtual {}
7+
}

0 commit comments

Comments
 (0)