Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions tsc/internal/checker/nodecopy.go
Original file line number Diff line number Diff line change
Expand Up @@ -294,15 +294,15 @@ func getExistingNodeTreeVisitor(b *NodeBuilderImpl, bound *recoveryBoundary) *as
// instead of re-closing-over all of these each time we need a visitor. In theory the compiler could handle this, but in practice closure inlining hasn't been reliable
var visitor *ast.NodeVisitor
// note: also handles renaming type parameters renamed within the current context
attachSymbolToLeftmostIdentifier := func(leftmost *ast.Node, node *ast.Node, sym *ast.Symbol) *ast.Node {
attachSymbolToLeftmostIdentifier := func(leftmost *ast.Node, node *ast.Node, sym *ast.Symbol, meaning ast.SymbolFlags) *ast.Node {
var vis *ast.NodeVisitor
visitorFunc := func(node *ast.Node) *ast.Node {
if node == leftmost {
var type_ *Type
var name *ast.Node
if sym != nil {
type_ = b.ch.getDeclaredTypeOfSymbol(sym)
if sym.Flags()&ast.SymbolFlagsTypeParameter != 0 {
if sym.Flags()&meaning&ast.SymbolFlagsTypeParameter != 0 {
name = b.typeParameterToName(type_).AsNode()
}
}
Expand Down Expand Up @@ -338,7 +338,7 @@ func getExistingNodeTreeVisitor(b *NodeBuilderImpl, bound *recoveryBoundary) *as
introducesError = true
b.ctx.tracker.ReportInaccessibleThisError()
}
return introducesError, attachSymbolToLeftmostIdentifier(leftmost, node, sym), nil
return introducesError, attachSymbolToLeftmostIdentifier(leftmost, node, sym, meaning), nil
}
sym = b.ch.resolveEntityName(leftmost, meaning, true, true, nil)
if b.ctx.enclosingDeclaration != nil && !(sym != nil && sym.Flags()&ast.SymbolFlagsTypeParameter != 0) {
Expand Down Expand Up @@ -371,17 +371,17 @@ func getExistingNodeTreeVisitor(b *NodeBuilderImpl, bound *recoveryBoundary) *as
// If a parameter is resolvable in the current context it is also visible, so no need to go to symbol accesibility
if sym.Flags()&ast.SymbolFlagsFunctionScopedVariable != 0 && sym.ValueDeclaration() != nil {
if ast.IsPartOfParameterDeclaration(sym.ValueDeclaration()) || ast.IsJSDocParameterTag(sym.ValueDeclaration()) {
return introducesError, attachSymbolToLeftmostIdentifier(leftmost, node, sym), nil
return introducesError, attachSymbolToLeftmostIdentifier(leftmost, node, sym, meaning), nil
}
}
if sym.Flags()&ast.SymbolFlagsTypeParameter == 0 /* Type parameters are visible in the current context if they are are resolvable */ && !ast.IsDeclarationName(node) &&
if sym.Flags()&meaning&ast.SymbolFlagsTypeParameter == 0 /* Type parameters are visible in the current context if they are are resolvable */ && !ast.IsDeclarationName(node) &&
b.ch.IsSymbolAccessible(sym, enclosingDeclaration, meaning, false).Accessibility != printer.SymbolAccessibilityAccessible {
b.ctx.tracker.ReportInferenceFallback(node)
introducesError = true
} else {
b.ctx.tracker.TrackSymbol(sym, enclosingDeclaration, meaning)
}
return introducesError, attachSymbolToLeftmostIdentifier(leftmost, node, sym), nil
return introducesError, attachSymbolToLeftmostIdentifier(leftmost, node, sym, meaning), nil
}
return introducesError, b.setTextRange(b.f.DeepCloneNode(node), node), nil
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
//// [tests/cases/compiler/declarationEmitShadowedTypeParameterSharesParameterName.ts] ////

//// [declarationEmitShadowedTypeParameterSharesParameterName.ts]
export function predicate<value>(value: value) {
return function <value>(value: value): value is value & string {
return typeof value === "string";
};
}

export function assertion<value>(value: value) {
return function <value>(value: value): asserts value is value & string {
if (typeof value !== "string") throw value;
};
}

export function truthyAssertion<value>(value: value) {
return function <value>(value: value): asserts value {
if (!value) throw value;
};
}

export function query<value>(value: value) {
return function <value>(value: value, other: typeof value): typeof value {
return value;
};
}

export function qualifiedQuery<value>(value: value) {
return function <value extends { a: number }>(value: value): typeof value.a {
return value.a;
};
}

declare const key: unique symbol;

export function computed<value>(value: value) {
return function <value>(value: typeof key): { [value]: number } {
return { [value]: 1 };
};
}

export function capturedPredicate<value>(value: value) {
return function <value>(value: value, value_1: unknown): value is value & string {
return typeof value === "string";
};
}

export function capturedAssertion<value>(value: value) {
return function <value>(value: value, value_1: unknown): asserts value is value & string {
if (typeof value !== "string") throw value;
};
}

export function capturedTruthyAssertion<value>(value: value) {
return function <value>(value: value, value_1: unknown): asserts value {
if (!value) throw value;
};
}

export function capturedQuery<value>(value: value) {
return function <value>(value: value, value_1: number): typeof value {
return value;
};
}

export function nested<value>(value: value) {
return function <value>(value: value) {
return function <value>(value: value): typeof value {
return value;
};
};
}

export const arrow = <value>(value: value) => <value>(value: value): value is value & string => typeof value === "string";

export function method<value>(value: value) {
return {
m<value>(value: value): asserts value {
if (!value) throw value;
},
};
}

export function local<value>(value: value) {
return function <value>(x: value) {
const value = 1;
const result: { a: typeof value; b: value } = { a: value, b: x };
return result;
};
}


//// [declarationEmitShadowedTypeParameterSharesParameterName.js]
export function predicate(value) {
return function (value) {
return typeof value === "string";
};
}
export function assertion(value) {
return function (value) {
if (typeof value !== "string")
throw value;
};
}
export function truthyAssertion(value) {
return function (value) {
if (!value)
throw value;
};
}
export function query(value) {
return function (value, other) {
return value;
};
}
export function qualifiedQuery(value) {
return function (value) {
return value.a;
};
}
export function computed(value) {
return function (value) {
return { [value]: 1 };
};
}
export function capturedPredicate(value) {
return function (value, value_1) {
return typeof value === "string";
};
}
export function capturedAssertion(value) {
return function (value, value_1) {
if (typeof value !== "string")
throw value;
};
}
export function capturedTruthyAssertion(value) {
return function (value, value_1) {
if (!value)
throw value;
};
}
export function capturedQuery(value) {
return function (value, value_1) {
return value;
};
}
export function nested(value) {
return function (value) {
return function (value) {
return value;
};
};
}
export const arrow = (value) => (value) => typeof value === "string";
export function method(value) {
return {
m(value) {
if (!value)
throw value;
},
};
}
export function local(value) {
return function (x) {
const value = 1;
const result = { a: value, b: x };
return result;
};
}


//// [declarationEmitShadowedTypeParameterSharesParameterName.d.ts]
export declare function predicate<value>(value: value): <value_1>(value: value_1) => value is value_1 & string;
export declare function assertion<value>(value: value): <value_1>(value: value_1) => asserts value is value_1 & string;
export declare function truthyAssertion<value>(value: value): <value_1>(value: value_1) => asserts value;
export declare function query<value>(value: value): <value_1>(value: value_1, other: typeof value) => typeof value;
export declare function qualifiedQuery<value>(value: value): <value_1 extends {
a: number;
}>(value: value_1) => typeof value.a;
declare const key: unique symbol;
export declare function computed<value>(value: value): <value_1>(value: typeof key) => {
[value]: number;
};
export declare function capturedPredicate<value>(value: value): <value_1>(value: value_1, value_1: unknown) => value is value_1 & string;
export declare function capturedAssertion<value>(value: value): <value_1>(value: value_1, value_1: unknown) => asserts value is value_1 & string;
export declare function capturedTruthyAssertion<value>(value: value): <value_1>(value: value_1, value_1: unknown) => asserts value;
export declare function capturedQuery<value>(value: value): <value_1>(value: value_1, value_1: number) => typeof value;
export declare function nested<value>(value: value): <value_1>(value: value_1) => <value_2>(value: value_2) => typeof value;
export declare const arrow: <value>(value: value) => <value_1>(value: value_1) => value is value_1 & string;
export declare function method<value>(value: value): {
m<value_1>(value: value_1): asserts value;
};
export declare function local<value>(value: value): <value_1>(x: value_1) => {
a: 1;
b: value_1;
};
export {};
Loading