-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e0cce03
commit d0bfed7
Showing
23 changed files
with
3,656 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { NoImplementation } from './impl/errors' | ||
import { DeliberateAny } from './typescript-helpers' | ||
|
||
/** | ||
* Emit an arc28 event log using either an ARC4Struct type or a named object type. | ||
* Object types must have an ARC4 equivalent type. | ||
* | ||
* Anonymous types cannot be used as the type name is used to determine the event prefix | ||
* @param event An ARC4Struct instance, or a plain object with a named type | ||
* | ||
* @example | ||
* class Demo extends Struct<{ a: UintN64 }> {} | ||
* emit(new Demo({ a: new UintN64(123) })) | ||
* | ||
* @example | ||
* type Demo = { a: uint64 } | ||
* emit<Demo>({a: 123}) | ||
* // or | ||
* const d: Demo = { a: 123 } | ||
* emit(d) | ||
*/ | ||
export function emit<TEvent extends Record<string, DeliberateAny>>(event: TEvent): void | ||
/** | ||
* Emit an arc28 event log using an explicit name and inferred property/field types. | ||
* Property types must be ARC4 or have an ARC4 equivalent type. | ||
* @param eventName The name of the event (must be a compile time constant) | ||
* @param eventProps A set of event properties (order is significant) | ||
* | ||
* @example | ||
* emit("Demo", new UintN64(123)) | ||
* | ||
* @example | ||
* const a: uint64 = 123 | ||
* emit("Demo", a) | ||
*/ | ||
export function emit<TProps extends [...DeliberateAny[]]>(eventName: string, ...eventProps: TProps): void | ||
export function emit<T>(event: T | string, ...eventProps: unknown[]): void { | ||
throw new NoImplementation() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
109 changes: 109 additions & 0 deletions
109
src/awst_build/eb/arc28/arc-28-emit-function-builder.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
import { nodeFactory } from '../../../awst/node-factory' | ||
import type { Expression } from '../../../awst/nodes' | ||
import type { SourceLocation } from '../../../awst/source-location' | ||
import { InternalError } from '../../../errors' | ||
import { logger } from '../../../logger' | ||
import { codeInvariant } from '../../../util' | ||
import { ptypeToArc4EncodedType } from '../../arc4-util' | ||
import type { PType } from '../../ptypes' | ||
import { arc28EmitFunction, ObjectPType, stringPType, voidPType } from '../../ptypes' | ||
import { ARC4EncodedType, ARC4StructType } from '../../ptypes/arc4-types' | ||
import { instanceEb } from '../../type-registry' | ||
import type { NodeBuilder } from '../index' | ||
import { FunctionBuilder } from '../index' | ||
import { requireStringConstant } from '../util' | ||
import { parseFunctionArgs } from '../util/arg-parsing' | ||
|
||
export class Arc28EmitFunctionBuilder extends FunctionBuilder { | ||
readonly ptype = arc28EmitFunction | ||
|
||
call(args: ReadonlyArray<NodeBuilder>, typeArgs: ReadonlyArray<PType>, sourceLocation: SourceLocation): NodeBuilder { | ||
const { | ||
args: [nameOrObj, ...props], | ||
ptypes: [genericArg], | ||
} = parseFunctionArgs({ | ||
args, | ||
typeArgs, | ||
genericTypeArgs: 1, | ||
callLocation: sourceLocation, | ||
funcName: this.typeDescription, | ||
argSpec: (a) => [a.required(), ...args.slice(1).map(() => a.required())], | ||
}) | ||
|
||
if (nameOrObj.ptype.equals(stringPType)) { | ||
const name = requireStringConstant(nameOrObj).value | ||
const thisModule = nameOrObj.sourceLocation.file ?? '' | ||
|
||
const fields: Record<string, ARC4EncodedType> = {} | ||
const values = new Map<string, Expression>() | ||
|
||
for (const [index, prop] of Object.entries(props)) { | ||
const arc4Type = ptypeToArc4EncodedType(prop.ptype, prop.sourceLocation) | ||
fields[index] = arc4Type | ||
values.set( | ||
index, | ||
prop.ptype instanceof ARC4EncodedType | ||
? prop.resolve() | ||
: nodeFactory.aRC4Encode({ | ||
value: prop.resolve(), | ||
wtype: arc4Type.wtype, | ||
sourceLocation: prop.sourceLocation, | ||
}), | ||
) | ||
} | ||
|
||
const structType = new ARC4StructType({ | ||
name, | ||
module: thisModule, | ||
fields, | ||
description: undefined, | ||
sourceLocation, | ||
}) | ||
const structExpression = nodeFactory.newStruct({ | ||
wtype: structType.wtype, | ||
values, | ||
sourceLocation, | ||
}) | ||
|
||
return emitStruct(structType, structExpression, sourceLocation) | ||
} | ||
codeInvariant(props.length === 0, 'Unexpected args', props[0]?.sourceLocation) | ||
|
||
const eventBuilder = nameOrObj.resolveToPType(genericArg) | ||
|
||
const eventType = eventBuilder.ptype | ||
if (eventType instanceof ARC4StructType) { | ||
return emitStruct(eventType, nameOrObj.resolve(), sourceLocation) | ||
} else if (eventType instanceof ObjectPType) { | ||
if (eventType.isAnonymous) { | ||
logger.error( | ||
eventBuilder.sourceLocation, | ||
'Event cannot be an anonymous type. If a named type exists, try specifying it explicitly via the generic parameter. Eg. `emit<YourType>({...})`', | ||
) | ||
} | ||
const arc4Equivalent = ptypeToArc4EncodedType(eventType, sourceLocation) | ||
return emitStruct( | ||
arc4Equivalent, | ||
nodeFactory.aRC4Encode({ | ||
wtype: arc4Equivalent.wtype, | ||
sourceLocation: nameOrObj.sourceLocation, | ||
value: nameOrObj.resolve(), | ||
}), | ||
sourceLocation, | ||
) | ||
} | ||
throw new InternalError('Unexpected type for arg 0 of emit', { sourceLocation }) | ||
} | ||
} | ||
|
||
function emitStruct(ptype: ARC4StructType, expression: Expression, sourceLocation: SourceLocation) { | ||
return instanceEb( | ||
nodeFactory.emit({ | ||
signature: ptype.signature, | ||
value: expression, | ||
wtype: voidPType.wtype, | ||
sourceLocation, | ||
}), | ||
voidPType, | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import type { uint64 } from '@algorandfoundation/algorand-typescript' | ||
import { Contract, emit } from '@algorandfoundation/algorand-typescript' | ||
import { Struct, UintN64 } from '@algorandfoundation/algorand-typescript/arc4' | ||
|
||
type Swapped = { | ||
a: uint64 | ||
b: uint64 | ||
} | ||
|
||
class SwappedArc4 extends Struct<{ a: UintN64; b: UintN64 }> {} | ||
|
||
class EventEmitter extends Contract { | ||
emitSwapped(a: uint64, b: uint64) { | ||
emit<Swapped>({ a: b, b: a }) | ||
|
||
const x: Swapped = { a: b, b: a } | ||
emit(x) | ||
|
||
const y = new SwappedArc4({ | ||
a: new UintN64(b), | ||
b: new UintN64(a), | ||
}) | ||
emit(y) | ||
|
||
emit('Swapped', b, a) | ||
} | ||
|
||
emitCustom(arg0: string, arg1: boolean) { | ||
emit('Custom', arg0, arg1) | ||
} | ||
} |
Oops, something went wrong.