Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
104 changes: 0 additions & 104 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8024,14 +8024,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return file.moduleName;
}
if (!file) {
if (context.tracker.trackReferencedAmbientModule) {
const ambientDecls = filter(symbol.declarations, isAmbientModule);
if (length(ambientDecls)) {
for (const decl of ambientDecls!) {
context.tracker.trackReferencedAmbientModule(decl, symbol);
}
}
}
if (ambientModuleSymbolRegex.test(symbol.escapedName as string)) {
return (symbol.escapedName as string).substring(1, (symbol.escapedName as string).length - 1);
}
Expand Down Expand Up @@ -48820,8 +48812,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const node = getParseTreeNode(nodeIn, hasPossibleExternalModuleReference);
return node && getExternalModuleFileFromDeclaration(node);
},
getTypeReferenceDirectivesForEntityName,
getTypeReferenceDirectivesForSymbol,
isLiteralConstDeclaration,
isLateBound: (nodeIn: Declaration): nodeIn is LateBoundDeclaration => {
const node = getParseTreeNode(nodeIn, isDeclaration);
Expand Down Expand Up @@ -48891,93 +48881,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return false;
}

function isInHeritageClause(node: PropertyAccessEntityNameExpression) {
return node.parent && node.parent.kind === SyntaxKind.ExpressionWithTypeArguments && node.parent.parent && node.parent.parent.kind === SyntaxKind.HeritageClause;
}

// defined here to avoid outer scope pollution
function getTypeReferenceDirectivesForEntityName(node: EntityNameOrEntityNameExpression): [specifier: string, mode: ResolutionMode][] | undefined {
// program does not have any files with type reference directives - bail out
if (!fileToDirective) {
return undefined;
}
// computed property name should use node as value
// property access can only be used as values, or types when within an expression with type arguments inside a heritage clause
// qualified names can only be used as types\namespaces
// identifiers are treated as values only if they appear in type queries
let meaning;
if (node.parent.kind === SyntaxKind.ComputedPropertyName) {
meaning = SymbolFlags.Value | SymbolFlags.ExportValue;
}
else {
meaning = SymbolFlags.Type | SymbolFlags.Namespace;
if ((node.kind === SyntaxKind.Identifier && isInTypeQuery(node)) || (node.kind === SyntaxKind.PropertyAccessExpression && !isInHeritageClause(node))) {
meaning = SymbolFlags.Value | SymbolFlags.ExportValue;
}
}

const symbol = resolveEntityName(node, meaning, /*ignoreErrors*/ true);
return symbol && symbol !== unknownSymbol ? getTypeReferenceDirectivesForSymbol(symbol, meaning) : undefined;
}

// defined here to avoid outer scope pollution
function getTypeReferenceDirectivesForSymbol(symbol: Symbol, meaning?: SymbolFlags): [specifier: string, mode: ResolutionMode][] | undefined {
// program does not have any files with type reference directives - bail out
if (!fileToDirective || !isSymbolFromTypeDeclarationFile(symbol)) {
return undefined;
}
// check what declarations in the symbol can contribute to the target meaning
let typeReferenceDirectives: [specifier: string, mode: ResolutionMode][] | undefined;
for (const decl of symbol.declarations!) {
// check meaning of the local symbol to see if declaration needs to be analyzed further
if (decl.symbol && decl.symbol.flags & meaning!) {
const file = getSourceFileOfNode(decl);
const typeReferenceDirective = fileToDirective.get(file.path);
if (typeReferenceDirective) {
(typeReferenceDirectives || (typeReferenceDirectives = [])).push(typeReferenceDirective);
}
else {
// found at least one entry that does not originate from type reference directive
return undefined;
}
}
}
return typeReferenceDirectives;
}

function isSymbolFromTypeDeclarationFile(symbol: Symbol): boolean {
// bail out if symbol does not have associated declarations (i.e. this is transient symbol created for property in binding pattern)
if (!symbol.declarations) {
return false;
}

// walk the parent chain for symbols to make sure that top level parent symbol is in the global scope
// external modules cannot define or contribute to type declaration files
let current = symbol;
while (true) {
const parent = getParentOfSymbol(current);
if (parent) {
current = parent;
}
else {
break;
}
}

if (current.valueDeclaration && current.valueDeclaration.kind === SyntaxKind.SourceFile && current.flags & SymbolFlags.ValueModule) {
return false;
}

// check that at least one declaration of top level symbol originates from type declaration file
for (const decl of symbol.declarations) {
const file = getSourceFileOfNode(decl);
if (fileToDirective.has(file.path)) {
return true;
}
}
return false;
}

function addReferencedFilesToTypeDirective(file: SourceFile, key: string, mode: ResolutionMode) {
if (fileToDirective.has(file.path)) return;
fileToDirective.set(file.path, [key, mode]);
Expand Down Expand Up @@ -51353,13 +51256,6 @@ class SymbolTrackerImpl implements SymbolTracker {
}
}

trackReferencedAmbientModule(decl: ModuleDeclaration, symbol: Symbol): void {
if (this.inner?.trackReferencedAmbientModule) {
this.onDiagnosticReported();
this.inner.trackReferencedAmbientModule(decl, symbol);
}
}

trackExternalModuleSymbolOfImportTypeNode(symbol: Symbol): void {
if (this.inner?.trackExternalModuleSymbolOfImportTypeNode) {
this.onDiagnosticReported();
Expand Down
14 changes: 8 additions & 6 deletions src/compiler/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1109,8 +1109,6 @@ export const notImplementedResolver: EmitResolver = {
moduleExportsSomeValue: notImplemented,
isArgumentsLocalBinding: notImplemented,
getExternalModuleFileFromDeclaration: notImplemented,
getTypeReferenceDirectivesForEntityName: notImplemented,
getTypeReferenceDirectivesForSymbol: notImplemented,
isLiteralConstDeclaration: notImplemented,
getJsxFactoryEntity: notImplemented,
getJsxFragmentFactoryEntity: notImplemented,
Expand Down Expand Up @@ -4185,19 +4183,23 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
writeLine();
}
}
// TODO(jakebailey): clean up preserve duplication
for (const directive of files) {
writeComment(`/// <reference path="${directive.fileName}" />`);
const preserve = directive.preserve ? `preserve="true" ` : "";
writeComment(`/// <reference path="${directive.fileName}" ${preserve}/>`);
writeLine();
}
for (const directive of types) {
const preserve = directive.preserve ? `preserve="true" ` : "";
const resolutionMode = directive.resolutionMode && directive.resolutionMode !== currentSourceFile?.impliedNodeFormat
? `resolution-mode="${directive.resolutionMode === ModuleKind.ESNext ? "import" : "require"}"`
? `resolution-mode="${directive.resolutionMode === ModuleKind.ESNext ? "import" : "require"}" `
: "";
writeComment(`/// <reference types="${directive.fileName}" ${resolutionMode}/>`);
writeComment(`/// <reference types="${directive.fileName}" ${resolutionMode}${preserve}/>`);
writeLine();
}
for (const directive of libs) {
writeComment(`/// <reference lib="${directive.fileName}" />`);
const preserve = directive.preserve ? `preserve="true" ` : "";
writeComment(`/// <reference lib="${directive.fileName}" ${preserve}/>`);
writeLine();
}
}
Expand Down
9 changes: 5 additions & 4 deletions src/compiler/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10510,19 +10510,20 @@ export function processPragmasIntoFields(context: PragmaContext, reportDiagnosti
const typeReferenceDirectives = context.typeReferenceDirectives;
const libReferenceDirectives = context.libReferenceDirectives;
forEach(toArray(entryOrList) as PragmaPseudoMap["reference"][], arg => {
const { types, lib, path, ["resolution-mode"]: res } = arg.arguments;
const { types, lib, path, ["resolution-mode"]: res, preserve: _preserve } = arg.arguments;
const preserve = _preserve === "true" ? true : undefined;
if (arg.arguments["no-default-lib"] === "true") {
context.hasNoDefaultLib = true;
}
else if (types) {
const parsed = parseResolutionMode(res, types.pos, types.end, reportDiagnostic);
typeReferenceDirectives.push({ pos: types.pos, end: types.end, fileName: types.value, ...(parsed ? { resolutionMode: parsed } : {}) });
typeReferenceDirectives.push({ pos: types.pos, end: types.end, fileName: types.value, ...(parsed ? { resolutionMode: parsed } : {}), ...(preserve ? { preserve } : {}) });
}
else if (lib) {
libReferenceDirectives.push({ pos: lib.pos, end: lib.end, fileName: lib.value });
libReferenceDirectives.push({ pos: lib.pos, end: lib.end, fileName: lib.value, ...(preserve ? { preserve } : {}) });
}
else if (path) {
referencedFiles.push({ pos: path.pos, end: path.end, fileName: path.value });
referencedFiles.push({ pos: path.pos, end: path.end, fileName: path.value, ...(preserve ? { preserve } : {}) });
}
else {
reportDiagnostic(arg.range.pos, arg.range.end - arg.range.pos, Diagnostics.Invalid_reference_directive_syntax);
Expand Down
1 change: 0 additions & 1 deletion src/compiler/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2630,7 +2630,6 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
getSourceFile: program.getSourceFile,
getSourceFileByPath: program.getSourceFileByPath,
getSourceFiles: program.getSourceFiles,
getLibFileFromReference: program.getLibFileFromReference,
isSourceFileFromExternalLibrary,
getResolvedProjectReferenceToRedirect,
getProjectReferenceRedirect,
Expand Down
Loading