Checker and emitter changes to report errors on inaccessibility of symbols when writing types in declaration file

This commit is contained in:
Sheetal Nandi 2014-07-18 18:06:37 -07:00
parent bbb36dc933
commit 999b7fed92
3 changed files with 72 additions and 8 deletions

View file

@ -645,7 +645,7 @@ module ts {
}
// If symbol is directly available by its name in the symbol table
if (isAccessible(symbols[symbol.name])) {
if (hasProperty(symbols, symbol.name) && isAccessible(symbols[symbol.name])) {
return symbol;
}
@ -668,7 +668,7 @@ module ts {
var qualify = false;
forEachSymbolTableInScope(enclosingDeclaration, symbolTable => {
// If symbol of this name is not available in the symbol table we are ok
if (!symbolTable[symbol.name]) {
if (!hasProperty(symbolTable, symbol.name)) {
// Continue to the next symbol table
return false;
}
@ -693,8 +693,36 @@ module ts {
return qualify
}
function isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags): boolean {
// TODO(shkamat): Actual implementation
function isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags): SymbolAccessiblityResult {
if (symbol && enclosingDeclaration && !(symbol.flags & SymbolFlags.TypeParameter)) {
var initialSymbol = symbol;
var meaningToLook = meaning;
while (symbol) {
// Symbol is accessible if it by itself is accessible
var accessibleSymbol = getAccessibleSymbol(symbol, enclosingDeclaration, meaningToLook);
if (accessibleSymbol) {
if (forEach(accessibleSymbol.declarations, declaration => !isDeclarationVisible(declaration))) {
return {
accessibility: SymbolAccessibility.NotAccessible,
errorSymbolName: symbolToString(initialSymbol, enclosingDeclaration, meaning),
errorModuleName: symbol !== initialSymbol ? symbolToString(symbol, enclosingDeclaration, SymbolFlags.Namespace) : undefined
};
}
return { accessibility: SymbolAccessibility.Accessible };
}
meaningToLook = SymbolFlags.Namespace;
symbol = symbol.parent;
}
// This is a local symbol that cannot be named
return {
accessibility: SymbolAccessibility.CannotBeNamed,
errorSymbolName: symbolToString(initialSymbol, enclosingDeclaration, meaning),
};
}
return { accessibility: SymbolAccessibility.Accessible };
}
// Enclosing declaration is optional when we dont want to get qualified name in the enclosing declaration scope

View file

@ -1854,10 +1854,30 @@ module ts {
var decreaseIndent = writer.decreaseIndent;
var enclosingDeclaration: Node;
var reportedDeclarationError = false;
var getSymbolVisibilityDiagnosticMessage: (symbolAccesibilityResult: SymbolAccessiblityResult) => {
errorNode: Node;
diagnosticMessage: DiagnosticMessage;
typeName: Identifier
}
function writeSymbol(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags) {
// TODO(shkamat): Report error if the symbol is not accessible
resolver.writeSymbol(symbol, enclosingDeclaration, meaning, writer);
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
if (!getSymbolVisibilityDiagnosticMessage || symbolAccesibilityResult.accessibility === SymbolAccessibility.Accessible) {
resolver.writeSymbol(symbol, enclosingDeclaration, meaning, writer);
}
else {
// Report error
reportedDeclarationError = true;
var errorInfo = getSymbolVisibilityDiagnosticMessage(symbolAccesibilityResult);
diagnostics.push(createDiagnosticForNode(errorInfo.errorNode,
errorInfo.diagnosticMessage,
getSourceTextOfLocalNode(errorInfo.typeName),
symbolAccesibilityResult.errorSymbolName,
symbolAccesibilityResult.errorModuleName));
}
}
function emitLines(nodes: Node[]) {
@ -2296,7 +2316,11 @@ module ts {
});
}
writeFile(getModuleNameFromFilename(jsFilePath) + ".d.ts", referencePathsOutput + writer.getText());
// 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 shouldEmitDeclarations = resolver.shouldEmitDeclarations();

View file

@ -611,6 +611,18 @@ module ts {
WriteArrayAsGenericType = 0x00000001, // Declarations
}
export enum SymbolAccessibility {
Accessible,
NotAccessible,
CannotBeNamed
}
export interface SymbolAccessiblityResult {
accessibility: SymbolAccessibility;
errorSymbolName?: string // Optional symbol name that results in error
errorModuleName?: string // If the symbol is not visibile from module, module's name
}
export interface EmitResolver {
getProgram(): Program;
getModuleObjectName(node: ModuleDeclaration): string;
@ -627,7 +639,7 @@ module ts {
writeTypeAtLocation(location: Node, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: TextWriter): void;
writeReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: TextWriter): void;
writeSymbol(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags, writer: TextWriter): void;
isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags): boolean;
isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags): SymbolAccessiblityResult;
}
export enum SymbolFlags {