Skip to content

Commit

Permalink
chore(go): emit one file per type (#3698)
Browse files Browse the repository at this point in the history
Instead of generating one file will ALL the types in a given
(sub)module, emit one file per type within the (sub)module,
so that the compiler operates on smaller compilation units.
This should reduce the memory pressure the compiler
experiences when dealing with large libraries.

---

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

[Apache 2.0 license]: https://www.apache.org/licenses/LICENSE-2.0
  • Loading branch information
RomainMuller committed Aug 10, 2022
1 parent f5e0603 commit f584a17
Show file tree
Hide file tree
Showing 7 changed files with 15,042 additions and 11,848 deletions.
59 changes: 20 additions & 39 deletions packages/jsii-pacmak/lib/targets/go/package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@ import {
Type,
Submodule as JsiiSubmodule,
} from 'jsii-reflect';
import { basename, dirname, join } from 'path';
import { join } from 'path';
import * as semver from 'semver';

import { VERSION } from '../../version';
import { SpecialDependencies } from './dependencies';
import { EmitContext } from './emit-context';
import { ReadmeFile } from './readme-file';
import {
Expand Down Expand Up @@ -59,7 +58,7 @@ export abstract class Package {
root?: Package,
) {
this.directory = filePath;
this.file = `${this.directory}/${packageName}.go`;
this.file = join(this.directory, `${packageName}.go`);
this.root = root ?? this;
this.submodules = this.jsiiModule.submodules.map(
(sm) => new InternalPackage(this.root, this, sm),
Expand Down Expand Up @@ -111,13 +110,6 @@ export abstract class Package {
return `${prefix}${rootPackageName}${versionSuffix}${suffix}`;
}

/*
* The module names of this module's dependencies. Used for import statements.
*/
public get dependencyImports(): Set<string> {
return new Set(this.dependencies.map((pkg) => pkg.goModuleName));
}

/*
* Search for a type with a `fqn` within this. Searches all Children modules as well.
*/
Expand All @@ -126,13 +118,7 @@ export abstract class Package {
}

public emit(context: EmitContext): void {
const { code } = context;

code.openFile(this.file);
this.emitHeader(code);
this.emitImports(code);
this.emitTypes(context);
code.closeFile(this.file);

this.readmeFile?.emit(context);

Expand Down Expand Up @@ -200,20 +186,6 @@ export abstract class Package {
code.line();
}

protected get specialDependencies(): SpecialDependencies {
return this.types
.map((t) => t.specialDependencies)
.reduce(
(acc, elt) => ({
runtime: acc.runtime || elt.runtime,
init: acc.init || elt.init,
internal: acc.internal || elt.internal,
time: acc.time || elt.time,
}),
{ runtime: false, init: false, internal: false, time: false },
);
}

/**
* Emits a `func init() { ... }` in a dedicated file (so we don't have to
* worry about what needs to be imported and whatnot). This function is
Expand All @@ -226,10 +198,7 @@ export abstract class Package {
// form. It also saves us from "imported but unused" errors that would arise
// as a consequence.
if (this.types.length > 0) {
const initFile = join(
dirname(this.file),
`${basename(this.file, '.go')}.init.go`,
);
const initFile = join(this.directory, `${this.packageName}.go`);
code.openFile(initFile);
code.line(`package ${this.packageName}`);
code.line();
Expand All @@ -244,10 +213,10 @@ export abstract class Package {
}
}

private emitImports(code: CodeMaker) {
private emitImports(code: CodeMaker, type: GoType) {
const toImport = new Array<ImportedModule>();

const specialDeps = this.specialDependencies;
const specialDeps = type.specialDependencies;

if (specialDeps.time) {
toImport.push({ module: 'time' });
Expand All @@ -270,10 +239,12 @@ export abstract class Package {
});
}

for (const packageName of this.dependencyImports) {
for (const goModuleName of new Set(
type.dependencies.map(({ goModuleName }) => goModuleName),
)) {
// If the module is the same as the current one being written, don't emit an import statement
if (packageName !== this.packageName) {
toImport.push({ module: packageName });
if (goModuleName !== this.goModuleName) {
toImport.push({ module: goModuleName });
}
}

Expand All @@ -283,7 +254,17 @@ export abstract class Package {

private emitTypes(context: EmitContext) {
for (const type of this.types) {
const filePath = join(
this.directory,
`${this.packageName}_${type.name}.go`,
);
context.code.openFile(filePath);

this.emitHeader(context.code);
this.emitImports(context.code, type);
type.emit(context);

context.code.closeFile(filePath);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,12 @@ export class GoTypeRef {
if (ref.mapOfType) {
return containsDate(ref.mapOfType);
}
if (ref.unionOfTypes) {
return ref.unionOfTypes.some(containsDate);
}
// NOTE: UNION gets represented as interface{} so we don't need to import
// individual types here...
//
// if (ref.unionOfTypes) {
// return ref.unionOfTypes.some(containsDate);
// }
return false;
}
}
Expand Down
18 changes: 13 additions & 5 deletions packages/jsii-pacmak/lib/targets/go/types/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ import { GoMethod, GoProperty } from './type-member';

export class GoInterface extends GoType<InterfaceType> {
public readonly methods: InterfaceMethod[];
public readonly reimplementedMethods?: readonly InterfaceMethod[];
public readonly reimplementedMethods: readonly InterfaceMethod[];
public readonly properties: InterfaceProperty[];
public readonly reimplementedProperties?: readonly InterfaceProperty[];
public readonly reimplementedProperties: readonly InterfaceProperty[];

public constructor(pkg: Package, type: InterfaceType) {
super(pkg, type);
Expand Down Expand Up @@ -50,6 +50,9 @@ export class GoInterface extends GoType<InterfaceType> {
)
.map((property) => new InterfaceProperty(this, property))
.sort(comparators.byName);
} else {
this.reimplementedMethods = [];
this.reimplementedProperties = [];
}
}

Expand Down Expand Up @@ -94,7 +97,7 @@ export class GoInterface extends GoType<InterfaceType> {
method.emit(context);
}

for (const method of this.reimplementedMethods ?? []) {
for (const method of this.reimplementedMethods) {
method.emit(context);
}

Expand All @@ -106,7 +109,7 @@ export class GoInterface extends GoType<InterfaceType> {
}
}

for (const prop of this.reimplementedProperties ?? []) {
for (const prop of this.reimplementedProperties) {
prop.emitGetterProxy(context);

if (!prop.immutable) {
Expand Down Expand Up @@ -145,7 +148,9 @@ export class GoInterface extends GoType<InterfaceType> {
public get specialDependencies(): SpecialDependencies {
return [
...this.properties.map((p) => p.specialDependencies),
...this.reimplementedProperties.map((p) => p.specialDependencies),
...this.methods.map((m) => m.specialDependencies),
...this.reimplementedMethods.map((m) => m.specialDependencies),
].reduce(
(acc, elt) => ({
runtime: acc.runtime || elt.runtime,
Expand Down Expand Up @@ -184,8 +189,11 @@ export class GoInterface extends GoType<InterfaceType> {
return [
...this.extendsDependencies,
...getMemberDependencies(this.methods),
...getParamDependencies(this.methods),
...getMemberDependencies(this.reimplementedMethods),
...getMemberDependencies(this.properties),
...getMemberDependencies(this.reimplementedProperties),
...getParamDependencies(this.methods),
...getParamDependencies(this.reimplementedMethods),
];
}
}
Expand Down
19 changes: 5 additions & 14 deletions packages/jsii-pacmak/lib/targets/go/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,22 +50,13 @@ export function flatMap<T, R>(
export function getMemberDependencies(
members: readonly GoTypeMember[],
): Package[] {
const deps = new Array<Package>();
for (const member of members) {
deps.push(...(member.reference?.dependencies ?? []));
}

return deps;
return members.flatMap((member) => member.reference?.dependencies ?? []);
}

export function getParamDependencies(methods: GoMethod[]): Package[] {
const dependencies: Package[] = [];
for (const method of methods) {
for (const param of method.parameters) {
dependencies.push(...(param.reference?.dependencies ?? []));
}
}
return dependencies;
export function getParamDependencies(methods: readonly GoMethod[]): Package[] {
return methods.flatMap(({ parameters }) =>
parameters.flatMap((param) => param.reference?.dependencies ?? []),
);
}

const RESERVED_WORDS: { [word: string]: string } = {
Expand Down
Loading

0 comments on commit f584a17

Please sign in to comment.