Repository: microsoft/TypeScript
File: src/compiler/utilities.ts (TypeScript)

Code before:

/** @internal */
export function isJsxAttributeName(node: Node): node is JsxAttributeName {
    const kind = node.kind;
    return kind === SyntaxKind.Identifier
        || kind === SyntaxKind.JsxNamespacedName;
}

/** @internal */
export function getEscapedTextOfJsxNamespacedName(node: JsxNamespacedName): __String {
    return `${node.namespace.escapedText}:${idText(node.name)}` as __String;
}

/** @internal */
export function getTextOfJsxNamespacedName(node: JsxNamespacedName) {
    return `${idText(node.namespace)}:${idText(node.name)}`;
}

/** @internal */
export function intrinsicTagNameToString(node: Identifier | JsxNamespacedName) {
    return isIdentifier(node) ? idText(node) : getTextOfJsxNamespacedName(node);
}

/** @internal */
export function getOutermostDecoratedClass(node: Node) {
    return findAncestor(node.parent, n => isDecorator(n) && isClassLike(n.parent) && getContainingClass(n.parent.parent) === undefined);
}


Review comment (suggestion):
If you're concerned about walking to the top of the tree, you can always change this to short-circuit on the first class:

```suggestion
    return findAncestor(node.parent, n => isClassLike(n) ? "stop"
        : isDecorator(n) && isClassLike(n.parent) && getContainingClass(n.parent.parent) === undefined);
```

Code after:
            return !!(declaration as ParameterDeclaration).questionToken || isJSDocOptionalParameter(declaration as ParameterDeclaration);
        case SyntaxKind.JSDocPropertyTag:
        case SyntaxKind.JSDocParameterTag:
            return isOptionalJSDocPropertyLikeTag(declaration);
        default:
            return false;
    }
}

/** @internal */
export function isNonNullAccess(node: Node): node is AccessExpression {
    const kind = node.kind;
    return (kind === SyntaxKind.PropertyAccessExpression
        || kind === SyntaxKind.ElementAccessExpression) && isNonNullExpression((node as AccessExpression).expression);
}

/** @internal */
export function isJSDocSatisfiesExpression(node: Node): node is JSDocSatisfiesExpression {
    return isInJSFile(node) && isParenthesizedExpression(node) && hasJSDocNodes(node) && !!getJSDocSatisfiesTag(node);
}

/** @internal */
export function getJSDocSatisfiesExpressionType(node: JSDocSatisfiesExpression) {
    return Debug.checkDefined(tryGetJSDocSatisfiesTypeNode(node));
}

/** @internal */
export function tryGetJSDocSatisfiesTypeNode(node: Node) {
    const tag = getJSDocSatisfiesTag(node);
    return tag && tag.typeExpression && tag.typeExpression.type;
}

/** @internal */
export function getEscapedTextOfJsxAttributeName(node: JsxAttributeName): __String {
    return isIdentifier(node) ? node.escapedText : getEscapedTextOfJsxNamespacedName(node);
}

/** @internal */
export function getTextOfJsxAttributeName(node: JsxAttributeName): string {
    return isIdentifier(node) ? idText(node) : getTextOfJsxNamespacedName(node);
}

/** @internal */
export function isJsxAttributeName(node: Node): node is JsxAttributeName {
    const kind = node.kind;
    return kind === SyntaxKind.Identifier
        || kind === SyntaxKind.JsxNamespacedName;
}

/** @internal */
export function getEscapedTextOfJsxNamespacedName(node: JsxNamespacedName): __String {