mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-20 00:28:52 +01:00
Enforce ILocalizedString usage with f1 property via types (#162991)
* Enforce ILocalizedString usage with f1 property via types * complete comment * Visit all symbols when encountering a union type * use ILocalizedString * fix tests Co-authored-by: Alex Dima <alexdima@microsoft.com>
This commit is contained in:
committed by
GitHub
parent
24b8eb0d54
commit
3e4e351816
@@ -490,54 +490,56 @@ function markNodes(ts, languageService, options) {
|
||||
}
|
||||
const nodeSourceFile = node.getSourceFile();
|
||||
const loop = (node) => {
|
||||
const [symbol, symbolImportNode] = getRealNodeSymbol(ts, checker, node);
|
||||
if (symbolImportNode) {
|
||||
setColor(symbolImportNode, 2 /* NodeColor.Black */);
|
||||
const importDeclarationNode = findParentImportDeclaration(symbolImportNode);
|
||||
if (importDeclarationNode && ts.isStringLiteral(importDeclarationNode.moduleSpecifier)) {
|
||||
enqueueImport(importDeclarationNode, importDeclarationNode.moduleSpecifier.text);
|
||||
const symbols = getRealNodeSymbol(ts, checker, node);
|
||||
for (const { symbol, symbolImportNode } of symbols) {
|
||||
if (symbolImportNode) {
|
||||
setColor(symbolImportNode, 2 /* NodeColor.Black */);
|
||||
const importDeclarationNode = findParentImportDeclaration(symbolImportNode);
|
||||
if (importDeclarationNode && ts.isStringLiteral(importDeclarationNode.moduleSpecifier)) {
|
||||
enqueueImport(importDeclarationNode, importDeclarationNode.moduleSpecifier.text);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isSymbolWithDeclarations(symbol) && !nodeIsInItsOwnDeclaration(nodeSourceFile, node, symbol)) {
|
||||
for (let i = 0, len = symbol.declarations.length; i < len; i++) {
|
||||
const declaration = symbol.declarations[i];
|
||||
if (ts.isSourceFile(declaration)) {
|
||||
// Do not enqueue full source files
|
||||
// (they can be the declaration of a module import)
|
||||
continue;
|
||||
}
|
||||
if (options.shakeLevel === 2 /* ShakeLevel.ClassMembers */ && (ts.isClassDeclaration(declaration) || ts.isInterfaceDeclaration(declaration)) && !isLocalCodeExtendingOrInheritingFromDefaultLibSymbol(ts, program, checker, declaration)) {
|
||||
enqueue_black(declaration.name);
|
||||
for (let j = 0; j < declaration.members.length; j++) {
|
||||
const member = declaration.members[j];
|
||||
const memberName = member.name ? member.name.getText() : null;
|
||||
if (ts.isConstructorDeclaration(member)
|
||||
|| ts.isConstructSignatureDeclaration(member)
|
||||
|| ts.isIndexSignatureDeclaration(member)
|
||||
|| ts.isCallSignatureDeclaration(member)
|
||||
|| memberName === '[Symbol.iterator]'
|
||||
|| memberName === '[Symbol.toStringTag]'
|
||||
|| memberName === 'toJSON'
|
||||
|| memberName === 'toString'
|
||||
|| memberName === 'dispose' // TODO: keeping all `dispose` methods
|
||||
|| /^_(.*)Brand$/.test(memberName || '') // TODO: keeping all members ending with `Brand`...
|
||||
) {
|
||||
enqueue_black(member);
|
||||
if (isSymbolWithDeclarations(symbol) && !nodeIsInItsOwnDeclaration(nodeSourceFile, node, symbol)) {
|
||||
for (let i = 0, len = symbol.declarations.length; i < len; i++) {
|
||||
const declaration = symbol.declarations[i];
|
||||
if (ts.isSourceFile(declaration)) {
|
||||
// Do not enqueue full source files
|
||||
// (they can be the declaration of a module import)
|
||||
continue;
|
||||
}
|
||||
if (options.shakeLevel === 2 /* ShakeLevel.ClassMembers */ && (ts.isClassDeclaration(declaration) || ts.isInterfaceDeclaration(declaration)) && !isLocalCodeExtendingOrInheritingFromDefaultLibSymbol(ts, program, checker, declaration)) {
|
||||
enqueue_black(declaration.name);
|
||||
for (let j = 0; j < declaration.members.length; j++) {
|
||||
const member = declaration.members[j];
|
||||
const memberName = member.name ? member.name.getText() : null;
|
||||
if (ts.isConstructorDeclaration(member)
|
||||
|| ts.isConstructSignatureDeclaration(member)
|
||||
|| ts.isIndexSignatureDeclaration(member)
|
||||
|| ts.isCallSignatureDeclaration(member)
|
||||
|| memberName === '[Symbol.iterator]'
|
||||
|| memberName === '[Symbol.toStringTag]'
|
||||
|| memberName === 'toJSON'
|
||||
|| memberName === 'toString'
|
||||
|| memberName === 'dispose' // TODO: keeping all `dispose` methods
|
||||
|| /^_(.*)Brand$/.test(memberName || '') // TODO: keeping all members ending with `Brand`...
|
||||
) {
|
||||
enqueue_black(member);
|
||||
}
|
||||
if (isStaticMemberWithSideEffects(ts, member)) {
|
||||
enqueue_black(member);
|
||||
}
|
||||
}
|
||||
if (isStaticMemberWithSideEffects(ts, member)) {
|
||||
enqueue_black(member);
|
||||
// queue the heritage clauses
|
||||
if (declaration.heritageClauses) {
|
||||
for (const heritageClause of declaration.heritageClauses) {
|
||||
enqueue_black(heritageClause);
|
||||
}
|
||||
}
|
||||
}
|
||||
// queue the heritage clauses
|
||||
if (declaration.heritageClauses) {
|
||||
for (const heritageClause of declaration.heritageClauses) {
|
||||
enqueue_black(heritageClause);
|
||||
}
|
||||
else {
|
||||
enqueue_black(declaration);
|
||||
}
|
||||
}
|
||||
else {
|
||||
enqueue_black(declaration);
|
||||
}
|
||||
}
|
||||
}
|
||||
node.forEachChild(loop);
|
||||
@@ -736,13 +738,20 @@ function findSymbolFromHeritageType(ts, checker, type) {
|
||||
return findSymbolFromHeritageType(ts, checker, type.expression);
|
||||
}
|
||||
if (ts.isIdentifier(type)) {
|
||||
return getRealNodeSymbol(ts, checker, type)[0];
|
||||
const tmp = getRealNodeSymbol(ts, checker, type);
|
||||
return (tmp.length > 0 ? tmp[0].symbol : null);
|
||||
}
|
||||
if (ts.isPropertyAccessExpression(type)) {
|
||||
return findSymbolFromHeritageType(ts, checker, type.name);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
class SymbolImportTuple {
|
||||
constructor(symbol, symbolImportNode) {
|
||||
this.symbol = symbol;
|
||||
this.symbolImportNode = symbolImportNode;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Returns the node's symbol and the `import` node (if the symbol resolved from a different module)
|
||||
*/
|
||||
@@ -774,7 +783,7 @@ function getRealNodeSymbol(ts, checker, node) {
|
||||
}
|
||||
if (!ts.isShorthandPropertyAssignment(node)) {
|
||||
if (node.getChildCount() !== 0) {
|
||||
return [null, null];
|
||||
return [];
|
||||
}
|
||||
}
|
||||
const { parent } = node;
|
||||
@@ -820,10 +829,7 @@ function getRealNodeSymbol(ts, checker, node) {
|
||||
const type = checker.getTypeAtLocation(parent.parent);
|
||||
if (name && type) {
|
||||
if (type.isUnion()) {
|
||||
const prop = type.types[0].getProperty(name);
|
||||
if (prop) {
|
||||
symbol = prop;
|
||||
}
|
||||
return generateMultipleSymbols(type, name, importNode);
|
||||
}
|
||||
else {
|
||||
const prop = type.getProperty(name);
|
||||
@@ -854,9 +860,19 @@ function getRealNodeSymbol(ts, checker, node) {
|
||||
}
|
||||
}
|
||||
if (symbol && symbol.declarations) {
|
||||
return [symbol, importNode];
|
||||
return [new SymbolImportTuple(symbol, importNode)];
|
||||
}
|
||||
return [];
|
||||
function generateMultipleSymbols(type, name, importNode) {
|
||||
const result = [];
|
||||
for (const t of type.types) {
|
||||
const prop = t.getProperty(name);
|
||||
if (prop && prop.declarations) {
|
||||
result.push(new SymbolImportTuple(prop, importNode));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return [null, null];
|
||||
}
|
||||
/** Get the token whose text contains the position */
|
||||
function getTokenAtPosition(ts, sourceFile, position, allowPositionInLeadingTrivia, includeEndPosition) {
|
||||
|
||||
Reference in New Issue
Block a user