Skip to content

Commit

Permalink
Remove some properties from Identifier (#52170)
Browse files Browse the repository at this point in the history
  • Loading branch information
rbuckton authored Jan 12, 2023
1 parent 59e4e38 commit 9cdba99
Show file tree
Hide file tree
Showing 45 changed files with 334 additions and 256 deletions.
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 @@ -890,11 +893,13 @@ import {
ReverseMappedType,
sameMap,
SatisfiesExpression,
scanTokenAtPosition,
ScriptKind,
ScriptTarget,
SetAccessorDeclaration,
setCommentRange,
setEmitFlags,
setIdentifierTypeArguments,
setNodeFlags,
setOriginalNode,
setParent,
Expand Down Expand Up @@ -6794,12 +6799,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 @@ -6821,12 +6830,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 @@ -7544,7 +7557,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 @@ -7564,8 +7577,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 @@ -7619,7 +7632,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 @@ -7664,7 +7678,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 @@ -7699,7 +7715,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 @@ -7728,7 +7745,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 @@ -7746,8 +7764,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 @@ -23215,15 +23235,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 @@ -37483,8 +37505,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 @@ -44622,8 +44648,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 @@ -46894,7 +46921,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

0 comments on commit 9cdba99

Please sign in to comment.