diff --git a/package.json b/package.json index c926bf2c..c6659fe0 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "dev:examples": "tsx src/cli.ts build examples --output-awst --output-awst-json", "dev:approvals": "rimraf tests/approvals/out && tsx src/cli.ts build tests/approvals --dry-run", "dev:expected-output": "tsx src/cli.ts build tests/expected-output --dry-run", - "dev:testing": "tsx src/cli.ts build tests/approvals/avm11.algo.ts --output-awst --output-awst-json --output-ssa-ir --log-level=info --out-dir out/[name] --optimization-level=0", + "dev:testing": "tsx src/cli.ts build tests/approvals/state-totals.algo.ts --output-awst --output-awst-json --output-ssa-ir --log-level=info --out-dir out/[name] --optimization-level=0", "audit": "better-npm-audit audit", "format": "prettier --write .", "lint": "eslint \"src/**/*.ts\"", diff --git a/packages/algo-ts/src/base-contract.ts b/packages/algo-ts/src/base-contract.ts index f66a9780..64f6b93d 100644 --- a/packages/algo-ts/src/base-contract.ts +++ b/packages/algo-ts/src/base-contract.ts @@ -55,12 +55,12 @@ type ContractOptions = { * Allows defining what values should be used for global and local uint and bytes storage * values when creating a contract. Used when outputting ARC-32 application.json schemas. * - * If let unspecified, the totals will be determined by the compiler based on state + * If left unspecified, the totals will be determined by the compiler based on state * variables assigned to `this`. * * This setting is not inherited, and only applies to the exact `Contract` it is specified * on. If a base class does specify this setting, and a derived class does not, a warning - * will be emitted for the derived class. To resolve this warning, `state_totals` must be + * will be emitted for the derived class. To resolve this warning, `stateTotals` must be * specified. An empty object may be provided in order to indicate that this contract should * revert to the default behaviour */ diff --git a/src/awst_build/eb/contract-builder.ts b/src/awst_build/eb/contract-builder.ts index ea5bb191..953acff1 100644 --- a/src/awst_build/eb/contract-builder.ts +++ b/src/awst_build/eb/contract-builder.ts @@ -7,6 +7,7 @@ import { Constants } from '../../constants' import { CodeError } from '../../errors' import { codeInvariant, invariant } from '../../util' import type { AwstBuildContext } from '../context/awst-build-context' +import type { ContractOptionsDecoratorData } from '../models/decorator-data' import type { PType } from '../ptypes' import { arc4BaseContractType, @@ -23,7 +24,7 @@ import { instanceEb } from '../type-registry' import { BaseContractMethodExpressionBuilder, ContractMethodExpressionBuilder } from './free-subroutine-expression-builder' import type { NodeBuilder } from './index' import { DecoratorDataBuilder, FunctionBuilder, InstanceBuilder } from './index' -import { requireStringConstant } from './util' +import { requireIntegerConstant, requireStringConstant } from './util' import { parseFunctionArgs } from './util/arg-parsing' import { requireAvmVersion } from './util/avm-version' import { VoidExpressionBuilder } from './void-expression-builder' @@ -126,7 +127,7 @@ export class ContractOptionsDecoratorBuilder extends FunctionBuilder { readonly ptype = contractOptionsDecorator call(args: ReadonlyArray, typeArgs: ReadonlyArray, sourceLocation: SourceLocation): NodeBuilder { const { - args: [{ avmVersion, name }], + args: [{ avmVersion, name, stateTotals }], } = parseFunctionArgs({ args, typeArgs, @@ -145,9 +146,26 @@ export class ContractOptionsDecoratorBuilder extends FunctionBuilder { return new DecoratorDataBuilder(sourceLocation, { type: 'contract', - avmVersion: avmVersion ? requireAvmVersion(avmVersion) : undefined, - name: name ? requireStringConstant(name).value : undefined, + avmVersion: avmVersion && requireAvmVersion(avmVersion), + name: name && requireStringConstant(name).value, + stateTotals: stateTotals && buildStateTotals(stateTotals), sourceLocation, }) } } + +function buildStateTotals(builder: NodeBuilder): ContractOptionsDecoratorData['stateTotals'] { + function tryGetProp(name: string): bigint | undefined { + if (builder.hasProperty(name)) { + return requireIntegerConstant(builder.memberAccess(name, builder.sourceLocation)).value + } + return undefined + } + + return { + globalBytes: tryGetProp('globalBytes'), + globalUints: tryGetProp('globalUints'), + localBytes: tryGetProp('localBytes'), + localUints: tryGetProp('localUints'), + } +} diff --git a/src/awst_build/models/contract-class-model.ts b/src/awst_build/models/contract-class-model.ts index 3dca9a67..5b878a7c 100644 --- a/src/awst_build/models/contract-class-model.ts +++ b/src/awst_build/models/contract-class-model.ts @@ -49,14 +49,23 @@ export class ContractClassModel { this.options = props.options } + hasExplicitStateTotals() { + return this.options?.stateTotals !== undefined + } + buildContract(compilationSet: CompilationSet): awst.Contract { let approvalProgram: ContractMethod | null = this.approvalProgram let clearProgram: ContractMethod | null = this.clearProgram const methods: ContractMethod[] = [...this.methods, this.ctor] const methodResolutionOrder: ContractReference[] = [] + + let firstBaseWithStateTotals: ContractClassModel | undefined = undefined for (const baseType of this.type.allBases()) { const cref = ContractReference.fromPType(baseType) const baseClass = compilationSet.getContractClass(cref) + if (baseClass.hasExplicitStateTotals() && firstBaseWithStateTotals === undefined) { + firstBaseWithStateTotals = baseClass + } methodResolutionOrder.push(cref) approvalProgram ??= baseClass.approvalProgram clearProgram ??= baseClass.clearProgram @@ -91,13 +100,21 @@ export class ContractClassModel { codeInvariant(approvalProgram, 'must have approval') codeInvariant(clearProgram, 'must have clear') - // TODO: Tally from bases - const stateTotals = new StateTotals({ - globalBytes: this.options?.stateTotals?.globalBytes ?? null, - globalUints: this.options?.stateTotals?.globalUints ?? null, - localBytes: this.options?.stateTotals?.localBytes ?? null, - localUints: this.options?.stateTotals?.localUints ?? null, - }) + if (!this.hasExplicitStateTotals && firstBaseWithStateTotals) { + logger.warn( + this.options?.sourceLocation ?? this.sourceLocation, + `Contract extends base contract ${firstBaseWithStateTotals.id} with explicit stateTotals, but does not define its own stateTotals. This could result in insufficient reserved state at run time. An empty object may be provided in order to indicate that this contract should revert to the default behaviour`, + ) + } + + const stateTotals = this.options?.stateTotals + ? new StateTotals({ + globalBytes: this.options?.stateTotals?.globalBytes ?? null, + globalUints: this.options?.stateTotals?.globalUints ?? null, + localBytes: this.options?.stateTotals?.localBytes ?? null, + localUints: this.options?.stateTotals?.localUints ?? null, + }) + : null // TODO: Tally from bases const reservedScratchSpace = new Set() @@ -121,11 +138,11 @@ export class ContractClassModel { clearProgram, methodResolutionOrder, methods, - appState: this.appState, // TODO: Tally from base - stateTotals: stateTotals, // TODO: Tally + appState: this.appState, + stateTotals, reservedScratchSpace: reservedScratchSpace, sourceLocation: this.sourceLocation, - avmVersion: this.options?.avmVersion ?? null, // TODO: Allow this to be set with class decorator + avmVersion: this.options?.avmVersion ?? null, }) } diff --git a/tests/approvals/out/state-totals/BaseWithState.approval.teal b/tests/approvals/out/state-totals/BaseWithState.approval.teal new file mode 100644 index 00000000..561f511e --- /dev/null +++ b/tests/approvals/out/state-totals/BaseWithState.approval.teal @@ -0,0 +1,72 @@ +#pragma version 10 + +tests/approvals/state-totals.algo.ts::BaseWithState.approvalProgram: + intcblock 0 1 + txn ApplicationID + bnz main_after_if_else@2 + callsub constructor + +main_after_if_else@2: + callsub __puya_arc4_router__ + return + + +// tests/approvals/state-totals.algo.ts::BaseWithState.constructor() -> void: +constructor: + // tests/approvals/state-totals.algo.ts:4 + // export class BaseWithState extends Contract { + proto 0 0 + // tests/approvals/state-totals.algo.ts:5 + // oneGlobal = GlobalState({ initialValue: Uint64(1) }) + pushbytes "oneGlobal" + intc_1 // 1 + app_global_put + retsub + + +// tests/approvals/state-totals.algo.ts::BaseWithState.__puya_arc4_router__() -> uint64: +__puya_arc4_router__: + // tests/approvals/state-totals.algo.ts:4 + // export class BaseWithState extends Contract { + proto 0 1 + txn NumAppArgs + intc_0 // 0 + != + bz __puya_arc4_router___bare_routing@2 + b __puya_arc4_router___after_if_else@6 + +__puya_arc4_router___bare_routing@2: + // tests/approvals/state-totals.algo.ts:4 + // export class BaseWithState extends Contract { + txn OnCompletion + intc_0 // 0 + swap + match __puya_arc4_router_____algots__.defaultCreate@3 + b __puya_arc4_router___switch_case_default@4 + +__puya_arc4_router_____algots__.defaultCreate@3: + // tests/approvals/state-totals.algo.ts:4 + // export class BaseWithState extends Contract { + txn ApplicationID + intc_0 // 0 + == + assert // can only call when creating + callsub __algots__.defaultCreate + intc_1 // 1 + retsub + +__puya_arc4_router___switch_case_default@4: + +__puya_arc4_router___after_if_else@6: + // tests/approvals/state-totals.algo.ts:4 + // export class BaseWithState extends Contract { + intc_0 // 0 + retsub + + +// tests/approvals/state-totals.algo.ts::BaseWithState.__algots__.defaultCreate() -> void: +__algots__.defaultCreate: + // tests/approvals/state-totals.algo.ts:4 + // export class BaseWithState extends Contract { + proto 0 0 + retsub diff --git a/tests/approvals/out/state-totals/BaseWithState.arc32.json b/tests/approvals/out/state-totals/BaseWithState.arc32.json new file mode 100644 index 00000000..894c8ef8 --- /dev/null +++ b/tests/approvals/out/state-totals/BaseWithState.arc32.json @@ -0,0 +1,44 @@ +{ + "hints": {}, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6OkJhc2VXaXRoU3RhdGUuYXBwcm92YWxQcm9ncmFtOgogICAgaW50Y2Jsb2NrIDAgMQogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGJueiBtYWluX2FmdGVyX2lmX2Vsc2VAMgogICAgY2FsbHN1YiBjb25zdHJ1Y3RvcgoKbWFpbl9hZnRlcl9pZl9lbHNlQDI6CiAgICBjYWxsc3ViIF9fcHV5YV9hcmM0X3JvdXRlcl9fCiAgICByZXR1cm4KCgovLyB0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6OkJhc2VXaXRoU3RhdGUuY29uc3RydWN0b3IoKSAtPiB2b2lkOgpjb25zdHJ1Y3RvcjoKICAgIC8vIHRlc3RzL2FwcHJvdmFscy9zdGF0ZS10b3RhbHMuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQmFzZVdpdGhTdGF0ZSBleHRlbmRzIENvbnRyYWN0IHsKICAgIHByb3RvIDAgMAogICAgLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjUKICAgIC8vIG9uZUdsb2JhbCA9IEdsb2JhbFN0YXRlKHsgaW5pdGlhbFZhbHVlOiBVaW50NjQoMSkgfSkKICAgIHB1c2hieXRlcyAib25lR2xvYmFsIgogICAgaW50Y18xIC8vIDEKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6OkJhc2VXaXRoU3RhdGUuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBCYXNlV2l0aFN0YXRlIGV4dGVuZHMgQ29udHJhY3QgewogICAgcHJvdG8gMCAxCiAgICB0eG4gTnVtQXBwQXJncwogICAgaW50Y18wIC8vIDAKICAgICE9CiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAMgogICAgYiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDYKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0AyOgogICAgLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBCYXNlV2l0aFN0YXRlIGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuIE9uQ29tcGxldGlvbgogICAgaW50Y18wIC8vIDAKICAgIHN3YXAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX19fYWxnb3RzX18uZGVmYXVsdENyZWF0ZUAzCiAgICBiIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3N3aXRjaF9jYXNlX2RlZmF1bHRANAoKX19wdXlhX2FyYzRfcm91dGVyX19fX19hbGdvdHNfXy5kZWZhdWx0Q3JlYXRlQDM6CiAgICAvLyB0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEJhc2VXaXRoU3RhdGUgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgaW50Y18wIC8vIDAKICAgID09CiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIGNyZWF0aW5nCiAgICBjYWxsc3ViIF9fYWxnb3RzX18uZGVmYXVsdENyZWF0ZQogICAgaW50Y18xIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fc3dpdGNoX2Nhc2VfZGVmYXVsdEA0OgoKX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUA2OgogICAgLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBCYXNlV2l0aFN0YXRlIGV4dGVuZHMgQ29udHJhY3QgewogICAgaW50Y18wIC8vIDAKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FwcHJvdmFscy9zdGF0ZS10b3RhbHMuYWxnby50czo6QmFzZVdpdGhTdGF0ZS5fX2FsZ290c19fLmRlZmF1bHRDcmVhdGUoKSAtPiB2b2lkOgpfX2FsZ290c19fLmRlZmF1bHRDcmVhdGU6CiAgICAvLyB0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEJhc2VXaXRoU3RhdGUgZXh0ZW5kcyBDb250cmFjdCB7CiAgICBwcm90byAwIDAKICAgIHJldHN1Ygo=", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6OkJhc2VXaXRoU3RhdGUuY2xlYXJTdGF0ZVByb2dyYW06CiAgICBwdXNoaW50IDEgLy8gMQogICAgcmV0dXJuCg==" + }, + "state": { + "global": { + "num_byte_slices": 0, + "num_uints": 2 + }, + "local": { + "num_byte_slices": 0, + "num_uints": 0 + } + }, + "schema": { + "global": { + "declared": { + "oneGlobal": { + "type": "uint64", + "key": "oneGlobal" + }, + "twoGlobal": { + "type": "uint64", + "key": "twoGlobal" + } + }, + "reserved": {} + }, + "local": { + "declared": {}, + "reserved": {} + } + }, + "contract": { + "name": "BaseWithState", + "methods": [], + "networks": {} + }, + "bare_call_config": { + "no_op": "CREATE" + } +} \ No newline at end of file diff --git a/tests/approvals/out/state-totals/BaseWithState.arc56.json b/tests/approvals/out/state-totals/BaseWithState.arc56.json new file mode 100644 index 00000000..1d9a222b --- /dev/null +++ b/tests/approvals/out/state-totals/BaseWithState.arc56.json @@ -0,0 +1,72 @@ +{ + "name": "BaseWithState", + "structs": {}, + "methods": [], + "arcs": [ + 22, + 28 + ], + "networks": {}, + "state": { + "schema": { + "global": { + "ints": 2, + "bytes": 0 + }, + "local": { + "ints": 0, + "bytes": 0 + } + }, + "keys": { + "global": { + "oneGlobal": { + "keyType": "AVMString", + "valueType": "AVMUint64", + "key": "b25lR2xvYmFs" + }, + "twoGlobal": { + "keyType": "AVMString", + "valueType": "AVMUint64", + "key": "dHdvR2xvYmFs" + } + }, + "local": {}, + "box": {} + }, + "maps": { + "global": {}, + "local": {}, + "box": {} + } + }, + "bareActions": { + "create": [ + "NoOp" + ], + "call": [] + }, + "sourceInfo": { + "approval": { + "sourceInfo": [ + { + "pc": [ + 62 + ], + "errorMessage": "can only call when creating" + } + ], + "pcOffsetMethod": "none" + }, + "clear": { + "sourceInfo": [], + "pcOffsetMethod": "none" + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6OkJhc2VXaXRoU3RhdGUuYXBwcm92YWxQcm9ncmFtOgogICAgaW50Y2Jsb2NrIDAgMQogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGJueiBtYWluX2FmdGVyX2lmX2Vsc2VAMgogICAgY2FsbHN1YiBjb25zdHJ1Y3RvcgoKbWFpbl9hZnRlcl9pZl9lbHNlQDI6CiAgICBjYWxsc3ViIF9fcHV5YV9hcmM0X3JvdXRlcl9fCiAgICByZXR1cm4KCgovLyB0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6OkJhc2VXaXRoU3RhdGUuY29uc3RydWN0b3IoKSAtPiB2b2lkOgpjb25zdHJ1Y3RvcjoKICAgIC8vIHRlc3RzL2FwcHJvdmFscy9zdGF0ZS10b3RhbHMuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQmFzZVdpdGhTdGF0ZSBleHRlbmRzIENvbnRyYWN0IHsKICAgIHByb3RvIDAgMAogICAgLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjUKICAgIC8vIG9uZUdsb2JhbCA9IEdsb2JhbFN0YXRlKHsgaW5pdGlhbFZhbHVlOiBVaW50NjQoMSkgfSkKICAgIHB1c2hieXRlcyAib25lR2xvYmFsIgogICAgaW50Y18xIC8vIDEKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6OkJhc2VXaXRoU3RhdGUuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBCYXNlV2l0aFN0YXRlIGV4dGVuZHMgQ29udHJhY3QgewogICAgcHJvdG8gMCAxCiAgICB0eG4gTnVtQXBwQXJncwogICAgaW50Y18wIC8vIDAKICAgICE9CiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAMgogICAgYiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDYKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0AyOgogICAgLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBCYXNlV2l0aFN0YXRlIGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuIE9uQ29tcGxldGlvbgogICAgaW50Y18wIC8vIDAKICAgIHN3YXAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX19fYWxnb3RzX18uZGVmYXVsdENyZWF0ZUAzCiAgICBiIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3N3aXRjaF9jYXNlX2RlZmF1bHRANAoKX19wdXlhX2FyYzRfcm91dGVyX19fX19hbGdvdHNfXy5kZWZhdWx0Q3JlYXRlQDM6CiAgICAvLyB0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEJhc2VXaXRoU3RhdGUgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgaW50Y18wIC8vIDAKICAgID09CiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIGNyZWF0aW5nCiAgICBjYWxsc3ViIF9fYWxnb3RzX18uZGVmYXVsdENyZWF0ZQogICAgaW50Y18xIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fc3dpdGNoX2Nhc2VfZGVmYXVsdEA0OgoKX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUA2OgogICAgLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBCYXNlV2l0aFN0YXRlIGV4dGVuZHMgQ29udHJhY3QgewogICAgaW50Y18wIC8vIDAKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FwcHJvdmFscy9zdGF0ZS10b3RhbHMuYWxnby50czo6QmFzZVdpdGhTdGF0ZS5fX2FsZ290c19fLmRlZmF1bHRDcmVhdGUoKSAtPiB2b2lkOgpfX2FsZ290c19fLmRlZmF1bHRDcmVhdGU6CiAgICAvLyB0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEJhc2VXaXRoU3RhdGUgZXh0ZW5kcyBDb250cmFjdCB7CiAgICBwcm90byAwIDAKICAgIHJldHN1Ygo=", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6OkJhc2VXaXRoU3RhdGUuY2xlYXJTdGF0ZVByb2dyYW06CiAgICBwdXNoaW50IDEgLy8gMQogICAgcmV0dXJuCg==" + }, + "events": [], + "templateVariables": {} +} \ No newline at end of file diff --git a/tests/approvals/out/state-totals/BaseWithState.clear.teal b/tests/approvals/out/state-totals/BaseWithState.clear.teal new file mode 100644 index 00000000..7fd413dd --- /dev/null +++ b/tests/approvals/out/state-totals/BaseWithState.clear.teal @@ -0,0 +1,5 @@ +#pragma version 10 + +tests/approvals/state-totals.algo.ts::BaseWithState.clearStateProgram: + pushint 1 // 1 + return diff --git a/tests/approvals/out/state-totals/BaseWithState.ssa.ir b/tests/approvals/out/state-totals/BaseWithState.ssa.ir new file mode 100644 index 00000000..7f432413 --- /dev/null +++ b/tests/approvals/out/state-totals/BaseWithState.ssa.ir @@ -0,0 +1,49 @@ +contract tests/approvals/state-totals.algo.ts::BaseWithState: + program approval: + subroutine @algorandfoundation/algorand-typescript/arc4/index.d.ts::Contract.approvalProgram() -> bool: + block@0: // L1 + let reinterpret_bool%0#0: bool = (txn ApplicationID) + goto reinterpret_bool%0#0 ? block@2 : block@1 + block@1: // if_body_L1 + tests/approvals/state-totals.algo.ts::BaseWithState.constructor() + goto block@2 + block@2: // after_if_else_L1 + let tmp%0#0: bool = tests/approvals/state-totals.algo.ts::BaseWithState.__puya_arc4_router__() + return tmp%0#0 + + subroutine tests/approvals/state-totals.algo.ts::BaseWithState.constructor() -> void: + block@0: // L4 + (app_global_put "oneGlobal" 1u) + return + + subroutine tests/approvals/state-totals.algo.ts::BaseWithState.__puya_arc4_router__() -> bool: + block@0: // L4 + let tmp%0#0: uint64 = (txn NumAppArgs) + let tmp%1#0: bool = (!= tmp%0#0 0u) + goto tmp%1#0 ? block@1 : block@2 + block@1: // abi_routing_L4 + goto block@6 + block@2: // bare_routing_L4 + let tmp%2#0: uint64 = (txn OnCompletion) + switch tmp%2#0 {0u => block@3, * => block@4} + block@3: // __algots__.defaultCreate_L4 + let tmp%3#0: uint64 = (txn ApplicationID) + let tmp%4#0: bool = (== tmp%3#0 0u) + (assert tmp%4#0) // can only call when creating + tests/approvals/state-totals.algo.ts::BaseWithState.__algots__.defaultCreate() + return 1u + block@4: // switch_case_default_L4 + goto block@5 + block@5: // switch_case_next_L4 + goto block@6 + block@6: // after_if_else_L4 + return 0u + + subroutine tests/approvals/state-totals.algo.ts::BaseWithState.__algots__.defaultCreate() -> void: + block@0: // L4 + return + + program clear-state: + subroutine @algorandfoundation/algorand-typescript/base-contract.d.ts::BaseContract.clearStateProgram() -> bool: + block@0: // L1 + return 1u \ No newline at end of file diff --git a/tests/approvals/out/state-totals/ExtendsSubWithTotals.approval.teal b/tests/approvals/out/state-totals/ExtendsSubWithTotals.approval.teal new file mode 100644 index 00000000..3912cece --- /dev/null +++ b/tests/approvals/out/state-totals/ExtendsSubWithTotals.approval.teal @@ -0,0 +1,97 @@ +#pragma version 10 + +tests/approvals/state-totals.algo.ts::ExtendsSubWithTotals.approvalProgram: + intcblock 0 1 + txn ApplicationID + bnz main_after_if_else@2 + callsub constructor + +main_after_if_else@2: + callsub __puya_arc4_router__ + return + + +// tests/approvals/state-totals.algo.ts::ExtendsSubWithTotals.constructor() -> void: +constructor: + // tests/approvals/state-totals.algo.ts:16-17 + // @contract({ stateTotals: {} }) + // export class ExtendsSubWithTotals extends SubClassWithExplicitTotals { + proto 0 0 + callsub tests/approvals/state-totals.algo.ts::SubClassWithExplicitTotals.constructor + retsub + + +// tests/approvals/state-totals.algo.ts::SubClassWithExplicitTotals.constructor() -> void: +tests/approvals/state-totals.algo.ts::SubClassWithExplicitTotals.constructor: + // tests/approvals/state-totals.algo.ts:13-14 + // @contract({ stateTotals: { globalUints: 4, localUints: 0 } }) + // export class SubClassWithExplicitTotals extends BaseWithState {} + proto 0 0 + callsub tests/approvals/state-totals.algo.ts::BaseWithState.constructor + retsub + + +// tests/approvals/state-totals.algo.ts::BaseWithState.constructor() -> void: +tests/approvals/state-totals.algo.ts::BaseWithState.constructor: + // tests/approvals/state-totals.algo.ts:4 + // export class BaseWithState extends Contract { + proto 0 0 + // tests/approvals/state-totals.algo.ts:5 + // oneGlobal = GlobalState({ initialValue: Uint64(1) }) + pushbytes "oneGlobal" + intc_1 // 1 + app_global_put + retsub + + +// tests/approvals/state-totals.algo.ts::ExtendsSubWithTotals.__puya_arc4_router__() -> uint64: +__puya_arc4_router__: + // tests/approvals/state-totals.algo.ts:16-17 + // @contract({ stateTotals: {} }) + // export class ExtendsSubWithTotals extends SubClassWithExplicitTotals { + proto 0 1 + txn NumAppArgs + intc_0 // 0 + != + bz __puya_arc4_router___bare_routing@2 + b __puya_arc4_router___after_if_else@6 + +__puya_arc4_router___bare_routing@2: + // tests/approvals/state-totals.algo.ts:16-17 + // @contract({ stateTotals: {} }) + // export class ExtendsSubWithTotals extends SubClassWithExplicitTotals { + txn OnCompletion + intc_0 // 0 + swap + match __puya_arc4_router_____algots__.defaultCreate@3 + b __puya_arc4_router___switch_case_default@4 + +__puya_arc4_router_____algots__.defaultCreate@3: + // tests/approvals/state-totals.algo.ts:16-17 + // @contract({ stateTotals: {} }) + // export class ExtendsSubWithTotals extends SubClassWithExplicitTotals { + txn ApplicationID + intc_0 // 0 + == + assert // can only call when creating + callsub __algots__.defaultCreate + intc_1 // 1 + retsub + +__puya_arc4_router___switch_case_default@4: + +__puya_arc4_router___after_if_else@6: + // tests/approvals/state-totals.algo.ts:16-17 + // @contract({ stateTotals: {} }) + // export class ExtendsSubWithTotals extends SubClassWithExplicitTotals { + intc_0 // 0 + retsub + + +// tests/approvals/state-totals.algo.ts::ExtendsSubWithTotals.__algots__.defaultCreate() -> void: +__algots__.defaultCreate: + // tests/approvals/state-totals.algo.ts:16-17 + // @contract({ stateTotals: {} }) + // export class ExtendsSubWithTotals extends SubClassWithExplicitTotals { + proto 0 0 + retsub diff --git a/tests/approvals/out/state-totals/ExtendsSubWithTotals.arc32.json b/tests/approvals/out/state-totals/ExtendsSubWithTotals.arc32.json new file mode 100644 index 00000000..be362b6f --- /dev/null +++ b/tests/approvals/out/state-totals/ExtendsSubWithTotals.arc32.json @@ -0,0 +1,49 @@ +{ + "hints": {}, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6OkV4dGVuZHNTdWJXaXRoVG90YWxzLmFwcHJvdmFsUHJvZ3JhbToKICAgIGludGNibG9jayAwIDEKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBibnogbWFpbl9hZnRlcl9pZl9lbHNlQDIKICAgIGNhbGxzdWIgY29uc3RydWN0b3IKCm1haW5fYWZ0ZXJfaWZfZWxzZUAyOgogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjpFeHRlbmRzU3ViV2l0aFRvdGFscy5jb25zdHJ1Y3RvcigpIC0+IHZvaWQ6CmNvbnN0cnVjdG9yOgogICAgLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjE2LTE3CiAgICAvLyBAY29udHJhY3QoeyBzdGF0ZVRvdGFsczoge30gfSkKICAgIC8vIGV4cG9ydCBjbGFzcyBFeHRlbmRzU3ViV2l0aFRvdGFscyBleHRlbmRzIFN1YkNsYXNzV2l0aEV4cGxpY2l0VG90YWxzIHsKICAgIHByb3RvIDAgMAogICAgY2FsbHN1YiB0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6OlN1YkNsYXNzV2l0aEV4cGxpY2l0VG90YWxzLmNvbnN0cnVjdG9yCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6OlN1YkNsYXNzV2l0aEV4cGxpY2l0VG90YWxzLmNvbnN0cnVjdG9yKCkgLT4gdm9pZDoKdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjpTdWJDbGFzc1dpdGhFeHBsaWNpdFRvdGFscy5jb25zdHJ1Y3RvcjoKICAgIC8vIHRlc3RzL2FwcHJvdmFscy9zdGF0ZS10b3RhbHMuYWxnby50czoxMy0xNAogICAgLy8gQGNvbnRyYWN0KHsgc3RhdGVUb3RhbHM6IHsgZ2xvYmFsVWludHM6IDQsIGxvY2FsVWludHM6IDAgfSB9KQogICAgLy8gZXhwb3J0IGNsYXNzIFN1YkNsYXNzV2l0aEV4cGxpY2l0VG90YWxzIGV4dGVuZHMgQmFzZVdpdGhTdGF0ZSB7fQogICAgcHJvdG8gMCAwCiAgICBjYWxsc3ViIHRlc3RzL2FwcHJvdmFscy9zdGF0ZS10b3RhbHMuYWxnby50czo6QmFzZVdpdGhTdGF0ZS5jb25zdHJ1Y3RvcgogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjpCYXNlV2l0aFN0YXRlLmNvbnN0cnVjdG9yKCkgLT4gdm9pZDoKdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjpCYXNlV2l0aFN0YXRlLmNvbnN0cnVjdG9yOgogICAgLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBCYXNlV2l0aFN0YXRlIGV4dGVuZHMgQ29udHJhY3QgewogICAgcHJvdG8gMCAwCiAgICAvLyB0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6NQogICAgLy8gb25lR2xvYmFsID0gR2xvYmFsU3RhdGUoeyBpbml0aWFsVmFsdWU6IFVpbnQ2NCgxKSB9KQogICAgcHVzaGJ5dGVzICJvbmVHbG9iYWwiCiAgICBpbnRjXzEgLy8gMQogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FwcHJvdmFscy9zdGF0ZS10b3RhbHMuYWxnby50czo6RXh0ZW5kc1N1YldpdGhUb3RhbHMuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjE2LTE3CiAgICAvLyBAY29udHJhY3QoeyBzdGF0ZVRvdGFsczoge30gfSkKICAgIC8vIGV4cG9ydCBjbGFzcyBFeHRlbmRzU3ViV2l0aFRvdGFscyBleHRlbmRzIFN1YkNsYXNzV2l0aEV4cGxpY2l0VG90YWxzIHsKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGludGNfMCAvLyAwCiAgICAhPQogICAgYnogX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDIKICAgIGIgX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUA2CgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAMjoKICAgIC8vIHRlc3RzL2FwcHJvdmFscy9zdGF0ZS10b3RhbHMuYWxnby50czoxNi0xNwogICAgLy8gQGNvbnRyYWN0KHsgc3RhdGVUb3RhbHM6IHt9IH0pCiAgICAvLyBleHBvcnQgY2xhc3MgRXh0ZW5kc1N1YldpdGhUb3RhbHMgZXh0ZW5kcyBTdWJDbGFzc1dpdGhFeHBsaWNpdFRvdGFscyB7CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBpbnRjXzAgLy8gMAogICAgc3dhcAogICAgbWF0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fX19hbGdvdHNfXy5kZWZhdWx0Q3JlYXRlQDMKICAgIGIgX19wdXlhX2FyYzRfcm91dGVyX19fc3dpdGNoX2Nhc2VfZGVmYXVsdEA0CgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19fX2FsZ290c19fLmRlZmF1bHRDcmVhdGVAMzoKICAgIC8vIHRlc3RzL2FwcHJvdmFscy9zdGF0ZS10b3RhbHMuYWxnby50czoxNi0xNwogICAgLy8gQGNvbnRyYWN0KHsgc3RhdGVUb3RhbHM6IHt9IH0pCiAgICAvLyBleHBvcnQgY2xhc3MgRXh0ZW5kc1N1YldpdGhUb3RhbHMgZXh0ZW5kcyBTdWJDbGFzc1dpdGhFeHBsaWNpdFRvdGFscyB7CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgaW50Y18wIC8vIDAKICAgID09CiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIGNyZWF0aW5nCiAgICBjYWxsc3ViIF9fYWxnb3RzX18uZGVmYXVsdENyZWF0ZQogICAgaW50Y18xIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fc3dpdGNoX2Nhc2VfZGVmYXVsdEA0OgoKX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUA2OgogICAgLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjE2LTE3CiAgICAvLyBAY29udHJhY3QoeyBzdGF0ZVRvdGFsczoge30gfSkKICAgIC8vIGV4cG9ydCBjbGFzcyBFeHRlbmRzU3ViV2l0aFRvdGFscyBleHRlbmRzIFN1YkNsYXNzV2l0aEV4cGxpY2l0VG90YWxzIHsKICAgIGludGNfMCAvLyAwCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6OkV4dGVuZHNTdWJXaXRoVG90YWxzLl9fYWxnb3RzX18uZGVmYXVsdENyZWF0ZSgpIC0+IHZvaWQ6Cl9fYWxnb3RzX18uZGVmYXVsdENyZWF0ZToKICAgIC8vIHRlc3RzL2FwcHJvdmFscy9zdGF0ZS10b3RhbHMuYWxnby50czoxNi0xNwogICAgLy8gQGNvbnRyYWN0KHsgc3RhdGVUb3RhbHM6IHt9IH0pCiAgICAvLyBleHBvcnQgY2xhc3MgRXh0ZW5kc1N1YldpdGhUb3RhbHMgZXh0ZW5kcyBTdWJDbGFzc1dpdGhFeHBsaWNpdFRvdGFscyB7CiAgICBwcm90byAwIDAKICAgIHJldHN1Ygo=", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6OkV4dGVuZHNTdWJXaXRoVG90YWxzLmNsZWFyU3RhdGVQcm9ncmFtOgogICAgcHVzaGludCAxIC8vIDEKICAgIHJldHVybgo=" + }, + "state": { + "global": { + "num_byte_slices": 0, + "num_uints": 2 + }, + "local": { + "num_byte_slices": 0, + "num_uints": 1 + } + }, + "schema": { + "global": { + "declared": { + "oneGlobal": { + "type": "uint64", + "key": "oneGlobal" + }, + "twoGlobal": { + "type": "uint64", + "key": "twoGlobal" + } + }, + "reserved": {} + }, + "local": { + "declared": { + "oneLocal": { + "type": "uint64", + "key": "oneLocal" + } + }, + "reserved": {} + } + }, + "contract": { + "name": "ExtendsSubWithTotals", + "methods": [], + "networks": {} + }, + "bare_call_config": { + "no_op": "CREATE" + } +} \ No newline at end of file diff --git a/tests/approvals/out/state-totals/ExtendsSubWithTotals.arc56.json b/tests/approvals/out/state-totals/ExtendsSubWithTotals.arc56.json new file mode 100644 index 00000000..d0207dca --- /dev/null +++ b/tests/approvals/out/state-totals/ExtendsSubWithTotals.arc56.json @@ -0,0 +1,78 @@ +{ + "name": "ExtendsSubWithTotals", + "structs": {}, + "methods": [], + "arcs": [ + 22, + 28 + ], + "networks": {}, + "state": { + "schema": { + "global": { + "ints": 2, + "bytes": 0 + }, + "local": { + "ints": 1, + "bytes": 0 + } + }, + "keys": { + "global": { + "oneGlobal": { + "keyType": "AVMString", + "valueType": "AVMUint64", + "key": "b25lR2xvYmFs" + }, + "twoGlobal": { + "keyType": "AVMString", + "valueType": "AVMUint64", + "key": "dHdvR2xvYmFs" + } + }, + "local": { + "oneLocal": { + "keyType": "AVMString", + "valueType": "AVMUint64", + "key": "b25lTG9jYWw=" + } + }, + "box": {} + }, + "maps": { + "global": {}, + "local": {}, + "box": {} + } + }, + "bareActions": { + "create": [ + "NoOp" + ], + "call": [] + }, + "sourceInfo": { + "approval": { + "sourceInfo": [ + { + "pc": [ + 76 + ], + "errorMessage": "can only call when creating" + } + ], + "pcOffsetMethod": "none" + }, + "clear": { + "sourceInfo": [], + "pcOffsetMethod": "none" + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6OkV4dGVuZHNTdWJXaXRoVG90YWxzLmFwcHJvdmFsUHJvZ3JhbToKICAgIGludGNibG9jayAwIDEKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBibnogbWFpbl9hZnRlcl9pZl9lbHNlQDIKICAgIGNhbGxzdWIgY29uc3RydWN0b3IKCm1haW5fYWZ0ZXJfaWZfZWxzZUAyOgogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjpFeHRlbmRzU3ViV2l0aFRvdGFscy5jb25zdHJ1Y3RvcigpIC0+IHZvaWQ6CmNvbnN0cnVjdG9yOgogICAgLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjE2LTE3CiAgICAvLyBAY29udHJhY3QoeyBzdGF0ZVRvdGFsczoge30gfSkKICAgIC8vIGV4cG9ydCBjbGFzcyBFeHRlbmRzU3ViV2l0aFRvdGFscyBleHRlbmRzIFN1YkNsYXNzV2l0aEV4cGxpY2l0VG90YWxzIHsKICAgIHByb3RvIDAgMAogICAgY2FsbHN1YiB0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6OlN1YkNsYXNzV2l0aEV4cGxpY2l0VG90YWxzLmNvbnN0cnVjdG9yCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6OlN1YkNsYXNzV2l0aEV4cGxpY2l0VG90YWxzLmNvbnN0cnVjdG9yKCkgLT4gdm9pZDoKdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjpTdWJDbGFzc1dpdGhFeHBsaWNpdFRvdGFscy5jb25zdHJ1Y3RvcjoKICAgIC8vIHRlc3RzL2FwcHJvdmFscy9zdGF0ZS10b3RhbHMuYWxnby50czoxMy0xNAogICAgLy8gQGNvbnRyYWN0KHsgc3RhdGVUb3RhbHM6IHsgZ2xvYmFsVWludHM6IDQsIGxvY2FsVWludHM6IDAgfSB9KQogICAgLy8gZXhwb3J0IGNsYXNzIFN1YkNsYXNzV2l0aEV4cGxpY2l0VG90YWxzIGV4dGVuZHMgQmFzZVdpdGhTdGF0ZSB7fQogICAgcHJvdG8gMCAwCiAgICBjYWxsc3ViIHRlc3RzL2FwcHJvdmFscy9zdGF0ZS10b3RhbHMuYWxnby50czo6QmFzZVdpdGhTdGF0ZS5jb25zdHJ1Y3RvcgogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjpCYXNlV2l0aFN0YXRlLmNvbnN0cnVjdG9yKCkgLT4gdm9pZDoKdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjpCYXNlV2l0aFN0YXRlLmNvbnN0cnVjdG9yOgogICAgLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBCYXNlV2l0aFN0YXRlIGV4dGVuZHMgQ29udHJhY3QgewogICAgcHJvdG8gMCAwCiAgICAvLyB0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6NQogICAgLy8gb25lR2xvYmFsID0gR2xvYmFsU3RhdGUoeyBpbml0aWFsVmFsdWU6IFVpbnQ2NCgxKSB9KQogICAgcHVzaGJ5dGVzICJvbmVHbG9iYWwiCiAgICBpbnRjXzEgLy8gMQogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FwcHJvdmFscy9zdGF0ZS10b3RhbHMuYWxnby50czo6RXh0ZW5kc1N1YldpdGhUb3RhbHMuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjE2LTE3CiAgICAvLyBAY29udHJhY3QoeyBzdGF0ZVRvdGFsczoge30gfSkKICAgIC8vIGV4cG9ydCBjbGFzcyBFeHRlbmRzU3ViV2l0aFRvdGFscyBleHRlbmRzIFN1YkNsYXNzV2l0aEV4cGxpY2l0VG90YWxzIHsKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGludGNfMCAvLyAwCiAgICAhPQogICAgYnogX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDIKICAgIGIgX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUA2CgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAMjoKICAgIC8vIHRlc3RzL2FwcHJvdmFscy9zdGF0ZS10b3RhbHMuYWxnby50czoxNi0xNwogICAgLy8gQGNvbnRyYWN0KHsgc3RhdGVUb3RhbHM6IHt9IH0pCiAgICAvLyBleHBvcnQgY2xhc3MgRXh0ZW5kc1N1YldpdGhUb3RhbHMgZXh0ZW5kcyBTdWJDbGFzc1dpdGhFeHBsaWNpdFRvdGFscyB7CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBpbnRjXzAgLy8gMAogICAgc3dhcAogICAgbWF0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fX19hbGdvdHNfXy5kZWZhdWx0Q3JlYXRlQDMKICAgIGIgX19wdXlhX2FyYzRfcm91dGVyX19fc3dpdGNoX2Nhc2VfZGVmYXVsdEA0CgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19fX2FsZ290c19fLmRlZmF1bHRDcmVhdGVAMzoKICAgIC8vIHRlc3RzL2FwcHJvdmFscy9zdGF0ZS10b3RhbHMuYWxnby50czoxNi0xNwogICAgLy8gQGNvbnRyYWN0KHsgc3RhdGVUb3RhbHM6IHt9IH0pCiAgICAvLyBleHBvcnQgY2xhc3MgRXh0ZW5kc1N1YldpdGhUb3RhbHMgZXh0ZW5kcyBTdWJDbGFzc1dpdGhFeHBsaWNpdFRvdGFscyB7CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgaW50Y18wIC8vIDAKICAgID09CiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIGNyZWF0aW5nCiAgICBjYWxsc3ViIF9fYWxnb3RzX18uZGVmYXVsdENyZWF0ZQogICAgaW50Y18xIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fc3dpdGNoX2Nhc2VfZGVmYXVsdEA0OgoKX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUA2OgogICAgLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjE2LTE3CiAgICAvLyBAY29udHJhY3QoeyBzdGF0ZVRvdGFsczoge30gfSkKICAgIC8vIGV4cG9ydCBjbGFzcyBFeHRlbmRzU3ViV2l0aFRvdGFscyBleHRlbmRzIFN1YkNsYXNzV2l0aEV4cGxpY2l0VG90YWxzIHsKICAgIGludGNfMCAvLyAwCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6OkV4dGVuZHNTdWJXaXRoVG90YWxzLl9fYWxnb3RzX18uZGVmYXVsdENyZWF0ZSgpIC0+IHZvaWQ6Cl9fYWxnb3RzX18uZGVmYXVsdENyZWF0ZToKICAgIC8vIHRlc3RzL2FwcHJvdmFscy9zdGF0ZS10b3RhbHMuYWxnby50czoxNi0xNwogICAgLy8gQGNvbnRyYWN0KHsgc3RhdGVUb3RhbHM6IHt9IH0pCiAgICAvLyBleHBvcnQgY2xhc3MgRXh0ZW5kc1N1YldpdGhUb3RhbHMgZXh0ZW5kcyBTdWJDbGFzc1dpdGhFeHBsaWNpdFRvdGFscyB7CiAgICBwcm90byAwIDAKICAgIHJldHN1Ygo=", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6OkV4dGVuZHNTdWJXaXRoVG90YWxzLmNsZWFyU3RhdGVQcm9ncmFtOgogICAgcHVzaGludCAxIC8vIDEKICAgIHJldHVybgo=" + }, + "events": [], + "templateVariables": {} +} \ No newline at end of file diff --git a/tests/approvals/out/state-totals/ExtendsSubWithTotals.clear.teal b/tests/approvals/out/state-totals/ExtendsSubWithTotals.clear.teal new file mode 100644 index 00000000..92df2d7c --- /dev/null +++ b/tests/approvals/out/state-totals/ExtendsSubWithTotals.clear.teal @@ -0,0 +1,5 @@ +#pragma version 10 + +tests/approvals/state-totals.algo.ts::ExtendsSubWithTotals.clearStateProgram: + pushint 1 // 1 + return diff --git a/tests/approvals/out/state-totals/ExtendsSubWithTotals.ssa.ir b/tests/approvals/out/state-totals/ExtendsSubWithTotals.ssa.ir new file mode 100644 index 00000000..049a54fe --- /dev/null +++ b/tests/approvals/out/state-totals/ExtendsSubWithTotals.ssa.ir @@ -0,0 +1,59 @@ +contract tests/approvals/state-totals.algo.ts::ExtendsSubWithTotals: + program approval: + subroutine @algorandfoundation/algorand-typescript/arc4/index.d.ts::Contract.approvalProgram() -> bool: + block@0: // L1 + let reinterpret_bool%0#0: bool = (txn ApplicationID) + goto reinterpret_bool%0#0 ? block@2 : block@1 + block@1: // if_body_L1 + tests/approvals/state-totals.algo.ts::ExtendsSubWithTotals.constructor() + goto block@2 + block@2: // after_if_else_L1 + let tmp%0#0: bool = tests/approvals/state-totals.algo.ts::ExtendsSubWithTotals.__puya_arc4_router__() + return tmp%0#0 + + subroutine tests/approvals/state-totals.algo.ts::ExtendsSubWithTotals.constructor() -> void: + block@0: // L16 + tests/approvals/state-totals.algo.ts::SubClassWithExplicitTotals.constructor() + return + + subroutine tests/approvals/state-totals.algo.ts::SubClassWithExplicitTotals.constructor() -> void: + block@0: // L13 + tests/approvals/state-totals.algo.ts::BaseWithState.constructor() + return + + subroutine tests/approvals/state-totals.algo.ts::BaseWithState.constructor() -> void: + block@0: // L4 + (app_global_put "oneGlobal" 1u) + return + + subroutine tests/approvals/state-totals.algo.ts::ExtendsSubWithTotals.__puya_arc4_router__() -> bool: + block@0: // L16 + let tmp%0#0: uint64 = (txn NumAppArgs) + let tmp%1#0: bool = (!= tmp%0#0 0u) + goto tmp%1#0 ? block@1 : block@2 + block@1: // abi_routing_L16 + goto block@6 + block@2: // bare_routing_L16 + let tmp%2#0: uint64 = (txn OnCompletion) + switch tmp%2#0 {0u => block@3, * => block@4} + block@3: // __algots__.defaultCreate_L16 + let tmp%3#0: uint64 = (txn ApplicationID) + let tmp%4#0: bool = (== tmp%3#0 0u) + (assert tmp%4#0) // can only call when creating + tests/approvals/state-totals.algo.ts::ExtendsSubWithTotals.__algots__.defaultCreate() + return 1u + block@4: // switch_case_default_L16 + goto block@5 + block@5: // switch_case_next_L16 + goto block@6 + block@6: // after_if_else_L16 + return 0u + + subroutine tests/approvals/state-totals.algo.ts::ExtendsSubWithTotals.__algots__.defaultCreate() -> void: + block@0: // L16 + return + + program clear-state: + subroutine @algorandfoundation/algorand-typescript/base-contract.d.ts::BaseContract.clearStateProgram() -> bool: + block@0: // L1 + return 1u \ No newline at end of file diff --git a/tests/approvals/out/state-totals/SubClassWithExplicitTotals.approval.teal b/tests/approvals/out/state-totals/SubClassWithExplicitTotals.approval.teal new file mode 100644 index 00000000..6971104b --- /dev/null +++ b/tests/approvals/out/state-totals/SubClassWithExplicitTotals.approval.teal @@ -0,0 +1,87 @@ +#pragma version 10 + +tests/approvals/state-totals.algo.ts::SubClassWithExplicitTotals.approvalProgram: + intcblock 0 1 + txn ApplicationID + bnz main_after_if_else@2 + callsub constructor + +main_after_if_else@2: + callsub __puya_arc4_router__ + return + + +// tests/approvals/state-totals.algo.ts::SubClassWithExplicitTotals.constructor() -> void: +constructor: + // tests/approvals/state-totals.algo.ts:13-14 + // @contract({ stateTotals: { globalUints: 4, localUints: 0 } }) + // export class SubClassWithExplicitTotals extends BaseWithState {} + proto 0 0 + callsub tests/approvals/state-totals.algo.ts::BaseWithState.constructor + retsub + + +// tests/approvals/state-totals.algo.ts::BaseWithState.constructor() -> void: +tests/approvals/state-totals.algo.ts::BaseWithState.constructor: + // tests/approvals/state-totals.algo.ts:4 + // export class BaseWithState extends Contract { + proto 0 0 + // tests/approvals/state-totals.algo.ts:5 + // oneGlobal = GlobalState({ initialValue: Uint64(1) }) + pushbytes "oneGlobal" + intc_1 // 1 + app_global_put + retsub + + +// tests/approvals/state-totals.algo.ts::SubClassWithExplicitTotals.__puya_arc4_router__() -> uint64: +__puya_arc4_router__: + // tests/approvals/state-totals.algo.ts:13-14 + // @contract({ stateTotals: { globalUints: 4, localUints: 0 } }) + // export class SubClassWithExplicitTotals extends BaseWithState {} + proto 0 1 + txn NumAppArgs + intc_0 // 0 + != + bz __puya_arc4_router___bare_routing@2 + b __puya_arc4_router___after_if_else@6 + +__puya_arc4_router___bare_routing@2: + // tests/approvals/state-totals.algo.ts:13-14 + // @contract({ stateTotals: { globalUints: 4, localUints: 0 } }) + // export class SubClassWithExplicitTotals extends BaseWithState {} + txn OnCompletion + intc_0 // 0 + swap + match __puya_arc4_router_____algots__.defaultCreate@3 + b __puya_arc4_router___switch_case_default@4 + +__puya_arc4_router_____algots__.defaultCreate@3: + // tests/approvals/state-totals.algo.ts:13-14 + // @contract({ stateTotals: { globalUints: 4, localUints: 0 } }) + // export class SubClassWithExplicitTotals extends BaseWithState {} + txn ApplicationID + intc_0 // 0 + == + assert // can only call when creating + callsub __algots__.defaultCreate + intc_1 // 1 + retsub + +__puya_arc4_router___switch_case_default@4: + +__puya_arc4_router___after_if_else@6: + // tests/approvals/state-totals.algo.ts:13-14 + // @contract({ stateTotals: { globalUints: 4, localUints: 0 } }) + // export class SubClassWithExplicitTotals extends BaseWithState {} + intc_0 // 0 + retsub + + +// tests/approvals/state-totals.algo.ts::SubClassWithExplicitTotals.__algots__.defaultCreate() -> void: +__algots__.defaultCreate: + // tests/approvals/state-totals.algo.ts:13-14 + // @contract({ stateTotals: { globalUints: 4, localUints: 0 } }) + // export class SubClassWithExplicitTotals extends BaseWithState {} + proto 0 0 + retsub diff --git a/tests/approvals/out/state-totals/SubClassWithExplicitTotals.arc32.json b/tests/approvals/out/state-totals/SubClassWithExplicitTotals.arc32.json new file mode 100644 index 00000000..fa32776e --- /dev/null +++ b/tests/approvals/out/state-totals/SubClassWithExplicitTotals.arc32.json @@ -0,0 +1,44 @@ +{ + "hints": {}, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6OlN1YkNsYXNzV2l0aEV4cGxpY2l0VG90YWxzLmFwcHJvdmFsUHJvZ3JhbToKICAgIGludGNibG9jayAwIDEKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBibnogbWFpbl9hZnRlcl9pZl9lbHNlQDIKICAgIGNhbGxzdWIgY29uc3RydWN0b3IKCm1haW5fYWZ0ZXJfaWZfZWxzZUAyOgogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjpTdWJDbGFzc1dpdGhFeHBsaWNpdFRvdGFscy5jb25zdHJ1Y3RvcigpIC0+IHZvaWQ6CmNvbnN0cnVjdG9yOgogICAgLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjEzLTE0CiAgICAvLyBAY29udHJhY3QoeyBzdGF0ZVRvdGFsczogeyBnbG9iYWxVaW50czogNCwgbG9jYWxVaW50czogMCB9IH0pCiAgICAvLyBleHBvcnQgY2xhc3MgU3ViQ2xhc3NXaXRoRXhwbGljaXRUb3RhbHMgZXh0ZW5kcyBCYXNlV2l0aFN0YXRlIHt9CiAgICBwcm90byAwIDAKICAgIGNhbGxzdWIgdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjpCYXNlV2l0aFN0YXRlLmNvbnN0cnVjdG9yCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6OkJhc2VXaXRoU3RhdGUuY29uc3RydWN0b3IoKSAtPiB2b2lkOgp0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6OkJhc2VXaXRoU3RhdGUuY29uc3RydWN0b3I6CiAgICAvLyB0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEJhc2VXaXRoU3RhdGUgZXh0ZW5kcyBDb250cmFjdCB7CiAgICBwcm90byAwIDAKICAgIC8vIHRlc3RzL2FwcHJvdmFscy9zdGF0ZS10b3RhbHMuYWxnby50czo1CiAgICAvLyBvbmVHbG9iYWwgPSBHbG9iYWxTdGF0ZSh7IGluaXRpYWxWYWx1ZTogVWludDY0KDEpIH0pCiAgICBwdXNoYnl0ZXMgIm9uZUdsb2JhbCIKICAgIGludGNfMSAvLyAxCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjpTdWJDbGFzc1dpdGhFeHBsaWNpdFRvdGFscy5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICAvLyB0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6MTMtMTQKICAgIC8vIEBjb250cmFjdCh7IHN0YXRlVG90YWxzOiB7IGdsb2JhbFVpbnRzOiA0LCBsb2NhbFVpbnRzOiAwIH0gfSkKICAgIC8vIGV4cG9ydCBjbGFzcyBTdWJDbGFzc1dpdGhFeHBsaWNpdFRvdGFscyBleHRlbmRzIEJhc2VXaXRoU3RhdGUge30KICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGludGNfMCAvLyAwCiAgICAhPQogICAgYnogX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDIKICAgIGIgX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUA2CgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAMjoKICAgIC8vIHRlc3RzL2FwcHJvdmFscy9zdGF0ZS10b3RhbHMuYWxnby50czoxMy0xNAogICAgLy8gQGNvbnRyYWN0KHsgc3RhdGVUb3RhbHM6IHsgZ2xvYmFsVWludHM6IDQsIGxvY2FsVWludHM6IDAgfSB9KQogICAgLy8gZXhwb3J0IGNsYXNzIFN1YkNsYXNzV2l0aEV4cGxpY2l0VG90YWxzIGV4dGVuZHMgQmFzZVdpdGhTdGF0ZSB7fQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgaW50Y18wIC8vIDAKICAgIHN3YXAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX19fYWxnb3RzX18uZGVmYXVsdENyZWF0ZUAzCiAgICBiIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3N3aXRjaF9jYXNlX2RlZmF1bHRANAoKX19wdXlhX2FyYzRfcm91dGVyX19fX19hbGdvdHNfXy5kZWZhdWx0Q3JlYXRlQDM6CiAgICAvLyB0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6MTMtMTQKICAgIC8vIEBjb250cmFjdCh7IHN0YXRlVG90YWxzOiB7IGdsb2JhbFVpbnRzOiA0LCBsb2NhbFVpbnRzOiAwIH0gfSkKICAgIC8vIGV4cG9ydCBjbGFzcyBTdWJDbGFzc1dpdGhFeHBsaWNpdFRvdGFscyBleHRlbmRzIEJhc2VXaXRoU3RhdGUge30KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBpbnRjXzAgLy8gMAogICAgPT0KICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gY3JlYXRpbmcKICAgIGNhbGxzdWIgX19hbGdvdHNfXy5kZWZhdWx0Q3JlYXRlCiAgICBpbnRjXzEgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19zd2l0Y2hfY2FzZV9kZWZhdWx0QDQ6CgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDY6CiAgICAvLyB0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6MTMtMTQKICAgIC8vIEBjb250cmFjdCh7IHN0YXRlVG90YWxzOiB7IGdsb2JhbFVpbnRzOiA0LCBsb2NhbFVpbnRzOiAwIH0gfSkKICAgIC8vIGV4cG9ydCBjbGFzcyBTdWJDbGFzc1dpdGhFeHBsaWNpdFRvdGFscyBleHRlbmRzIEJhc2VXaXRoU3RhdGUge30KICAgIGludGNfMCAvLyAwCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6OlN1YkNsYXNzV2l0aEV4cGxpY2l0VG90YWxzLl9fYWxnb3RzX18uZGVmYXVsdENyZWF0ZSgpIC0+IHZvaWQ6Cl9fYWxnb3RzX18uZGVmYXVsdENyZWF0ZToKICAgIC8vIHRlc3RzL2FwcHJvdmFscy9zdGF0ZS10b3RhbHMuYWxnby50czoxMy0xNAogICAgLy8gQGNvbnRyYWN0KHsgc3RhdGVUb3RhbHM6IHsgZ2xvYmFsVWludHM6IDQsIGxvY2FsVWludHM6IDAgfSB9KQogICAgLy8gZXhwb3J0IGNsYXNzIFN1YkNsYXNzV2l0aEV4cGxpY2l0VG90YWxzIGV4dGVuZHMgQmFzZVdpdGhTdGF0ZSB7fQogICAgcHJvdG8gMCAwCiAgICByZXRzdWIK", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6OlN1YkNsYXNzV2l0aEV4cGxpY2l0VG90YWxzLmNsZWFyU3RhdGVQcm9ncmFtOgogICAgcHVzaGludCAxIC8vIDEKICAgIHJldHVybgo=" + }, + "state": { + "global": { + "num_byte_slices": 0, + "num_uints": 4 + }, + "local": { + "num_byte_slices": 0, + "num_uints": 0 + } + }, + "schema": { + "global": { + "declared": { + "oneGlobal": { + "type": "uint64", + "key": "oneGlobal" + }, + "twoGlobal": { + "type": "uint64", + "key": "twoGlobal" + } + }, + "reserved": {} + }, + "local": { + "declared": {}, + "reserved": {} + } + }, + "contract": { + "name": "SubClassWithExplicitTotals", + "methods": [], + "networks": {} + }, + "bare_call_config": { + "no_op": "CREATE" + } +} \ No newline at end of file diff --git a/tests/approvals/out/state-totals/SubClassWithExplicitTotals.arc56.json b/tests/approvals/out/state-totals/SubClassWithExplicitTotals.arc56.json new file mode 100644 index 00000000..4d81deca --- /dev/null +++ b/tests/approvals/out/state-totals/SubClassWithExplicitTotals.arc56.json @@ -0,0 +1,72 @@ +{ + "name": "SubClassWithExplicitTotals", + "structs": {}, + "methods": [], + "arcs": [ + 22, + 28 + ], + "networks": {}, + "state": { + "schema": { + "global": { + "ints": 4, + "bytes": 0 + }, + "local": { + "ints": 0, + "bytes": 0 + } + }, + "keys": { + "global": { + "oneGlobal": { + "keyType": "AVMString", + "valueType": "AVMUint64", + "key": "b25lR2xvYmFs" + }, + "twoGlobal": { + "keyType": "AVMString", + "valueType": "AVMUint64", + "key": "dHdvR2xvYmFs" + } + }, + "local": {}, + "box": {} + }, + "maps": { + "global": {}, + "local": {}, + "box": {} + } + }, + "bareActions": { + "create": [ + "NoOp" + ], + "call": [] + }, + "sourceInfo": { + "approval": { + "sourceInfo": [ + { + "pc": [ + 69 + ], + "errorMessage": "can only call when creating" + } + ], + "pcOffsetMethod": "none" + }, + "clear": { + "sourceInfo": [], + "pcOffsetMethod": "none" + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6OlN1YkNsYXNzV2l0aEV4cGxpY2l0VG90YWxzLmFwcHJvdmFsUHJvZ3JhbToKICAgIGludGNibG9jayAwIDEKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBibnogbWFpbl9hZnRlcl9pZl9lbHNlQDIKICAgIGNhbGxzdWIgY29uc3RydWN0b3IKCm1haW5fYWZ0ZXJfaWZfZWxzZUAyOgogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjpTdWJDbGFzc1dpdGhFeHBsaWNpdFRvdGFscy5jb25zdHJ1Y3RvcigpIC0+IHZvaWQ6CmNvbnN0cnVjdG9yOgogICAgLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjEzLTE0CiAgICAvLyBAY29udHJhY3QoeyBzdGF0ZVRvdGFsczogeyBnbG9iYWxVaW50czogNCwgbG9jYWxVaW50czogMCB9IH0pCiAgICAvLyBleHBvcnQgY2xhc3MgU3ViQ2xhc3NXaXRoRXhwbGljaXRUb3RhbHMgZXh0ZW5kcyBCYXNlV2l0aFN0YXRlIHt9CiAgICBwcm90byAwIDAKICAgIGNhbGxzdWIgdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjpCYXNlV2l0aFN0YXRlLmNvbnN0cnVjdG9yCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6OkJhc2VXaXRoU3RhdGUuY29uc3RydWN0b3IoKSAtPiB2b2lkOgp0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6OkJhc2VXaXRoU3RhdGUuY29uc3RydWN0b3I6CiAgICAvLyB0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEJhc2VXaXRoU3RhdGUgZXh0ZW5kcyBDb250cmFjdCB7CiAgICBwcm90byAwIDAKICAgIC8vIHRlc3RzL2FwcHJvdmFscy9zdGF0ZS10b3RhbHMuYWxnby50czo1CiAgICAvLyBvbmVHbG9iYWwgPSBHbG9iYWxTdGF0ZSh7IGluaXRpYWxWYWx1ZTogVWludDY0KDEpIH0pCiAgICBwdXNoYnl0ZXMgIm9uZUdsb2JhbCIKICAgIGludGNfMSAvLyAxCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjpTdWJDbGFzc1dpdGhFeHBsaWNpdFRvdGFscy5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICAvLyB0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6MTMtMTQKICAgIC8vIEBjb250cmFjdCh7IHN0YXRlVG90YWxzOiB7IGdsb2JhbFVpbnRzOiA0LCBsb2NhbFVpbnRzOiAwIH0gfSkKICAgIC8vIGV4cG9ydCBjbGFzcyBTdWJDbGFzc1dpdGhFeHBsaWNpdFRvdGFscyBleHRlbmRzIEJhc2VXaXRoU3RhdGUge30KICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGludGNfMCAvLyAwCiAgICAhPQogICAgYnogX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDIKICAgIGIgX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUA2CgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAMjoKICAgIC8vIHRlc3RzL2FwcHJvdmFscy9zdGF0ZS10b3RhbHMuYWxnby50czoxMy0xNAogICAgLy8gQGNvbnRyYWN0KHsgc3RhdGVUb3RhbHM6IHsgZ2xvYmFsVWludHM6IDQsIGxvY2FsVWludHM6IDAgfSB9KQogICAgLy8gZXhwb3J0IGNsYXNzIFN1YkNsYXNzV2l0aEV4cGxpY2l0VG90YWxzIGV4dGVuZHMgQmFzZVdpdGhTdGF0ZSB7fQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgaW50Y18wIC8vIDAKICAgIHN3YXAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX19fYWxnb3RzX18uZGVmYXVsdENyZWF0ZUAzCiAgICBiIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3N3aXRjaF9jYXNlX2RlZmF1bHRANAoKX19wdXlhX2FyYzRfcm91dGVyX19fX19hbGdvdHNfXy5kZWZhdWx0Q3JlYXRlQDM6CiAgICAvLyB0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6MTMtMTQKICAgIC8vIEBjb250cmFjdCh7IHN0YXRlVG90YWxzOiB7IGdsb2JhbFVpbnRzOiA0LCBsb2NhbFVpbnRzOiAwIH0gfSkKICAgIC8vIGV4cG9ydCBjbGFzcyBTdWJDbGFzc1dpdGhFeHBsaWNpdFRvdGFscyBleHRlbmRzIEJhc2VXaXRoU3RhdGUge30KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBpbnRjXzAgLy8gMAogICAgPT0KICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gY3JlYXRpbmcKICAgIGNhbGxzdWIgX19hbGdvdHNfXy5kZWZhdWx0Q3JlYXRlCiAgICBpbnRjXzEgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19zd2l0Y2hfY2FzZV9kZWZhdWx0QDQ6CgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDY6CiAgICAvLyB0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6MTMtMTQKICAgIC8vIEBjb250cmFjdCh7IHN0YXRlVG90YWxzOiB7IGdsb2JhbFVpbnRzOiA0LCBsb2NhbFVpbnRzOiAwIH0gfSkKICAgIC8vIGV4cG9ydCBjbGFzcyBTdWJDbGFzc1dpdGhFeHBsaWNpdFRvdGFscyBleHRlbmRzIEJhc2VXaXRoU3RhdGUge30KICAgIGludGNfMCAvLyAwCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6OlN1YkNsYXNzV2l0aEV4cGxpY2l0VG90YWxzLl9fYWxnb3RzX18uZGVmYXVsdENyZWF0ZSgpIC0+IHZvaWQ6Cl9fYWxnb3RzX18uZGVmYXVsdENyZWF0ZToKICAgIC8vIHRlc3RzL2FwcHJvdmFscy9zdGF0ZS10b3RhbHMuYWxnby50czoxMy0xNAogICAgLy8gQGNvbnRyYWN0KHsgc3RhdGVUb3RhbHM6IHsgZ2xvYmFsVWludHM6IDQsIGxvY2FsVWludHM6IDAgfSB9KQogICAgLy8gZXhwb3J0IGNsYXNzIFN1YkNsYXNzV2l0aEV4cGxpY2l0VG90YWxzIGV4dGVuZHMgQmFzZVdpdGhTdGF0ZSB7fQogICAgcHJvdG8gMCAwCiAgICByZXRzdWIK", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6OlN1YkNsYXNzV2l0aEV4cGxpY2l0VG90YWxzLmNsZWFyU3RhdGVQcm9ncmFtOgogICAgcHVzaGludCAxIC8vIDEKICAgIHJldHVybgo=" + }, + "events": [], + "templateVariables": {} +} \ No newline at end of file diff --git a/tests/approvals/out/state-totals/SubClassWithExplicitTotals.clear.teal b/tests/approvals/out/state-totals/SubClassWithExplicitTotals.clear.teal new file mode 100644 index 00000000..bb0cb81c --- /dev/null +++ b/tests/approvals/out/state-totals/SubClassWithExplicitTotals.clear.teal @@ -0,0 +1,5 @@ +#pragma version 10 + +tests/approvals/state-totals.algo.ts::SubClassWithExplicitTotals.clearStateProgram: + pushint 1 // 1 + return diff --git a/tests/approvals/out/state-totals/SubClassWithExplicitTotals.ssa.ir b/tests/approvals/out/state-totals/SubClassWithExplicitTotals.ssa.ir new file mode 100644 index 00000000..c5f91e65 --- /dev/null +++ b/tests/approvals/out/state-totals/SubClassWithExplicitTotals.ssa.ir @@ -0,0 +1,54 @@ +contract tests/approvals/state-totals.algo.ts::SubClassWithExplicitTotals: + program approval: + subroutine @algorandfoundation/algorand-typescript/arc4/index.d.ts::Contract.approvalProgram() -> bool: + block@0: // L1 + let reinterpret_bool%0#0: bool = (txn ApplicationID) + goto reinterpret_bool%0#0 ? block@2 : block@1 + block@1: // if_body_L1 + tests/approvals/state-totals.algo.ts::SubClassWithExplicitTotals.constructor() + goto block@2 + block@2: // after_if_else_L1 + let tmp%0#0: bool = tests/approvals/state-totals.algo.ts::SubClassWithExplicitTotals.__puya_arc4_router__() + return tmp%0#0 + + subroutine tests/approvals/state-totals.algo.ts::SubClassWithExplicitTotals.constructor() -> void: + block@0: // L13 + tests/approvals/state-totals.algo.ts::BaseWithState.constructor() + return + + subroutine tests/approvals/state-totals.algo.ts::BaseWithState.constructor() -> void: + block@0: // L4 + (app_global_put "oneGlobal" 1u) + return + + subroutine tests/approvals/state-totals.algo.ts::SubClassWithExplicitTotals.__puya_arc4_router__() -> bool: + block@0: // L13 + let tmp%0#0: uint64 = (txn NumAppArgs) + let tmp%1#0: bool = (!= tmp%0#0 0u) + goto tmp%1#0 ? block@1 : block@2 + block@1: // abi_routing_L13 + goto block@6 + block@2: // bare_routing_L13 + let tmp%2#0: uint64 = (txn OnCompletion) + switch tmp%2#0 {0u => block@3, * => block@4} + block@3: // __algots__.defaultCreate_L13 + let tmp%3#0: uint64 = (txn ApplicationID) + let tmp%4#0: bool = (== tmp%3#0 0u) + (assert tmp%4#0) // can only call when creating + tests/approvals/state-totals.algo.ts::SubClassWithExplicitTotals.__algots__.defaultCreate() + return 1u + block@4: // switch_case_default_L13 + goto block@5 + block@5: // switch_case_next_L13 + goto block@6 + block@6: // after_if_else_L13 + return 0u + + subroutine tests/approvals/state-totals.algo.ts::SubClassWithExplicitTotals.__algots__.defaultCreate() -> void: + block@0: // L13 + return + + program clear-state: + subroutine @algorandfoundation/algorand-typescript/base-contract.d.ts::BaseContract.clearStateProgram() -> bool: + block@0: // L1 + return 1u \ No newline at end of file diff --git a/tests/approvals/out/state-totals/SubClassWithState.approval.teal b/tests/approvals/out/state-totals/SubClassWithState.approval.teal new file mode 100644 index 00000000..0572b323 --- /dev/null +++ b/tests/approvals/out/state-totals/SubClassWithState.approval.teal @@ -0,0 +1,81 @@ +#pragma version 10 + +tests/approvals/state-totals.algo.ts::SubClassWithState.approvalProgram: + intcblock 0 1 + txn ApplicationID + bnz main_after_if_else@2 + callsub constructor + +main_after_if_else@2: + callsub __puya_arc4_router__ + return + + +// tests/approvals/state-totals.algo.ts::SubClassWithState.constructor() -> void: +constructor: + // tests/approvals/state-totals.algo.ts:9 + // export class SubClassWithState extends BaseWithState { + proto 0 0 + callsub tests/approvals/state-totals.algo.ts::BaseWithState.constructor + retsub + + +// tests/approvals/state-totals.algo.ts::BaseWithState.constructor() -> void: +tests/approvals/state-totals.algo.ts::BaseWithState.constructor: + // tests/approvals/state-totals.algo.ts:4 + // export class BaseWithState extends Contract { + proto 0 0 + // tests/approvals/state-totals.algo.ts:5 + // oneGlobal = GlobalState({ initialValue: Uint64(1) }) + pushbytes "oneGlobal" + intc_1 // 1 + app_global_put + retsub + + +// tests/approvals/state-totals.algo.ts::SubClassWithState.__puya_arc4_router__() -> uint64: +__puya_arc4_router__: + // tests/approvals/state-totals.algo.ts:9 + // export class SubClassWithState extends BaseWithState { + proto 0 1 + txn NumAppArgs + intc_0 // 0 + != + bz __puya_arc4_router___bare_routing@2 + b __puya_arc4_router___after_if_else@6 + +__puya_arc4_router___bare_routing@2: + // tests/approvals/state-totals.algo.ts:9 + // export class SubClassWithState extends BaseWithState { + txn OnCompletion + intc_0 // 0 + swap + match __puya_arc4_router_____algots__.defaultCreate@3 + b __puya_arc4_router___switch_case_default@4 + +__puya_arc4_router_____algots__.defaultCreate@3: + // tests/approvals/state-totals.algo.ts:9 + // export class SubClassWithState extends BaseWithState { + txn ApplicationID + intc_0 // 0 + == + assert // can only call when creating + callsub __algots__.defaultCreate + intc_1 // 1 + retsub + +__puya_arc4_router___switch_case_default@4: + +__puya_arc4_router___after_if_else@6: + // tests/approvals/state-totals.algo.ts:9 + // export class SubClassWithState extends BaseWithState { + intc_0 // 0 + retsub + + +// tests/approvals/state-totals.algo.ts::SubClassWithState.__algots__.defaultCreate() -> void: +__algots__.defaultCreate: + // tests/approvals/state-totals.algo.ts:9 + // export class SubClassWithState extends BaseWithState { + proto 0 0 + retsub diff --git a/tests/approvals/out/state-totals/SubClassWithState.arc32.json b/tests/approvals/out/state-totals/SubClassWithState.arc32.json new file mode 100644 index 00000000..cfee2bab --- /dev/null +++ b/tests/approvals/out/state-totals/SubClassWithState.arc32.json @@ -0,0 +1,48 @@ +{ + "hints": {}, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6OlN1YkNsYXNzV2l0aFN0YXRlLmFwcHJvdmFsUHJvZ3JhbToKICAgIGludGNibG9jayAwIDEKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBibnogbWFpbl9hZnRlcl9pZl9lbHNlQDIKICAgIGNhbGxzdWIgY29uc3RydWN0b3IKCm1haW5fYWZ0ZXJfaWZfZWxzZUAyOgogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjpTdWJDbGFzc1dpdGhTdGF0ZS5jb25zdHJ1Y3RvcigpIC0+IHZvaWQ6CmNvbnN0cnVjdG9yOgogICAgLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjkKICAgIC8vIGV4cG9ydCBjbGFzcyBTdWJDbGFzc1dpdGhTdGF0ZSBleHRlbmRzIEJhc2VXaXRoU3RhdGUgewogICAgcHJvdG8gMCAwCiAgICBjYWxsc3ViIHRlc3RzL2FwcHJvdmFscy9zdGF0ZS10b3RhbHMuYWxnby50czo6QmFzZVdpdGhTdGF0ZS5jb25zdHJ1Y3RvcgogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjpCYXNlV2l0aFN0YXRlLmNvbnN0cnVjdG9yKCkgLT4gdm9pZDoKdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjpCYXNlV2l0aFN0YXRlLmNvbnN0cnVjdG9yOgogICAgLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBCYXNlV2l0aFN0YXRlIGV4dGVuZHMgQ29udHJhY3QgewogICAgcHJvdG8gMCAwCiAgICAvLyB0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6NQogICAgLy8gb25lR2xvYmFsID0gR2xvYmFsU3RhdGUoeyBpbml0aWFsVmFsdWU6IFVpbnQ2NCgxKSB9KQogICAgcHVzaGJ5dGVzICJvbmVHbG9iYWwiCiAgICBpbnRjXzEgLy8gMQogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FwcHJvdmFscy9zdGF0ZS10b3RhbHMuYWxnby50czo6U3ViQ2xhc3NXaXRoU3RhdGUuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjkKICAgIC8vIGV4cG9ydCBjbGFzcyBTdWJDbGFzc1dpdGhTdGF0ZSBleHRlbmRzIEJhc2VXaXRoU3RhdGUgewogICAgcHJvdG8gMCAxCiAgICB0eG4gTnVtQXBwQXJncwogICAgaW50Y18wIC8vIDAKICAgICE9CiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAMgogICAgYiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDYKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0AyOgogICAgLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjkKICAgIC8vIGV4cG9ydCBjbGFzcyBTdWJDbGFzc1dpdGhTdGF0ZSBleHRlbmRzIEJhc2VXaXRoU3RhdGUgewogICAgdHhuIE9uQ29tcGxldGlvbgogICAgaW50Y18wIC8vIDAKICAgIHN3YXAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX19fYWxnb3RzX18uZGVmYXVsdENyZWF0ZUAzCiAgICBiIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3N3aXRjaF9jYXNlX2RlZmF1bHRANAoKX19wdXlhX2FyYzRfcm91dGVyX19fX19hbGdvdHNfXy5kZWZhdWx0Q3JlYXRlQDM6CiAgICAvLyB0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6OQogICAgLy8gZXhwb3J0IGNsYXNzIFN1YkNsYXNzV2l0aFN0YXRlIGV4dGVuZHMgQmFzZVdpdGhTdGF0ZSB7CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgaW50Y18wIC8vIDAKICAgID09CiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIGNyZWF0aW5nCiAgICBjYWxsc3ViIF9fYWxnb3RzX18uZGVmYXVsdENyZWF0ZQogICAgaW50Y18xIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fc3dpdGNoX2Nhc2VfZGVmYXVsdEA0OgoKX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUA2OgogICAgLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjkKICAgIC8vIGV4cG9ydCBjbGFzcyBTdWJDbGFzc1dpdGhTdGF0ZSBleHRlbmRzIEJhc2VXaXRoU3RhdGUgewogICAgaW50Y18wIC8vIDAKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FwcHJvdmFscy9zdGF0ZS10b3RhbHMuYWxnby50czo6U3ViQ2xhc3NXaXRoU3RhdGUuX19hbGdvdHNfXy5kZWZhdWx0Q3JlYXRlKCkgLT4gdm9pZDoKX19hbGdvdHNfXy5kZWZhdWx0Q3JlYXRlOgogICAgLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjkKICAgIC8vIGV4cG9ydCBjbGFzcyBTdWJDbGFzc1dpdGhTdGF0ZSBleHRlbmRzIEJhc2VXaXRoU3RhdGUgewogICAgcHJvdG8gMCAwCiAgICByZXRzdWIK", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6OlN1YkNsYXNzV2l0aFN0YXRlLmNsZWFyU3RhdGVQcm9ncmFtOgogICAgcHVzaGludCAxIC8vIDEKICAgIHJldHVybgo=" + }, + "state": { + "global": { + "num_byte_slices": 0, + "num_uints": 3 + }, + "local": { + "num_byte_slices": 0, + "num_uints": 0 + } + }, + "schema": { + "global": { + "declared": { + "oneGlobal": { + "type": "uint64", + "key": "oneGlobal" + }, + "threeGlobal": { + "type": "uint64", + "key": "threeGlobal" + }, + "twoGlobal": { + "type": "uint64", + "key": "twoGlobal" + } + }, + "reserved": {} + }, + "local": { + "declared": {}, + "reserved": {} + } + }, + "contract": { + "name": "SubClassWithState", + "methods": [], + "networks": {} + }, + "bare_call_config": { + "no_op": "CREATE" + } +} \ No newline at end of file diff --git a/tests/approvals/out/state-totals/SubClassWithState.arc56.json b/tests/approvals/out/state-totals/SubClassWithState.arc56.json new file mode 100644 index 00000000..fb33e536 --- /dev/null +++ b/tests/approvals/out/state-totals/SubClassWithState.arc56.json @@ -0,0 +1,77 @@ +{ + "name": "SubClassWithState", + "structs": {}, + "methods": [], + "arcs": [ + 22, + 28 + ], + "networks": {}, + "state": { + "schema": { + "global": { + "ints": 3, + "bytes": 0 + }, + "local": { + "ints": 0, + "bytes": 0 + } + }, + "keys": { + "global": { + "oneGlobal": { + "keyType": "AVMString", + "valueType": "AVMUint64", + "key": "b25lR2xvYmFs" + }, + "twoGlobal": { + "keyType": "AVMString", + "valueType": "AVMUint64", + "key": "dHdvR2xvYmFs" + }, + "threeGlobal": { + "keyType": "AVMString", + "valueType": "AVMUint64", + "key": "dGhyZWVHbG9iYWw=" + } + }, + "local": {}, + "box": {} + }, + "maps": { + "global": {}, + "local": {}, + "box": {} + } + }, + "bareActions": { + "create": [ + "NoOp" + ], + "call": [] + }, + "sourceInfo": { + "approval": { + "sourceInfo": [ + { + "pc": [ + 69 + ], + "errorMessage": "can only call when creating" + } + ], + "pcOffsetMethod": "none" + }, + "clear": { + "sourceInfo": [], + "pcOffsetMethod": "none" + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6OlN1YkNsYXNzV2l0aFN0YXRlLmFwcHJvdmFsUHJvZ3JhbToKICAgIGludGNibG9jayAwIDEKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBibnogbWFpbl9hZnRlcl9pZl9lbHNlQDIKICAgIGNhbGxzdWIgY29uc3RydWN0b3IKCm1haW5fYWZ0ZXJfaWZfZWxzZUAyOgogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjpTdWJDbGFzc1dpdGhTdGF0ZS5jb25zdHJ1Y3RvcigpIC0+IHZvaWQ6CmNvbnN0cnVjdG9yOgogICAgLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjkKICAgIC8vIGV4cG9ydCBjbGFzcyBTdWJDbGFzc1dpdGhTdGF0ZSBleHRlbmRzIEJhc2VXaXRoU3RhdGUgewogICAgcHJvdG8gMCAwCiAgICBjYWxsc3ViIHRlc3RzL2FwcHJvdmFscy9zdGF0ZS10b3RhbHMuYWxnby50czo6QmFzZVdpdGhTdGF0ZS5jb25zdHJ1Y3RvcgogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjpCYXNlV2l0aFN0YXRlLmNvbnN0cnVjdG9yKCkgLT4gdm9pZDoKdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjpCYXNlV2l0aFN0YXRlLmNvbnN0cnVjdG9yOgogICAgLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBCYXNlV2l0aFN0YXRlIGV4dGVuZHMgQ29udHJhY3QgewogICAgcHJvdG8gMCAwCiAgICAvLyB0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6NQogICAgLy8gb25lR2xvYmFsID0gR2xvYmFsU3RhdGUoeyBpbml0aWFsVmFsdWU6IFVpbnQ2NCgxKSB9KQogICAgcHVzaGJ5dGVzICJvbmVHbG9iYWwiCiAgICBpbnRjXzEgLy8gMQogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FwcHJvdmFscy9zdGF0ZS10b3RhbHMuYWxnby50czo6U3ViQ2xhc3NXaXRoU3RhdGUuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjkKICAgIC8vIGV4cG9ydCBjbGFzcyBTdWJDbGFzc1dpdGhTdGF0ZSBleHRlbmRzIEJhc2VXaXRoU3RhdGUgewogICAgcHJvdG8gMCAxCiAgICB0eG4gTnVtQXBwQXJncwogICAgaW50Y18wIC8vIDAKICAgICE9CiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAMgogICAgYiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDYKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0AyOgogICAgLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjkKICAgIC8vIGV4cG9ydCBjbGFzcyBTdWJDbGFzc1dpdGhTdGF0ZSBleHRlbmRzIEJhc2VXaXRoU3RhdGUgewogICAgdHhuIE9uQ29tcGxldGlvbgogICAgaW50Y18wIC8vIDAKICAgIHN3YXAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX19fYWxnb3RzX18uZGVmYXVsdENyZWF0ZUAzCiAgICBiIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3N3aXRjaF9jYXNlX2RlZmF1bHRANAoKX19wdXlhX2FyYzRfcm91dGVyX19fX19hbGdvdHNfXy5kZWZhdWx0Q3JlYXRlQDM6CiAgICAvLyB0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6OQogICAgLy8gZXhwb3J0IGNsYXNzIFN1YkNsYXNzV2l0aFN0YXRlIGV4dGVuZHMgQmFzZVdpdGhTdGF0ZSB7CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgaW50Y18wIC8vIDAKICAgID09CiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIGNyZWF0aW5nCiAgICBjYWxsc3ViIF9fYWxnb3RzX18uZGVmYXVsdENyZWF0ZQogICAgaW50Y18xIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fc3dpdGNoX2Nhc2VfZGVmYXVsdEA0OgoKX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUA2OgogICAgLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjkKICAgIC8vIGV4cG9ydCBjbGFzcyBTdWJDbGFzc1dpdGhTdGF0ZSBleHRlbmRzIEJhc2VXaXRoU3RhdGUgewogICAgaW50Y18wIC8vIDAKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FwcHJvdmFscy9zdGF0ZS10b3RhbHMuYWxnby50czo6U3ViQ2xhc3NXaXRoU3RhdGUuX19hbGdvdHNfXy5kZWZhdWx0Q3JlYXRlKCkgLT4gdm9pZDoKX19hbGdvdHNfXy5kZWZhdWx0Q3JlYXRlOgogICAgLy8gdGVzdHMvYXBwcm92YWxzL3N0YXRlLXRvdGFscy5hbGdvLnRzOjkKICAgIC8vIGV4cG9ydCBjbGFzcyBTdWJDbGFzc1dpdGhTdGF0ZSBleHRlbmRzIEJhc2VXaXRoU3RhdGUgewogICAgcHJvdG8gMCAwCiAgICByZXRzdWIK", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcHByb3ZhbHMvc3RhdGUtdG90YWxzLmFsZ28udHM6OlN1YkNsYXNzV2l0aFN0YXRlLmNsZWFyU3RhdGVQcm9ncmFtOgogICAgcHVzaGludCAxIC8vIDEKICAgIHJldHVybgo=" + }, + "events": [], + "templateVariables": {} +} \ No newline at end of file diff --git a/tests/approvals/out/state-totals/SubClassWithState.clear.teal b/tests/approvals/out/state-totals/SubClassWithState.clear.teal new file mode 100644 index 00000000..09c86e12 --- /dev/null +++ b/tests/approvals/out/state-totals/SubClassWithState.clear.teal @@ -0,0 +1,5 @@ +#pragma version 10 + +tests/approvals/state-totals.algo.ts::SubClassWithState.clearStateProgram: + pushint 1 // 1 + return diff --git a/tests/approvals/out/state-totals/SubClassWithState.ssa.ir b/tests/approvals/out/state-totals/SubClassWithState.ssa.ir new file mode 100644 index 00000000..17d38699 --- /dev/null +++ b/tests/approvals/out/state-totals/SubClassWithState.ssa.ir @@ -0,0 +1,54 @@ +contract tests/approvals/state-totals.algo.ts::SubClassWithState: + program approval: + subroutine @algorandfoundation/algorand-typescript/arc4/index.d.ts::Contract.approvalProgram() -> bool: + block@0: // L1 + let reinterpret_bool%0#0: bool = (txn ApplicationID) + goto reinterpret_bool%0#0 ? block@2 : block@1 + block@1: // if_body_L1 + tests/approvals/state-totals.algo.ts::SubClassWithState.constructor() + goto block@2 + block@2: // after_if_else_L1 + let tmp%0#0: bool = tests/approvals/state-totals.algo.ts::SubClassWithState.__puya_arc4_router__() + return tmp%0#0 + + subroutine tests/approvals/state-totals.algo.ts::SubClassWithState.constructor() -> void: + block@0: // L9 + tests/approvals/state-totals.algo.ts::BaseWithState.constructor() + return + + subroutine tests/approvals/state-totals.algo.ts::BaseWithState.constructor() -> void: + block@0: // L4 + (app_global_put "oneGlobal" 1u) + return + + subroutine tests/approvals/state-totals.algo.ts::SubClassWithState.__puya_arc4_router__() -> bool: + block@0: // L9 + let tmp%0#0: uint64 = (txn NumAppArgs) + let tmp%1#0: bool = (!= tmp%0#0 0u) + goto tmp%1#0 ? block@1 : block@2 + block@1: // abi_routing_L9 + goto block@6 + block@2: // bare_routing_L9 + let tmp%2#0: uint64 = (txn OnCompletion) + switch tmp%2#0 {0u => block@3, * => block@4} + block@3: // __algots__.defaultCreate_L9 + let tmp%3#0: uint64 = (txn ApplicationID) + let tmp%4#0: bool = (== tmp%3#0 0u) + (assert tmp%4#0) // can only call when creating + tests/approvals/state-totals.algo.ts::SubClassWithState.__algots__.defaultCreate() + return 1u + block@4: // switch_case_default_L9 + goto block@5 + block@5: // switch_case_next_L9 + goto block@6 + block@6: // after_if_else_L9 + return 0u + + subroutine tests/approvals/state-totals.algo.ts::SubClassWithState.__algots__.defaultCreate() -> void: + block@0: // L9 + return + + program clear-state: + subroutine @algorandfoundation/algorand-typescript/base-contract.d.ts::BaseContract.clearStateProgram() -> bool: + block@0: // L1 + return 1u \ No newline at end of file diff --git a/tests/approvals/out/state-totals/state-totals.awst b/tests/approvals/out/state-totals/state-totals.awst new file mode 100644 index 00000000..40aa3f51 --- /dev/null +++ b/tests/approvals/out/state-totals/state-totals.awst @@ -0,0 +1,180 @@ +contract BaseWithState +{ + globals { + ["oneGlobal"]: uint64 + ["twoGlobal"]: uint64 + } + approvalProgram(): bool + { + if (!Boolean(txn())) { + this.constructor() + } + return arc4Router() + } + + clearProgram(): bool + { + return True + } + + constructor(): void + { + void + GlobalState["oneGlobal"]: uint64 = 1 + } + + Contract::constructor(): void + { + this.constructor() + } + + BaseContract::constructor(): void + { + } + + __algots__.defaultCreate(): void + { + } + +} +contract SubClassWithState +{ + globals { + ["oneGlobal"]: uint64 + ["twoGlobal"]: uint64 + ["threeGlobal"]: uint64 + } + approvalProgram(): bool + { + if (!Boolean(txn())) { + this.constructor() + } + return arc4Router() + } + + clearProgram(): bool + { + return True + } + + constructor(): void + { + super.constructor() + } + + BaseWithState::constructor(): void + { + void + GlobalState["oneGlobal"]: uint64 = 1 + } + + Contract::constructor(): void + { + this.constructor() + } + + BaseContract::constructor(): void + { + } + + __algots__.defaultCreate(): void + { + } + +} +contract SubClassWithExplicitTotals +{ + globals { + ["oneGlobal"]: uint64 + ["twoGlobal"]: uint64 + } + approvalProgram(): bool + { + if (!Boolean(txn())) { + this.constructor() + } + return arc4Router() + } + + clearProgram(): bool + { + return True + } + + constructor(): void + { + super.constructor() + } + + BaseWithState::constructor(): void + { + void + GlobalState["oneGlobal"]: uint64 = 1 + } + + Contract::constructor(): void + { + this.constructor() + } + + BaseContract::constructor(): void + { + } + + __algots__.defaultCreate(): void + { + } + +} +contract ExtendsSubWithTotals +{ + globals { + ["oneGlobal"]: uint64 + ["twoGlobal"]: uint64 + } + locals { + ["oneLocal"]: uint64 + } + approvalProgram(): bool + { + if (!Boolean(txn())) { + this.constructor() + } + return arc4Router() + } + + clearProgram(): bool + { + return True + } + + constructor(): void + { + super.constructor() + } + + SubClassWithExplicitTotals::constructor(): void + { + super.constructor() + } + + BaseWithState::constructor(): void + { + void + GlobalState["oneGlobal"]: uint64 = 1 + } + + Contract::constructor(): void + { + this.constructor() + } + + BaseContract::constructor(): void + { + } + + __algots__.defaultCreate(): void + { + } + +} \ No newline at end of file diff --git a/tests/approvals/out/state-totals/state-totals.awst.json b/tests/approvals/out/state-totals/state-totals.awst.json new file mode 100644 index 00000000..3a45e5ef --- /dev/null +++ b/tests/approvals/out/state-totals/state-totals.awst.json @@ -0,0 +1,3154 @@ +[ + { + "_type": "Contract", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 4, + "end_line": 4, + "column": 0, + "end_column": 45 + }, + "id": "tests/approvals/state-totals.algo.ts::BaseWithState", + "name": "BaseWithState", + "description": null, + "method_resolution_order": [ + "@algorandfoundation/algorand-typescript/arc4/index.d.ts::Contract", + "@algorandfoundation/algorand-typescript/base-contract.d.ts::BaseContract" + ], + "approval_program": { + "_type": "ContractMethod", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "args": [], + "return_type": { + "_type": "WType", + "name": "bool", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "body": { + "_type": "Block", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "body": [ + { + "_type": "IfElse", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "condition": { + "_type": "Not", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "wtype": { + "_type": "WType", + "name": "bool", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "expr": { + "_type": "ReinterpretCast", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "wtype": { + "_type": "WType", + "name": "bool", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "expr": { + "_type": "IntrinsicCall", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "wtype": { + "_type": "WType", + "name": "uint64", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "op_code": "txn", + "immediates": [ + "ApplicationID" + ], + "stack_args": [] + } + } + }, + "if_branch": { + "_type": "Block", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "body": [ + { + "_type": "ExpressionStatement", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "expr": { + "_type": "SubroutineCallExpression", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "wtype": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + }, + "target": { + "_type": "InstanceMethodTarget", + "member_name": "constructor" + }, + "args": [] + } + } + ], + "label": null, + "comment": null + }, + "else_branch": null + }, + { + "_type": "Block", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "body": [ + { + "_type": "ReturnStatement", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "value": { + "_type": "ARC4Router", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "wtype": { + "_type": "WType", + "name": "bool", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + } + } + } + ], + "label": null, + "comment": null + } + ], + "label": null, + "comment": null + }, + "documentation": { + "_type": "MethodDocumentation", + "description": null, + "args": {}, + "returns": null + }, + "cref": "@algorandfoundation/algorand-typescript/arc4/index.d.ts::Contract", + "member_name": "approvalProgram", + "arc4_method_config": null + }, + "clear_program": { + "_type": "ContractMethod", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "args": [], + "return_type": { + "_type": "WType", + "name": "bool", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "body": { + "_type": "Block", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "body": [ + { + "_type": "ReturnStatement", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "value": { + "_type": "BoolConstant", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "wtype": { + "_type": "WType", + "name": "bool", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "value": true + } + } + ], + "label": null, + "comment": null + }, + "documentation": { + "_type": "MethodDocumentation", + "description": null, + "args": {}, + "returns": null + }, + "cref": "@algorandfoundation/algorand-typescript/base-contract.d.ts::BaseContract", + "member_name": "clearStateProgram", + "arc4_method_config": null + }, + "methods": [ + { + "_type": "ContractMethod", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 4, + "end_line": 4, + "column": 0, + "end_column": 45 + }, + "args": [], + "return_type": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + }, + "body": { + "_type": "Block", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 4, + "end_line": 4, + "column": 0, + "end_column": 45 + }, + "body": [ + { + "_type": "ExpressionStatement", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 4, + "end_line": 4, + "column": 0, + "end_column": 45 + }, + "expr": { + "_type": "VoidConstant", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 4, + "end_line": 4, + "column": 0, + "end_column": 45 + }, + "wtype": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + } + } + }, + { + "_type": "AssignmentStatement", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 5, + "end_line": 5, + "column": 2, + "end_column": 54 + }, + "target": { + "_type": "AppStateExpression", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 5, + "end_line": 5, + "column": 2, + "end_column": 11 + }, + "wtype": { + "_type": "WType", + "name": "uint64", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "key": { + "_type": "BytesConstant", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 5, + "end_line": 5, + "column": 2, + "end_column": 11 + }, + "wtype": { + "_type": "WType", + "name": "state_key", + "immutable": true, + "ephemeral": false, + "scalar_type": 1 + }, + "value": "Z*FBrY;R&=Yy", + "encoding": "utf8" + }, + "exists_assertion_message": null + }, + "value": { + "_type": "IntegerConstant", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 5, + "end_line": 5, + "column": 49, + "end_column": 50 + }, + "wtype": { + "_type": "WType", + "name": "uint64", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "value": "1", + "teal_alias": null + } + } + ], + "label": null, + "comment": null + }, + "documentation": { + "_type": "MethodDocumentation", + "description": null, + "args": {}, + "returns": null + }, + "cref": "tests/approvals/state-totals.algo.ts::BaseWithState", + "member_name": "constructor", + "arc4_method_config": null + }, + { + "_type": "ContractMethod", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "args": [], + "return_type": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + }, + "body": { + "_type": "Block", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "body": [ + { + "_type": "ExpressionStatement", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "expr": { + "_type": "SubroutineCallExpression", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "wtype": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + }, + "target": { + "_type": "InstanceMethodTarget", + "member_name": "constructor" + }, + "args": [] + } + } + ], + "label": null, + "comment": null + }, + "documentation": { + "_type": "MethodDocumentation", + "description": null, + "args": {}, + "returns": null + }, + "cref": "@algorandfoundation/algorand-typescript/arc4/index.d.ts::Contract", + "member_name": "constructor", + "arc4_method_config": null + }, + { + "_type": "ContractMethod", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "args": [], + "return_type": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + }, + "body": { + "_type": "Block", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "body": [], + "label": null, + "comment": null + }, + "documentation": { + "_type": "MethodDocumentation", + "description": null, + "args": {}, + "returns": null + }, + "cref": "@algorandfoundation/algorand-typescript/base-contract.d.ts::BaseContract", + "member_name": "constructor", + "arc4_method_config": null + }, + { + "_type": "ContractMethod", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 4, + "end_line": 4, + "column": 0, + "end_column": 45 + }, + "args": [], + "return_type": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + }, + "body": { + "_type": "Block", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 4, + "end_line": 4, + "column": 0, + "end_column": 45 + }, + "body": [], + "label": null, + "comment": null + }, + "documentation": { + "_type": "MethodDocumentation", + "description": "Implicitly generated create method", + "args": {}, + "returns": null + }, + "cref": "tests/approvals/state-totals.algo.ts::BaseWithState", + "member_name": "__algots__.defaultCreate", + "arc4_method_config": { + "_type": "ARC4BareMethodConfig", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 4, + "end_line": 4, + "column": 0, + "end_column": 45 + }, + "allowed_completion_types": [ + 0 + ], + "create": 2, + "is_bare": true + } + } + ], + "app_state": [ + { + "_type": "AppStorageDefinition", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 5, + "end_line": 5, + "column": 2, + "end_column": 11 + }, + "member_name": "oneGlobal", + "kind": 1, + "storage_wtype": { + "_type": "WType", + "name": "uint64", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "key_wtype": null, + "key": { + "_type": "BytesConstant", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 5, + "end_line": 5, + "column": 2, + "end_column": 11 + }, + "wtype": { + "_type": "WType", + "name": "state_key", + "immutable": true, + "ephemeral": false, + "scalar_type": 1 + }, + "value": "Z*FBrY;R&=Yy", + "encoding": "utf8" + }, + "description": null + }, + { + "_type": "AppStorageDefinition", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 6, + "end_line": 6, + "column": 2, + "end_column": 11 + }, + "member_name": "twoGlobal", + "kind": 1, + "storage_wtype": { + "_type": "WType", + "name": "uint64", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "key_wtype": null, + "key": { + "_type": "BytesConstant", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 6, + "end_line": 6, + "column": 2, + "end_column": 11 + }, + "wtype": { + "_type": "WType", + "name": "state_key", + "immutable": true, + "ephemeral": false, + "scalar_type": 1 + }, + "value": "ba!t@Y;R&=Yy", + "encoding": "utf8" + }, + "description": null + } + ], + "state_totals": null, + "reserved_scratch_space": [], + "avm_version": null + }, + { + "_type": "Contract", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 9, + "end_line": 9, + "column": 0, + "end_column": 54 + }, + "id": "tests/approvals/state-totals.algo.ts::SubClassWithState", + "name": "SubClassWithState", + "description": null, + "method_resolution_order": [ + "tests/approvals/state-totals.algo.ts::BaseWithState", + "@algorandfoundation/algorand-typescript/arc4/index.d.ts::Contract", + "@algorandfoundation/algorand-typescript/base-contract.d.ts::BaseContract" + ], + "approval_program": { + "_type": "ContractMethod", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "args": [], + "return_type": { + "_type": "WType", + "name": "bool", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "body": { + "_type": "Block", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "body": [ + { + "_type": "IfElse", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "condition": { + "_type": "Not", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "wtype": { + "_type": "WType", + "name": "bool", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "expr": { + "_type": "ReinterpretCast", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "wtype": { + "_type": "WType", + "name": "bool", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "expr": { + "_type": "IntrinsicCall", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "wtype": { + "_type": "WType", + "name": "uint64", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "op_code": "txn", + "immediates": [ + "ApplicationID" + ], + "stack_args": [] + } + } + }, + "if_branch": { + "_type": "Block", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "body": [ + { + "_type": "ExpressionStatement", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "expr": { + "_type": "SubroutineCallExpression", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "wtype": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + }, + "target": { + "_type": "InstanceMethodTarget", + "member_name": "constructor" + }, + "args": [] + } + } + ], + "label": null, + "comment": null + }, + "else_branch": null + }, + { + "_type": "Block", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "body": [ + { + "_type": "ReturnStatement", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "value": { + "_type": "ARC4Router", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "wtype": { + "_type": "WType", + "name": "bool", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + } + } + } + ], + "label": null, + "comment": null + } + ], + "label": null, + "comment": null + }, + "documentation": { + "_type": "MethodDocumentation", + "description": null, + "args": {}, + "returns": null + }, + "cref": "@algorandfoundation/algorand-typescript/arc4/index.d.ts::Contract", + "member_name": "approvalProgram", + "arc4_method_config": null + }, + "clear_program": { + "_type": "ContractMethod", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "args": [], + "return_type": { + "_type": "WType", + "name": "bool", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "body": { + "_type": "Block", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "body": [ + { + "_type": "ReturnStatement", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "value": { + "_type": "BoolConstant", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "wtype": { + "_type": "WType", + "name": "bool", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "value": true + } + } + ], + "label": null, + "comment": null + }, + "documentation": { + "_type": "MethodDocumentation", + "description": null, + "args": {}, + "returns": null + }, + "cref": "@algorandfoundation/algorand-typescript/base-contract.d.ts::BaseContract", + "member_name": "clearStateProgram", + "arc4_method_config": null + }, + "methods": [ + { + "_type": "ContractMethod", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 9, + "end_line": 9, + "column": 0, + "end_column": 54 + }, + "args": [], + "return_type": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + }, + "body": { + "_type": "Block", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 9, + "end_line": 9, + "column": 0, + "end_column": 54 + }, + "body": [ + { + "_type": "ExpressionStatement", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 9, + "end_line": 9, + "column": 0, + "end_column": 54 + }, + "expr": { + "_type": "SubroutineCallExpression", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 9, + "end_line": 9, + "column": 0, + "end_column": 54 + }, + "wtype": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + }, + "target": { + "_type": "InstanceSuperMethodTarget", + "member_name": "constructor" + }, + "args": [] + } + } + ], + "label": null, + "comment": null + }, + "documentation": { + "_type": "MethodDocumentation", + "description": null, + "args": {}, + "returns": null + }, + "cref": "tests/approvals/state-totals.algo.ts::SubClassWithState", + "member_name": "constructor", + "arc4_method_config": null + }, + { + "_type": "ContractMethod", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 4, + "end_line": 4, + "column": 0, + "end_column": 45 + }, + "args": [], + "return_type": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + }, + "body": { + "_type": "Block", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 4, + "end_line": 4, + "column": 0, + "end_column": 45 + }, + "body": [ + { + "_type": "ExpressionStatement", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 4, + "end_line": 4, + "column": 0, + "end_column": 45 + }, + "expr": { + "_type": "VoidConstant", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 4, + "end_line": 4, + "column": 0, + "end_column": 45 + }, + "wtype": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + } + } + }, + { + "_type": "AssignmentStatement", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 5, + "end_line": 5, + "column": 2, + "end_column": 54 + }, + "target": { + "_type": "AppStateExpression", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 5, + "end_line": 5, + "column": 2, + "end_column": 11 + }, + "wtype": { + "_type": "WType", + "name": "uint64", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "key": { + "_type": "BytesConstant", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 5, + "end_line": 5, + "column": 2, + "end_column": 11 + }, + "wtype": { + "_type": "WType", + "name": "state_key", + "immutable": true, + "ephemeral": false, + "scalar_type": 1 + }, + "value": "Z*FBrY;R&=Yy", + "encoding": "utf8" + }, + "exists_assertion_message": null + }, + "value": { + "_type": "IntegerConstant", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 5, + "end_line": 5, + "column": 49, + "end_column": 50 + }, + "wtype": { + "_type": "WType", + "name": "uint64", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "value": "1", + "teal_alias": null + } + } + ], + "label": null, + "comment": null + }, + "documentation": { + "_type": "MethodDocumentation", + "description": null, + "args": {}, + "returns": null + }, + "cref": "tests/approvals/state-totals.algo.ts::BaseWithState", + "member_name": "constructor", + "arc4_method_config": null + }, + { + "_type": "ContractMethod", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "args": [], + "return_type": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + }, + "body": { + "_type": "Block", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "body": [ + { + "_type": "ExpressionStatement", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "expr": { + "_type": "SubroutineCallExpression", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "wtype": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + }, + "target": { + "_type": "InstanceMethodTarget", + "member_name": "constructor" + }, + "args": [] + } + } + ], + "label": null, + "comment": null + }, + "documentation": { + "_type": "MethodDocumentation", + "description": null, + "args": {}, + "returns": null + }, + "cref": "@algorandfoundation/algorand-typescript/arc4/index.d.ts::Contract", + "member_name": "constructor", + "arc4_method_config": null + }, + { + "_type": "ContractMethod", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "args": [], + "return_type": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + }, + "body": { + "_type": "Block", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "body": [], + "label": null, + "comment": null + }, + "documentation": { + "_type": "MethodDocumentation", + "description": null, + "args": {}, + "returns": null + }, + "cref": "@algorandfoundation/algorand-typescript/base-contract.d.ts::BaseContract", + "member_name": "constructor", + "arc4_method_config": null + }, + { + "_type": "ContractMethod", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 9, + "end_line": 9, + "column": 0, + "end_column": 54 + }, + "args": [], + "return_type": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + }, + "body": { + "_type": "Block", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 9, + "end_line": 9, + "column": 0, + "end_column": 54 + }, + "body": [], + "label": null, + "comment": null + }, + "documentation": { + "_type": "MethodDocumentation", + "description": "Implicitly generated create method", + "args": {}, + "returns": null + }, + "cref": "tests/approvals/state-totals.algo.ts::SubClassWithState", + "member_name": "__algots__.defaultCreate", + "arc4_method_config": { + "_type": "ARC4BareMethodConfig", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 9, + "end_line": 9, + "column": 0, + "end_column": 54 + }, + "allowed_completion_types": [ + 0 + ], + "create": 2, + "is_bare": true + } + } + ], + "app_state": [ + { + "_type": "AppStorageDefinition", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 5, + "end_line": 5, + "column": 2, + "end_column": 11 + }, + "member_name": "oneGlobal", + "kind": 1, + "storage_wtype": { + "_type": "WType", + "name": "uint64", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "key_wtype": null, + "key": { + "_type": "BytesConstant", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 5, + "end_line": 5, + "column": 2, + "end_column": 11 + }, + "wtype": { + "_type": "WType", + "name": "state_key", + "immutable": true, + "ephemeral": false, + "scalar_type": 1 + }, + "value": "Z*FBrY;R&=Yy", + "encoding": "utf8" + }, + "description": null + }, + { + "_type": "AppStorageDefinition", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 6, + "end_line": 6, + "column": 2, + "end_column": 11 + }, + "member_name": "twoGlobal", + "kind": 1, + "storage_wtype": { + "_type": "WType", + "name": "uint64", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "key_wtype": null, + "key": { + "_type": "BytesConstant", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 6, + "end_line": 6, + "column": 2, + "end_column": 11 + }, + "wtype": { + "_type": "WType", + "name": "state_key", + "immutable": true, + "ephemeral": false, + "scalar_type": 1 + }, + "value": "ba!t@Y;R&=Yy", + "encoding": "utf8" + }, + "description": null + }, + { + "_type": "AppStorageDefinition", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 10, + "end_line": 10, + "column": 2, + "end_column": 13 + }, + "member_name": "threeGlobal", + "kind": 1, + "storage_wtype": { + "_type": "WType", + "name": "uint64", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "key_wtype": null, + "key": { + "_type": "BytesConstant", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 10, + "end_line": 10, + "column": 2, + "end_column": 13 + }, + "wtype": { + "_type": "WType", + "name": "state_key", + "immutable": true, + "ephemeral": false, + "scalar_type": 1 + }, + "value": "bZByAWk+mpVqt6", + "encoding": "utf8" + }, + "description": null + } + ], + "state_totals": null, + "reserved_scratch_space": [], + "avm_version": null + }, + { + "_type": "Contract", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 13, + "end_line": 14, + "column": 0, + "end_column": 64 + }, + "id": "tests/approvals/state-totals.algo.ts::SubClassWithExplicitTotals", + "name": "SubClassWithExplicitTotals", + "description": null, + "method_resolution_order": [ + "tests/approvals/state-totals.algo.ts::BaseWithState", + "@algorandfoundation/algorand-typescript/arc4/index.d.ts::Contract", + "@algorandfoundation/algorand-typescript/base-contract.d.ts::BaseContract" + ], + "approval_program": { + "_type": "ContractMethod", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "args": [], + "return_type": { + "_type": "WType", + "name": "bool", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "body": { + "_type": "Block", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "body": [ + { + "_type": "IfElse", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "condition": { + "_type": "Not", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "wtype": { + "_type": "WType", + "name": "bool", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "expr": { + "_type": "ReinterpretCast", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "wtype": { + "_type": "WType", + "name": "bool", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "expr": { + "_type": "IntrinsicCall", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "wtype": { + "_type": "WType", + "name": "uint64", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "op_code": "txn", + "immediates": [ + "ApplicationID" + ], + "stack_args": [] + } + } + }, + "if_branch": { + "_type": "Block", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "body": [ + { + "_type": "ExpressionStatement", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "expr": { + "_type": "SubroutineCallExpression", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "wtype": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + }, + "target": { + "_type": "InstanceMethodTarget", + "member_name": "constructor" + }, + "args": [] + } + } + ], + "label": null, + "comment": null + }, + "else_branch": null + }, + { + "_type": "Block", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "body": [ + { + "_type": "ReturnStatement", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "value": { + "_type": "ARC4Router", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "wtype": { + "_type": "WType", + "name": "bool", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + } + } + } + ], + "label": null, + "comment": null + } + ], + "label": null, + "comment": null + }, + "documentation": { + "_type": "MethodDocumentation", + "description": null, + "args": {}, + "returns": null + }, + "cref": "@algorandfoundation/algorand-typescript/arc4/index.d.ts::Contract", + "member_name": "approvalProgram", + "arc4_method_config": null + }, + "clear_program": { + "_type": "ContractMethod", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "args": [], + "return_type": { + "_type": "WType", + "name": "bool", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "body": { + "_type": "Block", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "body": [ + { + "_type": "ReturnStatement", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "value": { + "_type": "BoolConstant", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "wtype": { + "_type": "WType", + "name": "bool", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "value": true + } + } + ], + "label": null, + "comment": null + }, + "documentation": { + "_type": "MethodDocumentation", + "description": null, + "args": {}, + "returns": null + }, + "cref": "@algorandfoundation/algorand-typescript/base-contract.d.ts::BaseContract", + "member_name": "clearStateProgram", + "arc4_method_config": null + }, + "methods": [ + { + "_type": "ContractMethod", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 13, + "end_line": 14, + "column": 0, + "end_column": 64 + }, + "args": [], + "return_type": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + }, + "body": { + "_type": "Block", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 13, + "end_line": 14, + "column": 0, + "end_column": 64 + }, + "body": [ + { + "_type": "ExpressionStatement", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 13, + "end_line": 14, + "column": 0, + "end_column": 64 + }, + "expr": { + "_type": "SubroutineCallExpression", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 13, + "end_line": 14, + "column": 0, + "end_column": 64 + }, + "wtype": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + }, + "target": { + "_type": "InstanceSuperMethodTarget", + "member_name": "constructor" + }, + "args": [] + } + } + ], + "label": null, + "comment": null + }, + "documentation": { + "_type": "MethodDocumentation", + "description": null, + "args": {}, + "returns": null + }, + "cref": "tests/approvals/state-totals.algo.ts::SubClassWithExplicitTotals", + "member_name": "constructor", + "arc4_method_config": null + }, + { + "_type": "ContractMethod", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 4, + "end_line": 4, + "column": 0, + "end_column": 45 + }, + "args": [], + "return_type": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + }, + "body": { + "_type": "Block", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 4, + "end_line": 4, + "column": 0, + "end_column": 45 + }, + "body": [ + { + "_type": "ExpressionStatement", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 4, + "end_line": 4, + "column": 0, + "end_column": 45 + }, + "expr": { + "_type": "VoidConstant", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 4, + "end_line": 4, + "column": 0, + "end_column": 45 + }, + "wtype": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + } + } + }, + { + "_type": "AssignmentStatement", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 5, + "end_line": 5, + "column": 2, + "end_column": 54 + }, + "target": { + "_type": "AppStateExpression", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 5, + "end_line": 5, + "column": 2, + "end_column": 11 + }, + "wtype": { + "_type": "WType", + "name": "uint64", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "key": { + "_type": "BytesConstant", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 5, + "end_line": 5, + "column": 2, + "end_column": 11 + }, + "wtype": { + "_type": "WType", + "name": "state_key", + "immutable": true, + "ephemeral": false, + "scalar_type": 1 + }, + "value": "Z*FBrY;R&=Yy", + "encoding": "utf8" + }, + "exists_assertion_message": null + }, + "value": { + "_type": "IntegerConstant", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 5, + "end_line": 5, + "column": 49, + "end_column": 50 + }, + "wtype": { + "_type": "WType", + "name": "uint64", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "value": "1", + "teal_alias": null + } + } + ], + "label": null, + "comment": null + }, + "documentation": { + "_type": "MethodDocumentation", + "description": null, + "args": {}, + "returns": null + }, + "cref": "tests/approvals/state-totals.algo.ts::BaseWithState", + "member_name": "constructor", + "arc4_method_config": null + }, + { + "_type": "ContractMethod", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "args": [], + "return_type": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + }, + "body": { + "_type": "Block", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "body": [ + { + "_type": "ExpressionStatement", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "expr": { + "_type": "SubroutineCallExpression", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "wtype": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + }, + "target": { + "_type": "InstanceMethodTarget", + "member_name": "constructor" + }, + "args": [] + } + } + ], + "label": null, + "comment": null + }, + "documentation": { + "_type": "MethodDocumentation", + "description": null, + "args": {}, + "returns": null + }, + "cref": "@algorandfoundation/algorand-typescript/arc4/index.d.ts::Contract", + "member_name": "constructor", + "arc4_method_config": null + }, + { + "_type": "ContractMethod", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "args": [], + "return_type": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + }, + "body": { + "_type": "Block", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "body": [], + "label": null, + "comment": null + }, + "documentation": { + "_type": "MethodDocumentation", + "description": null, + "args": {}, + "returns": null + }, + "cref": "@algorandfoundation/algorand-typescript/base-contract.d.ts::BaseContract", + "member_name": "constructor", + "arc4_method_config": null + }, + { + "_type": "ContractMethod", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 13, + "end_line": 14, + "column": 0, + "end_column": 64 + }, + "args": [], + "return_type": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + }, + "body": { + "_type": "Block", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 13, + "end_line": 14, + "column": 0, + "end_column": 64 + }, + "body": [], + "label": null, + "comment": null + }, + "documentation": { + "_type": "MethodDocumentation", + "description": "Implicitly generated create method", + "args": {}, + "returns": null + }, + "cref": "tests/approvals/state-totals.algo.ts::SubClassWithExplicitTotals", + "member_name": "__algots__.defaultCreate", + "arc4_method_config": { + "_type": "ARC4BareMethodConfig", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 13, + "end_line": 14, + "column": 0, + "end_column": 64 + }, + "allowed_completion_types": [ + 0 + ], + "create": 2, + "is_bare": true + } + } + ], + "app_state": [ + { + "_type": "AppStorageDefinition", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 5, + "end_line": 5, + "column": 2, + "end_column": 11 + }, + "member_name": "oneGlobal", + "kind": 1, + "storage_wtype": { + "_type": "WType", + "name": "uint64", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "key_wtype": null, + "key": { + "_type": "BytesConstant", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 5, + "end_line": 5, + "column": 2, + "end_column": 11 + }, + "wtype": { + "_type": "WType", + "name": "state_key", + "immutable": true, + "ephemeral": false, + "scalar_type": 1 + }, + "value": "Z*FBrY;R&=Yy", + "encoding": "utf8" + }, + "description": null + }, + { + "_type": "AppStorageDefinition", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 6, + "end_line": 6, + "column": 2, + "end_column": 11 + }, + "member_name": "twoGlobal", + "kind": 1, + "storage_wtype": { + "_type": "WType", + "name": "uint64", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "key_wtype": null, + "key": { + "_type": "BytesConstant", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 6, + "end_line": 6, + "column": 2, + "end_column": 11 + }, + "wtype": { + "_type": "WType", + "name": "state_key", + "immutable": true, + "ephemeral": false, + "scalar_type": 1 + }, + "value": "ba!t@Y;R&=Yy", + "encoding": "utf8" + }, + "description": null + } + ], + "state_totals": { + "_type": "StateTotals", + "global_uints": "4", + "local_uints": "0", + "global_bytes": null, + "local_bytes": null + }, + "reserved_scratch_space": [], + "avm_version": null + }, + { + "_type": "Contract", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 16, + "end_line": 17, + "column": 0, + "end_column": 70 + }, + "id": "tests/approvals/state-totals.algo.ts::ExtendsSubWithTotals", + "name": "ExtendsSubWithTotals", + "description": null, + "method_resolution_order": [ + "tests/approvals/state-totals.algo.ts::SubClassWithExplicitTotals", + "tests/approvals/state-totals.algo.ts::BaseWithState", + "@algorandfoundation/algorand-typescript/arc4/index.d.ts::Contract", + "@algorandfoundation/algorand-typescript/base-contract.d.ts::BaseContract" + ], + "approval_program": { + "_type": "ContractMethod", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "args": [], + "return_type": { + "_type": "WType", + "name": "bool", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "body": { + "_type": "Block", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "body": [ + { + "_type": "IfElse", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "condition": { + "_type": "Not", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "wtype": { + "_type": "WType", + "name": "bool", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "expr": { + "_type": "ReinterpretCast", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "wtype": { + "_type": "WType", + "name": "bool", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "expr": { + "_type": "IntrinsicCall", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "wtype": { + "_type": "WType", + "name": "uint64", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "op_code": "txn", + "immediates": [ + "ApplicationID" + ], + "stack_args": [] + } + } + }, + "if_branch": { + "_type": "Block", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "body": [ + { + "_type": "ExpressionStatement", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "expr": { + "_type": "SubroutineCallExpression", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "wtype": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + }, + "target": { + "_type": "InstanceMethodTarget", + "member_name": "constructor" + }, + "args": [] + } + } + ], + "label": null, + "comment": null + }, + "else_branch": null + }, + { + "_type": "Block", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "body": [ + { + "_type": "ReturnStatement", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "value": { + "_type": "ARC4Router", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "wtype": { + "_type": "WType", + "name": "bool", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + } + } + } + ], + "label": null, + "comment": null + } + ], + "label": null, + "comment": null + }, + "documentation": { + "_type": "MethodDocumentation", + "description": null, + "args": {}, + "returns": null + }, + "cref": "@algorandfoundation/algorand-typescript/arc4/index.d.ts::Contract", + "member_name": "approvalProgram", + "arc4_method_config": null + }, + "clear_program": { + "_type": "ContractMethod", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "args": [], + "return_type": { + "_type": "WType", + "name": "bool", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "body": { + "_type": "Block", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "body": [ + { + "_type": "ReturnStatement", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "value": { + "_type": "BoolConstant", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "wtype": { + "_type": "WType", + "name": "bool", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "value": true + } + } + ], + "label": null, + "comment": null + }, + "documentation": { + "_type": "MethodDocumentation", + "description": null, + "args": {}, + "returns": null + }, + "cref": "@algorandfoundation/algorand-typescript/base-contract.d.ts::BaseContract", + "member_name": "clearStateProgram", + "arc4_method_config": null + }, + "methods": [ + { + "_type": "ContractMethod", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 16, + "end_line": 17, + "column": 0, + "end_column": 70 + }, + "args": [], + "return_type": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + }, + "body": { + "_type": "Block", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 16, + "end_line": 17, + "column": 0, + "end_column": 70 + }, + "body": [ + { + "_type": "ExpressionStatement", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 16, + "end_line": 17, + "column": 0, + "end_column": 70 + }, + "expr": { + "_type": "SubroutineCallExpression", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 16, + "end_line": 17, + "column": 0, + "end_column": 70 + }, + "wtype": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + }, + "target": { + "_type": "InstanceSuperMethodTarget", + "member_name": "constructor" + }, + "args": [] + } + } + ], + "label": null, + "comment": null + }, + "documentation": { + "_type": "MethodDocumentation", + "description": null, + "args": {}, + "returns": null + }, + "cref": "tests/approvals/state-totals.algo.ts::ExtendsSubWithTotals", + "member_name": "constructor", + "arc4_method_config": null + }, + { + "_type": "ContractMethod", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 13, + "end_line": 14, + "column": 0, + "end_column": 64 + }, + "args": [], + "return_type": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + }, + "body": { + "_type": "Block", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 13, + "end_line": 14, + "column": 0, + "end_column": 64 + }, + "body": [ + { + "_type": "ExpressionStatement", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 13, + "end_line": 14, + "column": 0, + "end_column": 64 + }, + "expr": { + "_type": "SubroutineCallExpression", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 13, + "end_line": 14, + "column": 0, + "end_column": 64 + }, + "wtype": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + }, + "target": { + "_type": "InstanceSuperMethodTarget", + "member_name": "constructor" + }, + "args": [] + } + } + ], + "label": null, + "comment": null + }, + "documentation": { + "_type": "MethodDocumentation", + "description": null, + "args": {}, + "returns": null + }, + "cref": "tests/approvals/state-totals.algo.ts::SubClassWithExplicitTotals", + "member_name": "constructor", + "arc4_method_config": null + }, + { + "_type": "ContractMethod", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 4, + "end_line": 4, + "column": 0, + "end_column": 45 + }, + "args": [], + "return_type": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + }, + "body": { + "_type": "Block", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 4, + "end_line": 4, + "column": 0, + "end_column": 45 + }, + "body": [ + { + "_type": "ExpressionStatement", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 4, + "end_line": 4, + "column": 0, + "end_column": 45 + }, + "expr": { + "_type": "VoidConstant", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 4, + "end_line": 4, + "column": 0, + "end_column": 45 + }, + "wtype": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + } + } + }, + { + "_type": "AssignmentStatement", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 5, + "end_line": 5, + "column": 2, + "end_column": 54 + }, + "target": { + "_type": "AppStateExpression", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 5, + "end_line": 5, + "column": 2, + "end_column": 11 + }, + "wtype": { + "_type": "WType", + "name": "uint64", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "key": { + "_type": "BytesConstant", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 5, + "end_line": 5, + "column": 2, + "end_column": 11 + }, + "wtype": { + "_type": "WType", + "name": "state_key", + "immutable": true, + "ephemeral": false, + "scalar_type": 1 + }, + "value": "Z*FBrY;R&=Yy", + "encoding": "utf8" + }, + "exists_assertion_message": null + }, + "value": { + "_type": "IntegerConstant", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 5, + "end_line": 5, + "column": 49, + "end_column": 50 + }, + "wtype": { + "_type": "WType", + "name": "uint64", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "value": "1", + "teal_alias": null + } + } + ], + "label": null, + "comment": null + }, + "documentation": { + "_type": "MethodDocumentation", + "description": null, + "args": {}, + "returns": null + }, + "cref": "tests/approvals/state-totals.algo.ts::BaseWithState", + "member_name": "constructor", + "arc4_method_config": null + }, + { + "_type": "ContractMethod", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "args": [], + "return_type": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + }, + "body": { + "_type": "Block", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "body": [ + { + "_type": "ExpressionStatement", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "expr": { + "_type": "SubroutineCallExpression", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "wtype": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + }, + "target": { + "_type": "InstanceMethodTarget", + "member_name": "constructor" + }, + "args": [] + } + } + ], + "label": null, + "comment": null + }, + "documentation": { + "_type": "MethodDocumentation", + "description": null, + "args": {}, + "returns": null + }, + "cref": "@algorandfoundation/algorand-typescript/arc4/index.d.ts::Contract", + "member_name": "constructor", + "arc4_method_config": null + }, + { + "_type": "ContractMethod", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "args": [], + "return_type": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + }, + "body": { + "_type": "Block", + "source_location": { + "_type": "SourceLocation", + "file": null, + "line": 1, + "end_line": 1, + "column": 0, + "end_column": 1 + }, + "body": [], + "label": null, + "comment": null + }, + "documentation": { + "_type": "MethodDocumentation", + "description": null, + "args": {}, + "returns": null + }, + "cref": "@algorandfoundation/algorand-typescript/base-contract.d.ts::BaseContract", + "member_name": "constructor", + "arc4_method_config": null + }, + { + "_type": "ContractMethod", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 16, + "end_line": 17, + "column": 0, + "end_column": 70 + }, + "args": [], + "return_type": { + "_type": "WType", + "name": "void", + "immutable": true, + "ephemeral": false, + "scalar_type": null + }, + "body": { + "_type": "Block", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 16, + "end_line": 17, + "column": 0, + "end_column": 70 + }, + "body": [], + "label": null, + "comment": null + }, + "documentation": { + "_type": "MethodDocumentation", + "description": "Implicitly generated create method", + "args": {}, + "returns": null + }, + "cref": "tests/approvals/state-totals.algo.ts::ExtendsSubWithTotals", + "member_name": "__algots__.defaultCreate", + "arc4_method_config": { + "_type": "ARC4BareMethodConfig", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 16, + "end_line": 17, + "column": 0, + "end_column": 70 + }, + "allowed_completion_types": [ + 0 + ], + "create": 2, + "is_bare": true + } + } + ], + "app_state": [ + { + "_type": "AppStorageDefinition", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 5, + "end_line": 5, + "column": 2, + "end_column": 11 + }, + "member_name": "oneGlobal", + "kind": 1, + "storage_wtype": { + "_type": "WType", + "name": "uint64", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "key_wtype": null, + "key": { + "_type": "BytesConstant", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 5, + "end_line": 5, + "column": 2, + "end_column": 11 + }, + "wtype": { + "_type": "WType", + "name": "state_key", + "immutable": true, + "ephemeral": false, + "scalar_type": 1 + }, + "value": "Z*FBrY;R&=Yy", + "encoding": "utf8" + }, + "description": null + }, + { + "_type": "AppStorageDefinition", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 6, + "end_line": 6, + "column": 2, + "end_column": 11 + }, + "member_name": "twoGlobal", + "kind": 1, + "storage_wtype": { + "_type": "WType", + "name": "uint64", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "key_wtype": null, + "key": { + "_type": "BytesConstant", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 6, + "end_line": 6, + "column": 2, + "end_column": 11 + }, + "wtype": { + "_type": "WType", + "name": "state_key", + "immutable": true, + "ephemeral": false, + "scalar_type": 1 + }, + "value": "ba!t@Y;R&=Yy", + "encoding": "utf8" + }, + "description": null + }, + { + "_type": "AppStorageDefinition", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 18, + "end_line": 18, + "column": 2, + "end_column": 10 + }, + "member_name": "oneLocal", + "kind": 2, + "storage_wtype": { + "_type": "WType", + "name": "uint64", + "immutable": true, + "ephemeral": false, + "scalar_type": 2 + }, + "key_wtype": null, + "key": { + "_type": "BytesConstant", + "source_location": { + "file": "tests/approvals/state-totals.algo.ts", + "line": 18, + "end_line": 18, + "column": 2, + "end_column": 10 + }, + "wtype": { + "_type": "WType", + "name": "state_key", + "immutable": true, + "ephemeral": false, + "scalar_type": 1 + }, + "value": "Z*FBwZ)0I>", + "encoding": "utf8" + }, + "description": null + } + ], + "state_totals": { + "_type": "StateTotals", + "global_uints": null, + "local_uints": null, + "global_bytes": null, + "local_bytes": null + }, + "reserved_scratch_space": [], + "avm_version": null + } +] \ No newline at end of file diff --git a/tests/approvals/state-totals.algo.ts b/tests/approvals/state-totals.algo.ts new file mode 100644 index 00000000..c4a5732c --- /dev/null +++ b/tests/approvals/state-totals.algo.ts @@ -0,0 +1,37 @@ +import type { bytes, uint64 } from '@algorandfoundation/algorand-typescript' +import { abimethod, contract, Contract, GlobalState, LocalState, Txn, Uint64 } from '@algorandfoundation/algorand-typescript' + +export class BaseWithState extends Contract { + oneGlobal = GlobalState({ initialValue: Uint64(1) }) + twoGlobal = GlobalState() + oneLocalBytes = LocalState() + + setState(n: uint64) { + this.oneGlobal.value = n + this.twoGlobal.value = n + } +} + +export class SubClassWithState extends BaseWithState { + threeGlobal = GlobalState() + twoLocalBytes = LocalState() + setState(n: uint64) { + super.setState(n) + this.threeGlobal.value = n + } +} + +@contract({ stateTotals: { globalUints: 4, localUints: 0 } }) +export class SubClassWithExplicitTotals extends BaseWithState {} + +@contract({ stateTotals: {} }) +export class ExtendsSubWithTotals extends SubClassWithExplicitTotals { + oneLocal = LocalState() + + @abimethod({ allowActions: 'OptIn' }) + setState(n: uint64) { + super.setState(n) + + this.oneLocal(Txn.sender).value = n + } +} diff --git a/tests/onchain/state-totals.spec.ts b/tests/onchain/state-totals.spec.ts new file mode 100644 index 00000000..137c03f8 --- /dev/null +++ b/tests/onchain/state-totals.spec.ts @@ -0,0 +1,57 @@ +import { OnApplicationComplete } from 'algosdk' +import { describe, expect } from 'vitest' +import { createArc4TestFixture } from './util/test-fixture' + +describe('State totals', () => { + const test = createArc4TestFixture('tests/approvals/state-totals.algo.ts', { + ExtendsSubWithTotals: {}, + BaseWithState: {}, + SubClassWithState: {}, + SubClassWithExplicitTotals: {}, + }) + + test('BaseWithState has correct totals', ({ appSpecBaseWithState }) => { + expect(appSpecBaseWithState.state.global.num_uints).toBe(2) + expect(appSpecBaseWithState.state.local.num_byte_slices).toBe(1) + }) + test('BaseWithState runs', async ({ appClientBaseWithState }) => { + await appClientBaseWithState.send.call({ method: 'setState', args: [123] }) + + const state = await appClientBaseWithState.getGlobalState() + expect(state['oneGlobal'].value).toBe(123n) + expect(state['twoGlobal'].value).toBe(123n) + }) + test('SubClassWithState has correct totals', ({ appSpecSubClassWithState }) => { + expect(appSpecSubClassWithState.state.global.num_uints).toBe(3) + expect(appSpecSubClassWithState.state.local.num_byte_slices).toBe(2) + }) + test('SubClassWithState runs', async ({ appClientSubClassWithState }) => { + await appClientSubClassWithState.send.call({ method: 'setState', args: [456] }) + + const state = await appClientSubClassWithState.getGlobalState() + expect(state['oneGlobal'].value).toBe(456n) + expect(state['twoGlobal'].value).toBe(456n) + expect(state['threeGlobal'].value).toBe(456n) + }) + test('SubClassWithExplicitTotals has correct totals', ({ appSpecSubClassWithExplicitTotals }) => { + expect(appSpecSubClassWithExplicitTotals.state.global.num_uints).toBe(4) + expect(appSpecSubClassWithExplicitTotals.state.global.num_byte_slices).toBe(0) + expect(appSpecSubClassWithExplicitTotals.state.local.num_uints).toBe(0) + expect(appSpecSubClassWithExplicitTotals.state.local.num_byte_slices).toBe(1) + }) + test('ExtendsSubWithTotals has correct totals', ({ appSpecExtendsSubWithTotals }) => { + expect(appSpecExtendsSubWithTotals.state.global.num_uints).toBe(2) + expect(appSpecExtendsSubWithTotals.state.local.num_uints).toBe(1) + expect(appSpecExtendsSubWithTotals.state.local.num_byte_slices).toBe(1) + }) + test('ExtendsSubWithTotals runs', async ({ appClientExtendsSubWithTotals, testAccount }) => { + await appClientExtendsSubWithTotals.send.call({ method: 'setState', args: [789], onComplete: OnApplicationComplete.OptInOC }) + + const state = await appClientExtendsSubWithTotals.getGlobalState() + expect(state['oneGlobal'].value).toBe(789n) + expect(state['twoGlobal'].value).toBe(789n) + const localState = await appClientExtendsSubWithTotals.getLocalState(testAccount) + + expect(localState['oneLocal'].value).toBe(789n) + }) +}) diff --git a/tests/onchain/util/test-fixture.ts b/tests/onchain/util/test-fixture.ts index a9a46a2c..1d6a631f 100644 --- a/tests/onchain/util/test-fixture.ts +++ b/tests/onchain/util/test-fixture.ts @@ -123,6 +123,8 @@ type Arc4FixtureContextFor = { [key in T as `appFactory${key}`]: AppFactory } & { [key in T as `appClient${key}`]: AppClient +} & { + [key in T as `appSpec${key}`]: AppSpec } type ContractConfig = { @@ -139,16 +141,26 @@ export function createArc4TestFixture(path: stri logger: nullLogger, }) + function getAppSpec(expect: ExpectStatic, contractName: string) { + const appSpec = lazyCompile.getCompileResult(expect).appSpecs.find((s) => s.contract.name === contractName) + if (appSpec === undefined) { + expect.fail(`${path} does not contain an ARC4 contract "${contractName}"`) + } else { + return appSpec + } + } + const ctx: DeliberateAny = {} for (const [contractName, config] of Object.entries(contracts) as Array<[TContracts, ContractConfig]>) { + ctx[`appSpec${contractName}`] = async ({ expect }: { expect: ExpectStatic }, use: Use) => { + await use(getAppSpec(expect, contractName)) + } + ctx[`appFactory${contractName}`] = async ( { expect, localnet }: { expect: ExpectStatic; localnet: AlgorandFixture }, use: Use, ) => { - const appSpec = lazyCompile.getCompileResult(expect).appSpecs.find((s) => s.contract.name === contractName) - if (appSpec === undefined) { - expect.fail(`${path} does not contain an ARC4 contract "${contractName}"`) - } + const appSpec = getAppSpec(expect, contractName) await use( localnet.algorand.client.getAppFactory({ defaultSender: localnet.context.testAccount.addr, @@ -160,10 +172,7 @@ export function createArc4TestFixture(path: stri { expect, localnet }: { expect: ExpectStatic; localnet: AlgorandFixture }, use: Use, ) => { - const appSpec = lazyCompile.getCompileResult(expect).appSpecs.find((s) => s.contract.name === contractName) - if (appSpec === undefined) { - expect.fail(`${path} does not contain an ARC4 contract "${contractName}"`) - } + const appSpec = getAppSpec(expect, contractName) const appFactory = localnet.algorand.client.getAppFactory({ defaultSender: localnet.context.testAccount.addr, appSpec: appSpec!,