Skip to content

Commit

Permalink
Merge pull request #159 from ConsenSys/rework-deprecated-funcs
Browse files Browse the repository at this point in the history
Rework deprecated functionality
  • Loading branch information
blitz-1306 authored Nov 22, 2022
2 parents c4feb1a + 8d7bb0a commit 0acc69f
Show file tree
Hide file tree
Showing 40 changed files with 1,379 additions and 1,529 deletions.
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

0 comments on commit 0acc69f

Please sign in to comment.