-
Notifications
You must be signed in to change notification settings - Fork 246
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(go): represent jsii structs as go structs (only) (#2600)
As proposed in aws/aws-cdk-rfcs#292 (this is *Approach 4*), stop rendering go interfaces to represent jsii structs, and instead only emit a plain go struct with the flattened list of fields (own + all super interfaces). Made the necessary code changes to de-serialize structs returned by-reference by the `@jsii/kernel` by eagerly fecthing all properties. Also, implemented the option to offer convenience conversion functions to easily create a parent type from a child type.
- Loading branch information
1 parent
6e74bf9
commit e7cc93e
Showing
9 changed files
with
335 additions
and
1,630 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
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 |
---|---|---|
@@ -1,28 +1,93 @@ | ||
import * as assert from 'assert'; | ||
import { CodeMaker } from 'codemaker'; | ||
import { InterfaceType } from 'jsii-reflect'; | ||
|
||
import { EmitContext } from '../emit-context'; | ||
import { Package } from '../package'; | ||
import { JSII_RT_ALIAS } from '../runtime'; | ||
import { GoStruct } from './go-type'; | ||
import { getMemberDependencies } from '../util'; | ||
import { GoType } from './go-type'; | ||
import { GoTypeRef } from './go-type-reference'; | ||
import { GoProperty } from './type-member'; | ||
|
||
/* | ||
* Struct wraps a JSII datatype interface aka, structs | ||
*/ | ||
export class Struct extends GoStruct { | ||
public constructor(parent: Package, type: InterfaceType) { | ||
export class Struct extends GoType { | ||
private readonly properties: readonly GoProperty[]; | ||
|
||
public constructor(parent: Package, public readonly type: InterfaceType) { | ||
super(parent, type); | ||
// TODO check if datatype? (isDataType() on jsii-reflect seems wrong) | ||
|
||
assert( | ||
type.isDataType(), | ||
`The provided interface ${type.fqn} is not a struct!`, | ||
); | ||
|
||
this.properties = type.allProperties.map( | ||
(prop) => new GoProperty(this, prop), | ||
); | ||
} | ||
|
||
public get dependencies(): Package[] { | ||
return getMemberDependencies(this.properties); | ||
} | ||
|
||
public get usesRuntimePackage(): boolean { | ||
return false; | ||
} | ||
|
||
public get usesInitPackage(): boolean { | ||
return false; | ||
} | ||
|
||
public emit(context: EmitContext): void { | ||
const { code, documenter } = context; | ||
documenter.emit(this.type.docs); | ||
code.openBlock(`type ${this.name} struct`); | ||
for (const property of this.properties) { | ||
property.emitStructMember(context); | ||
} | ||
code.closeBlock(); | ||
code.line(); | ||
|
||
this.emitBaseConversions(context); | ||
} | ||
|
||
public emitRegistration(code: CodeMaker): void { | ||
code.open(`${JSII_RT_ALIAS}.RegisterStruct(`); | ||
code.line(`"${this.fqn}",`); | ||
code.line(`reflect.TypeOf((*${this.name})(nil)).Elem(),`); | ||
code.line(`reflect.TypeOf((*${this.interfaceName})(nil)).Elem(),`); | ||
code.close(')'); | ||
} | ||
|
||
public get usesRuntimePackage(): boolean { | ||
return this.properties.some((p) => p.usesRuntimePackage); | ||
private emitBaseConversions({ code }: EmitContext) { | ||
for (const base of this.type.getInterfaces(true)) { | ||
const baseType = this.pkg.root.findType(base.fqn) as Struct; | ||
const funcName = `To${baseType.name}`; | ||
const instanceVar = this.name[0].toLowerCase(); | ||
const valType = new GoTypeRef(this.pkg.root, base.reference).scopedName( | ||
this.pkg, | ||
); | ||
|
||
code.line( | ||
`// ${funcName} is a convenience function to obtain a new ${valType} from this ${this.name}.`, | ||
); | ||
// Note - using a pointer receiver here as a convenience, as otherwise | ||
// user code that somehow has only a pointer would need to first | ||
// dereference it, which tends to be a code smell. | ||
code.openBlock( | ||
`func (${instanceVar} *${this.name}) ${funcName}() ${valType}`, | ||
); | ||
|
||
code.openBlock(`return ${valType}`); | ||
for (const prop of baseType.properties) { | ||
code.line(`${prop.name}: ${instanceVar}.${prop.name},`); | ||
} | ||
code.closeBlock(); | ||
|
||
code.closeBlock(); | ||
code.line(); | ||
} | ||
} | ||
} |
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
Oops, something went wrong.