Skip to content
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

Rework deprecated functionality #159

Merged
merged 11 commits into from
Nov 22, 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
6 changes: 3 additions & 3 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@
]
},
"ignorePatterns": [
"src/types/typeStrings/typeString_parser_header.ts",
"src/types/typeStrings/typeString_parser.ts",
"src/compile/inference/file_level_definitions_parser_header.ts",
"src/compile/inference/file_level_definitions_parser.ts"
"src/compile/inference/file_level_definitions_parser.ts",
"test/utils/typeStrings/typeString_parser_header.ts",
"test/utils/typeStrings/typeString_parser.ts"
]
}
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ dist
docs
coverage
*.tgz
src/types/typeStrings/typeString_parser.ts
src/compile/inference/file_level_definitions_parser.ts
test/utils/typeStrings/typeString_parser.ts
1 change: 0 additions & 1 deletion .nycrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
"**/coverage/**",
"**/docs/**",
"**/.compiler_cache/**",
"src/types/typeStrings/typeString_parser*.ts",
"src/compile/inference/file_level_definitions_parser*.ts"
],
"reporter": ["lcov", "text-summary"],
Expand Down
563 changes: 276 additions & 287 deletions package-lock.json

Large diffs are not rendered by default.

27 changes: 13 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,22 @@
"sol-ast-compile": "dist/bin/compile.js"
},
"scripts": {
"clean": "rm -rf dist/ src/ast/typestrings/typeString_parser.ts src/compile/inference/file_level_definitions_parser.ts",
"clean": "rm -rf dist/ src/compile/inference/file_level_definitions_parser.ts test/utils/typeStrings/typeString_parser.ts",
"transpile": "tsc",
"build-type-parser": "tspegjs -o src/types/typeStrings/typeString_parser.ts --custom-header-file src/types/typeStrings/typeString_parser_header.ts --cache src/types/typeStrings/typeString_grammar.pegjs",
"build-type-parser": "tspegjs -o test/utils/typeStrings/typeString_parser.ts --custom-header-file test/utils/typeStrings/typeString_parser_header.ts --cache test/utils/typeStrings/typeString_grammar.pegjs",
"build-file-level-definitions-parser": "tspegjs -o src/compile/inference/file_level_definitions_parser.ts --custom-header-file src/compile/inference/file_level_definitions_parser_header.ts --cache src/compile/inference/file_level_definitions.pegjs",
"build-parsers": "npm run build-type-parser && npm run build-file-level-definitions-parser",
"build": "npm run clean && npm run build-parsers && npm run transpile && chmod u+x dist/bin/compile.js",
"build": "npm run clean && npm run build-file-level-definitions-parser && npm run transpile && chmod u+x dist/bin/compile.js",
"lint": "eslint src/ test/ --ext=ts",
"lint:fix": "eslint src/ test/ --ext=ts --fix",
"test": "NODE_OPTIONS='--max-old-space-size=2048' nyc mocha",
"test": "npm run build-type-parser && NODE_OPTIONS='--max-old-space-size=2048' nyc mocha",
"coverage": "nyc report",
"docs:render": "typedoc",
"docs:clear": "rm -rf docs/",
"docs:refresh": "npm run docs:clear && npm run docs:render",
"prepare": "npm run build"
},
"dependencies": {
"axios": "^1.1.0",
"axios": "^1.1.3",
"commander": "^9.4.1",
"findup-sync": "^5.0.0",
"fs-extra": "^10.1.0",
Expand All @@ -37,26 +36,26 @@
"solc": "^0.8.17",
"src-location": "^1.1.0",
"web3-eth-abi": "^1.8.0",
"decimal.js": "^10.4.1"
"decimal.js": "^10.4.2"
},
"devDependencies": {
"@types/fs-extra": "^9.0.13",
"@types/mocha": "^10.0.0",
"@types/node": "^16.11.64",
"@types/node": "^16.18.0",
"@types/semver": "^7.3.12",
"@typescript-eslint/eslint-plugin": "^5.39.0",
"@typescript-eslint/parser": "^5.39.0",
"eslint": "^8.24.0",
"@typescript-eslint/eslint-plugin": "^5.40.1",
"@typescript-eslint/parser": "^5.40.1",
"eslint": "^8.26.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-prettier": "^4.2.1",
"expect": "^29.1.2",
"mocha": "^10.0.0",
"expect": "^29.2.1",
"mocha": "^10.1.0",
"nyc": "^15.1.0",
"peggy": "^2.0.1",
"prettier": "2.7.1",
"ts-node": "^10.9.1",
"ts-pegjs": "^2.1.0",
"typedoc": "^0.23.15",
"typedoc": "^0.23.18",
"typescript": "^4.8.4"
},
"homepage": "https://consensys.github.io/solc-typed-ast",
Expand Down
127 changes: 61 additions & 66 deletions src/ast/definitions.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { gte, lt } from "semver";
import { FunctionVisibility } from ".";
import { forAll, pp } from "../misc";
import { ABIEncoderVersion } from "../types/abi";
import { assert, forAll, pp } from "../misc";
import { ABIEncoderVersion, InferType } from "../types";
import { ASTNode } from "./ast_node";
import { StateVariableVisibility } from "./constants";
import { ContractDefinition } from "./implementation/declaration/contract_definition";
Expand Down Expand Up @@ -115,8 +115,10 @@ function getContainingScope(node: ASTNode, version: string): ScopeNode | undefin
if (pt instanceof Block || pt instanceof UncheckedBlock) {
if (gte(version, "0.5.0")) {
const ptChildren = pt.children;

for (let i = ptChildren.indexOf(node) - 1; i >= 0; i--) {
const sibling = ptChildren[i];

if (sibling instanceof VariableDeclarationStatement) {
return sibling;
}
Expand All @@ -135,6 +137,7 @@ function getContainingScope(node: ASTNode, version: string): ScopeNode | undefin
*/
function* lookupInSourceUnit(
name: string,
inference: InferType,
scope: SourceUnit,
visitedUnits: Set<SourceUnit>
): Iterable<AnyResolvable> {
Expand Down Expand Up @@ -170,7 +173,7 @@ function* lookupInSourceUnit(
} else if (child.vSymbolAliases.length === 0) {
// import "..."
// @todo maybe its better to go through child.vSourceUnit.vExportedSymbols here?
yield* lookupInScope(name, child.vSourceUnit, visitedUnits, false);
yield* lookupInScope(name, child.vSourceUnit, inference, visitedUnits, false);
} else {
// `import {<name>} from "..."` or `import {a as <name>} from "..."`
for (const [foreignDef, alias] of child.vSymbolAliases) {
Expand All @@ -182,13 +185,11 @@ function* lookupInSourceUnit(
if (foreignDef instanceof ImportDirective) {
symImportName = foreignDef.unitAlias;

if (symImportName === "") {
throw new Error(
`Unexpected ImportDirective foreign def with non-unit alias ${pp(
foreignDef
)}`
);
}
assert(
symImportName !== "",
"Unexpected ImportDirective foreign def with non-unit alias {0}",
foreignDef
);
} else {
symImportName = foreignDef.name;
}
Expand All @@ -208,6 +209,7 @@ function* lookupInSourceUnit(
*/
function* lookupInContractDefinition(
name: string,
inference: InferType,
scope: ContractDefinition,
ignoreVisiblity: boolean
): Iterable<AnyResolvable> {
Expand Down Expand Up @@ -239,22 +241,16 @@ function* lookupInContractDefinition(
continue;
}

let sigHash: string | undefined;

if (child instanceof FunctionDefinition) {
// Its a safe to assume V2 as its backward-compatible and
// we only use it internally here
sigHash = child.canonicalSignatureHash(ABIEncoderVersion.V2);
} else if (
child instanceof VariableDeclaration &&
child.visibility === StateVariableVisibility.Public
) {
// Its a safe to assume V2 as its backward-compatible and
// we only use it internally here
sigHash = child.getterCanonicalSignatureHash(ABIEncoderVersion.V2);
} else if (child instanceof EventDefinition) {
sigHash = child.canonicalSignatureHash(ABIEncoderVersion.V2);
}
/**
* Its a safe to assume V2 as its backward-compatible and we only use it internally here
*/
const sigHash =
child instanceof FunctionDefinition ||
child instanceof EventDefinition ||
(child instanceof VariableDeclaration &&
child.visibility === StateVariableVisibility.Public)
? inference.signatureHash(child, ABIEncoderVersion.V2)
: undefined;

if (sigHash !== undefined) {
if (overridenSigHashes.has(sigHash)) {
Expand Down Expand Up @@ -292,10 +288,11 @@ function* lookupInFunctionDefinition(
function* lookupInBlock(
name: string,
scope: Block | UncheckedBlock,
version: string
inference: InferType
): Iterable<AnyResolvable> {
let declarations: VariableDeclaration[];
if (version && lt(version, "0.5.0")) {

if (lt(inference.version, "0.5.0")) {
declarations = scope.getChildrenByType(VariableDeclaration);
} else {
declarations = scope.children
Expand Down Expand Up @@ -324,24 +321,24 @@ function* lookupInBlock(
function lookupInScope(
name: string,
scope: ScopeNode,
inference: InferType,
visitedUnits = new Set<SourceUnit>(),
ignoreVisiblity: boolean,
version = ""
ignoreVisiblity: boolean
): Set<AnyResolvable> {
let results: Iterable<AnyResolvable>;

if (scope instanceof SourceUnit) {
results = lookupInSourceUnit(name, scope, visitedUnits);
results = lookupInSourceUnit(name, inference, scope, visitedUnits);
} else if (scope instanceof ContractDefinition) {
results = lookupInContractDefinition(name, scope, ignoreVisiblity);
results = lookupInContractDefinition(name, inference, scope, ignoreVisiblity);
} else if (scope instanceof FunctionDefinition) {
results = lookupInFunctionDefinition(name, scope);
} else if (scope instanceof ModifierDefinition) {
results = scope.vParameters.vParameters.filter((parameter) => parameter.name === name);
} else if (scope instanceof VariableDeclarationStatement) {
results = scope.vDeclarations.filter((decl) => decl.name === name);
} else if (scope instanceof Block || scope instanceof UncheckedBlock) {
results = lookupInBlock(name, scope, version);
results = lookupInBlock(name, scope, inference);
} else if (scope instanceof TryCatchClause) {
results = scope.vParameters
? scope.vParameters.vParameters.filter((param) => param.name === name)
Expand Down Expand Up @@ -371,12 +368,14 @@ function lookupInScope(
export function resolveAny(
name: string,
ctx: ASTNode,
version: string,
inference: InferType,
inclusive = false,
ignoreVisiblity = false
): Set<AnyResolvable> {
let scope: ScopeNode | undefined =
inclusive && isScope(ctx, version) ? ctx : getContainingScope(ctx, version);
inclusive && isScope(ctx, inference.version)
? ctx
: getContainingScope(ctx, inference.version);

const elements = name.split(".");

Expand All @@ -389,29 +388,27 @@ export function resolveAny(
// If this is the first element (e.g. `A` in `A.B.C`), walk up the
// stack of scopes starting from the current context, looking for `A`
while (scope !== undefined) {
res = lookupInScope(element, scope, undefined, ignoreVisiblity, version);
res = lookupInScope(element, scope, inference, undefined, ignoreVisiblity);

if (res.size > 0) {
// Sanity check - when multiple results are found, they must either be overloaded events
// or overloaded functions/public state vars.
if (res.size > 1) {
if (
!forAll(
assert(
forAll(
res,
(def) =>
def instanceof EventDefinition ||
def instanceof FunctionDefinition ||
(def instanceof VariableDeclaration &&
def.stateVariable &&
def.visibility === StateVariableVisibility.Public)
)
) {
throw new Error(
`Unexpected intermediate def for ${element} in ${name}: ${[
...res
].map((n) => `${n.constructor.name}#${n.id}`)}`
);
}
),
"Unexpected intermediate def for {0} in {1}: {2}",
element,
name,
res
);
}

const first = [...res][0];
Expand All @@ -428,12 +425,12 @@ export function resolveAny(
}
}

scope = getContainingScope(scope, version);
scope = getContainingScope(scope, inference.version);
}
} else {
// If this is a later segment (e.g. `B` or `C` in `A.B.C`),
// then resolve it recursively in the current scope.
res = resolveAny(element, scope as ASTNode, version, true, ignoreVisiblity);
res = resolveAny(element, scope as ASTNode, inference, true, ignoreVisiblity);
}

// We didn't find anything - return empty set
Expand All @@ -449,29 +446,27 @@ export function resolveAny(
// We found multiple definitions for an intermediate segment of
// identifier path (e.g. multiple resolutions for `A` in `A.B`). This
// shouldn't happen.
if (res.size > 1) {
throw new Error(
`Ambigious path resolution for ${element} in ${name} in ctx ${pp(ctx)}: got ${[
...res
]
.map(pp)
.join(",")}`
);
}
assert(
res.size === 1,
"Ambigious path resolution for {0} in {1} in ctx {2}: got {3}",
element,
name,
ctx,
res
);

const resolvedNode = [...res][0];

// An intermediate segment in an identifier path (e.g. `A` in `A.B`) should always resolve to a
// single imported source unit or contract.
if (
!(resolvedNode instanceof ImportDirective || resolvedNode instanceof ContractDefinition)
) {
throw new Error(
`Unexpected non-scope node for ${element} in ${name} in ctx ${pp(ctx)}: got ${pp(
resolvedNode
)}`
);
}
assert(
resolvedNode instanceof ImportDirective || resolvedNode instanceof ContractDefinition,
"Unexpected non-scope node for {0} in {1} in ctx {2}: got {3}",
element,
name,
ctx,
resolvedNode
);

scope = resolvedNode instanceof ImportDirective ? resolvedNode.vSourceUnit : resolvedNode;
}
Expand Down
Loading