Test case for emitting partial part of import syntax

This commit is contained in:
Sheetal Nandi
2015-02-10 17:09:29 -08:00
parent c90f820b6c
commit 863e73c75e
4 changed files with 171 additions and 51 deletions

View File

@@ -574,19 +574,21 @@ module ts {
}
}
function emitSeparatedList(nodes: Node[], separator: string, eachNodeEmitFn: (node: Node) => void) {
function emitSeparatedList(nodes: Node[], separator: string, eachNodeEmitFn: (node: Node) => void, canEmitFn?: (node: Node) => boolean) {
var currentWriterPos = writer.getTextPos();
for (var i = 0, n = nodes.length; i < n; i++) {
if (currentWriterPos !== writer.getTextPos()) {
write(separator);
if (!canEmitFn || canEmitFn(nodes[i])) {
if (currentWriterPos !== writer.getTextPos()) {
write(separator);
}
currentWriterPos = writer.getTextPos();
eachNodeEmitFn(nodes[i]);
}
currentWriterPos = writer.getTextPos();
eachNodeEmitFn(nodes[i]);
}
}
function emitCommaList(nodes: Node[], eachNodeEmitFn: (node: Node) => void) {
emitSeparatedList(nodes, ", ", eachNodeEmitFn);
function emitCommaList(nodes: Node[], eachNodeEmitFn: (node: Node) => void, canEmitFn?: (node: Node) => boolean) {
emitSeparatedList(nodes, ", ", eachNodeEmitFn, canEmitFn);
}
function writeJsDocComments(declaration: Node) {
@@ -822,22 +824,22 @@ module ts {
}
write("import ");
if (node.importClause) {
var beforeDefaultBindingEmitPos = writer.getTextPos();
var currentWriterPos = writer.getTextPos();
if (node.importClause.name && resolver.isDeclarationVisible(node.importClause)) {
writeTextOfNode(currentSourceFile, node.importClause.name);
}
if (node.importClause.namedBindings && isVisibleNamedBinding(node.importClause.namedBindings)) {
if (beforeDefaultBindingEmitPos !== writer.getTextPos()) {
if (currentWriterPos !== writer.getTextPos()) {
// If the default binding was emitted, write the separated
write(", ");
}
if (node.importClause.namedBindings.kind === SyntaxKind.NamespaceImport) {
write("* as ");
writeTextOfNode(currentSourceFile,(<NamespaceImport>node.importClause.namedBindings).name);
writeTextOfNode(currentSourceFile, (<NamespaceImport>node.importClause.namedBindings).name);
}
else {
write("{");
emitCommaList((<NamedImports>node.importClause.namedBindings).elements, emitImportSpecifier);
write("{ ");
emitCommaList((<NamedImports>node.importClause.namedBindings).elements, emitImportSpecifier, resolver.isDeclarationVisible);
write(" }");
}
}
@@ -849,14 +851,11 @@ module ts {
}
function emitImportSpecifier(node: ImportSpecifier) {
if (resolver.isDeclarationVisible(node)) {
write(" ");
if (node.propertyName) {
writeTextOfNode(currentSourceFile, node.propertyName);
write(" as ");
}
writeTextOfNode(currentSourceFile, node.name);
if (node.propertyName) {
writeTextOfNode(currentSourceFile, node.propertyName);
write(" as ");
}
writeTextOfNode(currentSourceFile, node.name);
}
function emitModuleDeclaration(node: ModuleDeclaration) {
@@ -1121,56 +1120,52 @@ module ts {
}
function emitVariableDeclaration(node: VariableDeclaration) {
// If we are emitting property it isn't moduleElement and hence we already know it needs to be emitted
// so there is no check needed to see if declaration is visible
if (node.kind !== SyntaxKind.VariableDeclaration || resolver.isDeclarationVisible(node)) {
// 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(currentSourceFile, node.name);
// If optional property emit ?
if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature) && hasQuestionToken(node)) {
write("?");
}
if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature) && node.parent.kind === SyntaxKind.TypeLiteral) {
emitTypeOfVariableDeclarationFromTypeLiteral(node);
}
else if (!(node.flags & NodeFlags.Private)) {
writeTypeOfDeclaration(node, node.type, getVariableDeclarationTypeVisibilityError);
}
// 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(currentSourceFile, node.name);
// If optional property emit ?
if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature) && hasQuestionToken(node)) {
write("?");
}
if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature) && node.parent.kind === SyntaxKind.TypeLiteral) {
emitTypeOfVariableDeclarationFromTypeLiteral(node);
}
else if (!(node.flags & NodeFlags.Private)) {
writeTypeOfDeclaration(node, node.type, getVariableDeclarationTypeVisibilityError);
}
function getVariableDeclarationTypeVisibilityError(symbolAccesibilityResult: SymbolAccessiblityResult): SymbolAccessibilityDiagnostic {
var diagnosticMessage: DiagnosticMessage;
if (node.kind === SyntaxKind.VariableDeclaration) {
diagnosticMessage = symbolAccesibilityResult.errorModuleName ?
symbolAccesibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
Diagnostics.Exported_variable_0_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
Diagnostics.Exported_variable_0_has_or_is_using_name_1_from_private_module_2 :
Diagnostics.Exported_variable_0_has_or_is_using_private_name_1;
symbolAccesibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
Diagnostics.Exported_variable_0_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
Diagnostics.Exported_variable_0_has_or_is_using_name_1_from_private_module_2 :
Diagnostics.Exported_variable_0_has_or_is_using_private_name_1;
}
// This check is to ensure we don't report error on constructor parameter property as that error would be reported during parameter emit
else if (node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature) {
// TODO(jfreeman): Deal with computed properties in error reporting.
if (node.flags & NodeFlags.Static) {
diagnosticMessage = symbolAccesibilityResult.errorModuleName ?
symbolAccesibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 :
Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_private_name_1;
symbolAccesibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 :
Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_private_name_1;
}
else if (node.parent.kind === SyntaxKind.ClassDeclaration) {
diagnosticMessage = symbolAccesibilityResult.errorModuleName ?
symbolAccesibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 :
Diagnostics.Public_property_0_of_exported_class_has_or_is_using_private_name_1;
symbolAccesibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 :
Diagnostics.Public_property_0_of_exported_class_has_or_is_using_private_name_1;
}
else {
// Interfaces cannot have types that cannot be named
diagnosticMessage = symbolAccesibilityResult.errorModuleName ?
Diagnostics.Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2 :
Diagnostics.Property_0_of_exported_interface_has_or_is_using_private_name_1;
Diagnostics.Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2 :
Diagnostics.Property_0_of_exported_interface_has_or_is_using_private_name_1;
}
}
@@ -1206,7 +1201,7 @@ module ts {
else {
write("var ");
}
emitCommaList(node.declarationList.declarations, emitVariableDeclaration);
emitCommaList(node.declarationList.declarations, emitVariableDeclaration, resolver.isDeclarationVisible);
write(";");
writeLine();
}

View File

@@ -0,0 +1,60 @@
//// [tests/cases/compiler/es6ImportNamedImportWithTypesAndValues.ts] ////
//// [server.ts]
export interface I {
prop: string;
}
export interface I2 {
prop2: string;
}
export class C implements I {
prop = "hello";
}
export class C2 implements I2 {
prop2 = "world";
}
//// [client.ts]
import { C, I, C2 } from "server"; // Shouldnt emit I and C2 into the js file and emit C and I in .d.ts file
export type cValInterface = I;
export var cVal = new C();
//// [server.js]
var C = (function () {
function C() {
this.prop = "hello";
}
return C;
})();
exports.C = C;
var C2 = (function () {
function C2() {
this.prop2 = "world";
}
return C2;
})();
exports.C2 = C2;
//// [client.js]
var _a = require("server");
var C = _a.C; // Shouldnt emit I and C2 into the js file and emit C and I in .d.ts file
exports.cVal = new C();
//// [server.d.ts]
export interface I {
prop: string;
}
export interface I2 {
prop2: string;
}
export declare class C implements I {
prop: string;
}
export declare class C2 implements I2 {
prop2: string;
}
//// [client.d.ts]
import { C, I } from "server";
export declare type cValInterface = I;
export declare var cVal: C;

View File

@@ -0,0 +1,44 @@
=== tests/cases/compiler/server.ts ===
export interface I {
>I : I
prop: string;
>prop : string
}
export interface I2 {
>I2 : I2
prop2: string;
>prop2 : string
}
export class C implements I {
>C : C
>I : I
prop = "hello";
>prop : string
}
export class C2 implements I2 {
>C2 : C2
>I2 : I2
prop2 = "world";
>prop2 : string
}
=== tests/cases/compiler/client.ts ===
import { C, I, C2 } from "server"; // Shouldnt emit I and C2 into the js file and emit C and I in .d.ts file
>C : typeof C
>I : unknown
>C2 : typeof C2
export type cValInterface = I;
>cValInterface : I
>I : I
export var cVal = new C();
>cVal : C
>new C() : C
>C : typeof C

View File

@@ -0,0 +1,21 @@
// @module: commonjs
// @declaration: true
// @filename: server.ts
export interface I {
prop: string;
}
export interface I2 {
prop2: string;
}
export class C implements I {
prop = "hello";
}
export class C2 implements I2 {
prop2 = "world";
}
// @filename: client.ts
import { C, I, C2 } from "server"; // Shouldnt emit I and C2 into the js file and emit C and I in .d.ts file
export type cValInterface = I;
export var cVal = new C();