in src/languages/go.ts [471:542]
public override propertyAccessExpression(
node: ts.PropertyAccessExpression,
renderer: GoRenderer,
submoduleReference?: SubmoduleReference,
): OTree {
if (submoduleReference != null) {
return new OTree([
renderer
.updateContext({ isExported: false, isPtr: false, wrapPtr: false })
.convert(submoduleReference.lastNode),
]);
}
const expressionType = typeOfExpression(renderer.typeChecker, node.expression);
const valueSymbol = renderer.typeChecker.getSymbolAtLocation(node.name);
const isStaticMember = valueSymbol?.valueDeclaration != null && isStatic(valueSymbol.valueDeclaration);
const isClassStaticPropertyAccess =
isStaticMember &&
expressionType?.symbol?.valueDeclaration != null &&
valueSymbol.valueDeclaration != null &&
ts.isClassDeclaration(expressionType.symbol.valueDeclaration) &&
(ts.isPropertyDeclaration(valueSymbol.valueDeclaration) || ts.isAccessor(valueSymbol.valueDeclaration));
const isClassStaticMethodAccess =
isStaticMember &&
!isClassStaticPropertyAccess &&
valueSymbol.valueDeclaration != null &&
ts.isMethodDeclaration(valueSymbol.valueDeclaration);
// When the expression has an unknown type (unresolved symbol), has an upper-case first letter,
// and doesn't end in a call expression (as hinted by the presence of parentheses), we assume
// it's a type name... In such cases, what comes after can be considered a static member access.
// Note that the expression might be further qualified, so we check using a regex that checks
// for the last "." - delimited segment if there's dots in there...
const expressionLooksLikeTypeReference =
expressionType.symbol == null &&
/(?:\.|^)[A-Z][^.)]*$/.exec(node.expression.getText(node.expression.getSourceFile())) != null;
// Whether the node is an enum member reference.
const isEnumMember =
expressionType?.symbol?.valueDeclaration != null && ts.isEnumDeclaration(expressionType.symbol.valueDeclaration);
const jsiiSymbol = lookupJsiiSymbolFromNode(renderer.typeChecker, node.name);
const isExportedTypeName = jsiiSymbol != null && jsiiSymbol.symbolType !== 'module';
const delimiter =
isEnumMember || isClassStaticPropertyAccess || isClassStaticMethodAccess || expressionLooksLikeTypeReference
? '_'
: '.';
return new OTree([
renderer.convert(node.expression),
delimiter,
renderer
.updateContext({
isExported:
isClassStaticPropertyAccess ||
isClassStaticMethodAccess ||
expressionLooksLikeTypeReference ||
isEnumMember ||
isExportedTypeName,
})
.convert(node.name),
...(isClassStaticPropertyAccess
? ['()']
: // If the parent's not a call-like expression, and it's an inferred static property access, we need to put call
// parentheses at the end, as static properties are accessed via synthetic readers.
expressionLooksLikeTypeReference && findUp(node, ts.isCallLikeExpression) == null
? ['()']
: []),
]);
}