-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
@typedef: Improve error spans from declaration emit #42501
Changes from 3 commits
e42c1d6
3b6b0a4
70343e4
8f60abb
a215bd2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4183,7 +4183,8 @@ namespace ts { | |
return { | ||
accessibility: SymbolAccessibility.CannotBeNamed, | ||
errorSymbolName: symbolToString(symbol, enclosingDeclaration, meaning), | ||
errorModuleName: symbolToString(symbolExternalModule) | ||
errorModuleName: symbolToString(symbolExternalModule), | ||
errorNode: isInJSFile(enclosingDeclaration) ? enclosingDeclaration : undefined, | ||
}; | ||
} | ||
} | ||
|
@@ -4699,7 +4700,7 @@ namespace ts { | |
|
||
function createMappedTypeNodeFromType(type: MappedType) { | ||
Debug.assert(!!(type.flags & TypeFlags.Object)); | ||
const readonlyToken = type.declaration.readonlyToken ? <ReadonlyToken | PlusToken | MinusToken>factory.createToken(type.declaration.readonlyToken.kind) : undefined; | ||
const readonlyToken = type.declaration.readonlyToken ? <ReadonlyKeyword | PlusToken | MinusToken>factory.createToken(type.declaration.readonlyToken.kind) : undefined; | ||
const questionToken = type.declaration.questionToken ? <QuestionToken | PlusToken | MinusToken>factory.createToken(type.declaration.questionToken.kind) : undefined; | ||
let appropriateConstraintTypeNode: TypeNode; | ||
if (isMappedTypeWithKeyofConstraintDeclaration(type)) { | ||
|
@@ -6183,7 +6184,7 @@ namespace ts { | |
tracker: { | ||
...oldcontext.tracker, | ||
trackSymbol: (sym, decl, meaning) => { | ||
const accessibleResult = isSymbolAccessible(sym, decl, meaning, /*computeALiases*/ false); | ||
const accessibleResult = isSymbolAccessible(sym, decl, meaning, /*computeAliases*/ false); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. drive-by case fix |
||
if (accessibleResult.accessibility === SymbolAccessibility.Accessible) { | ||
// Lookup the root symbol of the chain of refs we'll use to access it and serialize it | ||
const chain = lookupSymbolChainWorker(sym, context, meaning); | ||
|
@@ -6625,16 +6626,17 @@ namespace ts { | |
function addResult(node: Statement, additionalModifierFlags: ModifierFlags) { | ||
if (canHaveModifiers(node)) { | ||
let newModifierFlags: ModifierFlags = ModifierFlags.None; | ||
const enclosingDeclaration = context.enclosingDeclaration && | ||
(isJSDocTypeAlias(context.enclosingDeclaration) ? getSourceFileOfNode(context.enclosingDeclaration) : context.enclosingDeclaration); | ||
if (additionalModifierFlags & ModifierFlags.Export && | ||
context.enclosingDeclaration && | ||
(isExportingScope(context.enclosingDeclaration) || isModuleDeclaration(context.enclosingDeclaration)) && | ||
enclosingDeclaration && (isExportingScope(enclosingDeclaration) || isModuleDeclaration(enclosingDeclaration)) && | ||
canHaveExportModifier(node) | ||
) { | ||
// Classes, namespaces, variables, functions, interfaces, and types should all be `export`ed in a module context if not private | ||
newModifierFlags |= ModifierFlags.Export; | ||
} | ||
if (addingDeclare && !(newModifierFlags & ModifierFlags.Export) && | ||
(!context.enclosingDeclaration || !(context.enclosingDeclaration.flags & NodeFlags.Ambient)) && | ||
(!enclosingDeclaration || !(enclosingDeclaration.flags & NodeFlags.Ambient)) && | ||
(isEnumDeclaration(node) || isVariableStatement(node) || isFunctionDeclaration(node) || isClassDeclaration(node) || isModuleDeclaration(node))) { | ||
// Classes, namespaces, variables, enums, and functions all need `declare` modifiers to be valid in a declaration file top-level scope | ||
newModifierFlags |= ModifierFlags.Ambient; | ||
|
@@ -6654,9 +6656,12 @@ namespace ts { | |
const typeParams = getSymbolLinks(symbol).typeParameters; | ||
const typeParamDecls = map(typeParams, p => typeParameterToDeclaration(p, context)); | ||
const jsdocAliasDecl = find(symbol.declarations, isJSDocTypeAlias); | ||
|
||
const commentText = jsdocAliasDecl ? jsdocAliasDecl.comment || jsdocAliasDecl.parent.comment : undefined; | ||
const oldFlags = context.flags; | ||
context.flags |= NodeBuilderFlags.InTypeAlias; | ||
const oldEnclosingDecl = context.enclosingDeclaration; | ||
context.enclosingDeclaration = jsdocAliasDecl; | ||
const typeNode = jsdocAliasDecl && jsdocAliasDecl.typeExpression | ||
&& isJSDocTypeExpression(jsdocAliasDecl.typeExpression) | ||
&& serializeExistingTypeNode(context, jsdocAliasDecl.typeExpression.type, includePrivateSymbol, bundled) | ||
|
@@ -6666,6 +6671,7 @@ namespace ts { | |
!commentText ? [] : [{ kind: SyntaxKind.MultiLineCommentTrivia, text: "*\n * " + commentText.replace(/\n/g, "\n * ") + "\n ", pos: -1, end: -1, hasTrailingNewLine: true }] | ||
), modifierFlags); | ||
context.flags = oldFlags; | ||
context.enclosingDeclaration = oldEnclosingDecl; | ||
} | ||
|
||
function serializeInterface(symbol: Symbol, symbolName: string, modifierFlags: ModifierFlags) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
tests/cases/conformance/jsdoc/declarations/file.js(8,1): error TS9006: Declaration emit for this file requires using private name 'Base' from module '"tests/cases/conformance/jsdoc/declarations/base"'. An explicit type annotation may unblock declaration emit. | ||
tests/cases/conformance/jsdoc/declarations/file.js(1,5): error TS4081: Exported type alias 'BaseFactory' has or is using private name 'Base'. | ||
|
||
|
||
==== tests/cases/conformance/jsdoc/declarations/base.js (0 errors) ==== | ||
|
@@ -16,15 +16,15 @@ tests/cases/conformance/jsdoc/declarations/file.js(8,1): error TS9006: Declarati | |
|
||
==== tests/cases/conformance/jsdoc/declarations/file.js (1 errors) ==== | ||
/** @typedef {import('./base')} BaseFactory */ | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
!!! error TS4081: Exported type alias 'BaseFactory' has or is using private name 'Base'. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you think we should add a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the general case, yes -- in this case, with the |
||
|
||
/** | ||
* | ||
* @param {InstanceType<BaseFactory["Base"]>} base | ||
* @returns {InstanceType<BaseFactory["Base"]>} | ||
*/ | ||
const test = (base) => { | ||
~~~~~ | ||
!!! error TS9006: Declaration emit for this file requires using private name 'Base' from module '"tests/cases/conformance/jsdoc/declarations/base"'. An explicit type annotation may unblock declaration emit. | ||
return base; | ||
}; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
drive-by deprecation fix