mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 16:38:05 -06:00
Emit unexported aliases that need to be emitted to .d.ts to make correct result
This commit is contained in:
parent
0b227d5196
commit
875d0c0c75
@ -726,6 +726,7 @@ module ts {
|
||||
}
|
||||
|
||||
function isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags): SymbolAccessiblityResult {
|
||||
var aliasesToMakeVisible: ImportDeclaration[];
|
||||
if (symbol && enclosingDeclaration && !(symbol.flags & SymbolFlags.TypeParameter)) {
|
||||
var initialSymbol = symbol;
|
||||
var meaningToLook = meaning;
|
||||
@ -733,14 +734,14 @@ module ts {
|
||||
// Symbol is accessible if it by itself is accessible
|
||||
var accessibleSymbol = getAccessibleSymbol(symbol, enclosingDeclaration, meaningToLook);
|
||||
if (accessibleSymbol) {
|
||||
if (forEach(accessibleSymbol.declarations, declaration => !isDeclarationVisible(declaration))) {
|
||||
if (forEach(accessibleSymbol.declarations, declaration => !getIsDeclarationVisible(declaration))) {
|
||||
return {
|
||||
accessibility: SymbolAccessibility.NotAccessible,
|
||||
errorSymbolName: symbolToString(initialSymbol, enclosingDeclaration, meaning),
|
||||
errorModuleName: symbol !== initialSymbol ? symbolToString(symbol, enclosingDeclaration, SymbolFlags.Namespace) : undefined
|
||||
errorModuleName: symbol !== initialSymbol ? symbolToString(symbol, enclosingDeclaration, SymbolFlags.Namespace) : undefined,
|
||||
};
|
||||
}
|
||||
return { accessibility: SymbolAccessibility.Accessible };
|
||||
return { accessibility: SymbolAccessibility.Accessible, aliasesToMakeVisible: aliasesToMakeVisible };
|
||||
}
|
||||
|
||||
// TODO(shkamat): Handle static method of class
|
||||
@ -769,6 +770,32 @@ module ts {
|
||||
}
|
||||
|
||||
return { accessibility: SymbolAccessibility.Accessible };
|
||||
|
||||
function getIsDeclarationVisible(declaration: Declaration) {
|
||||
if (!isDeclarationVisible(declaration)) {
|
||||
// Mark the unexported alias as visible if its parent is visible
|
||||
// because these kind of aliases can be used to name types in declaration file
|
||||
if (declaration.kind === SyntaxKind.ImportDeclaration &&
|
||||
!(declaration.flags & NodeFlags.Export) &&
|
||||
isDeclarationVisible(declaration.parent)) {
|
||||
getNodeLinks(declaration).isVisible = true;
|
||||
if (aliasesToMakeVisible) {
|
||||
if (!contains(aliasesToMakeVisible, declaration)) {
|
||||
aliasesToMakeVisible.push(declaration);
|
||||
}
|
||||
}
|
||||
else {
|
||||
aliasesToMakeVisible = [declaration];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Declaration is not visible
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Enclosing declaration is optional when we dont want to get qualified name in the enclosing declaration scope
|
||||
@ -1091,7 +1118,6 @@ module ts {
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
if (!(node.flags & NodeFlags.Export)) {
|
||||
// TODO(shkamat): non exported aliases can be visible if they are referenced else where for value/type/namespace
|
||||
return isGlobalSourceFile(node.parent) || isUsedInExportAssignment(node);
|
||||
}
|
||||
// Exported members are visible if parent is visible
|
||||
@ -1125,7 +1151,7 @@ module ts {
|
||||
if (node) {
|
||||
var links = getNodeLinks(node);
|
||||
if (links.isVisible === undefined) {
|
||||
links.isVisible = determineIfDeclarationIsVisible();
|
||||
links.isVisible = !!determineIfDeclarationIsVisible();
|
||||
}
|
||||
return links.isVisible;
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ module ts {
|
||||
getTextPos(): number;
|
||||
getLine(): number;
|
||||
getColumn(): number;
|
||||
getIndent(): number;
|
||||
}
|
||||
|
||||
var indentStrings: string[] = [];
|
||||
@ -141,6 +142,7 @@ module ts {
|
||||
writeLine: writeLine,
|
||||
increaseIndent: () => indent++,
|
||||
decreaseIndent: () => indent--,
|
||||
getIndent: () => indent,
|
||||
getTextPos: () => output.length,
|
||||
getLine: () => lineCount + 1,
|
||||
getColumn: () => lineStart ? indent * 4 + 1 : output.length - linePos + 1,
|
||||
@ -1867,6 +1869,13 @@ module ts {
|
||||
var enclosingDeclaration: Node;
|
||||
var reportedDeclarationError = false;
|
||||
|
||||
var aliasDeclarationEmitInfo: {
|
||||
declaration: ImportDeclaration;
|
||||
outputPos: number;
|
||||
indent: number;
|
||||
asynchronousOutput?: string; // If the output for alias was written asynchronously, the corresponding output
|
||||
}[] = [];
|
||||
|
||||
var getSymbolVisibilityDiagnosticMessage: (symbolAccesibilityResult: SymbolAccessiblityResult) => {
|
||||
errorNode: Node;
|
||||
diagnosticMessage: DiagnosticMessage;
|
||||
@ -1875,9 +1884,25 @@ module ts {
|
||||
|
||||
function writeSymbol(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags) {
|
||||
var symbolAccesibilityResult = resolver.isSymbolAccessible(symbol, enclosingDeclaration, meaning);
|
||||
// TODO(shkamat): Since we dont have error reporting for all the cases as yet we have this check on handler being present
|
||||
// TODO(shkamat): Since we dont have error reporting for all the cases as yet we have this check on handler being present
|
||||
if (!getSymbolVisibilityDiagnosticMessage || symbolAccesibilityResult.accessibility === SymbolAccessibility.Accessible) {
|
||||
resolver.writeSymbol(symbol, enclosingDeclaration, meaning, writer);
|
||||
|
||||
// write the aliases
|
||||
if (symbolAccesibilityResult && symbolAccesibilityResult.aliasesToMakeVisible) {
|
||||
var oldWriter = writer;
|
||||
forEach(symbolAccesibilityResult.aliasesToMakeVisible.sort(), aliasToWrite => {
|
||||
var aliasEmitInfo = forEach(aliasDeclarationEmitInfo, declEmitInfo => declEmitInfo.declaration === aliasToWrite ? declEmitInfo : undefined);
|
||||
writer = createTextWriter(writeSymbol);
|
||||
for (var declarationIndent = aliasEmitInfo.indent; declarationIndent; declarationIndent--) {
|
||||
writer.increaseIndent();
|
||||
}
|
||||
|
||||
writeImportDeclaration(aliasToWrite);
|
||||
aliasEmitInfo.asynchronousOutput = writer.getText();
|
||||
});
|
||||
writer = oldWriter;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Report error
|
||||
@ -1951,26 +1976,39 @@ module ts {
|
||||
}
|
||||
|
||||
function emitImportDeclaration(node: ImportDeclaration) {
|
||||
if (resolver.isDeclarationVisible(node)) {
|
||||
if (node.flags & NodeFlags.Export) {
|
||||
write("export ");
|
||||
}
|
||||
write("import ");
|
||||
emitSourceTextOfNode(node.name);
|
||||
write(" = ");
|
||||
if (node.entityName) {
|
||||
emitSourceTextOfNode(node.entityName);
|
||||
write(";");
|
||||
}
|
||||
else {
|
||||
write("require(");
|
||||
emitSourceTextOfNode(node.externalModuleName);
|
||||
write(");");
|
||||
}
|
||||
writeLine();
|
||||
var nodeEmitInfo = {
|
||||
declaration: node,
|
||||
outputPos: writer.getTextPos(),
|
||||
indent: writer.getIndent(),
|
||||
hasWritten: resolver.isDeclarationVisible(node)
|
||||
};
|
||||
aliasDeclarationEmitInfo.push(nodeEmitInfo);
|
||||
if (nodeEmitInfo.hasWritten) {
|
||||
writeImportDeclaration(node);
|
||||
}
|
||||
}
|
||||
|
||||
function writeImportDeclaration(node: ImportDeclaration) {
|
||||
// note usage of writer. methods instead of aliases created, just to make sure we are using
|
||||
// correct writer especially to handle asynchronous alias writing
|
||||
if (node.flags & NodeFlags.Export) {
|
||||
writer.write("export ");
|
||||
}
|
||||
writer.write("import ");
|
||||
writer.write(getSourceTextOfLocalNode(node.name));
|
||||
writer.write(" = ");
|
||||
if (node.entityName) {
|
||||
writer.write(getSourceTextOfLocalNode(node.entityName));
|
||||
writer.write(";");
|
||||
}
|
||||
else {
|
||||
writer.write("require(");
|
||||
writer.write(getSourceTextOfLocalNode(node.externalModuleName));
|
||||
writer.write(");");
|
||||
}
|
||||
writer.writeLine();
|
||||
}
|
||||
|
||||
function emitModuleDeclaration(node: ModuleDeclaration) {
|
||||
if (resolver.isDeclarationVisible(node)) {
|
||||
emitDeclarationFlags(node);
|
||||
@ -2484,7 +2522,19 @@ module ts {
|
||||
// TODO(shkamat): Should we not write any declaration file if any of them can produce error,
|
||||
// or should we just not write this file like we are doing now
|
||||
if (!reportedDeclarationError) {
|
||||
writeFile(getModuleNameFromFilename(jsFilePath) + ".d.ts", referencePathsOutput + writer.getText());
|
||||
var declarationOutput = referencePathsOutput;
|
||||
var synchronousDeclarationOutput = writer.getText();
|
||||
// apply additions
|
||||
var appliedSyncOutputPos = 0;
|
||||
forEach(aliasDeclarationEmitInfo, aliasEmitInfo => {
|
||||
if (aliasEmitInfo.asynchronousOutput) {
|
||||
declarationOutput += synchronousDeclarationOutput.substring(appliedSyncOutputPos, aliasEmitInfo.outputPos);
|
||||
declarationOutput += aliasEmitInfo.asynchronousOutput;
|
||||
appliedSyncOutputPos = aliasEmitInfo.outputPos;
|
||||
}
|
||||
});
|
||||
declarationOutput += synchronousDeclarationOutput.substring(appliedSyncOutputPos);
|
||||
writeFile(getModuleNameFromFilename(jsFilePath) + ".d.ts", declarationOutput);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -638,6 +638,7 @@ module ts {
|
||||
accessibility: SymbolAccessibility;
|
||||
errorSymbolName?: string // Optional symbol name that results in error
|
||||
errorModuleName?: string // If the symbol is not visibile from module, module's name
|
||||
aliasesToMakeVisible?: ImportDeclaration[]; // aliases that need to have this symbol visible
|
||||
}
|
||||
|
||||
export interface EmitResolver {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user