Skip to content
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

Remove some properties from Identifier #52170

Merged
merged 13 commits into from
Jan 12, 2023
15 changes: 9 additions & 6 deletions src/compiler/binder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ import {
HasLocals,
hasSyntacticModifier,
Identifier,
identifierToKeywordKind,
idText,
IfStatement,
ImportClause,
Expand Down Expand Up @@ -413,7 +414,7 @@ function getModuleInstanceStateWorker(node: Node, visited: Map<number, ModuleIns
case SyntaxKind.Identifier:
// Only jsdoc typedef definition can exist in jsdoc namespace, and it should
// be considered the same as type alias
if ((node as Identifier).isInJSDocNamespace) {
if (node.flags & NodeFlags.IdentifierIsInJSDocNamespace) {
return ModuleInstanceState.NonInstantiated;
}
}
Expand Down Expand Up @@ -1030,6 +1031,7 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void {
else if (containerFlags & ContainerFlags.IsInterface) {
seenThisKeyword = false;
bindChildren(node);
Debug.assertNotNode(node, isIdentifier); // ContainsThis cannot overlap with HasExtendedUnicodeEscape on Identifier
node.flags = seenThisKeyword ? node.flags | NodeFlags.ContainsThis : node.flags & ~NodeFlags.ContainsThis;
}
else {
Expand Down Expand Up @@ -2420,13 +2422,14 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void {
!isIdentifierName(node)) {

// strict mode identifiers
const originalKeywordKind = identifierToKeywordKind(node);
if (inStrictMode &&
node.originalKeywordKind! >= SyntaxKind.FirstFutureReservedWord &&
node.originalKeywordKind! <= SyntaxKind.LastFutureReservedWord) {
originalKeywordKind! >= SyntaxKind.FirstFutureReservedWord &&
originalKeywordKind! <= SyntaxKind.LastFutureReservedWord) {
file.bindDiagnostics.push(createDiagnosticForNode(node,
getStrictModeIdentifierMessage(node), declarationNameToString(node)));
}
else if (node.originalKeywordKind === SyntaxKind.AwaitKeyword) {
else if (originalKeywordKind === SyntaxKind.AwaitKeyword) {
if (isExternalModule(file) && isInTopLevelContext(node)) {
file.bindDiagnostics.push(createDiagnosticForNode(node,
Diagnostics.Identifier_expected_0_is_a_reserved_word_at_the_top_level_of_a_module,
Expand All @@ -2438,7 +2441,7 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void {
declarationNameToString(node)));
}
}
else if (node.originalKeywordKind === SyntaxKind.YieldKeyword && node.flags & NodeFlags.YieldContext) {
else if (originalKeywordKind === SyntaxKind.YieldKeyword && node.flags & NodeFlags.YieldContext) {
file.bindDiagnostics.push(createDiagnosticForNode(node,
Diagnostics.Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here,
declarationNameToString(node)));
Expand Down Expand Up @@ -2731,7 +2734,7 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void {
// for typedef type names with namespaces, bind the new jsdoc type symbol here
// because it requires all containing namespaces to be in effect, namely the
// current "blockScopeContainer" needs to be set to its immediate namespace parent.
if ((node as Identifier).isInJSDocNamespace) {
if (node.flags & NodeFlags.IdentifierIsInJSDocNamespace) {
let parentNode = node.parent;
while (parentNode && !isJSDocTypeAlias(parentNode)) {
parentNode = parentNode.parent;
Expand Down
89 changes: 58 additions & 31 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,8 @@ import {
getFirstIdentifier,
getFunctionFlags,
getHostSignatureFromJSDoc,
getIdentifierGeneratedImportReference,
getIdentifierTypeArguments,
getImmediatelyInvokedFunctionExpression,
getInitializerOfBinaryExpression,
getInterfaceBaseTypeNodes,
Expand Down Expand Up @@ -375,6 +377,7 @@ import {
hasSyntacticModifiers,
HeritageClause,
Identifier,
identifierToKeywordKind,
IdentifierTypePredicate,
idText,
IfStatement,
Expand Down Expand Up @@ -888,11 +891,13 @@ import {
ReverseMappedType,
sameMap,
SatisfiesExpression,
scanTokenAtPosition,
ScriptKind,
ScriptTarget,
SetAccessorDeclaration,
setCommentRange,
setEmitFlags,
setIdentifierTypeArguments,
setNodeFlags,
setOriginalNode,
setParent,
Expand Down Expand Up @@ -6792,12 +6797,16 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
let qualifier = root.qualifier;
if (qualifier) {
if (isIdentifier(qualifier)) {
qualifier = factory.updateIdentifier(qualifier, typeArguments);
if (typeArguments !== getIdentifierTypeArguments(qualifier)) {
qualifier = setIdentifierTypeArguments(factory.cloneNode(qualifier), typeArguments);
}
}
else {
qualifier = factory.updateQualifiedName(qualifier,
qualifier.left,
factory.updateIdentifier(qualifier.right, typeArguments));
if (typeArguments !== getIdentifierTypeArguments(qualifier.right)) {
qualifier = factory.updateQualifiedName(qualifier,
qualifier.left,
setIdentifierTypeArguments(factory.cloneNode(qualifier.right), typeArguments));
}
}
}
typeArguments = ref.typeArguments;
Expand All @@ -6819,12 +6828,16 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
let typeArguments = root.typeArguments;
let typeName = root.typeName;
if (isIdentifier(typeName)) {
typeName = factory.updateIdentifier(typeName, typeArguments);
if (typeArguments !== getIdentifierTypeArguments(typeName)) {
typeName = setIdentifierTypeArguments(factory.cloneNode(typeName), typeArguments);
}
}
else {
typeName = factory.updateQualifiedName(typeName,
typeName.left,
factory.updateIdentifier(typeName.right, typeArguments));
if (typeArguments !== getIdentifierTypeArguments(typeName.right)) {
typeName = factory.updateQualifiedName(typeName,
typeName.left,
setIdentifierTypeArguments(factory.cloneNode(typeName.right), typeArguments));
}
}
typeArguments = ref.typeArguments;
// then move qualifiers
Expand Down Expand Up @@ -7542,7 +7555,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (!nonRootParts || isEntityName(nonRootParts)) {
if (nonRootParts) {
const lastId = isIdentifier(nonRootParts) ? nonRootParts : nonRootParts.right;
lastId.typeArguments = undefined;
setIdentifierTypeArguments(lastId, /*typeArguments*/ undefined);
}
return factory.createImportTypeNode(lit, assertion, nonRootParts as EntityName, typeParameterNodes as readonly TypeNode[], isTypeOf);
}
Expand All @@ -7562,8 +7575,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
else {
const lastId = isIdentifier(entityName) ? entityName : entityName.right;
const lastTypeArgs = lastId.typeArguments;
lastId.typeArguments = undefined;
const lastTypeArgs = getIdentifierTypeArguments(lastId);
setIdentifierTypeArguments(lastId, /*typeArguments*/ undefined);
return factory.createTypeReferenceNode(entityName, lastTypeArgs as NodeArray<TypeNode>);
}

Expand Down Expand Up @@ -7617,7 +7630,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
}

const identifier = setEmitFlags(factory.createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping);
const identifier = setEmitFlags(factory.createIdentifier(symbolName), EmitFlags.NoAsciiEscaping);
if (typeParameterNodes) setIdentifierTypeArguments(identifier, factory.createNodeArray<TypeNode | TypeParameterDeclaration>(typeParameterNodes));
identifier.symbol = symbol;

if (index > stopper) {
Expand Down Expand Up @@ -7662,7 +7676,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
text = `${rawtext}_${i}`;
}
if (text !== rawtext) {
result = factory.createIdentifier(text, result.typeArguments);
const typeArguments = getIdentifierTypeArguments(result);
result = factory.createIdentifier(text);
setIdentifierTypeArguments(result, typeArguments);
}
// avoiding iterations of the above loop turns out to be worth it when `i` starts to get large, so we cache the max
// `i` we've used thus far, to save work later
Expand Down Expand Up @@ -7697,7 +7713,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
context.flags ^= NodeBuilderFlags.InInitialEntityName;
}

const identifier = setEmitFlags(factory.createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping);
const identifier = setEmitFlags(factory.createIdentifier(symbolName), EmitFlags.NoAsciiEscaping);
if (typeParameterNodes) setIdentifierTypeArguments(identifier, factory.createNodeArray<TypeNode | TypeParameterDeclaration>(typeParameterNodes));
identifier.symbol = symbol;

return index > 0 ? factory.createQualifiedName(createEntityNameFromSymbolChain(chain, index - 1), identifier) : identifier;
Expand Down Expand Up @@ -7726,7 +7743,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return factory.createStringLiteral(getSpecifierForModuleSymbol(symbol, context));
}
if (index === 0 || canUsePropertyAccess(symbolName, languageVersion)) {
const identifier = setEmitFlags(factory.createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping);
const identifier = setEmitFlags(factory.createIdentifier(symbolName), EmitFlags.NoAsciiEscaping);
if (typeParameterNodes) setIdentifierTypeArguments(identifier, factory.createNodeArray<TypeNode | TypeParameterDeclaration>(typeParameterNodes));
identifier.symbol = symbol;

return index > 0 ? factory.createPropertyAccessExpression(createExpressionFromSymbolChain(chain, index - 1), identifier) : identifier;
Expand All @@ -7744,8 +7762,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
expression = factory.createNumericLiteral(+symbolName);
}
if (!expression) {
expression = setEmitFlags(factory.createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping);
(expression as Identifier).symbol = symbol;
const identifier = setEmitFlags(factory.createIdentifier(symbolName), EmitFlags.NoAsciiEscaping);
if (typeParameterNodes) setIdentifierTypeArguments(identifier, factory.createNodeArray<TypeNode | TypeParameterDeclaration>(typeParameterNodes));
identifier.symbol = symbol;
expression = identifier;
}
return factory.createElementAccessExpression(createExpressionFromSymbolChain(chain, index - 1), expression);
}
Expand Down Expand Up @@ -23192,15 +23212,17 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
break;
case SyntaxKind.Parameter:
const param = declaration as ParameterDeclaration;
if (isIdentifier(param.name) &&
(isCallSignatureDeclaration(param.parent) || isMethodSignature(param.parent) || isFunctionTypeNode(param.parent)) &&
param.parent.parameters.indexOf(param) > -1 &&
(resolveName(param, param.name.escapedText, SymbolFlags.Type, undefined, param.name.escapedText, /*isUse*/ true) ||
param.name.originalKeywordKind && isTypeNodeKind(param.name.originalKeywordKind))) {
const newName = "arg" + param.parent.parameters.indexOf(param);
const typeName = declarationNameToString(param.name) + (param.dotDotDotToken ? "[]" : "");
errorOrSuggestion(noImplicitAny, declaration, Diagnostics.Parameter_has_a_name_but_no_type_Did_you_mean_0_Colon_1, newName, typeName);
return;
if (isIdentifier(param.name)) {
const originalKeywordKind = identifierToKeywordKind(param.name);
if ((isCallSignatureDeclaration(param.parent) || isMethodSignature(param.parent) || isFunctionTypeNode(param.parent)) &&
param.parent.parameters.indexOf(param) > -1 &&
(resolveName(param, param.name.escapedText, SymbolFlags.Type, undefined, param.name.escapedText, /*isUse*/ true) ||
originalKeywordKind && isTypeNodeKind(originalKeywordKind))) {
const newName = "arg" + param.parent.parameters.indexOf(param);
const typeName = declarationNameToString(param.name) + (param.dotDotDotToken ? "[]" : "");
errorOrSuggestion(noImplicitAny, declaration, Diagnostics.Parameter_has_a_name_but_no_type_Did_you_mean_0_Colon_1, newName, typeName);
return;
}
}
diagnostic = (declaration as ParameterDeclaration).dotDotDotToken ?
noImplicitAny ? Diagnostics.Rest_parameter_0_implicitly_has_an_any_type : Diagnostics.Rest_parameter_0_implicitly_has_an_any_type_but_a_better_type_may_be_inferred_from_usage :
Expand Down Expand Up @@ -37442,8 +37464,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {

function checkTypeReferenceNode(node: TypeReferenceNode | ExpressionWithTypeArguments) {
checkGrammarTypeArguments(node, node.typeArguments);
if (node.kind === SyntaxKind.TypeReference && node.typeName.jsdocDotPos !== undefined && !isInJSFile(node) && !isInJSDoc(node)) {
grammarErrorAtPos(node, node.typeName.jsdocDotPos, 1, Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments);
if (node.kind === SyntaxKind.TypeReference && !isInJSFile(node) && !isInJSDoc(node) && node.typeArguments && node.typeName.end !== node.typeArguments.pos) {
// If there was a token between the type name and the type arguments, check if it was a DotToken
const sourceFile = getSourceFileOfNode(node);
if (scanTokenAtPosition(sourceFile, node.typeName.end) === SyntaxKind.DotToken) {
grammarErrorAtPos(node, skipTrivia(sourceFile.text, node.typeName.end), 1, Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments);
}
}
forEach(node.typeArguments, checkSourceElement);
const type = getTypeFromTypeReference(node);
Expand Down Expand Up @@ -44578,8 +44604,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// When resolved as an expression identifier, if the given node references an import, return the declaration of
// that import. Otherwise, return undefined.
function getReferencedImportDeclaration(nodeIn: Identifier): Declaration | undefined {
if (nodeIn.generatedImportReference) {
return nodeIn.generatedImportReference;
const specifier = getIdentifierGeneratedImportReference(nodeIn);
if (specifier) {
return specifier;
}
const node = getParseTreeNode(nodeIn, isIdentifier);
if (node) {
Expand Down Expand Up @@ -46850,7 +46877,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {

function checkGrammarNameInLetOrConstDeclarations(name: Identifier | BindingPattern): boolean {
if (name.kind === SyntaxKind.Identifier) {
if (name.originalKeywordKind === SyntaxKind.LetKeyword) {
if (name.escapedText === "let") {
return grammarErrorOnNode(name, Diagnostics.let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations);
}
}
Expand Down
Loading