Skip to content

Conversation

@MrArnoldPalmer
Copy link
Contributor

@MrArnoldPalmer MrArnoldPalmer commented Aug 15, 2020

Adds logic for emitting submodules and namespace aware types.

Creates a Module base class that is extended by both Package and Submodule. Module represents a single .go source code file that has a package xxx declaration at the top. For the root file, this is the package name. For all submodules, this is the submodule name. All instances of Module have a reference to the root package so they are able to search the entire package for a type by fqn.

All instances of GoType now have a property parent that is the instance of Module that the type is defined in. This is used to pass to any instances of GoTypeRef that the type may refer to. GoTypeRef can resolve the corresponding instance of GoType using the types parent Module as described above.

The combination of these things means that starting at the root Package, an AST is defined that mimics the structure of the .jsii assembly but with all go specific emit logic. This makes it possible to access distant nodes in the tree which is what allows for namespace resolution of foreign type references.


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@mergify mergify bot added the contribution/core This is a PR that came from AWS. label Aug 15, 2020
@mergify
Copy link
Contributor

mergify bot commented Aug 15, 2020

The title of this Pull Request does not conform with [Conventional Commits] guidelines. It will need to be adjusted before the PR can be merged.
[Conventional Commits]: https://www.conventionalcommits.org

@MrArnoldPalmer MrArnoldPalmer force-pushed the golang/code-generation-ast branch from 6038e1f to a5c9801 Compare August 15, 2020 01:15
Copy link
Contributor

@SoManyHs SoManyHs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't reference lines bc the snapshot diff is too large, but I was seeing:

import (

    "github.com/aws-cdk/jsii/jsii"
    "child"
    "child"
    "child"
    "jsiicalc"

)

so looks like something in the import generation is not quite right?

let t: Enum | Interface | GoClass | undefined;
function buildModuleTypes(parent: Module, types: readonly Type[]): ModuleTypes {
return types.map(
(type: Type): ModuleType => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Can we use a switch statement on the expression type.kind here instead?

Copy link
Contributor Author

@MrArnoldPalmer MrArnoldPalmer Aug 18, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem with a switch on Type.Kind is that typescript can't infer the type of the Type.

  public get types(): ModuleTypes {
    return this.typeSpec.map(
      (type: Type): ModuleType => {
        switch (type.kind) {
          case TypeKind.Class:
            return new GoClass(this, type);
          // ...
          default:
            throw new Error(
              `Type: ${type.name} with kind ${type.kind} is not a supported type`,
            );
        }
      },
    );
  }

Throws a type error Argument of type 'Type' is not assignable to parameter of type 'ClassType'. The isXxxType() methods on the jsii-reflect.Type class are type discriminators so that's why they are used here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Err it's pretty much a discriminated union, I reckon this could be made to work... perhaps the issue is with how we modeled the class hierarchy here that prevents the compiler from making the correct type reduction?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could make it work using return new GoClass(this, type as Class). I generally prefer not to use as if possible.

Fixes compiler errors on generated code with the following:

1. Return placeholder types from JSII class method calls
2. Prevent recursive structs by detecting types nested as properties
within themselves and use a pointer instead
3. Map TS `any` types to an empty struct `GoAny` to be provided by the
JSII runtime library
4. Fix `map` and slice type signatures in struct properties
5. Fix submodule struct and `package` names
6. Fix broken PascalCasing of return types in class methods when
returning a named JSII type

Also misc cleanup/enhancements:
1. Call a dummy NoOp method inside JSII class method calls provided by
runtime
2. Add import statement for runtime library to modules
3. Consolidate import statements
@MrArnoldPalmer MrArnoldPalmer force-pushed the golang/code-generation-ast branch from 46c5ca0 to ccb1261 Compare August 18, 2020 03:37
Add some doc comments and cleanup.

Changes the `Module` interface to an abstract base class that is
extended by `Package` and `Submodule` to avoid repeating module build
and emit logic.

Change dynamic getters for module submodules and types to be built and
set in constructor to avoid unecessary recomputation.
@MrArnoldPalmer MrArnoldPalmer force-pushed the golang/code-generation-ast branch from ccb1261 to 0db0dbb Compare August 18, 2020 04:04
Minimizes changes to interface type for refactoring to class layout
based on struct/interface differences.
@MrArnoldPalmer MrArnoldPalmer marked this pull request as ready for review August 18, 2020 04:37
@RomainMuller RomainMuller changed the title feature: go namespace aware types feat(golfing): namespace aware types Aug 18, 2020
@RomainMuller RomainMuller changed the title feat(golfing): namespace aware types feat(golang): namespace aware types Aug 18, 2020
@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • CodeBuild project: AutoBuildProject6AEA49D1-Blkkw9bQFn8A
  • Commit ID: 572f151
  • Result: FAILED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

/*
* Format NPM package names as idiomatic Go module name
*/
export function goModuleName(name: string): string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: should we call this goPackageName?

}

/*
* The module names of this modules dependencies. Used for import statements
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: module's

code.line();
}

public get returnType(): string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noop: Just noting for posterity that we should include a comment here about how type resolution stuff has to happen outside the constructor.

@SoManyHs SoManyHs dismissed stale reviews from RomainMuller and themself August 18, 2020 23:56

outdated

@SoManyHs SoManyHs merged commit 572f151 into aws:golang/code-generation Aug 19, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contribution/core This is a PR that came from AWS.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants