package declarations import ( "github.com/microsoft/typescript-go/internal/ast" "github.com/microsoft/typescript-go/internal/core" "github.com/microsoft/typescript-go/internal/printer" ) func needsScopeMarker(result *ast.Node) bool { return !ast.IsAnyImportOrReExport(result) && !ast.IsExportAssignment(result) && !ast.HasSyntacticModifier(result, ast.ModifierFlagsExport) && !ast.IsAmbientModule(result) } func canHaveLiteralInitializer(host DeclarationEmitHost, node *ast.Node) bool { switch node.Kind { case ast.KindPropertyDeclaration, ast.KindPropertySignature: return host.GetEffectiveDeclarationFlags(node, ast.ModifierFlagsPrivate) == 0 case ast.KindParameter, ast.KindVariableDeclaration: return true } return false } func canProduceDiagnostics(node *ast.Node) bool { return ast.IsVariableDeclaration(node) || ast.IsPropertyDeclaration(node) || ast.IsPropertySignatureDeclaration(node) || ast.IsBindingElement(node) || ast.IsSetAccessorDeclaration(node) || ast.IsGetAccessorDeclaration(node) || ast.IsConstructSignatureDeclaration(node) || ast.IsCallSignatureDeclaration(node) || ast.IsMethodDeclaration(node) || ast.IsMethodSignatureDeclaration(node) || ast.IsFunctionDeclaration(node) || ast.IsParameterDeclaration(node) || ast.IsTypeParameterDeclaration(node) || ast.IsExpressionWithTypeArguments(node) || ast.IsImportEqualsDeclaration(node) || ast.IsTypeAliasDeclaration(node) || ast.IsJSTypeAliasDeclaration(node) || ast.IsConstructorDeclaration(node) || ast.IsIndexSignatureDeclaration(node) || ast.IsPropertyAccessExpression(node) || ast.IsElementAccessExpression(node) || ast.IsBinaryExpression(node) || ast.IsCallExpression(node) // || // !!! TODO: JSDoc support /* ast.IsJSDocTypeAlias(node); */ } func canReuseModifierNodes(nodes []*ast.Node) bool { for _, node := range nodes { if ast.IsModifier(node) && node.Flags&ast.NodeFlagsReparsed != 0 { return false } } return true } func isDeclarationAndNotVisible(emitContext *printer.EmitContext, resolver printer.EmitResolver, node *ast.Node) bool { node = emitContext.ParseNode(node) switch node.Kind { case ast.KindFunctionDeclaration, ast.KindModuleDeclaration, ast.KindInterfaceDeclaration, ast.KindClassDeclaration, ast.KindTypeAliasDeclaration, ast.KindJSTypeAliasDeclaration, ast.KindEnumDeclaration: return !resolver.IsDeclarationVisible(node) // The following should be doing their own visibility checks based on filtering their members case ast.KindVariableDeclaration: return !getBindingNameVisible(resolver, node) case ast.KindImportEqualsDeclaration, ast.KindImportDeclaration, ast.KindJSImportDeclaration, ast.KindExportDeclaration, ast.KindExportAssignment: return false case ast.KindClassStaticBlockDeclaration: return true } return false } func getBindingNameVisible(resolver printer.EmitResolver, elem *ast.Node) bool { if ast.IsOmittedExpression(elem) { return false } // TODO: parseArrayBindingElement _never_ parses out an OmittedExpression anymore, instead producing a nameless binding element // Audit if OmittedExpression should be removed if elem.Name() == nil { return false } if ast.IsBindingPattern(elem.Name()) { // If any child binding pattern element has been marked visible (usually by collect linked aliases), then this is visible for _, elem := range elem.Name().Elements() { if getBindingNameVisible(resolver, elem) { return true } } return false } else { return resolver.IsDeclarationVisible(elem) } } func isEnclosingDeclaration(node *ast.Node) bool { return ast.IsSourceFile(node) || ast.IsTypeAliasDeclaration(node) || ast.IsJSTypeAliasDeclaration(node) || ast.IsModuleDeclaration(node) || ast.IsClassDeclaration(node) || ast.IsInterfaceDeclaration(node) || ast.IsFunctionLike(node) || ast.IsIndexSignatureDeclaration(node) || ast.IsMappedTypeNode(node) || ast.IsVariableDeclaration(node) } func isAlwaysType(node *ast.Node) bool { if node.Kind == ast.KindInterfaceDeclaration { return true } return false } func maskModifierFlags(node *ast.Node, modifierMask ast.ModifierFlags, modifierAdditions ast.ModifierFlags) ast.ModifierFlags { flags := (ast.GetCombinedModifierFlags(node) & modifierMask) | modifierAdditions if flags&ast.ModifierFlagsDefault != 0 && (flags&ast.ModifierFlagsExport == 0) { // A non-exported default is a nonsequitor - we usually try to remove all export modifiers // from statements in ambient declarations; but a default export must retain its export modifier to be syntactically valid flags ^= ast.ModifierFlagsExport } if flags&ast.ModifierFlagsDefault != 0 && flags&ast.ModifierFlagsAmbient != 0 { flags ^= ast.ModifierFlagsAmbient // `declare` is never required alongside `default` (and would be an error if printed) } return flags } func unwrapParenthesizedExpression(o *ast.Node) *ast.Node { for o.Kind == ast.KindParenthesizedExpression { o = o.Expression() } return o } func isPrivateMethodTypeParameter(host DeclarationEmitHost, node *ast.TypeParameterDeclaration) bool { return node.AsNode().Parent.Kind == ast.KindMethodDeclaration && host.GetEffectiveDeclarationFlags(node.AsNode().Parent, ast.ModifierFlagsPrivate) != 0 } // Returns true if expando properties should be emitted for this function. // Properties are emitted if any overload in the symbol has a body (implementation). func shouldEmitFunctionProperties(input *ast.FunctionDeclaration) bool { if input.Body != nil { return true } return !core.Every(input.Symbol.Declarations, func(decl *ast.Node) bool { return !ast.IsFunctionDeclaration(decl) || decl.AsFunctionDeclaration().Body == nil }) } func getEffectiveBaseTypeNode(node *ast.Node) *ast.Node { baseType := ast.GetClassExtendsHeritageElement(node) // !!! TODO: JSDoc support // if (baseType && isInJSFile(node)) { // // Prefer an @augments tag because it may have type parameters. // const tag = getJSDocAugmentsTag(node); // if (tag) { // return tag.class; // } // } return baseType } func isScopeMarker(node *ast.Node) bool { return ast.IsExportAssignment(node) || ast.IsExportDeclaration(node) } func hasScopeMarker(statements *ast.StatementList) bool { if statements == nil { return false } return core.Some(statements.Nodes, isScopeMarker) }