Add support for declaration emit

This commit is contained in:
Ron Buckton
2017-04-29 15:18:34 -07:00
parent d8cb3c628a
commit 0c1eef70b0
3 changed files with 53 additions and 19 deletions
+14 -1
View File
@@ -2184,7 +2184,9 @@ namespace ts {
function isEntityNameVisible(entityName: EntityNameOrEntityNameExpression, enclosingDeclaration: Node): SymbolVisibilityResult {
// get symbol of the first identifier of the entityName
let meaning: SymbolFlags;
if (entityName.parent.kind === SyntaxKind.TypeQuery || isExpressionWithTypeArgumentsInClassExtendsClause(entityName.parent)) {
if (entityName.parent.kind === SyntaxKind.TypeQuery ||
isExpressionWithTypeArgumentsInClassExtendsClause(entityName.parent) ||
entityName.parent.kind === SyntaxKind.ComputedPropertyName) {
// Typeof value
meaning = SymbolFlags.Value | SymbolFlags.ExportValue;
}
@@ -22822,6 +22824,16 @@ namespace ts {
return undefined;
}
function isLiteralDynamicName(name: ComputedPropertyName) {
name = getParseTreeNode(name, isComputedPropertyName);
if (name) {
// TODO(rbuckton): ESSymbolLiteral
const nameType = checkComputedPropertyName(name);
return (nameType.flags & TypeFlags.StringOrNumberLiteral) !== 0;
}
return false;
}
function isLiteralConstDeclaration(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration): boolean {
if (isConst(node)) {
const type = getTypeOfSymbol(getSymbolOfNode(node));
@@ -22895,6 +22907,7 @@ namespace ts {
getTypeReferenceDirectivesForEntityName,
getTypeReferenceDirectivesForSymbol,
isLiteralConstDeclaration,
isLiteralDynamicName,
writeLiteralConstValue,
getJsxFactoryEntity: () => _jsxFactoryEntity
};
+38 -18
View File
@@ -452,19 +452,6 @@ namespace ts {
return emitTypePredicate(<TypePredicateNode>type);
}
function writeEntityName(entityName: EntityName | Expression) {
if (entityName.kind === SyntaxKind.Identifier) {
writeTextOfNode(currentText, entityName);
}
else {
const left = entityName.kind === SyntaxKind.QualifiedName ? (<QualifiedName>entityName).left : (<PropertyAccessExpression>entityName).expression;
const right = entityName.kind === SyntaxKind.QualifiedName ? (<QualifiedName>entityName).right : (<PropertyAccessExpression>entityName).name;
writeEntityName(left);
write(".");
writeTextOfNode(currentText, right);
}
}
function emitEntityName(entityName: EntityNameOrEntityNameExpression) {
const visibilityResult = resolver.isEntityNameVisible(entityName,
// Aliases can be written asynchronously so use correct enclosing declaration
@@ -584,6 +571,19 @@ namespace ts {
}
}
function writeEntityName(entityName: EntityName | Expression) {
if (entityName.kind === SyntaxKind.Identifier) {
writeTextOfNode(currentText, entityName);
}
else {
const left = entityName.kind === SyntaxKind.QualifiedName ? (<QualifiedName>entityName).left : (<PropertyAccessExpression>entityName).expression;
const right = entityName.kind === SyntaxKind.QualifiedName ? (<QualifiedName>entityName).right : (<PropertyAccessExpression>entityName).name;
writeEntityName(left);
write(".");
writeTextOfNode(currentText, right);
}
}
function emitSourceFile(node: SourceFile) {
currentText = node.text;
currentLineMap = getLineStarts(node);
@@ -1202,7 +1202,7 @@ namespace ts {
}
function emitPropertyDeclaration(node: Declaration) {
if (hasDynamicName(node)) {
if (hasDynamicName(node) && !resolver.isLiteralDynamicName(<ComputedPropertyName>node.name)) {
return;
}
@@ -1221,10 +1221,17 @@ namespace ts {
emitBindingPattern(<BindingPattern>node.name);
}
else {
// If this node is a computed name, it can only be a symbol, because we've already skipped
// it if it's not a well known symbol. In that case, the text of the name will be exactly
// what we want, namely the name expression enclosed in brackets.
writeTextOfNode(currentText, node.name);
if (isDynamicName(node.name)) {
// If this node has a dynamic name, it can only be an identifier or property access because
// we've already skipped it otherwise.
emitDynamicName(<EntityNameExpression>(<ComputedPropertyName>node.name).expression);
}
else {
// If this node is a computed name, it can only be a symbol, because we've already skipped
// it if it's not a well known symbol. In that case, the text of the name will be exactly
// what we want, namely the name expression enclosed in brackets.
writeTextOfNode(currentText, node.name);
}
// If optional property emit ? but in the case of parameterProperty declaration with "?" indicating optional parameter for the constructor
// we don't want to emit property declaration with "?"
if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature ||
@@ -1287,6 +1294,19 @@ namespace ts {
} : undefined;
}
function emitDynamicName(entityName: EntityNameExpression) {
writer.getSymbolAccessibilityDiagnostic = getVariableDeclarationTypeVisibilityError;
const visibilityResult = resolver.isEntityNameVisible(entityName, enclosingDeclaration);
if (visibilityResult.accessibility !== SymbolAccessibility.Accessible) {
resolver.writeTypeOfExpression(entityName, enclosingDeclaration, TypeFormatFlags.None, writer);
}
else {
handleSymbolAccessibilityError(visibilityResult);
recordTypeReferenceDirectivesIfNecessary(resolver.getTypeReferenceDirectivesForEntityName(entityName));
writeTextOfNode(currentText, node.name);
}
}
function emitBindingPattern(bindingPattern: BindingPattern) {
// Only select non-omitted expression from the bindingPattern's elements.
// We have to do this to avoid emitting trailing commas.
+1
View File
@@ -2721,6 +2721,7 @@ namespace ts {
isTopLevelValueImportEqualsWithEntityName(node: ImportEqualsDeclaration): boolean;
getNodeCheckFlags(node: Node): NodeCheckFlags;
isDeclarationVisible(node: Declaration): boolean;
isLiteralDynamicName(node: ComputedPropertyName): boolean;
collectLinkedAliases(node: Identifier): Node[];
isImplementationOfOverload(node: FunctionLikeDeclaration): boolean;
isRequiredInitializedParameter(node: ParameterDeclaration): boolean;