diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts
index 6edba58cb11..2993ec3aa0c 100644
--- a/src/compiler/binder.ts
+++ b/src/compiler/binder.ts
@@ -1,3 +1,4 @@
+///
///
/* @internal */
@@ -6,8 +7,8 @@ namespace ts {
export const enum ModuleInstanceState {
NonInstantiated = 0,
- Instantiated = 1,
- ConstEnumOnly = 2
+ Instantiated = 1,
+ ConstEnumOnly = 2
}
const enum Reachability {
@@ -188,6 +189,11 @@ namespace ts {
}
if (node.name.kind === SyntaxKind.ComputedPropertyName) {
const nameExpression = (node.name).expression;
+ // treat computed property names where expression is string/numeric literal as just string/numeric literal
+ if (isStringOrNumericLiteral(nameExpression.kind)) {
+ return (nameExpression).text;
+ }
+
Debug.assert(isWellKnownSymbolSyntactically(nameExpression));
return getPropertyNameForKnownSymbolName((nameExpression).name.text);
}
@@ -208,6 +214,9 @@ namespace ts {
return "__export";
case SyntaxKind.ExportAssignment:
return (node).isExportEquals ? "export=" : "default";
+ case SyntaxKind.BinaryExpression:
+ // Binary expression case is for JS module 'module.exports = expr'
+ return "export=";
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.ClassDeclaration:
return node.flags & NodeFlags.Default ? "default" : undefined;
@@ -1069,7 +1078,7 @@ namespace ts {
return "__" + indexOf((node.parent).parameters, node);
}
- function bind(node: Node) {
+ function bind(node: Node): void {
if (!node) {
return;
}
@@ -1145,9 +1154,18 @@ namespace ts {
function bindWorker(node: Node) {
switch (node.kind) {
+ /* Strict mode checks */
case SyntaxKind.Identifier:
return checkStrictModeIdentifier(node);
case SyntaxKind.BinaryExpression:
+ if (isInJavaScriptFile(node)) {
+ if (isExportsPropertyAssignment(node)) {
+ bindExportsPropertyAssignment(node);
+ }
+ else if (isModuleExportsAssignment(node)) {
+ bindModuleExportsAssignment(node);
+ }
+ }
return checkStrictModeBinaryExpression(node);
case SyntaxKind.CatchClause:
return checkStrictModeCatchClause(node);
@@ -1213,6 +1231,14 @@ namespace ts {
checkStrictModeFunctionName(node);
const bindingName = (node).name ? (node).name.text : "__function";
return bindAnonymousDeclaration(node, SymbolFlags.Function, bindingName);
+
+ case SyntaxKind.CallExpression:
+ if (isInJavaScriptFile(node)) {
+ bindCallExpression(node);
+ }
+ break;
+
+ // Members of classes, interfaces, and modules
case SyntaxKind.ClassExpression:
case SyntaxKind.ClassDeclaration:
return bindClassLikeDeclaration(node);
@@ -1224,6 +1250,8 @@ namespace ts {
return bindEnumDeclaration(node);
case SyntaxKind.ModuleDeclaration:
return bindModuleDeclaration(node);
+
+ // Imports and exports
case SyntaxKind.ImportEqualsDeclaration:
case SyntaxKind.NamespaceImport:
case SyntaxKind.ImportSpecifier:
@@ -1243,16 +1271,21 @@ namespace ts {
function bindSourceFileIfExternalModule() {
setExportContextFlag(file);
if (isExternalModule(file)) {
- bindAnonymousDeclaration(file, SymbolFlags.ValueModule, `"${removeFileExtension(file.fileName)}"`);
+ bindSourceFileAsExternalModule();
}
}
- function bindExportAssignment(node: ExportAssignment) {
+ function bindSourceFileAsExternalModule() {
+ bindAnonymousDeclaration(file, SymbolFlags.ValueModule, `"${removeFileExtension(file.fileName) }"`);
+ }
+
+ function bindExportAssignment(node: ExportAssignment | BinaryExpression) {
+ const boundExpression = node.kind === SyntaxKind.ExportAssignment ? (node).expression : (node).right;
if (!container.symbol || !container.symbol.exports) {
// Export assignment in some sort of block construct
bindAnonymousDeclaration(node, SymbolFlags.Alias, getDeclarationName(node));
}
- else if (node.expression.kind === SyntaxKind.Identifier) {
+ else if (boundExpression.kind === SyntaxKind.Identifier) {
// An export default clause with an identifier exports all meanings of that identifier
declareSymbol(container.symbol.exports, container.symbol, node, SymbolFlags.Alias, SymbolFlags.PropertyExcludes | SymbolFlags.AliasExcludes);
}
@@ -1279,6 +1312,34 @@ namespace ts {
}
}
+ function setCommonJsModuleIndicator(node: Node) {
+ if (!file.commonJsModuleIndicator) {
+ file.commonJsModuleIndicator = node;
+ bindSourceFileAsExternalModule();
+ }
+ }
+
+ function bindExportsPropertyAssignment(node: BinaryExpression) {
+ // When we create a property via 'exports.foo = bar', the 'exports.foo' property access
+ // expression is the declaration
+ setCommonJsModuleIndicator(node);
+ declareSymbol(file.symbol.exports, file.symbol, node.left, SymbolFlags.Property | SymbolFlags.Export, SymbolFlags.None);
+ }
+
+ function bindModuleExportsAssignment(node: BinaryExpression) {
+ // 'module.exports = expr' assignment
+ setCommonJsModuleIndicator(node);
+ bindExportAssignment(node);
+ }
+
+ function bindCallExpression(node: CallExpression) {
+ // We're only inspecting call expressions to detect CommonJS modules, so we can skip
+ // this check if we've already seen the module indicator
+ if (!file.commonJsModuleIndicator && isRequireCall(node)) {
+ setCommonJsModuleIndicator(node);
+ }
+ }
+
function bindClassLikeDeclaration(node: ClassLikeDeclaration) {
if (node.kind === SyntaxKind.ClassDeclaration) {
bindBlockScopedDeclaration(node, SymbolFlags.Class, SymbolFlags.ClassExcludes);
diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index bfd2eb8d7b8..d9f5474e2ff 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -364,7 +364,7 @@ namespace ts {
}
function isGlobalSourceFile(node: Node) {
- return node.kind === SyntaxKind.SourceFile && !isExternalModule(node);
+ return node.kind === SyntaxKind.SourceFile && !isExternalOrCommonJsModule(node);
}
function getSymbol(symbols: SymbolTable, name: string, meaning: SymbolFlags): Symbol {
@@ -480,7 +480,7 @@ namespace ts {
}
switch (location.kind) {
case SyntaxKind.SourceFile:
- if (!isExternalModule(location)) break;
+ if (!isExternalOrCommonJsModule(location)) break;
case SyntaxKind.ModuleDeclaration:
const moduleExports = getSymbolOfNode(location).exports;
if (location.kind === SyntaxKind.SourceFile ||
@@ -990,11 +990,16 @@ namespace ts {
// Module names are escaped in our symbol table. However, string literal values aren't.
// Escape the name in the "require(...)" clause to ensure we find the right symbol.
- const moduleName = escapeIdentifier(moduleReferenceLiteral.text);
+ let moduleName = escapeIdentifier(moduleReferenceLiteral.text);
if (moduleName === undefined) {
return;
}
+
+ if (moduleName.indexOf("!") >= 0) {
+ moduleName = moduleName.substr(0, moduleName.indexOf("!"));
+ }
+
const isRelative = isExternalModuleNameRelative(moduleName);
if (!isRelative) {
const symbol = getSymbol(globals, "\"" + moduleName + "\"", SymbolFlags.ValueModule);
@@ -1205,7 +1210,7 @@ namespace ts {
}
switch (location.kind) {
case SyntaxKind.SourceFile:
- if (!isExternalModule(location)) {
+ if (!isExternalOrCommonJsModule(location)) {
break;
}
case SyntaxKind.ModuleDeclaration:
@@ -1387,7 +1392,7 @@ namespace ts {
function hasExternalModuleSymbol(declaration: Node) {
return (declaration.kind === SyntaxKind.ModuleDeclaration && (declaration).name.kind === SyntaxKind.StringLiteral) ||
- (declaration.kind === SyntaxKind.SourceFile && isExternalModule(declaration));
+ (declaration.kind === SyntaxKind.SourceFile && isExternalOrCommonJsModule(declaration));
}
function hasVisibleDeclarations(symbol: Symbol): SymbolVisibilityResult {
@@ -2061,7 +2066,7 @@ namespace ts {
}
}
else if (node.kind === SyntaxKind.SourceFile) {
- return isExternalModule(node) ? node : undefined;
+ return isExternalOrCommonJsModule(node) ? node : undefined;
}
}
Debug.fail("getContainingModule cant reach here");
@@ -2182,7 +2187,7 @@ namespace ts {
case SyntaxKind.SourceFile:
return true;
- // Export assignements do not create name bindings outside the module
+ // Export assignments do not create name bindings outside the module
case SyntaxKind.ExportAssignment:
return false;
@@ -2337,6 +2342,26 @@ namespace ts {
return symbol && getSymbolLinks(symbol).type || getTypeForVariableLikeDeclaration(node);
}
+ function getTextOfPropertyName(name: PropertyName): string {
+ switch (name.kind) {
+ case SyntaxKind.Identifier:
+ return (name).text;
+ case SyntaxKind.StringLiteral:
+ case SyntaxKind.NumericLiteral:
+ return (name).text;
+ case SyntaxKind.ComputedPropertyName:
+ if (isStringOrNumericLiteral((name).expression.kind)) {
+ return ((name).expression).text;
+ }
+ }
+
+ return undefined;
+ }
+
+ function isComputedNonLiteralName(name: PropertyName): boolean {
+ return name.kind === SyntaxKind.ComputedPropertyName && !isStringOrNumericLiteral((name).expression.kind);
+ }
+
// Return the inferred type for a binding element
function getTypeForBindingElement(declaration: BindingElement): Type {
const pattern = declaration.parent;
@@ -2359,10 +2384,17 @@ namespace ts {
if (pattern.kind === SyntaxKind.ObjectBindingPattern) {
// Use explicitly specified property name ({ p: xxx } form), or otherwise the implied name ({ p } form)
const name = declaration.propertyName || declaration.name;
+ if (isComputedNonLiteralName(name)) {
+ // computed properties with non-literal names are treated as 'any'
+ return anyType;
+ }
+
// Use type of the specified property, or otherwise, for a numeric name, the type of the numeric index signature,
// or otherwise the type of the string index signature.
- type = getTypeOfPropertyOfType(parentType, name.text) ||
- isNumericLiteralName(name.text) && getIndexTypeOfType(parentType, IndexKind.Number) ||
+ const text = getTextOfPropertyName(name);
+
+ type = getTypeOfPropertyOfType(parentType, text) ||
+ isNumericLiteralName(text) && getIndexTypeOfType(parentType, IndexKind.Number) ||
getIndexTypeOfType(parentType, IndexKind.String);
if (!type) {
error(name, Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(parentType), declarationNameToString(name));
@@ -2473,10 +2505,18 @@ namespace ts {
// Return the type implied by an object binding pattern
function getTypeFromObjectBindingPattern(pattern: BindingPattern, includePatternInType: boolean): Type {
const members: SymbolTable = {};
+ let hasComputedProperties = false;
forEach(pattern.elements, e => {
- const flags = SymbolFlags.Property | SymbolFlags.Transient | (e.initializer ? SymbolFlags.Optional : 0);
const name = e.propertyName || e.name;
- const symbol = createSymbol(flags, name.text);
+ if (isComputedNonLiteralName(name)) {
+ // do not include computed properties in the implied type
+ hasComputedProperties = true;
+ return;
+ }
+
+ const text = getTextOfPropertyName(name);
+ const flags = SymbolFlags.Property | SymbolFlags.Transient | (e.initializer ? SymbolFlags.Optional : 0);
+ const symbol = createSymbol(flags, text);
symbol.type = getTypeFromBindingElement(e, includePatternInType);
symbol.bindingElement = e;
members[symbol.name] = symbol;
@@ -2485,6 +2525,9 @@ namespace ts {
if (includePatternInType) {
result.pattern = pattern;
}
+ if (hasComputedProperties) {
+ result.flags |= TypeFlags.ObjectLiteralPatternWithComputedProperties;
+ }
return result;
}
@@ -2567,6 +2610,14 @@ namespace ts {
if (declaration.kind === SyntaxKind.ExportAssignment) {
return links.type = checkExpression((declaration).expression);
}
+ // Handle module.exports = expr
+ if (declaration.kind === SyntaxKind.BinaryExpression) {
+ return links.type = checkExpression((declaration).right);
+ }
+ // Handle exports.p = expr
+ if (declaration.kind === SyntaxKind.PropertyAccessExpression) {
+ return checkExpressionCached((declaration.parent).right);
+ }
// Handle variable, parameter or property
if (!pushTypeResolution(symbol, TypeSystemPropertyName.Type)) {
return unknownType;
@@ -2870,23 +2921,25 @@ namespace ts {
function resolveBaseTypesOfClass(type: InterfaceType): void {
type.resolvedBaseTypes = type.resolvedBaseTypes || emptyArray;
- const baseContructorType = getBaseConstructorTypeOfClass(type);
- if (!(baseContructorType.flags & TypeFlags.ObjectType)) {
+ const baseConstructorType = getBaseConstructorTypeOfClass(type);
+ if (!(baseConstructorType.flags & TypeFlags.ObjectType)) {
return;
}
const baseTypeNode = getBaseTypeNodeOfClass(type);
let baseType: Type;
- if (baseContructorType.symbol && baseContructorType.symbol.flags & SymbolFlags.Class) {
- // When base constructor type is a class we know that the constructors all have the same type parameters as the
+ const originalBaseType = baseConstructorType && baseConstructorType.symbol ? getDeclaredTypeOfSymbol(baseConstructorType.symbol) : undefined;
+ if (baseConstructorType.symbol && baseConstructorType.symbol.flags & SymbolFlags.Class &&
+ areAllOuterTypeParametersApplied(originalBaseType)) {
+ // When base constructor type is a class with no captured type arguments we know that the constructors all have the same type parameters as the
// class and all return the instance type of the class. There is no need for further checks and we can apply the
// type arguments in the same manner as a type reference to get the same error reporting experience.
- baseType = getTypeFromClassOrInterfaceReference(baseTypeNode, baseContructorType.symbol);
+ baseType = getTypeFromClassOrInterfaceReference(baseTypeNode, baseConstructorType.symbol);
}
else {
// The class derives from a "class-like" constructor function, check that we have at least one construct signature
// with a matching number of type parameters and use the return type of the first instantiated signature. Elsewhere
// we check that all instantiated signatures return the same type.
- const constructors = getInstantiatedConstructorsForTypeArguments(baseContructorType, baseTypeNode.typeArguments);
+ const constructors = getInstantiatedConstructorsForTypeArguments(baseConstructorType, baseTypeNode.typeArguments);
if (!constructors.length) {
error(baseTypeNode.expression, Diagnostics.No_base_constructor_has_the_specified_number_of_type_arguments);
return;
@@ -2913,6 +2966,18 @@ namespace ts {
}
}
+ function areAllOuterTypeParametersApplied(type: Type): boolean {
+ // An unapplied type parameter has its symbol still the same as the matching argument symbol.
+ // Since parameters are applied outer-to-inner, only the last outer parameter needs to be checked.
+ const outerTypeParameters = (type).outerTypeParameters;
+ if (outerTypeParameters) {
+ const last = outerTypeParameters.length - 1;
+ const typeArguments = (type).typeArguments;
+ return outerTypeParameters[last].symbol !== typeArguments[last].symbol;
+ }
+ return true;
+ }
+
function resolveBaseTypesOfInterface(type: InterfaceType): void {
type.resolvedBaseTypes = type.resolvedBaseTypes || emptyArray;
for (const declaration of type.symbol.declarations) {
@@ -3841,6 +3906,18 @@ namespace ts {
return result;
}
+ function resolveExternalModuleTypeByLiteral(name: StringLiteral) {
+ const moduleSym = resolveExternalModuleName(name, name);
+ if (moduleSym) {
+ const resolvedModuleSymbol = resolveExternalModuleSymbol(moduleSym);
+ if (resolvedModuleSymbol) {
+ return getTypeOfSymbol(resolvedModuleSymbol);
+ }
+ }
+
+ return anyType;
+ }
+
function getReturnTypeOfSignature(signature: Signature): Type {
if (!signature.resolvedReturnType) {
if (!pushTypeResolution(signature, TypeSystemPropertyName.ResolvedReturnType)) {
@@ -4988,7 +5065,7 @@ namespace ts {
}
function hasExcessProperties(source: FreshObjectLiteralType, target: Type, reportErrors: boolean): boolean {
- if (someConstituentTypeHasKind(target, TypeFlags.ObjectType)) {
+ if (!(target.flags & TypeFlags.ObjectLiteralPatternWithComputedProperties) && someConstituentTypeHasKind(target, TypeFlags.ObjectType)) {
for (const prop of getPropertiesOfObjectType(source)) {
if (!isKnownProperty(target, prop.name)) {
if (reportErrors) {
@@ -7442,6 +7519,7 @@ namespace ts {
(contextualType.pattern.kind === SyntaxKind.ObjectBindingPattern || contextualType.pattern.kind === SyntaxKind.ObjectLiteralExpression);
let typeFlags: TypeFlags = 0;
+ let patternWithComputedProperties = false;
for (const memberDecl of node.properties) {
let member = memberDecl.symbol;
if (memberDecl.kind === SyntaxKind.PropertyAssignment ||
@@ -7469,8 +7547,11 @@ namespace ts {
if (isOptional) {
prop.flags |= SymbolFlags.Optional;
}
+ if (hasDynamicName(memberDecl)) {
+ patternWithComputedProperties = true;
+ }
}
- else if (contextualTypeHasPattern) {
+ else if (contextualTypeHasPattern && !(contextualType.flags & TypeFlags.ObjectLiteralPatternWithComputedProperties)) {
// If object literal is contextually typed by the implied type of a binding pattern, and if the
// binding pattern specifies a default value for the property, make the property optional.
const impliedProp = getPropertyOfType(contextualType, member.name);
@@ -7527,7 +7608,7 @@ namespace ts {
const numberIndexType = getIndexType(IndexKind.Number);
const result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexType, numberIndexType);
const freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : TypeFlags.FreshObjectLiteral;
- result.flags |= TypeFlags.ObjectLiteral | TypeFlags.ContainsObjectLiteral | freshObjectLiteralFlag | (typeFlags & TypeFlags.PropagatingFlags);
+ result.flags |= TypeFlags.ObjectLiteral | TypeFlags.ContainsObjectLiteral | freshObjectLiteralFlag | (typeFlags & TypeFlags.PropagatingFlags) | (patternWithComputedProperties ? TypeFlags.ObjectLiteralPatternWithComputedProperties : 0);
if (inDestructuringPattern) {
result.pattern = node;
}
@@ -9426,6 +9507,12 @@ namespace ts {
return anyType;
}
}
+
+ // In JavaScript files, calls to any identifier 'require' are treated as external module imports
+ if (isInJavaScriptFile(node) && isRequireCall(node)) {
+ return resolveExternalModuleTypeByLiteral(node.arguments[0]);
+ }
+
return getReturnTypeOfSignature(signature);
}
@@ -10051,19 +10138,27 @@ namespace ts {
const properties = node.properties;
for (const p of properties) {
if (p.kind === SyntaxKind.PropertyAssignment || p.kind === SyntaxKind.ShorthandPropertyAssignment) {
- // TODO(andersh): Computed property support
- const name = (p).name;
+ const name = (p).name;
+ if (name.kind === SyntaxKind.ComputedPropertyName) {
+ checkComputedPropertyName(name);
+ }
+ if (isComputedNonLiteralName(name)) {
+ continue;
+ }
+
+ const text = getTextOfPropertyName(name);
const type = isTypeAny(sourceType)
? sourceType
- : getTypeOfPropertyOfType(sourceType, name.text) ||
- isNumericLiteralName(name.text) && getIndexTypeOfType(sourceType, IndexKind.Number) ||
+ : getTypeOfPropertyOfType(sourceType, text) ||
+ isNumericLiteralName(text) && getIndexTypeOfType(sourceType, IndexKind.Number) ||
getIndexTypeOfType(sourceType, IndexKind.String);
if (type) {
if (p.kind === SyntaxKind.ShorthandPropertyAssignment) {
checkDestructuringAssignment(p, type);
}
else {
- checkDestructuringAssignment((p).initializer || name, type);
+ // non-shorthand property assignments should always have initializers
+ checkDestructuringAssignment((p).initializer, type);
}
}
else {
@@ -12067,7 +12162,7 @@ namespace ts {
// In case of variable declaration, node.parent is variable statement so look at the variable statement's parent
const parent = getDeclarationContainer(node);
- if (parent.kind === SyntaxKind.SourceFile && isExternalModule(parent)) {
+ if (parent.kind === SyntaxKind.SourceFile && isExternalOrCommonJsModule(parent)) {
// If the declaration happens to be in external module, report error that require and exports are reserved keywords
error(name, Diagnostics.Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module,
declarationNameToString(name), declarationNameToString(name));
@@ -12196,6 +12291,14 @@ namespace ts {
checkExpressionCached(node.initializer);
}
}
+
+ if (node.kind === SyntaxKind.BindingElement) {
+ // check computed properties inside property names of binding elements
+ if (node.propertyName && node.propertyName.kind === SyntaxKind.ComputedPropertyName) {
+ checkComputedPropertyName(node.propertyName);
+ }
+ }
+
// For a binding pattern, check contained binding elements
if (isBindingPattern(node.name)) {
forEach((node.name).elements, checkSourceElement);
@@ -13307,11 +13410,14 @@ namespace ts {
const enumIsConst = isConst(node);
for (const member of node.members) {
- if (member.name.kind === SyntaxKind.ComputedPropertyName) {
+ if (isComputedNonLiteralName(member.name)) {
error(member.name, Diagnostics.Computed_property_names_are_not_allowed_in_enums);
}
- else if (isNumericLiteralName((member.name).text)) {
- error(member.name, Diagnostics.An_enum_member_cannot_have_a_numeric_name);
+ else {
+ const text = getTextOfPropertyName(member.name);
+ if (isNumericLiteralName(text)) {
+ error(member.name, Diagnostics.An_enum_member_cannot_have_a_numeric_name);
+ }
}
const previousEnumMemberIsNonConstant = autoValue === undefined;
@@ -14150,7 +14256,7 @@ namespace ts {
forEach(node.statements, checkSourceElement);
checkFunctionAndClassExpressionBodies(node);
- if (isExternalModule(node)) {
+ if (isExternalOrCommonJsModule(node)) {
checkExternalModuleExports(node);
}
@@ -14253,7 +14359,7 @@ namespace ts {
switch (location.kind) {
case SyntaxKind.SourceFile:
- if (!isExternalModule(location)) {
+ if (!isExternalOrCommonJsModule(location)) {
break;
}
case SyntaxKind.ModuleDeclaration:
@@ -14999,16 +15105,16 @@ namespace ts {
// Initialize global symbol table
forEach(host.getSourceFiles(), file => {
- if (!isExternalModule(file)) {
+ if (!isExternalOrCommonJsModule(file)) {
mergeSymbolTable(globals, file.locals);
}
});
- // Initialize special symbols
getSymbolLinks(undefinedSymbol).type = undefinedType;
getSymbolLinks(argumentsSymbol).type = getGlobalType("IArguments");
getSymbolLinks(unknownSymbol).type = unknownType;
globals[undefinedSymbol.name] = undefinedSymbol;
+
// Initialize special types
globalArrayType = getGlobalType("Array", /*arity*/ 1);
globalObjectType = getGlobalType("Object");
@@ -15769,7 +15875,7 @@ namespace ts {
}
function checkGrammarForNonSymbolComputedProperty(node: DeclarationName, message: DiagnosticMessage) {
- if (node.kind === SyntaxKind.ComputedPropertyName && !isWellKnownSymbolSyntactically((node).expression)) {
+ if (isDynamicName(node)) {
return grammarErrorOnNode(node, message);
}
}
diff --git a/src/compiler/core.ts b/src/compiler/core.ts
index 2ce3bbfaf3b..c866cf41a92 100644
--- a/src/compiler/core.ts
+++ b/src/compiler/core.ts
@@ -739,12 +739,7 @@ namespace ts {
* List of supported extensions in order of file resolution precedence.
*/
export const supportedExtensions = [".ts", ".tsx", ".d.ts"];
- /**
- * List of extensions that will be used to look for external modules.
- * This list is kept separate from supportedExtensions to for cases when we'll allow to include .js files in compilation,
- * but still would like to load only TypeScript files as modules
- */
- export const moduleFileExtensions = supportedExtensions;
+ export const supportedJsExtensions = supportedExtensions.concat(".js", ".jsx");
export function isSupportedSourceFileName(fileName: string) {
if (!fileName) { return false; }
diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts
index a43f4ded66c..d0314649b88 100644
--- a/src/compiler/emitter.ts
+++ b/src/compiler/emitter.ts
@@ -4244,15 +4244,22 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
return node;
}
- function createPropertyAccessForDestructuringProperty(object: Expression, propName: Identifier | LiteralExpression): Expression {
- // We create a synthetic copy of the identifier in order to avoid the rewriting that might
- // otherwise occur when the identifier is emitted.
- const syntheticName = createSynthesizedNode(propName.kind);
- syntheticName.text = propName.text;
- if (syntheticName.kind !== SyntaxKind.Identifier) {
- return createElementAccessExpression(object, syntheticName);
+ function createPropertyAccessForDestructuringProperty(object: Expression, propName: PropertyName): Expression {
+ let index: Expression;
+ const nameIsComputed = propName.kind === SyntaxKind.ComputedPropertyName;
+ if (nameIsComputed) {
+ index = ensureIdentifier((propName).expression, /* reuseIdentifierExpression */ false);
}
- return createPropertyAccessExpression(object, syntheticName);
+ else {
+ // We create a synthetic copy of the identifier in order to avoid the rewriting that might
+ // otherwise occur when the identifier is emitted.
+ index = createSynthesizedNode(propName.kind);
+ (index).text = (propName).text;
+ }
+
+ return !nameIsComputed && index.kind === SyntaxKind.Identifier
+ ? createPropertyAccessExpression(object, index)
+ : createElementAccessExpression(object, index);
}
function createSliceCall(value: Expression, sliceIndex: number): CallExpression {
diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts
index 39b5a5d322e..96c8e19e7bc 100644
--- a/src/compiler/parser.ts
+++ b/src/compiler/parser.ts
@@ -1,5 +1,5 @@
-///
///
+///
namespace ts {
/* @internal */ export let parseTime = 0;
@@ -534,7 +534,8 @@ namespace ts {
let parseErrorBeforeNextFinishedNode = false;
export function parseSourceFile(fileName: string, _sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor, setParentNodes?: boolean): SourceFile {
- initializeState(fileName, _sourceText, languageVersion, _syntaxCursor);
+ const isJavaScriptFile = hasJavaScriptFileExtension(fileName) || _sourceText.lastIndexOf("// @language=javascript", 0) === 0;
+ initializeState(fileName, _sourceText, languageVersion, isJavaScriptFile, _syntaxCursor);
const result = parseSourceFileWorker(fileName, languageVersion, setParentNodes);
@@ -543,7 +544,7 @@ namespace ts {
return result;
}
- function initializeState(fileName: string, _sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor) {
+ function initializeState(fileName: string, _sourceText: string, languageVersion: ScriptTarget, isJavaScriptFile: boolean, _syntaxCursor: IncrementalParser.SyntaxCursor) {
NodeConstructor = objectAllocator.getNodeConstructor();
SourceFileConstructor = objectAllocator.getSourceFileConstructor();
@@ -556,14 +557,14 @@ namespace ts {
identifierCount = 0;
nodeCount = 0;
- contextFlags = isJavaScript(fileName) ? ParserContextFlags.JavaScriptFile : ParserContextFlags.None;
+ contextFlags = isJavaScriptFile ? ParserContextFlags.JavaScriptFile : ParserContextFlags.None;
parseErrorBeforeNextFinishedNode = false;
// Initialize and prime the scanner before parsing the source elements.
scanner.setText(sourceText);
scanner.setOnError(scanError);
scanner.setScriptTarget(languageVersion);
- scanner.setLanguageVariant(isTsx(fileName) ? LanguageVariant.JSX : LanguageVariant.Standard);
+ scanner.setLanguageVariant(allowsJsxExpressions(fileName) ? LanguageVariant.JSX : LanguageVariant.Standard);
}
function clearState() {
@@ -582,6 +583,10 @@ namespace ts {
function parseSourceFileWorker(fileName: string, languageVersion: ScriptTarget, setParentNodes: boolean): SourceFile {
sourceFile = createSourceFile(fileName, languageVersion);
+ if (contextFlags & ParserContextFlags.JavaScriptFile) {
+ sourceFile.parserContextFlags = ParserContextFlags.JavaScriptFile;
+ }
+
// Prime the scanner.
token = nextToken();
processReferenceComments(sourceFile);
@@ -604,7 +609,7 @@ namespace ts {
// If this is a javascript file, proactively see if we can get JSDoc comments for
// relevant nodes in the file. We'll use these to provide typing informaion if they're
// available.
- if (isJavaScript(fileName)) {
+ if (isSourceFileJavaScript(sourceFile)) {
addJSDocComments();
}
@@ -677,7 +682,7 @@ namespace ts {
sourceFile.languageVersion = languageVersion;
sourceFile.fileName = normalizePath(fileName);
sourceFile.flags = fileExtensionIs(sourceFile.fileName, ".d.ts") ? NodeFlags.DeclarationFile : 0;
- sourceFile.languageVariant = isTsx(sourceFile.fileName) ? LanguageVariant.JSX : LanguageVariant.Standard;
+ sourceFile.languageVariant = allowsJsxExpressions(sourceFile.fileName) ? LanguageVariant.JSX : LanguageVariant.Standard;
return sourceFile;
}
@@ -1202,7 +1207,7 @@ namespace ts {
case ParsingContext.ObjectLiteralMembers:
return token === SyntaxKind.OpenBracketToken || token === SyntaxKind.AsteriskToken || isLiteralPropertyName();
case ParsingContext.ObjectBindingElements:
- return isLiteralPropertyName();
+ return token === SyntaxKind.OpenBracketToken || isLiteralPropertyName();
case ParsingContext.HeritageClauseElement:
// If we see { } then only consume it as an expression if it is followed by , or {
// That way we won't consume the body of a class in its heritage clause.
@@ -4582,7 +4587,6 @@ namespace ts {
function parseObjectBindingElement(): BindingElement {
const node = createNode(SyntaxKind.BindingElement);
- // TODO(andersh): Handle computed properties
const tokenIsIdentifier = isIdentifier();
const propertyName = parsePropertyName();
if (tokenIsIdentifier && token !== SyntaxKind.ColonToken) {
@@ -4590,7 +4594,7 @@ namespace ts {
}
else {
parseExpected(SyntaxKind.ColonToken);
- node.propertyName = propertyName;
+ node.propertyName = propertyName;
node.name = parseIdentifierOrPattern();
}
node.initializer = parseBindingElementInitializer(/*inParameter*/ false);
@@ -5519,7 +5523,7 @@ namespace ts {
}
export function parseJSDocTypeExpressionForTests(content: string, start: number, length: number) {
- initializeState("file.js", content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined);
+ initializeState("file.js", content, ScriptTarget.Latest, /*isJavaScriptFile*/ true, /*_syntaxCursor:*/ undefined);
const jsDocTypeExpression = parseJSDocTypeExpression(start, length);
const diagnostics = parseDiagnostics;
clearState();
@@ -5840,7 +5844,7 @@ namespace ts {
}
export function parseIsolatedJSDocComment(content: string, start: number, length: number) {
- initializeState("file.js", content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined);
+ initializeState("file.js", content, ScriptTarget.Latest, /*isJavaScriptFile*/ true, /*_syntaxCursor:*/ undefined);
const jsDocComment = parseJSDocComment(/*parent:*/ undefined, start, length);
const diagnostics = parseDiagnostics;
clearState();
diff --git a/src/compiler/program.ts b/src/compiler/program.ts
index 8f031a4de43..08321da82e9 100644
--- a/src/compiler/program.ts
+++ b/src/compiler/program.ts
@@ -53,13 +53,13 @@ namespace ts {
if (getRootLength(moduleName) !== 0 || nameStartsWithDotSlashOrDotDotSlash(moduleName)) {
const failedLookupLocations: string[] = [];
const candidate = normalizePath(combinePaths(containingDirectory, moduleName));
- let resolvedFileName = loadNodeModuleFromFile(candidate, failedLookupLocations, host);
+ let resolvedFileName = loadNodeModuleFromFile(supportedJsExtensions, candidate, failedLookupLocations, host);
if (resolvedFileName) {
return { resolvedModule: { resolvedFileName }, failedLookupLocations };
}
- resolvedFileName = loadNodeModuleFromDirectory(candidate, failedLookupLocations, host);
+ resolvedFileName = loadNodeModuleFromDirectory(supportedJsExtensions, candidate, failedLookupLocations, host);
return resolvedFileName
? { resolvedModule: { resolvedFileName }, failedLookupLocations }
: { resolvedModule: undefined, failedLookupLocations };
@@ -69,8 +69,8 @@ namespace ts {
}
}
- function loadNodeModuleFromFile(candidate: string, failedLookupLocation: string[], host: ModuleResolutionHost): string {
- return forEach(moduleFileExtensions, tryLoad);
+ function loadNodeModuleFromFile(extensions: string[], candidate: string, failedLookupLocation: string[], host: ModuleResolutionHost): string {
+ return forEach(extensions, tryLoad);
function tryLoad(ext: string): string {
const fileName = fileExtensionIs(candidate, ext) ? candidate : candidate + ext;
@@ -84,7 +84,7 @@ namespace ts {
}
}
- function loadNodeModuleFromDirectory(candidate: string, failedLookupLocation: string[], host: ModuleResolutionHost): string {
+ function loadNodeModuleFromDirectory(extensions: string[], candidate: string, failedLookupLocation: string[], host: ModuleResolutionHost): string {
const packageJsonPath = combinePaths(candidate, "package.json");
if (host.fileExists(packageJsonPath)) {
@@ -100,7 +100,7 @@ namespace ts {
}
if (jsonContent.typings) {
- const result = loadNodeModuleFromFile(normalizePath(combinePaths(candidate, jsonContent.typings)), failedLookupLocation, host);
+ const result = loadNodeModuleFromFile(extensions, normalizePath(combinePaths(candidate, jsonContent.typings)), failedLookupLocation, host);
if (result) {
return result;
}
@@ -111,7 +111,7 @@ namespace ts {
failedLookupLocation.push(packageJsonPath);
}
- return loadNodeModuleFromFile(combinePaths(candidate, "index"), failedLookupLocation, host);
+ return loadNodeModuleFromFile(extensions, combinePaths(candidate, "index"), failedLookupLocation, host);
}
function loadModuleFromNodeModules(moduleName: string, directory: string, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations {
@@ -122,12 +122,12 @@ namespace ts {
if (baseName !== "node_modules") {
const nodeModulesFolder = combinePaths(directory, "node_modules");
const candidate = normalizePath(combinePaths(nodeModulesFolder, moduleName));
- let result = loadNodeModuleFromFile(candidate, failedLookupLocations, host);
+ let result = loadNodeModuleFromFile(supportedExtensions, candidate, failedLookupLocations, host);
if (result) {
return { resolvedModule: { resolvedFileName: result, isExternalLibraryImport: true }, failedLookupLocations };
}
- result = loadNodeModuleFromDirectory(candidate, failedLookupLocations, host);
+ result = loadNodeModuleFromDirectory(supportedExtensions, candidate, failedLookupLocations, host);
if (result) {
return { resolvedModule: { resolvedFileName: result, isExternalLibraryImport: true }, failedLookupLocations };
}
@@ -162,9 +162,10 @@ namespace ts {
const failedLookupLocations: string[] = [];
let referencedSourceFile: string;
+ const extensions = compilerOptions.allowNonTsExtensions ? supportedJsExtensions : supportedExtensions;
while (true) {
searchName = normalizePath(combinePaths(searchPath, moduleName));
- referencedSourceFile = forEach(supportedExtensions, extension => {
+ referencedSourceFile = forEach(extensions, extension => {
if (extension === ".tsx" && !compilerOptions.jsx) {
// resolve .tsx files only if jsx support is enabled
// 'logical not' handles both undefined and None cases
@@ -688,45 +689,60 @@ namespace ts {
return;
}
+ const isJavaScriptFile = isSourceFileJavaScript(file);
+
let imports: LiteralExpression[];
for (const node of file.statements) {
- collect(node, /* allowRelativeModuleNames */ true);
+ collect(node, /* allowRelativeModuleNames */ true, /* collectOnlyRequireCalls */ false);
}
file.imports = imports || emptyArray;
- function collect(node: Node, allowRelativeModuleNames: boolean): void {
- switch (node.kind) {
- case SyntaxKind.ImportDeclaration:
- case SyntaxKind.ImportEqualsDeclaration:
- case SyntaxKind.ExportDeclaration:
- let moduleNameExpr = getExternalModuleName(node);
- if (!moduleNameExpr || moduleNameExpr.kind !== SyntaxKind.StringLiteral) {
- break;
- }
- if (!(moduleNameExpr).text) {
- break;
- }
+ return;
- if (allowRelativeModuleNames || !isExternalModuleNameRelative((moduleNameExpr).text)) {
- (imports || (imports = [])).push(moduleNameExpr);
- }
- break;
- case SyntaxKind.ModuleDeclaration:
- if ((node).name.kind === SyntaxKind.StringLiteral && (node.flags & NodeFlags.Ambient || isDeclarationFile(file))) {
- // TypeScript 1.0 spec (April 2014): 12.1.6
- // An AmbientExternalModuleDeclaration declares an external module.
- // This type of declaration is permitted only in the global module.
- // The StringLiteral must specify a top - level external module name.
- // Relative external module names are not permitted
- forEachChild((node).body, node => {
+ function collect(node: Node, allowRelativeModuleNames: boolean, collectOnlyRequireCalls: boolean): void {
+ if (!collectOnlyRequireCalls) {
+ switch (node.kind) {
+ case SyntaxKind.ImportDeclaration:
+ case SyntaxKind.ImportEqualsDeclaration:
+ case SyntaxKind.ExportDeclaration:
+ let moduleNameExpr = getExternalModuleName(node);
+ if (!moduleNameExpr || moduleNameExpr.kind !== SyntaxKind.StringLiteral) {
+ break;
+ }
+ if (!(moduleNameExpr).text) {
+ break;
+ }
+
+ if (allowRelativeModuleNames || !isExternalModuleNameRelative((moduleNameExpr).text)) {
+ (imports || (imports = [])).push(moduleNameExpr);
+ }
+ break;
+ case SyntaxKind.ModuleDeclaration:
+ if ((node).name.kind === SyntaxKind.StringLiteral && (node.flags & NodeFlags.Ambient || isDeclarationFile(file))) {
// TypeScript 1.0 spec (April 2014): 12.1.6
- // An ExternalImportDeclaration in anAmbientExternalModuleDeclaration may reference other external modules
- // only through top - level external module names. Relative external module names are not permitted.
- collect(node, /* allowRelativeModuleNames */ false);
- });
- }
- break;
+ // An AmbientExternalModuleDeclaration declares an external module.
+ // This type of declaration is permitted only in the global module.
+ // The StringLiteral must specify a top - level external module name.
+ // Relative external module names are not permitted
+ forEachChild((node).body, node => {
+ // TypeScript 1.0 spec (April 2014): 12.1.6
+ // An ExternalImportDeclaration in anAmbientExternalModuleDeclaration may reference other external modules
+ // only through top - level external module names. Relative external module names are not permitted.
+ collect(node, /* allowRelativeModuleNames */ false, collectOnlyRequireCalls);
+ });
+ }
+ break;
+ }
+ }
+
+ if (isJavaScriptFile) {
+ if (isRequireCall(node)) {
+ (imports || (imports = [])).push((node).arguments[0]);
+ }
+ else {
+ forEachChild(node, node => collect(node, allowRelativeModuleNames, /* collectOnlyRequireCalls */ true));
+ }
}
}
}
diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts
index 79158cf4e9d..f560a15dfb9 100644
--- a/src/compiler/tsc.ts
+++ b/src/compiler/tsc.ts
@@ -346,9 +346,20 @@ namespace ts {
return;
}
}
+ if (!cachedConfigFileText) {
+ const error = createCompilerDiagnostic(Diagnostics.File_0_not_found, configFileName);
+ reportDiagnostics([error], /* compilerHost */ undefined);
+ sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
+ return;
+ }
const result = parseConfigFileTextToJson(configFileName, cachedConfigFileText);
const configObject = result.config;
+ if (!configObject) {
+ reportDiagnostics([result.error], /* compilerHost */ undefined);
+ sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
+ return;
+ }
const configParseResult = parseJsonConfigFileContent(configObject, sys, getDirectoryPath(configFileName));
if (configParseResult.errors.length > 0) {
reportDiagnostics(configParseResult.errors, /* compilerHost */ undefined);
diff --git a/src/compiler/types.ts b/src/compiler/types.ts
index 2489c049b68..eb3322e60b9 100644
--- a/src/compiler/types.ts
+++ b/src/compiler/types.ts
@@ -574,7 +574,7 @@ namespace ts {
// @kind(SyntaxKind.BindingElement)
export interface BindingElement extends Declaration {
- propertyName?: Identifier; // Binding property name (in object binding pattern)
+ propertyName?: PropertyName; // Binding property name (in object binding pattern)
dotDotDotToken?: Node; // Present on rest binding element
name: Identifier | BindingPattern; // Declared binding element name
initializer?: Expression; // Optional initializer
@@ -626,7 +626,7 @@ namespace ts {
// SyntaxKind.ShorthandPropertyAssignment
// SyntaxKind.EnumMember
export interface VariableLikeDeclaration extends Declaration {
- propertyName?: Identifier;
+ propertyName?: PropertyName;
dotDotDotToken?: Node;
name: DeclarationName;
questionToken?: Node;
@@ -878,7 +878,8 @@ namespace ts {
}
// @kind(SyntaxKind.BinaryExpression)
- export interface BinaryExpression extends Expression {
+ // Binary expressions can be declarations if they are 'exports.foo = bar' expressions in JS files
+ export interface BinaryExpression extends Expression, Declaration {
left: Expression;
operatorToken: Node;
right: Expression;
@@ -959,7 +960,7 @@ namespace ts {
}
// @kind(SyntaxKind.PropertyAccessExpression)
- export interface PropertyAccessExpression extends MemberExpression {
+ export interface PropertyAccessExpression extends MemberExpression, Declaration {
expression: LeftHandSideExpression;
dotToken: Node;
name: Identifier;
@@ -1531,6 +1532,8 @@ namespace ts {
// The first node that causes this file to be an external module
/* @internal */ externalModuleIndicator: Node;
+ // The first node that causes this file to be a CommonJS module
+ /* @internal */ commonJsModuleIndicator: Node;
/* @internal */ identifiers: Map;
/* @internal */ nodeCount: number;
@@ -2068,6 +2071,7 @@ namespace ts {
ContainsAnyFunctionType = 0x00800000, // Type is or contains object literal type
ESSymbol = 0x01000000, // Type of symbol primitive introduced in ES6
ThisType = 0x02000000, // This type
+ ObjectLiteralPatternWithComputedProperties = 0x04000000, // Object literal type implied by binding pattern has computed properties
/* @internal */
Intrinsic = Any | String | Number | Boolean | ESSymbol | Void | Undefined | Null,
diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts
index 199ca4e636f..1e4ee1bed47 100644
--- a/src/compiler/utilities.ts
+++ b/src/compiler/utilities.ts
@@ -1,4 +1,3 @@
-///
///
/* @internal */
@@ -362,6 +361,10 @@ namespace ts {
return file.externalModuleIndicator !== undefined;
}
+ export function isExternalOrCommonJsModule(file: SourceFile): boolean {
+ return (file.externalModuleIndicator || file.commonJsModuleIndicator) !== undefined;
+ }
+
export function isDeclarationFile(file: SourceFile): boolean {
return (file.flags & NodeFlags.DeclarationFile) !== 0;
}
@@ -1056,6 +1059,57 @@ namespace ts {
return node.kind === SyntaxKind.ImportEqualsDeclaration && (node).moduleReference.kind !== SyntaxKind.ExternalModuleReference;
}
+ export function isSourceFileJavaScript(file: SourceFile): boolean {
+ return isInJavaScriptFile(file);
+ }
+
+ export function isInJavaScriptFile(node: Node): boolean {
+ return node && !!(node.parserContextFlags & ParserContextFlags.JavaScriptFile);
+ }
+
+ /**
+ * Returns true if the node is a CallExpression to the identifier 'require' with
+ * exactly one string literal argument.
+ * This function does not test if the node is in a JavaScript file or not.
+ */
+ export function isRequireCall(expression: Node): expression is CallExpression {
+ // of the form 'require("name")'
+ return expression.kind === SyntaxKind.CallExpression &&
+ (expression).expression.kind === SyntaxKind.Identifier &&
+ ((expression).expression).text === "require" &&
+ (expression).arguments.length === 1 &&
+ (expression).arguments[0].kind === SyntaxKind.StringLiteral;
+ }
+
+ /**
+ * Returns true if the node is an assignment to a property on the identifier 'exports'.
+ * This function does not test if the node is in a JavaScript file or not.
+ */
+ export function isExportsPropertyAssignment(expression: Node): boolean {
+ // of the form 'exports.name = expr' where 'name' and 'expr' are arbitrary
+ return isInJavaScriptFile(expression) &&
+ (expression.kind === SyntaxKind.BinaryExpression) &&
+ ((expression).operatorToken.kind === SyntaxKind.EqualsToken) &&
+ ((expression).left.kind === SyntaxKind.PropertyAccessExpression) &&
+ (((expression).left).expression.kind === SyntaxKind.Identifier) &&
+ (((((expression).left).expression)).text === "exports");
+ }
+
+ /**
+ * Returns true if the node is an assignment to the property access expression 'module.exports'.
+ * This function does not test if the node is in a JavaScript file or not.
+ */
+ export function isModuleExportsAssignment(expression: Node): boolean {
+ // of the form 'module.exports = expr' where 'expr' is arbitrary
+ return isInJavaScriptFile(expression) &&
+ (expression.kind === SyntaxKind.BinaryExpression) &&
+ ((expression).operatorToken.kind === SyntaxKind.EqualsToken) &&
+ ((expression).left.kind === SyntaxKind.PropertyAccessExpression) &&
+ (((expression).left).expression.kind === SyntaxKind.Identifier) &&
+ (((((expression).left).expression)).text === "module") &&
+ (((expression).left).name.text === "exports");
+ }
+
export function getExternalModuleName(node: Node): Expression {
if (node.kind === SyntaxKind.ImportDeclaration) {
return (node).moduleSpecifier;
@@ -1435,6 +1489,10 @@ namespace ts {
return isFunctionLike(node) && (node.flags & NodeFlags.Async) !== 0 && !isAccessor(node);
}
+ export function isStringOrNumericLiteral(kind: SyntaxKind): boolean {
+ return kind === SyntaxKind.StringLiteral || kind === SyntaxKind.NumericLiteral;
+ }
+
/**
* A declaration has a dynamic name if both of the following are true:
* 1. The declaration has a computed property name
@@ -1443,9 +1501,13 @@ namespace ts {
* Symbol.
*/
export function hasDynamicName(declaration: Declaration): boolean {
- return declaration.name &&
- declaration.name.kind === SyntaxKind.ComputedPropertyName &&
- !isWellKnownSymbolSyntactically((declaration.name).expression);
+ return declaration.name && isDynamicName(declaration.name);
+ }
+
+ export function isDynamicName(name: DeclarationName): boolean {
+ return name.kind === SyntaxKind.ComputedPropertyName &&
+ !isStringOrNumericLiteral((name).expression.kind) &&
+ !isWellKnownSymbolSyntactically((name).expression);
}
/**
@@ -2210,12 +2272,12 @@ namespace ts {
return symbol && symbol.valueDeclaration && (symbol.valueDeclaration.flags & NodeFlags.Default) ? symbol.valueDeclaration.localSymbol : undefined;
}
- export function isJavaScript(fileName: string) {
- return fileExtensionIs(fileName, ".js");
+ export function hasJavaScriptFileExtension(fileName: string) {
+ return fileExtensionIs(fileName, ".js") || fileExtensionIs(fileName, ".jsx");
}
- export function isTsx(fileName: string) {
- return fileExtensionIs(fileName, ".tsx");
+ export function allowsJsxExpressions(fileName: string) {
+ return fileExtensionIs(fileName, ".tsx") || fileExtensionIs(fileName, ".jsx");
}
/**
diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts
index bf8b9493829..1c8593a9e12 100644
--- a/src/harness/fourslash.ts
+++ b/src/harness/fourslash.ts
@@ -223,10 +223,22 @@ namespace FourSlash {
// Add input file which has matched file name with the given reference-file path.
// This is necessary when resolveReference flag is specified
- private addMatchedInputFile(referenceFilePath: string) {
- const inputFile = this.inputFiles[referenceFilePath];
- if (inputFile && !Harness.isLibraryFile(referenceFilePath)) {
- this.languageServiceAdapterHost.addScript(referenceFilePath, inputFile);
+ private addMatchedInputFile(referenceFilePath: string, extensions: string[]) {
+ const inputFiles = this.inputFiles;
+ const languageServiceAdapterHost = this.languageServiceAdapterHost;
+ if (!extensions) {
+ tryAdd(referenceFilePath);
+ }
+ else {
+ tryAdd(referenceFilePath) || ts.forEach(extensions, ext => tryAdd(referenceFilePath + ext));
+ }
+
+ function tryAdd(path: string) {
+ const inputFile = inputFiles[path];
+ if (inputFile && !Harness.isLibraryFile(path)) {
+ languageServiceAdapterHost.addScript(path, inputFile);
+ return true;
+ }
}
}
@@ -280,15 +292,15 @@ namespace FourSlash {
ts.forEach(referencedFiles, referenceFile => {
// Fourslash insert tests/cases/fourslash into inputFile.unitName so we will properly append the same base directory to refFile path
const referenceFilePath = this.basePath + "/" + referenceFile.fileName;
- this.addMatchedInputFile(referenceFilePath);
+ this.addMatchedInputFile(referenceFilePath, /* extensions */ undefined);
});
// Add import files into language-service host
ts.forEach(importedFiles, importedFile => {
// Fourslash insert tests/cases/fourslash into inputFile.unitName and import statement doesn't require ".ts"
// so convert them before making appropriate comparison
- const importedFilePath = this.basePath + "/" + importedFile.fileName + ".ts";
- this.addMatchedInputFile(importedFilePath);
+ const importedFilePath = this.basePath + "/" + importedFile.fileName;
+ this.addMatchedInputFile(importedFilePath, compilationOptions.allowNonTsExtensions ? ts.supportedJsExtensions : ts.supportedExtensions);
});
// Check if no-default-lib flag is false and if so add default library
@@ -2257,15 +2269,15 @@ namespace FourSlash {
const details = this.getCompletionEntryDetails(item.name);
if (documentation !== undefined) {
- assert.equal(ts.displayPartsToString(details.documentation), documentation, assertionMessage("completion item documentation"));
+ assert.equal(ts.displayPartsToString(details.documentation), documentation, assertionMessage("completion item documentation for " + name));
}
if (text !== undefined) {
- assert.equal(ts.displayPartsToString(details.displayParts), text, assertionMessage("completion item detail text"));
+ assert.equal(ts.displayPartsToString(details.displayParts), text, assertionMessage("completion item detail text for " + name));
}
}
if (kind !== undefined) {
- assert.equal(item.kind, kind, assertionMessage("completion item kind"));
+ assert.equal(item.kind, kind, assertionMessage("completion item kind for " + name));
}
return;
diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts
index 50dbef5a410..faf0ad28eb5 100644
--- a/src/harness/harnessLanguageService.ts
+++ b/src/harness/harnessLanguageService.ts
@@ -197,7 +197,7 @@ namespace Harness.LanguageService {
getHost() { return this.host; }
getLanguageService(): ts.LanguageService { return ts.createLanguageService(this.host); }
getClassifier(): ts.Classifier { return ts.createClassifier(); }
- getPreProcessedFileInfo(fileName: string, fileContents: string): ts.PreProcessedFileInfo { return ts.preProcessFile(fileContents); }
+ getPreProcessedFileInfo(fileName: string, fileContents: string): ts.PreProcessedFileInfo { return ts.preProcessFile(fileContents, /* readImportFiles */ true, ts.hasJavaScriptFileExtension(fileName)); }
}
/// Shim adapter
diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts
index 6543dc67af0..333cea2745d 100644
--- a/src/server/editorServices.ts
+++ b/src/server/editorServices.ts
@@ -371,6 +371,10 @@ namespace ts.server {
openRefCount = 0;
constructor(public projectService: ProjectService, public projectOptions?: ProjectOptions) {
+ if (projectOptions && projectOptions.files) {
+ // If files are listed explicitly, allow all extensions
+ projectOptions.compilerOptions.allowNonTsExtensions = true;
+ }
this.compilerService = new CompilerService(this, projectOptions && projectOptions.compilerOptions);
}
@@ -461,6 +465,7 @@ namespace ts.server {
setProjectOptions(projectOptions: ProjectOptions) {
this.projectOptions = projectOptions;
if (projectOptions.compilerOptions) {
+ projectOptions.compilerOptions.allowNonTsExtensions = true;
this.compilerService.setCompilerOptions(projectOptions.compilerOptions);
}
}
@@ -1316,7 +1321,9 @@ namespace ts.server {
this.setCompilerOptions(opt);
}
else {
- this.setCompilerOptions(ts.getDefaultCompilerOptions());
+ const defaultOpts = ts.getDefaultCompilerOptions();
+ defaultOpts.allowNonTsExtensions = true;
+ this.setCompilerOptions(defaultOpts);
}
this.languageService = ts.createLanguageService(this.host, this.documentRegistry);
this.classifier = ts.createClassifier();
diff --git a/src/services/services.ts b/src/services/services.ts
index 529a70b1453..9fb2eef2152 100644
--- a/src/services/services.ts
+++ b/src/services/services.ts
@@ -801,6 +801,7 @@ namespace ts {
public isDefaultLib: boolean;
public hasNoDefaultLib: boolean;
public externalModuleIndicator: Node; // The first node that causes this file to be an external module
+ public commonJsModuleIndicator: Node; // The first node that causes this file to be a CommonJS module
public nodeCount: number;
public identifierCount: number;
public symbolCount: number;
@@ -2124,7 +2125,7 @@ namespace ts {
};
}
- export function preProcessFile(sourceText: string, readImportFiles = true): PreProcessedFileInfo {
+ export function preProcessFile(sourceText: string, readImportFiles = true, detectJavaScriptImports = false): PreProcessedFileInfo {
let referencedFiles: FileReference[] = [];
let importedFiles: FileReference[] = [];
let ambientExternalModules: string[];
@@ -2162,9 +2163,225 @@ namespace ts {
});
}
- function processImport(): void {
+ /**
+ * Returns true if at least one token was consumed from the stream
+ */
+ function tryConsumeDeclare(): boolean {
+ let token = scanner.getToken();
+ if (token === SyntaxKind.DeclareKeyword) {
+ // declare module "mod"
+ token = scanner.scan();
+ if (token === SyntaxKind.ModuleKeyword) {
+ token = scanner.scan();
+ if (token === SyntaxKind.StringLiteral) {
+ recordAmbientExternalModule();
+ }
+ }
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns true if at least one token was consumed from the stream
+ */
+ function tryConsumeImport(): boolean {
+ let token = scanner.getToken();
+ if (token === SyntaxKind.ImportKeyword) {
+ token = scanner.scan();
+ if (token === SyntaxKind.StringLiteral) {
+ // import "mod";
+ recordModuleName();
+ return true;
+ }
+ else {
+ if (token === SyntaxKind.Identifier || isKeyword(token)) {
+ token = scanner.scan();
+ if (token === SyntaxKind.FromKeyword) {
+ token = scanner.scan();
+ if (token === SyntaxKind.StringLiteral) {
+ // import d from "mod";
+ recordModuleName();
+ return true;
+ }
+ }
+ else if (token === SyntaxKind.EqualsToken) {
+ if (tryConsumeRequireCall(/* skipCurrentToken */ true)) {
+ return true;
+ }
+ }
+ else if (token === SyntaxKind.CommaToken) {
+ // consume comma and keep going
+ token = scanner.scan();
+ }
+ else {
+ // unknown syntax
+ return true;
+ }
+ }
+
+ if (token === SyntaxKind.OpenBraceToken) {
+ token = scanner.scan();
+ // consume "{ a as B, c, d as D}" clauses
+ // make sure that it stops on EOF
+ while (token !== SyntaxKind.CloseBraceToken && token !== SyntaxKind.EndOfFileToken) {
+ token = scanner.scan();
+ }
+
+ if (token === SyntaxKind.CloseBraceToken) {
+ token = scanner.scan();
+ if (token === SyntaxKind.FromKeyword) {
+ token = scanner.scan();
+ if (token === SyntaxKind.StringLiteral) {
+ // import {a as A} from "mod";
+ // import d, {a, b as B} from "mod"
+ recordModuleName();
+ }
+ }
+ }
+ }
+ else if (token === SyntaxKind.AsteriskToken) {
+ token = scanner.scan();
+ if (token === SyntaxKind.AsKeyword) {
+ token = scanner.scan();
+ if (token === SyntaxKind.Identifier || isKeyword(token)) {
+ token = scanner.scan();
+ if (token === SyntaxKind.FromKeyword) {
+ token = scanner.scan();
+ if (token === SyntaxKind.StringLiteral) {
+ // import * as NS from "mod"
+ // import d, * as NS from "mod"
+ recordModuleName();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ function tryConsumeExport(): boolean {
+ let token = scanner.getToken();
+ if (token === SyntaxKind.ExportKeyword) {
+ token = scanner.scan();
+ if (token === SyntaxKind.OpenBraceToken) {
+ token = scanner.scan();
+ // consume "{ a as B, c, d as D}" clauses
+ // make sure it stops on EOF
+ while (token !== SyntaxKind.CloseBraceToken && token !== SyntaxKind.EndOfFileToken) {
+ token = scanner.scan();
+ }
+
+ if (token === SyntaxKind.CloseBraceToken) {
+ token = scanner.scan();
+ if (token === SyntaxKind.FromKeyword) {
+ token = scanner.scan();
+ if (token === SyntaxKind.StringLiteral) {
+ // export {a as A} from "mod";
+ // export {a, b as B} from "mod"
+ recordModuleName();
+ }
+ }
+ }
+ }
+ else if (token === SyntaxKind.AsteriskToken) {
+ token = scanner.scan();
+ if (token === SyntaxKind.FromKeyword) {
+ token = scanner.scan();
+ if (token === SyntaxKind.StringLiteral) {
+ // export * from "mod"
+ recordModuleName();
+ }
+ }
+ }
+ else if (token === SyntaxKind.ImportKeyword) {
+ token = scanner.scan();
+ if (token === SyntaxKind.Identifier || isKeyword(token)) {
+ token = scanner.scan();
+ if (token === SyntaxKind.EqualsToken) {
+ if (tryConsumeRequireCall(/* skipCurrentToken */ true)) {
+ return true;
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ function tryConsumeRequireCall(skipCurrentToken: boolean): boolean {
+ let token = skipCurrentToken ? scanner.scan() : scanner.getToken();
+ if (token === SyntaxKind.RequireKeyword) {
+ token = scanner.scan();
+ if (token === SyntaxKind.OpenParenToken) {
+ token = scanner.scan();
+ if (token === SyntaxKind.StringLiteral) {
+ // require("mod");
+ recordModuleName();
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ function tryConsumeDefine(): boolean {
+ let token = scanner.getToken();
+ if (token === SyntaxKind.Identifier && scanner.getTokenValue() === "define") {
+ token = scanner.scan();
+ if (token !== SyntaxKind.OpenParenToken) {
+ return true;
+ }
+
+ token = scanner.scan();
+ if (token === SyntaxKind.StringLiteral) {
+ // looks like define ("modname", ... - skip string literal and comma
+ token = scanner.scan();
+ if (token === SyntaxKind.CommaToken) {
+ token = scanner.scan();
+ }
+ else {
+ // unexpected token
+ return true;
+ }
+ }
+
+ // should be start of dependency list
+ if (token !== SyntaxKind.OpenBracketToken) {
+ return true;
+ }
+
+ // skip open bracket
+ token = scanner.scan();
+ let i = 0;
+ // scan until ']' or EOF
+ while (token !== SyntaxKind.CloseBracketToken && token !== SyntaxKind.EndOfFileToken) {
+ // record string literals as module names
+ if (token === SyntaxKind.StringLiteral) {
+ recordModuleName();
+ i++;
+ }
+
+ token = scanner.scan();
+ }
+ return true;
+
+ }
+ return false;
+ }
+
+ function processImports(): void {
scanner.setText(sourceText);
- let token = scanner.scan();
+ scanner.scan();
// Look for:
// import "mod";
// import d from "mod"
@@ -2176,157 +2393,30 @@ namespace ts {
// export * from "mod"
// export {a as b} from "mod"
// export import i = require("mod")
+ // (for JavaScript files) require("mod")
- while (token !== SyntaxKind.EndOfFileToken) {
- if (token === SyntaxKind.DeclareKeyword) {
- // declare module "mod"
- token = scanner.scan();
- if (token === SyntaxKind.ModuleKeyword) {
- token = scanner.scan();
- if (token === SyntaxKind.StringLiteral) {
- recordAmbientExternalModule();
- continue;
- }
- }
+ while (true) {
+ if (scanner.getToken() === SyntaxKind.EndOfFileToken) {
+ break;
}
- else if (token === SyntaxKind.ImportKeyword) {
- token = scanner.scan();
- if (token === SyntaxKind.StringLiteral) {
- // import "mod";
- recordModuleName();
- continue;
- }
- else {
- if (token === SyntaxKind.Identifier || isKeyword(token)) {
- token = scanner.scan();
- if (token === SyntaxKind.FromKeyword) {
- token = scanner.scan();
- if (token === SyntaxKind.StringLiteral) {
- // import d from "mod";
- recordModuleName();
- continue
- }
- }
- else if (token === SyntaxKind.EqualsToken) {
- token = scanner.scan();
- if (token === SyntaxKind.RequireKeyword) {
- token = scanner.scan();
- if (token === SyntaxKind.OpenParenToken) {
- token = scanner.scan();
- if (token === SyntaxKind.StringLiteral) {
- // import i = require("mod");
- recordModuleName();
- continue;
- }
- }
- }
- }
- else if (token === SyntaxKind.CommaToken) {
- // consume comma and keep going
- token = scanner.scan();
- }
- else {
- // unknown syntax
- continue;
- }
- }
- if (token === SyntaxKind.OpenBraceToken) {
- token = scanner.scan();
- // consume "{ a as B, c, d as D}" clauses
- while (token !== SyntaxKind.CloseBraceToken) {
- token = scanner.scan();
- }
-
- if (token === SyntaxKind.CloseBraceToken) {
- token = scanner.scan();
- if (token === SyntaxKind.FromKeyword) {
- token = scanner.scan();
- if (token === SyntaxKind.StringLiteral) {
- // import {a as A} from "mod";
- // import d, {a, b as B} from "mod"
- recordModuleName();
- }
- }
- }
- }
- else if (token === SyntaxKind.AsteriskToken) {
- token = scanner.scan();
- if (token === SyntaxKind.AsKeyword) {
- token = scanner.scan();
- if (token === SyntaxKind.Identifier || isKeyword(token)) {
- token = scanner.scan();
- if (token === SyntaxKind.FromKeyword) {
- token = scanner.scan();
- if (token === SyntaxKind.StringLiteral) {
- // import * as NS from "mod"
- // import d, * as NS from "mod"
- recordModuleName();
- }
- }
- }
- }
- }
- }
+ // check if at least one of alternative have moved scanner forward
+ if (tryConsumeDeclare() ||
+ tryConsumeImport() ||
+ tryConsumeExport() ||
+ (detectJavaScriptImports && (tryConsumeRequireCall(/* skipCurrentToken */ false) || tryConsumeDefine()))) {
+ continue;
}
- else if (token === SyntaxKind.ExportKeyword) {
- token = scanner.scan();
- if (token === SyntaxKind.OpenBraceToken) {
- token = scanner.scan();
- // consume "{ a as B, c, d as D}" clauses
- while (token !== SyntaxKind.CloseBraceToken) {
- token = scanner.scan();
- }
-
- if (token === SyntaxKind.CloseBraceToken) {
- token = scanner.scan();
- if (token === SyntaxKind.FromKeyword) {
- token = scanner.scan();
- if (token === SyntaxKind.StringLiteral) {
- // export {a as A} from "mod";
- // export {a, b as B} from "mod"
- recordModuleName();
- }
- }
- }
- }
- else if (token === SyntaxKind.AsteriskToken) {
- token = scanner.scan();
- if (token === SyntaxKind.FromKeyword) {
- token = scanner.scan();
- if (token === SyntaxKind.StringLiteral) {
- // export * from "mod"
- recordModuleName();
- }
- }
- }
- else if (token === SyntaxKind.ImportKeyword) {
- token = scanner.scan();
- if (token === SyntaxKind.Identifier || isKeyword(token)) {
- token = scanner.scan();
- if (token === SyntaxKind.EqualsToken) {
- token = scanner.scan();
- if (token === SyntaxKind.RequireKeyword) {
- token = scanner.scan();
- if (token === SyntaxKind.OpenParenToken) {
- token = scanner.scan();
- if (token === SyntaxKind.StringLiteral) {
- // export import i = require("mod");
- recordModuleName();
- }
- }
- }
- }
- }
- }
+ else {
+ scanner.scan();
}
- token = scanner.scan();
}
+
scanner.setText(undefined);
}
if (readImportFiles) {
- processImport();
+ processImports();
}
processTripleSlashDirectives();
return { referencedFiles, importedFiles, isLibFile: isNoDefaultLib, ambientExternalModules };
@@ -2815,7 +2905,7 @@ namespace ts {
// For JavaScript files, we don't want to report the normal typescript semantic errors.
// Instead, we just report errors for using TypeScript-only constructs from within a
// JavaScript file.
- if (isJavaScript(fileName)) {
+ if (isSourceFileJavaScript(targetSourceFile)) {
return getJavaScriptSemanticDiagnostics(targetSourceFile);
}
@@ -3054,7 +3144,7 @@ namespace ts {
let typeChecker = program.getTypeChecker();
let syntacticStart = new Date().getTime();
let sourceFile = getValidSourceFile(fileName);
- let isJavaScriptFile = isJavaScript(fileName);
+ let isJavaScriptFile = isSourceFileJavaScript(sourceFile);
let isJsDocTagName = false;
@@ -3826,7 +3916,10 @@ namespace ts {
let existingName: string;
if (m.kind === SyntaxKind.BindingElement && (m).propertyName) {
- existingName = (m).propertyName.text;
+ // include only identifiers in completion list
+ if ((m).propertyName.kind === SyntaxKind.Identifier) {
+ existingName = ((m).propertyName).text
+ }
}
else {
// TODO(jfreeman): Account for computed property name
@@ -3875,22 +3968,25 @@ namespace ts {
let { symbols, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot, isJsDocTagName } = completionData;
- let entries: CompletionEntry[];
if (isJsDocTagName) {
// If the current position is a jsDoc tag name, only tag names should be provided for completion
return { isMemberCompletion: false, isNewIdentifierLocation: false, entries: getAllJsDocCompletionEntries() };
}
- if (isRightOfDot && isJavaScript(fileName)) {
- entries = getCompletionEntriesFromSymbols(symbols);
- addRange(entries, getJavaScriptCompletionEntries());
+ let sourceFile = getValidSourceFile(fileName);
+
+ let entries: CompletionEntry[] = [];
+
+ if (isRightOfDot && isSourceFileJavaScript(sourceFile)) {
+ const uniqueNames = getCompletionEntriesFromSymbols(symbols, entries);
+ addRange(entries, getJavaScriptCompletionEntries(sourceFile, uniqueNames));
}
else {
if (!symbols || symbols.length === 0) {
return undefined;
}
- entries = getCompletionEntriesFromSymbols(symbols);
+ getCompletionEntriesFromSymbols(symbols, entries);
}
// Add keywords if this is not a member completion list
@@ -3900,26 +3996,23 @@ namespace ts {
return { isMemberCompletion, isNewIdentifierLocation, entries };
- function getJavaScriptCompletionEntries(): CompletionEntry[] {
+ function getJavaScriptCompletionEntries(sourceFile: SourceFile, uniqueNames: Map): CompletionEntry[] {
let entries: CompletionEntry[] = [];
- let allNames: Map = {};
let target = program.getCompilerOptions().target;
- for (let sourceFile of program.getSourceFiles()) {
- let nameTable = getNameTable(sourceFile);
- for (let name in nameTable) {
- if (!allNames[name]) {
- allNames[name] = name;
- let displayName = getCompletionEntryDisplayName(name, target, /*performCharacterChecks:*/ true);
- if (displayName) {
- let entry = {
- name: displayName,
- kind: ScriptElementKind.warning,
- kindModifiers: "",
- sortText: "1"
- };
- entries.push(entry);
- }
+ let nameTable = getNameTable(sourceFile);
+ for (let name in nameTable) {
+ if (!uniqueNames[name]) {
+ uniqueNames[name] = name;
+ let displayName = getCompletionEntryDisplayName(name, target, /*performCharacterChecks:*/ true);
+ if (displayName) {
+ let entry = {
+ name: displayName,
+ kind: ScriptElementKind.warning,
+ kindModifiers: "",
+ sortText: "1"
+ };
+ entries.push(entry);
}
}
}
@@ -3963,26 +4056,24 @@ namespace ts {
};
}
- function getCompletionEntriesFromSymbols(symbols: Symbol[]): CompletionEntry[] {
+ function getCompletionEntriesFromSymbols(symbols: Symbol[], entries: CompletionEntry[]): Map {
let start = new Date().getTime();
- let entries: CompletionEntry[] = [];
-
+ let uniqueNames: Map = {};
if (symbols) {
- let nameToSymbol: Map = {};
for (let symbol of symbols) {
let entry = createCompletionEntry(symbol, location);
if (entry) {
let id = escapeIdentifier(entry.name);
- if (!lookUp(nameToSymbol, id)) {
+ if (!lookUp(uniqueNames, id)) {
entries.push(entry);
- nameToSymbol[id] = symbol;
+ uniqueNames[id] = id;
}
}
}
}
log("getCompletionsAtPosition: getCompletionEntriesFromSymbols: " + (new Date().getTime() - start));
- return entries;
+ return uniqueNames;
}
}
diff --git a/src/services/shims.ts b/src/services/shims.ts
index fca72e49d36..6b656ea2738 100644
--- a/src/services/shims.ts
+++ b/src/services/shims.ts
@@ -956,7 +956,8 @@ namespace ts {
return this.forwardJSONCall(
"getPreProcessedFileInfo('" + fileName + "')",
() => {
- var result = preProcessFile(sourceTextSnapshot.getText(0, sourceTextSnapshot.getLength()));
+ // for now treat files as JavaScript
+ var result = preProcessFile(sourceTextSnapshot.getText(0, sourceTextSnapshot.getLength()), /* readImportFiles */ true, /* detectJavaScriptImports */ true);
var convertResult = {
referencedFiles: [],
importedFiles: [],
diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts
index df321647e5c..02e36e185a5 100644
--- a/src/services/signatureHelp.ts
+++ b/src/services/signatureHelp.ts
@@ -204,7 +204,7 @@ namespace ts.SignatureHelp {
if (!candidates.length) {
// We didn't have any sig help items produced by the TS compiler. If this is a JS
// file, then see if we can figure out anything better.
- if (isJavaScript(sourceFile.fileName)) {
+ if (isSourceFileJavaScript(sourceFile)) {
return createJavaScriptSignatureHelpItems(argumentInfo);
}
diff --git a/tests/baselines/reference/computedPropertiesInDestructuring1.errors.txt b/tests/baselines/reference/computedPropertiesInDestructuring1.errors.txt
new file mode 100644
index 00000000000..dc536e544b2
--- /dev/null
+++ b/tests/baselines/reference/computedPropertiesInDestructuring1.errors.txt
@@ -0,0 +1,52 @@
+tests/cases/compiler/computedPropertiesInDestructuring1.ts(20,8): error TS2349: Cannot invoke an expression whose type lacks a call signature.
+tests/cases/compiler/computedPropertiesInDestructuring1.ts(21,12): error TS2339: Property 'toExponential' does not exist on type 'string'.
+tests/cases/compiler/computedPropertiesInDestructuring1.ts(33,4): error TS2349: Cannot invoke an expression whose type lacks a call signature.
+tests/cases/compiler/computedPropertiesInDestructuring1.ts(34,5): error TS2365: Operator '+' cannot be applied to types 'number' and '{}'.
+
+
+==== tests/cases/compiler/computedPropertiesInDestructuring1.ts (4 errors) ====
+ // destructuring in variable declarations
+ let foo = "bar";
+ let {[foo]: bar} = {bar: "bar"};
+
+ let {["bar"]: bar2} = {bar: "bar"};
+
+ let foo2 = () => "bar";
+ let {[foo2()]: bar3} = {bar: "bar"};
+
+ let [{[foo]: bar4}] = [{bar: "bar"}];
+ let [{[foo2()]: bar5}] = [{bar: "bar"}];
+
+ function f1({["bar"]: x}: { bar: number }) {}
+ function f2({[foo]: x}: { bar: number }) {}
+ function f3({[foo2()]: x}: { bar: number }) {}
+ function f4([{[foo]: x}]: [{ bar: number }]) {}
+ function f5([{[foo2()]: x}]: [{ bar: number }]) {}
+
+ // report errors on type errors in computed properties used in destructuring
+ let [{[foo()]: bar6}] = [{bar: "bar"}];
+ ~~~~~
+!!! error TS2349: Cannot invoke an expression whose type lacks a call signature.
+ let [{[foo.toExponential()]: bar7}] = [{bar: "bar"}];
+ ~~~~~~~~~~~~~
+!!! error TS2339: Property 'toExponential' does not exist on type 'string'.
+
+ // destructuring assignment
+ ({[foo]: bar} = {bar: "bar"});
+
+ ({["bar"]: bar2} = {bar: "bar"});
+
+ ({[foo2()]: bar3} = {bar: "bar"});
+
+ [{[foo]: bar4}] = [{bar: "bar"}];
+ [{[foo2()]: bar5}] = [{bar: "bar"}];
+
+ [{[foo()]: bar4}] = [{bar: "bar"}];
+ ~~~~~
+!!! error TS2349: Cannot invoke an expression whose type lacks a call signature.
+ [{[(1 + {})]: bar4}] = [{bar: "bar"}];
+ ~~~~~~
+!!! error TS2365: Operator '+' cannot be applied to types 'number' and '{}'.
+
+
+
\ No newline at end of file
diff --git a/tests/baselines/reference/computedPropertiesInDestructuring1.js b/tests/baselines/reference/computedPropertiesInDestructuring1.js
new file mode 100644
index 00000000000..0bc4286ed7b
--- /dev/null
+++ b/tests/baselines/reference/computedPropertiesInDestructuring1.js
@@ -0,0 +1,75 @@
+//// [computedPropertiesInDestructuring1.ts]
+// destructuring in variable declarations
+let foo = "bar";
+let {[foo]: bar} = {bar: "bar"};
+
+let {["bar"]: bar2} = {bar: "bar"};
+
+let foo2 = () => "bar";
+let {[foo2()]: bar3} = {bar: "bar"};
+
+let [{[foo]: bar4}] = [{bar: "bar"}];
+let [{[foo2()]: bar5}] = [{bar: "bar"}];
+
+function f1({["bar"]: x}: { bar: number }) {}
+function f2({[foo]: x}: { bar: number }) {}
+function f3({[foo2()]: x}: { bar: number }) {}
+function f4([{[foo]: x}]: [{ bar: number }]) {}
+function f5([{[foo2()]: x}]: [{ bar: number }]) {}
+
+// report errors on type errors in computed properties used in destructuring
+let [{[foo()]: bar6}] = [{bar: "bar"}];
+let [{[foo.toExponential()]: bar7}] = [{bar: "bar"}];
+
+// destructuring assignment
+({[foo]: bar} = {bar: "bar"});
+
+({["bar"]: bar2} = {bar: "bar"});
+
+({[foo2()]: bar3} = {bar: "bar"});
+
+[{[foo]: bar4}] = [{bar: "bar"}];
+[{[foo2()]: bar5}] = [{bar: "bar"}];
+
+[{[foo()]: bar4}] = [{bar: "bar"}];
+[{[(1 + {})]: bar4}] = [{bar: "bar"}];
+
+
+
+
+//// [computedPropertiesInDestructuring1.js]
+// destructuring in variable declarations
+var foo = "bar";
+var _a = foo, bar = { bar: "bar" }[_a];
+var _b = "bar", bar2 = { bar: "bar" }[_b];
+var foo2 = function () { return "bar"; };
+var _c = foo2(), bar3 = { bar: "bar" }[_c];
+var _d = foo, bar4 = [{ bar: "bar" }][0][_d];
+var _e = foo2(), bar5 = [{ bar: "bar" }][0][_e];
+function f1(_a) {
+ var _b = "bar", x = _a[_b];
+}
+function f2(_a) {
+ var _b = foo, x = _a[_b];
+}
+function f3(_a) {
+ var _b = foo2(), x = _a[_b];
+}
+function f4(_a) {
+ var _b = foo, x = _a[0][_b];
+}
+function f5(_a) {
+ var _b = foo2(), x = _a[0][_b];
+}
+// report errors on type errors in computed properties used in destructuring
+var _f = foo(), bar6 = [{ bar: "bar" }][0][_f];
+var _g = foo.toExponential(), bar7 = [{ bar: "bar" }][0][_g];
+// destructuring assignment
+(_h = { bar: "bar" }, _j = foo, bar = _h[_j], _h);
+(_k = { bar: "bar" }, _l = "bar", bar2 = _k[_l], _k);
+(_m = { bar: "bar" }, _o = foo2(), bar3 = _m[_o], _m);
+_p = foo, bar4 = [{ bar: "bar" }][0][_p];
+_q = foo2(), bar5 = [{ bar: "bar" }][0][_q];
+_r = foo(), bar4 = [{ bar: "bar" }][0][_r];
+_s = (1 + {}), bar4 = [{ bar: "bar" }][0][_s];
+var _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
diff --git a/tests/baselines/reference/computedPropertiesInDestructuring1_ES6.errors.txt b/tests/baselines/reference/computedPropertiesInDestructuring1_ES6.errors.txt
new file mode 100644
index 00000000000..96ab892d1b9
--- /dev/null
+++ b/tests/baselines/reference/computedPropertiesInDestructuring1_ES6.errors.txt
@@ -0,0 +1,51 @@
+tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(21,8): error TS2349: Cannot invoke an expression whose type lacks a call signature.
+tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(22,12): error TS2339: Property 'toExponential' does not exist on type 'string'.
+tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(34,4): error TS2349: Cannot invoke an expression whose type lacks a call signature.
+tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(35,5): error TS2365: Operator '+' cannot be applied to types 'number' and '{}'.
+
+
+==== tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts (4 errors) ====
+ // destructuring in variable declarations
+ let foo = "bar";
+ let {[foo]: bar} = {bar: "bar"};
+
+ let {["bar"]: bar2} = {bar: "bar"};
+ let {[11]: bar2_1} = {11: "bar"};
+
+ let foo2 = () => "bar";
+ let {[foo2()]: bar3} = {bar: "bar"};
+
+ let [{[foo]: bar4}] = [{bar: "bar"}];
+ let [{[foo2()]: bar5}] = [{bar: "bar"}];
+
+ function f1({["bar"]: x}: { bar: number }) {}
+ function f2({[foo]: x}: { bar: number }) {}
+ function f3({[foo2()]: x}: { bar: number }) {}
+ function f4([{[foo]: x}]: [{ bar: number }]) {}
+ function f5([{[foo2()]: x}]: [{ bar: number }]) {}
+
+ // report errors on type errors in computed properties used in destructuring
+ let [{[foo()]: bar6}] = [{bar: "bar"}];
+ ~~~~~
+!!! error TS2349: Cannot invoke an expression whose type lacks a call signature.
+ let [{[foo.toExponential()]: bar7}] = [{bar: "bar"}];
+ ~~~~~~~~~~~~~
+!!! error TS2339: Property 'toExponential' does not exist on type 'string'.
+
+ // destructuring assignment
+ ({[foo]: bar} = {bar: "bar"});
+
+ ({["bar"]: bar2} = {bar: "bar"});
+
+ ({[foo2()]: bar3} = {bar: "bar"});
+
+ [{[foo]: bar4}] = [{bar: "bar"}];
+ [{[foo2()]: bar5}] = [{bar: "bar"}];
+
+ [{[foo()]: bar4}] = [{bar: "bar"}];
+ ~~~~~
+!!! error TS2349: Cannot invoke an expression whose type lacks a call signature.
+ [{[(1 + {})]: bar4}] = [{bar: "bar"}];
+ ~~~~~~
+!!! error TS2365: Operator '+' cannot be applied to types 'number' and '{}'.
+
\ No newline at end of file
diff --git a/tests/baselines/reference/computedPropertiesInDestructuring1_ES6.js b/tests/baselines/reference/computedPropertiesInDestructuring1_ES6.js
new file mode 100644
index 00000000000..e6e19f93b80
--- /dev/null
+++ b/tests/baselines/reference/computedPropertiesInDestructuring1_ES6.js
@@ -0,0 +1,64 @@
+//// [computedPropertiesInDestructuring1_ES6.ts]
+// destructuring in variable declarations
+let foo = "bar";
+let {[foo]: bar} = {bar: "bar"};
+
+let {["bar"]: bar2} = {bar: "bar"};
+let {[11]: bar2_1} = {11: "bar"};
+
+let foo2 = () => "bar";
+let {[foo2()]: bar3} = {bar: "bar"};
+
+let [{[foo]: bar4}] = [{bar: "bar"}];
+let [{[foo2()]: bar5}] = [{bar: "bar"}];
+
+function f1({["bar"]: x}: { bar: number }) {}
+function f2({[foo]: x}: { bar: number }) {}
+function f3({[foo2()]: x}: { bar: number }) {}
+function f4([{[foo]: x}]: [{ bar: number }]) {}
+function f5([{[foo2()]: x}]: [{ bar: number }]) {}
+
+// report errors on type errors in computed properties used in destructuring
+let [{[foo()]: bar6}] = [{bar: "bar"}];
+let [{[foo.toExponential()]: bar7}] = [{bar: "bar"}];
+
+// destructuring assignment
+({[foo]: bar} = {bar: "bar"});
+
+({["bar"]: bar2} = {bar: "bar"});
+
+({[foo2()]: bar3} = {bar: "bar"});
+
+[{[foo]: bar4}] = [{bar: "bar"}];
+[{[foo2()]: bar5}] = [{bar: "bar"}];
+
+[{[foo()]: bar4}] = [{bar: "bar"}];
+[{[(1 + {})]: bar4}] = [{bar: "bar"}];
+
+
+//// [computedPropertiesInDestructuring1_ES6.js]
+// destructuring in variable declarations
+let foo = "bar";
+let { [foo]: bar } = { bar: "bar" };
+let { ["bar"]: bar2 } = { bar: "bar" };
+let { [11]: bar2_1 } = { 11: "bar" };
+let foo2 = () => "bar";
+let { [foo2()]: bar3 } = { bar: "bar" };
+let [{ [foo]: bar4 }] = [{ bar: "bar" }];
+let [{ [foo2()]: bar5 }] = [{ bar: "bar" }];
+function f1({ ["bar"]: x }) { }
+function f2({ [foo]: x }) { }
+function f3({ [foo2()]: x }) { }
+function f4([{ [foo]: x }]) { }
+function f5([{ [foo2()]: x }]) { }
+// report errors on type errors in computed properties used in destructuring
+let [{ [foo()]: bar6 }] = [{ bar: "bar" }];
+let [{ [foo.toExponential()]: bar7 }] = [{ bar: "bar" }];
+// destructuring assignment
+({ [foo]: bar } = { bar: "bar" });
+({ ["bar"]: bar2 } = { bar: "bar" });
+({ [foo2()]: bar3 } = { bar: "bar" });
+[{ [foo]: bar4 }] = [{ bar: "bar" }];
+[{ [foo2()]: bar5 }] = [{ bar: "bar" }];
+[{ [foo()]: bar4 }] = [{ bar: "bar" }];
+[{ [(1 + {})]: bar4 }] = [{ bar: "bar" }];
diff --git a/tests/baselines/reference/computedPropertiesInDestructuring2.js b/tests/baselines/reference/computedPropertiesInDestructuring2.js
new file mode 100644
index 00000000000..8579881b775
--- /dev/null
+++ b/tests/baselines/reference/computedPropertiesInDestructuring2.js
@@ -0,0 +1,7 @@
+//// [computedPropertiesInDestructuring2.ts]
+let foo2 = () => "bar";
+let {[foo2()]: bar3} = {};
+
+//// [computedPropertiesInDestructuring2.js]
+var foo2 = function () { return "bar"; };
+var _a = foo2(), bar3 = {}[_a];
diff --git a/tests/baselines/reference/computedPropertiesInDestructuring2.symbols b/tests/baselines/reference/computedPropertiesInDestructuring2.symbols
new file mode 100644
index 00000000000..4ae6d5323e1
--- /dev/null
+++ b/tests/baselines/reference/computedPropertiesInDestructuring2.symbols
@@ -0,0 +1,8 @@
+=== tests/cases/compiler/computedPropertiesInDestructuring2.ts ===
+let foo2 = () => "bar";
+>foo2 : Symbol(foo2, Decl(computedPropertiesInDestructuring2.ts, 0, 3))
+
+let {[foo2()]: bar3} = {};
+>foo2 : Symbol(foo2, Decl(computedPropertiesInDestructuring2.ts, 0, 3))
+>bar3 : Symbol(bar3, Decl(computedPropertiesInDestructuring2.ts, 1, 5))
+
diff --git a/tests/baselines/reference/computedPropertiesInDestructuring2.types b/tests/baselines/reference/computedPropertiesInDestructuring2.types
new file mode 100644
index 00000000000..0fa20662270
--- /dev/null
+++ b/tests/baselines/reference/computedPropertiesInDestructuring2.types
@@ -0,0 +1,12 @@
+=== tests/cases/compiler/computedPropertiesInDestructuring2.ts ===
+let foo2 = () => "bar";
+>foo2 : () => string
+>() => "bar" : () => string
+>"bar" : string
+
+let {[foo2()]: bar3} = {};
+>foo2() : string
+>foo2 : () => string
+>bar3 : any
+>{} : {}
+
diff --git a/tests/baselines/reference/computedPropertiesInDestructuring2_ES6.js b/tests/baselines/reference/computedPropertiesInDestructuring2_ES6.js
new file mode 100644
index 00000000000..e0bd16287ee
--- /dev/null
+++ b/tests/baselines/reference/computedPropertiesInDestructuring2_ES6.js
@@ -0,0 +1,8 @@
+//// [computedPropertiesInDestructuring2_ES6.ts]
+
+let foo2 = () => "bar";
+let {[foo2()]: bar3} = {};
+
+//// [computedPropertiesInDestructuring2_ES6.js]
+let foo2 = () => "bar";
+let { [foo2()]: bar3 } = {};
diff --git a/tests/baselines/reference/computedPropertiesInDestructuring2_ES6.symbols b/tests/baselines/reference/computedPropertiesInDestructuring2_ES6.symbols
new file mode 100644
index 00000000000..cd7cfda9844
--- /dev/null
+++ b/tests/baselines/reference/computedPropertiesInDestructuring2_ES6.symbols
@@ -0,0 +1,9 @@
+=== tests/cases/compiler/computedPropertiesInDestructuring2_ES6.ts ===
+
+let foo2 = () => "bar";
+>foo2 : Symbol(foo2, Decl(computedPropertiesInDestructuring2_ES6.ts, 1, 3))
+
+let {[foo2()]: bar3} = {};
+>foo2 : Symbol(foo2, Decl(computedPropertiesInDestructuring2_ES6.ts, 1, 3))
+>bar3 : Symbol(bar3, Decl(computedPropertiesInDestructuring2_ES6.ts, 2, 5))
+
diff --git a/tests/baselines/reference/computedPropertiesInDestructuring2_ES6.types b/tests/baselines/reference/computedPropertiesInDestructuring2_ES6.types
new file mode 100644
index 00000000000..f0d8b1033c8
--- /dev/null
+++ b/tests/baselines/reference/computedPropertiesInDestructuring2_ES6.types
@@ -0,0 +1,13 @@
+=== tests/cases/compiler/computedPropertiesInDestructuring2_ES6.ts ===
+
+let foo2 = () => "bar";
+>foo2 : () => string
+>() => "bar" : () => string
+>"bar" : string
+
+let {[foo2()]: bar3} = {};
+>foo2() : string
+>foo2 : () => string
+>bar3 : any
+>{} : {}
+
diff --git a/tests/baselines/reference/computedPropertyNames10_ES5.types b/tests/baselines/reference/computedPropertyNames10_ES5.types
index 87648c1ed80..9dea9cfca93 100644
--- a/tests/baselines/reference/computedPropertyNames10_ES5.types
+++ b/tests/baselines/reference/computedPropertyNames10_ES5.types
@@ -9,8 +9,8 @@ var a: any;
>a : any
var v = {
->v : {}
->{ [s]() { }, [n]() { }, [s + s]() { }, [s + n]() { }, [+s]() { }, [""]() { }, [0]() { }, [a]() { }, [true]() { }, [`hello bye`]() { }, [`hello ${a} bye`]() { }} : {}
+>v : { [0](): void; [""](): void; }
+>{ [s]() { }, [n]() { }, [s + s]() { }, [s + n]() { }, [+s]() { }, [""]() { }, [0]() { }, [a]() { }, [true]() { }, [`hello bye`]() { }, [`hello ${a} bye`]() { }} : { [0](): void; [""](): void; }
[s]() { },
>s : string
diff --git a/tests/baselines/reference/computedPropertyNames10_ES6.types b/tests/baselines/reference/computedPropertyNames10_ES6.types
index 996dfc99fe9..d2faa138980 100644
--- a/tests/baselines/reference/computedPropertyNames10_ES6.types
+++ b/tests/baselines/reference/computedPropertyNames10_ES6.types
@@ -9,8 +9,8 @@ var a: any;
>a : any
var v = {
->v : {}
->{ [s]() { }, [n]() { }, [s + s]() { }, [s + n]() { }, [+s]() { }, [""]() { }, [0]() { }, [a]() { }, [true]() { }, [`hello bye`]() { }, [`hello ${a} bye`]() { }} : {}
+>v : { [0](): void; [""](): void; }
+>{ [s]() { }, [n]() { }, [s + s]() { }, [s + n]() { }, [+s]() { }, [""]() { }, [0]() { }, [a]() { }, [true]() { }, [`hello bye`]() { }, [`hello ${a} bye`]() { }} : { [0](): void; [""](): void; }
[s]() { },
>s : string
diff --git a/tests/baselines/reference/computedPropertyNames11_ES5.js b/tests/baselines/reference/computedPropertyNames11_ES5.js
index 64c0b0bd67e..0917f824770 100644
--- a/tests/baselines/reference/computedPropertyNames11_ES5.js
+++ b/tests/baselines/reference/computedPropertyNames11_ES5.js
@@ -46,16 +46,8 @@ var v = (_a = {},
enumerable: true,
configurable: true
}),
- Object.defineProperty(_a, "", {
- set: function (v) { },
- enumerable: true,
- configurable: true
- }),
- Object.defineProperty(_a, 0, {
- get: function () { return 0; },
- enumerable: true,
- configurable: true
- }),
+ ,
+ ,
Object.defineProperty(_a, a, {
set: function (v) { },
enumerable: true,
diff --git a/tests/baselines/reference/computedPropertyNames11_ES5.types b/tests/baselines/reference/computedPropertyNames11_ES5.types
index c3c59c2eb9c..e0787fc3ee7 100644
--- a/tests/baselines/reference/computedPropertyNames11_ES5.types
+++ b/tests/baselines/reference/computedPropertyNames11_ES5.types
@@ -9,8 +9,8 @@ var a: any;
>a : any
var v = {
->v : {}
->{ get [s]() { return 0; }, set [n](v) { }, get [s + s]() { return 0; }, set [s + n](v) { }, get [+s]() { return 0; }, set [""](v) { }, get [0]() { return 0; }, set [a](v) { }, get [true]() { return 0; }, set [`hello bye`](v) { }, get [`hello ${a} bye`]() { return 0; }} : {}
+>v : { [0]: number; [""]: any; }
+>{ get [s]() { return 0; }, set [n](v) { }, get [s + s]() { return 0; }, set [s + n](v) { }, get [+s]() { return 0; }, set [""](v) { }, get [0]() { return 0; }, set [a](v) { }, get [true]() { return 0; }, set [`hello bye`](v) { }, get [`hello ${a} bye`]() { return 0; }} : { [0]: number; [""]: any; }
get [s]() { return 0; },
>s : string
diff --git a/tests/baselines/reference/computedPropertyNames11_ES6.types b/tests/baselines/reference/computedPropertyNames11_ES6.types
index ef11511baae..8ad31a7c2a1 100644
--- a/tests/baselines/reference/computedPropertyNames11_ES6.types
+++ b/tests/baselines/reference/computedPropertyNames11_ES6.types
@@ -9,8 +9,8 @@ var a: any;
>a : any
var v = {
->v : {}
->{ get [s]() { return 0; }, set [n](v) { }, get [s + s]() { return 0; }, set [s + n](v) { }, get [+s]() { return 0; }, set [""](v) { }, get [0]() { return 0; }, set [a](v) { }, get [true]() { return 0; }, set [`hello bye`](v) { }, get [`hello ${a} bye`]() { return 0; }} : {}
+>v : { [0]: number; [""]: any; }
+>{ get [s]() { return 0; }, set [n](v) { }, get [s + s]() { return 0; }, set [s + n](v) { }, get [+s]() { return 0; }, set [""](v) { }, get [0]() { return 0; }, set [a](v) { }, get [true]() { return 0; }, set [`hello bye`](v) { }, get [`hello ${a} bye`]() { return 0; }} : { [0]: number; [""]: any; }
get [s]() { return 0; },
>s : string
diff --git a/tests/baselines/reference/computedPropertyNames12_ES5.errors.txt b/tests/baselines/reference/computedPropertyNames12_ES5.errors.txt
index 9d07f34f3c4..71f81c27245 100644
--- a/tests/baselines/reference/computedPropertyNames12_ES5.errors.txt
+++ b/tests/baselines/reference/computedPropertyNames12_ES5.errors.txt
@@ -3,15 +3,13 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES5.ts(6,
tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES5.ts(7,12): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol.
tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES5.ts(8,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol.
tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES5.ts(9,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol.
-tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES5.ts(10,12): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol.
-tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES5.ts(11,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol.
tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES5.ts(12,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol.
tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES5.ts(13,12): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol.
tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES5.ts(14,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol.
tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES5.ts(15,12): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol.
-==== tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES5.ts (11 errors) ====
+==== tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES5.ts (9 errors) ====
var s: string;
var n: number;
var a: any;
@@ -32,11 +30,7 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES5.ts(15
~~~~
!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol.
static [""]: number;
- ~~~~
-!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol.
[0]: number;
- ~~~
-!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol.
[a]: number;
~~~
!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol.
diff --git a/tests/baselines/reference/computedPropertyNames12_ES6.errors.txt b/tests/baselines/reference/computedPropertyNames12_ES6.errors.txt
index f0a2267f8b3..8d8cce7e140 100644
--- a/tests/baselines/reference/computedPropertyNames12_ES6.errors.txt
+++ b/tests/baselines/reference/computedPropertyNames12_ES6.errors.txt
@@ -3,15 +3,13 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES6.ts(6,
tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES6.ts(7,12): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol.
tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES6.ts(8,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol.
tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES6.ts(9,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol.
-tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES6.ts(10,12): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol.
-tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES6.ts(11,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol.
tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES6.ts(12,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol.
tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES6.ts(13,12): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol.
tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES6.ts(14,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol.
tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES6.ts(15,12): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol.
-==== tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES6.ts (11 errors) ====
+==== tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES6.ts (9 errors) ====
var s: string;
var n: number;
var a: any;
@@ -32,11 +30,7 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES6.ts(15
~~~~
!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol.
static [""]: number;
- ~~~~
-!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol.
[0]: number;
- ~~~
-!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol.
[a]: number;
~~~
!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol.
diff --git a/tests/baselines/reference/computedPropertyNames16_ES5.js b/tests/baselines/reference/computedPropertyNames16_ES5.js
index 2c7316e1398..f4d90579d63 100644
--- a/tests/baselines/reference/computedPropertyNames16_ES5.js
+++ b/tests/baselines/reference/computedPropertyNames16_ES5.js
@@ -48,16 +48,6 @@ var C = (function () {
enumerable: true,
configurable: true
});
- Object.defineProperty(C, "", {
- set: function (v) { },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(C.prototype, 0, {
- get: function () { return 0; },
- enumerable: true,
- configurable: true
- });
Object.defineProperty(C.prototype, a, {
set: function (v) { },
enumerable: true,
diff --git a/tests/baselines/reference/computedPropertyNames36_ES5.js b/tests/baselines/reference/computedPropertyNames36_ES5.js
index 5519a6d284c..4bb10ea7543 100644
--- a/tests/baselines/reference/computedPropertyNames36_ES5.js
+++ b/tests/baselines/reference/computedPropertyNames36_ES5.js
@@ -27,10 +27,6 @@ var C = (function () {
Object.defineProperty(C.prototype, "get1", {
// Computed properties
get: function () { return new Foo; },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(C.prototype, "set1", {
set: function (p) { },
enumerable: true,
configurable: true
diff --git a/tests/baselines/reference/computedPropertyNames37_ES5.js b/tests/baselines/reference/computedPropertyNames37_ES5.js
index 54a7243f3fa..c2a346608fe 100644
--- a/tests/baselines/reference/computedPropertyNames37_ES5.js
+++ b/tests/baselines/reference/computedPropertyNames37_ES5.js
@@ -27,10 +27,6 @@ var C = (function () {
Object.defineProperty(C.prototype, "get1", {
// Computed properties
get: function () { return new Foo; },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(C.prototype, "set1", {
set: function (p) { },
enumerable: true,
configurable: true
diff --git a/tests/baselines/reference/computedPropertyNames40_ES5.errors.txt b/tests/baselines/reference/computedPropertyNames40_ES5.errors.txt
index e8ceef0d581..482978064d1 100644
--- a/tests/baselines/reference/computedPropertyNames40_ES5.errors.txt
+++ b/tests/baselines/reference/computedPropertyNames40_ES5.errors.txt
@@ -1,7 +1,9 @@
+tests/cases/conformance/es6/computedProperties/computedPropertyNames40_ES5.ts(8,5): error TS2393: Duplicate function implementation.
tests/cases/conformance/es6/computedProperties/computedPropertyNames40_ES5.ts(8,5): error TS2411: Property '[""]' of type '() => Foo' is not assignable to string index type '() => Foo2'.
+tests/cases/conformance/es6/computedProperties/computedPropertyNames40_ES5.ts(9,5): error TS2393: Duplicate function implementation.
-==== tests/cases/conformance/es6/computedProperties/computedPropertyNames40_ES5.ts (1 errors) ====
+==== tests/cases/conformance/es6/computedProperties/computedPropertyNames40_ES5.ts (3 errors) ====
class Foo { x }
class Foo2 { x; y }
@@ -10,7 +12,11 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames40_ES5.ts(8,
// Computed properties
[""]() { return new Foo }
+ ~~~~
+!!! error TS2393: Duplicate function implementation.
~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2411: Property '[""]' of type '() => Foo' is not assignable to string index type '() => Foo2'.
[""]() { return new Foo2 }
+ ~~~~
+!!! error TS2393: Duplicate function implementation.
}
\ No newline at end of file
diff --git a/tests/baselines/reference/computedPropertyNames40_ES6.errors.txt b/tests/baselines/reference/computedPropertyNames40_ES6.errors.txt
index 1a032a87b2b..669d0d04e66 100644
--- a/tests/baselines/reference/computedPropertyNames40_ES6.errors.txt
+++ b/tests/baselines/reference/computedPropertyNames40_ES6.errors.txt
@@ -1,7 +1,9 @@
+tests/cases/conformance/es6/computedProperties/computedPropertyNames40_ES6.ts(8,5): error TS2393: Duplicate function implementation.
tests/cases/conformance/es6/computedProperties/computedPropertyNames40_ES6.ts(8,5): error TS2411: Property '[""]' of type '() => Foo' is not assignable to string index type '() => Foo2'.
+tests/cases/conformance/es6/computedProperties/computedPropertyNames40_ES6.ts(9,5): error TS2393: Duplicate function implementation.
-==== tests/cases/conformance/es6/computedProperties/computedPropertyNames40_ES6.ts (1 errors) ====
+==== tests/cases/conformance/es6/computedProperties/computedPropertyNames40_ES6.ts (3 errors) ====
class Foo { x }
class Foo2 { x; y }
@@ -10,7 +12,11 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames40_ES6.ts(8,
// Computed properties
[""]() { return new Foo }
+ ~~~~
+!!! error TS2393: Duplicate function implementation.
~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2411: Property '[""]' of type '() => Foo' is not assignable to string index type '() => Foo2'.
[""]() { return new Foo2 }
+ ~~~~
+!!! error TS2393: Duplicate function implementation.
}
\ No newline at end of file
diff --git a/tests/baselines/reference/computedPropertyNames42_ES5.errors.txt b/tests/baselines/reference/computedPropertyNames42_ES5.errors.txt
index 94153c47aa5..bdb978220a0 100644
--- a/tests/baselines/reference/computedPropertyNames42_ES5.errors.txt
+++ b/tests/baselines/reference/computedPropertyNames42_ES5.errors.txt
@@ -1,8 +1,7 @@
-tests/cases/conformance/es6/computedProperties/computedPropertyNames42_ES5.ts(8,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol.
tests/cases/conformance/es6/computedProperties/computedPropertyNames42_ES5.ts(8,5): error TS2411: Property '[""]' of type 'Foo' is not assignable to string index type 'Foo2'.
-==== tests/cases/conformance/es6/computedProperties/computedPropertyNames42_ES5.ts (2 errors) ====
+==== tests/cases/conformance/es6/computedProperties/computedPropertyNames42_ES5.ts (1 errors) ====
class Foo { x }
class Foo2 { x; y }
@@ -11,8 +10,6 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames42_ES5.ts(8,
// Computed properties
[""]: Foo;
- ~~~~
-!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol.
~~~~~~~~~~
!!! error TS2411: Property '[""]' of type 'Foo' is not assignable to string index type 'Foo2'.
}
\ No newline at end of file
diff --git a/tests/baselines/reference/computedPropertyNames42_ES6.errors.txt b/tests/baselines/reference/computedPropertyNames42_ES6.errors.txt
index 1f4e27d6e81..9feb6ba3d32 100644
--- a/tests/baselines/reference/computedPropertyNames42_ES6.errors.txt
+++ b/tests/baselines/reference/computedPropertyNames42_ES6.errors.txt
@@ -1,8 +1,7 @@
-tests/cases/conformance/es6/computedProperties/computedPropertyNames42_ES6.ts(8,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol.
tests/cases/conformance/es6/computedProperties/computedPropertyNames42_ES6.ts(8,5): error TS2411: Property '[""]' of type 'Foo' is not assignable to string index type 'Foo2'.
-==== tests/cases/conformance/es6/computedProperties/computedPropertyNames42_ES6.ts (2 errors) ====
+==== tests/cases/conformance/es6/computedProperties/computedPropertyNames42_ES6.ts (1 errors) ====
class Foo { x }
class Foo2 { x; y }
@@ -11,8 +10,6 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames42_ES6.ts(8,
// Computed properties
[""]: Foo;
- ~~~~
-!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol.
~~~~~~~~~~
!!! error TS2411: Property '[""]' of type 'Foo' is not assignable to string index type 'Foo2'.
}
\ No newline at end of file
diff --git a/tests/baselines/reference/computedPropertyNames43_ES5.js b/tests/baselines/reference/computedPropertyNames43_ES5.js
index c3b7f6a71d0..57026c3c706 100644
--- a/tests/baselines/reference/computedPropertyNames43_ES5.js
+++ b/tests/baselines/reference/computedPropertyNames43_ES5.js
@@ -41,10 +41,6 @@ var D = (function (_super) {
Object.defineProperty(D.prototype, "get1", {
// Computed properties
get: function () { return new Foo; },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(D.prototype, "set1", {
set: function (p) { },
enumerable: true,
configurable: true
diff --git a/tests/baselines/reference/computedPropertyNames45_ES5.errors.txt b/tests/baselines/reference/computedPropertyNames45_ES5.errors.txt
index 83855c5f0b7..8baae68f337 100644
--- a/tests/baselines/reference/computedPropertyNames45_ES5.errors.txt
+++ b/tests/baselines/reference/computedPropertyNames45_ES5.errors.txt
@@ -1,12 +1,15 @@
+tests/cases/conformance/es6/computedProperties/computedPropertyNames45_ES5.ts(5,5): error TS2411: Property '["get1"]' of type 'Foo' is not assignable to string index type 'Foo2'.
tests/cases/conformance/es6/computedProperties/computedPropertyNames45_ES5.ts(11,5): error TS2411: Property '["set1"]' of type 'Foo' is not assignable to string index type 'Foo2'.
-==== tests/cases/conformance/es6/computedProperties/computedPropertyNames45_ES5.ts (1 errors) ====
+==== tests/cases/conformance/es6/computedProperties/computedPropertyNames45_ES5.ts (2 errors) ====
class Foo { x }
class Foo2 { x; y }
class C {
get ["get1"]() { return new Foo }
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+!!! error TS2411: Property '["get1"]' of type 'Foo' is not assignable to string index type 'Foo2'.
}
class D extends C {
diff --git a/tests/baselines/reference/computedPropertyNames45_ES6.errors.txt b/tests/baselines/reference/computedPropertyNames45_ES6.errors.txt
index 963e01ed86b..e329785f4cf 100644
--- a/tests/baselines/reference/computedPropertyNames45_ES6.errors.txt
+++ b/tests/baselines/reference/computedPropertyNames45_ES6.errors.txt
@@ -1,12 +1,15 @@
+tests/cases/conformance/es6/computedProperties/computedPropertyNames45_ES6.ts(5,5): error TS2411: Property '["get1"]' of type 'Foo' is not assignable to string index type 'Foo2'.
tests/cases/conformance/es6/computedProperties/computedPropertyNames45_ES6.ts(11,5): error TS2411: Property '["set1"]' of type 'Foo' is not assignable to string index type 'Foo2'.
-==== tests/cases/conformance/es6/computedProperties/computedPropertyNames45_ES6.ts (1 errors) ====
+==== tests/cases/conformance/es6/computedProperties/computedPropertyNames45_ES6.ts (2 errors) ====
class Foo { x }
class Foo2 { x; y }
class C {
get ["get1"]() { return new Foo }
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+!!! error TS2411: Property '["get1"]' of type 'Foo' is not assignable to string index type 'Foo2'.
}
class D extends C {
diff --git a/tests/baselines/reference/computedPropertyNames4_ES5.types b/tests/baselines/reference/computedPropertyNames4_ES5.types
index 51baca26586..6984d2e69b8 100644
--- a/tests/baselines/reference/computedPropertyNames4_ES5.types
+++ b/tests/baselines/reference/computedPropertyNames4_ES5.types
@@ -9,8 +9,8 @@ var a: any;
>a : any
var v = {
->v : {}
->{ [s]: 0, [n]: n, [s + s]: 1, [s + n]: 2, [+s]: s, [""]: 0, [0]: 0, [a]: 1, [true]: 0, [`hello bye`]: 0, [`hello ${a} bye`]: 0} : {}
+>v : { [0]: number; [""]: number; }
+>{ [s]: 0, [n]: n, [s + s]: 1, [s + n]: 2, [+s]: s, [""]: 0, [0]: 0, [a]: 1, [true]: 0, [`hello bye`]: 0, [`hello ${a} bye`]: 0} : { [0]: number; [""]: number; }
[s]: 0,
>s : string
diff --git a/tests/baselines/reference/computedPropertyNames4_ES6.types b/tests/baselines/reference/computedPropertyNames4_ES6.types
index 05267049517..1fece561f5a 100644
--- a/tests/baselines/reference/computedPropertyNames4_ES6.types
+++ b/tests/baselines/reference/computedPropertyNames4_ES6.types
@@ -9,8 +9,8 @@ var a: any;
>a : any
var v = {
->v : {}
->{ [s]: 0, [n]: n, [s + s]: 1, [s + n]: 2, [+s]: s, [""]: 0, [0]: 0, [a]: 1, [true]: 0, [`hello bye`]: 0, [`hello ${a} bye`]: 0} : {}
+>v : { [0]: number; [""]: number; }
+>{ [s]: 0, [n]: n, [s + s]: 1, [s + n]: 2, [+s]: s, [""]: 0, [0]: 0, [a]: 1, [true]: 0, [`hello bye`]: 0, [`hello ${a} bye`]: 0} : { [0]: number; [""]: number; }
[s]: 0,
>s : string
diff --git a/tests/baselines/reference/computedPropertyNamesSourceMap2_ES5.types b/tests/baselines/reference/computedPropertyNamesSourceMap2_ES5.types
index 9470aee8eb6..147b2966509 100644
--- a/tests/baselines/reference/computedPropertyNamesSourceMap2_ES5.types
+++ b/tests/baselines/reference/computedPropertyNamesSourceMap2_ES5.types
@@ -1,7 +1,7 @@
=== tests/cases/conformance/es6/computedProperties/computedPropertyNamesSourceMap2_ES5.ts ===
var v = {
->v : {}
->{ ["hello"]() { debugger; }} : {}
+>v : { ["hello"](): void; }
+>{ ["hello"]() { debugger; }} : { ["hello"](): void; }
["hello"]() {
>"hello" : string
diff --git a/tests/baselines/reference/computedPropertyNamesSourceMap2_ES6.types b/tests/baselines/reference/computedPropertyNamesSourceMap2_ES6.types
index c4f02155a95..00334680362 100644
--- a/tests/baselines/reference/computedPropertyNamesSourceMap2_ES6.types
+++ b/tests/baselines/reference/computedPropertyNamesSourceMap2_ES6.types
@@ -1,7 +1,7 @@
=== tests/cases/conformance/es6/computedProperties/computedPropertyNamesSourceMap2_ES6.ts ===
var v = {
->v : {}
->{ ["hello"]() { debugger; }} : {}
+>v : { ["hello"](): void; }
+>{ ["hello"]() { debugger; }} : { ["hello"](): void; }
["hello"]() {
>"hello" : string
diff --git a/tests/baselines/reference/emitClassDeclarationWithGetterSetterInES6.js b/tests/baselines/reference/emitClassDeclarationWithGetterSetterInES6.js
index ece24d691da..e7f88b92775 100644
--- a/tests/baselines/reference/emitClassDeclarationWithGetterSetterInES6.js
+++ b/tests/baselines/reference/emitClassDeclarationWithGetterSetterInES6.js
@@ -10,16 +10,16 @@ class C {
static get ["computedname"]() {
return "";
}
- get ["computedname"]() {
+ get ["computedname1"]() {
return "";
}
- get ["computedname"]() {
+ get ["computedname2"]() {
return "";
}
- set ["computedname"](x: any) {
+ set ["computedname3"](x: any) {
}
- set ["computedname"](y: string) {
+ set ["computedname4"](y: string) {
}
set foo(a: string) { }
@@ -38,15 +38,15 @@ class C {
static get ["computedname"]() {
return "";
}
- get ["computedname"]() {
+ get ["computedname1"]() {
return "";
}
- get ["computedname"]() {
+ get ["computedname2"]() {
return "";
}
- set ["computedname"](x) {
+ set ["computedname3"](x) {
}
- set ["computedname"](y) {
+ set ["computedname4"](y) {
}
set foo(a) { }
static set bar(b) { }
diff --git a/tests/baselines/reference/emitClassDeclarationWithGetterSetterInES6.symbols b/tests/baselines/reference/emitClassDeclarationWithGetterSetterInES6.symbols
index 2d249348f9b..b2b1a000dc9 100644
--- a/tests/baselines/reference/emitClassDeclarationWithGetterSetterInES6.symbols
+++ b/tests/baselines/reference/emitClassDeclarationWithGetterSetterInES6.symbols
@@ -21,18 +21,18 @@ class C {
static get ["computedname"]() {
return "";
}
- get ["computedname"]() {
+ get ["computedname1"]() {
return "";
}
- get ["computedname"]() {
+ get ["computedname2"]() {
return "";
}
- set ["computedname"](x: any) {
->x : Symbol(x, Decl(emitClassDeclarationWithGetterSetterInES6.ts, 18, 25))
+ set ["computedname3"](x: any) {
+>x : Symbol(x, Decl(emitClassDeclarationWithGetterSetterInES6.ts, 18, 26))
}
- set ["computedname"](y: string) {
->y : Symbol(y, Decl(emitClassDeclarationWithGetterSetterInES6.ts, 20, 25))
+ set ["computedname4"](y: string) {
+>y : Symbol(y, Decl(emitClassDeclarationWithGetterSetterInES6.ts, 20, 26))
}
set foo(a: string) { }
diff --git a/tests/baselines/reference/emitClassDeclarationWithGetterSetterInES6.types b/tests/baselines/reference/emitClassDeclarationWithGetterSetterInES6.types
index 292fb961b10..e4f7d6c00b4 100644
--- a/tests/baselines/reference/emitClassDeclarationWithGetterSetterInES6.types
+++ b/tests/baselines/reference/emitClassDeclarationWithGetterSetterInES6.types
@@ -25,25 +25,25 @@ class C {
return "";
>"" : string
}
- get ["computedname"]() {
->"computedname" : string
+ get ["computedname1"]() {
+>"computedname1" : string
return "";
>"" : string
}
- get ["computedname"]() {
->"computedname" : string
+ get ["computedname2"]() {
+>"computedname2" : string
return "";
>"" : string
}
- set ["computedname"](x: any) {
->"computedname" : string
+ set ["computedname3"](x: any) {
+>"computedname3" : string
>x : any
}
- set ["computedname"](y: string) {
->"computedname" : string
+ set ["computedname4"](y: string) {
+>"computedname4" : string
>y : string
}
diff --git a/tests/baselines/reference/emitClassDeclarationWithMethodInES6.js b/tests/baselines/reference/emitClassDeclarationWithMethodInES6.js
index fc0a510461b..8a79d45b678 100644
--- a/tests/baselines/reference/emitClassDeclarationWithMethodInES6.js
+++ b/tests/baselines/reference/emitClassDeclarationWithMethodInES6.js
@@ -2,18 +2,18 @@
class D {
_bar: string;
foo() { }
- ["computedName"]() { }
- ["computedName"](a: string) { }
- ["computedName"](a: string): number { return 1; }
+ ["computedName1"]() { }
+ ["computedName2"](a: string) { }
+ ["computedName3"](a: string): number { return 1; }
bar(): string {
return this._bar;
}
baz(a: any, x: string): string {
return "HELLO";
}
- static ["computedname"]() { }
- static ["computedname"](a: string) { }
- static ["computedname"](a: string): boolean { return true; }
+ static ["computedname4"]() { }
+ static ["computedname5"](a: string) { }
+ static ["computedname6"](a: string): boolean { return true; }
static staticMethod() {
var x = 1 + 2;
return x
@@ -25,18 +25,18 @@ class D {
//// [emitClassDeclarationWithMethodInES6.js]
class D {
foo() { }
- ["computedName"]() { }
- ["computedName"](a) { }
- ["computedName"](a) { return 1; }
+ ["computedName1"]() { }
+ ["computedName2"](a) { }
+ ["computedName3"](a) { return 1; }
bar() {
return this._bar;
}
baz(a, x) {
return "HELLO";
}
- static ["computedname"]() { }
- static ["computedname"](a) { }
- static ["computedname"](a) { return true; }
+ static ["computedname4"]() { }
+ static ["computedname5"](a) { }
+ static ["computedname6"](a) { return true; }
static staticMethod() {
var x = 1 + 2;
return x;
diff --git a/tests/baselines/reference/emitClassDeclarationWithMethodInES6.symbols b/tests/baselines/reference/emitClassDeclarationWithMethodInES6.symbols
index b7a4dbbf341..970076f6b78 100644
--- a/tests/baselines/reference/emitClassDeclarationWithMethodInES6.symbols
+++ b/tests/baselines/reference/emitClassDeclarationWithMethodInES6.symbols
@@ -8,15 +8,15 @@ class D {
foo() { }
>foo : Symbol(foo, Decl(emitClassDeclarationWithMethodInES6.ts, 1, 17))
- ["computedName"]() { }
- ["computedName"](a: string) { }
->a : Symbol(a, Decl(emitClassDeclarationWithMethodInES6.ts, 4, 21))
+ ["computedName1"]() { }
+ ["computedName2"](a: string) { }
+>a : Symbol(a, Decl(emitClassDeclarationWithMethodInES6.ts, 4, 22))
- ["computedName"](a: string): number { return 1; }
->a : Symbol(a, Decl(emitClassDeclarationWithMethodInES6.ts, 5, 21))
+ ["computedName3"](a: string): number { return 1; }
+>a : Symbol(a, Decl(emitClassDeclarationWithMethodInES6.ts, 5, 22))
bar(): string {
->bar : Symbol(bar, Decl(emitClassDeclarationWithMethodInES6.ts, 5, 53))
+>bar : Symbol(bar, Decl(emitClassDeclarationWithMethodInES6.ts, 5, 54))
return this._bar;
>this._bar : Symbol(_bar, Decl(emitClassDeclarationWithMethodInES6.ts, 0, 9))
@@ -30,15 +30,15 @@ class D {
return "HELLO";
}
- static ["computedname"]() { }
- static ["computedname"](a: string) { }
->a : Symbol(a, Decl(emitClassDeclarationWithMethodInES6.ts, 13, 28))
+ static ["computedname4"]() { }
+ static ["computedname5"](a: string) { }
+>a : Symbol(a, Decl(emitClassDeclarationWithMethodInES6.ts, 13, 29))
- static ["computedname"](a: string): boolean { return true; }
->a : Symbol(a, Decl(emitClassDeclarationWithMethodInES6.ts, 14, 28))
+ static ["computedname6"](a: string): boolean { return true; }
+>a : Symbol(a, Decl(emitClassDeclarationWithMethodInES6.ts, 14, 29))
static staticMethod() {
->staticMethod : Symbol(D.staticMethod, Decl(emitClassDeclarationWithMethodInES6.ts, 14, 64))
+>staticMethod : Symbol(D.staticMethod, Decl(emitClassDeclarationWithMethodInES6.ts, 14, 65))
var x = 1 + 2;
>x : Symbol(x, Decl(emitClassDeclarationWithMethodInES6.ts, 16, 11))
diff --git a/tests/baselines/reference/emitClassDeclarationWithMethodInES6.types b/tests/baselines/reference/emitClassDeclarationWithMethodInES6.types
index 10ae930c244..02a90729486 100644
--- a/tests/baselines/reference/emitClassDeclarationWithMethodInES6.types
+++ b/tests/baselines/reference/emitClassDeclarationWithMethodInES6.types
@@ -8,15 +8,15 @@ class D {
foo() { }
>foo : () => void
- ["computedName"]() { }
->"computedName" : string
+ ["computedName1"]() { }
+>"computedName1" : string
- ["computedName"](a: string) { }
->"computedName" : string
+ ["computedName2"](a: string) { }
+>"computedName2" : string
>a : string
- ["computedName"](a: string): number { return 1; }
->"computedName" : string
+ ["computedName3"](a: string): number { return 1; }
+>"computedName3" : string
>a : string
>1 : number
@@ -36,15 +36,15 @@ class D {
return "HELLO";
>"HELLO" : string
}
- static ["computedname"]() { }
->"computedname" : string
+ static ["computedname4"]() { }
+>"computedname4" : string
- static ["computedname"](a: string) { }
->"computedname" : string
+ static ["computedname5"](a: string) { }
+>"computedname5" : string
>a : string
- static ["computedname"](a: string): boolean { return true; }
->"computedname" : string
+ static ["computedname6"](a: string): boolean { return true; }
+>"computedname6" : string
>a : string
>true : boolean
diff --git a/tests/baselines/reference/genericClassExpressionInFunction.js b/tests/baselines/reference/genericClassExpressionInFunction.js
new file mode 100644
index 00000000000..bb45587eea1
--- /dev/null
+++ b/tests/baselines/reference/genericClassExpressionInFunction.js
@@ -0,0 +1,104 @@
+//// [genericClassExpressionInFunction.ts]
+class A {
+ genericVar: T
+}
+function B1() {
+ // class expression can use T
+ return class extends A { }
+}
+class B2 {
+ anon = class extends A { }
+}
+function B3() {
+ return class Inner extends A { }
+}
+// extends can call B
+class K extends B1() {
+ namae: string;
+}
+class C extends (new B2().anon) {
+ name: string;
+}
+let b3Number = B3();
+class S extends b3Number {
+ nom: string;
+}
+var c = new C();
+var k = new K();
+var s = new S();
+c.genericVar = 12;
+k.genericVar = 12;
+s.genericVar = 12;
+
+
+//// [genericClassExpressionInFunction.js]
+var __extends = (this && this.__extends) || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var A = (function () {
+ function A() {
+ }
+ return A;
+})();
+function B1() {
+ // class expression can use T
+ return (function (_super) {
+ __extends(class_1, _super);
+ function class_1() {
+ _super.apply(this, arguments);
+ }
+ return class_1;
+ })(A);
+}
+var B2 = (function () {
+ function B2() {
+ this.anon = (function (_super) {
+ __extends(class_2, _super);
+ function class_2() {
+ _super.apply(this, arguments);
+ }
+ return class_2;
+ })(A);
+ }
+ return B2;
+})();
+function B3() {
+ return (function (_super) {
+ __extends(Inner, _super);
+ function Inner() {
+ _super.apply(this, arguments);
+ }
+ return Inner;
+ })(A);
+}
+// extends can call B
+var K = (function (_super) {
+ __extends(K, _super);
+ function K() {
+ _super.apply(this, arguments);
+ }
+ return K;
+})(B1());
+var C = (function (_super) {
+ __extends(C, _super);
+ function C() {
+ _super.apply(this, arguments);
+ }
+ return C;
+})((new B2().anon));
+var b3Number = B3();
+var S = (function (_super) {
+ __extends(S, _super);
+ function S() {
+ _super.apply(this, arguments);
+ }
+ return S;
+})(b3Number);
+var c = new C();
+var k = new K();
+var s = new S();
+c.genericVar = 12;
+k.genericVar = 12;
+s.genericVar = 12;
diff --git a/tests/baselines/reference/genericClassExpressionInFunction.symbols b/tests/baselines/reference/genericClassExpressionInFunction.symbols
new file mode 100644
index 00000000000..b5a6b8c6c70
--- /dev/null
+++ b/tests/baselines/reference/genericClassExpressionInFunction.symbols
@@ -0,0 +1,92 @@
+=== tests/cases/conformance/classes/classExpressions/genericClassExpressionInFunction.ts ===
+class A {
+>A : Symbol(A, Decl(genericClassExpressionInFunction.ts, 0, 0))
+>T : Symbol(T, Decl(genericClassExpressionInFunction.ts, 0, 8))
+
+ genericVar: T
+>genericVar : Symbol(genericVar, Decl(genericClassExpressionInFunction.ts, 0, 12))
+>T : Symbol(T, Decl(genericClassExpressionInFunction.ts, 0, 8))
+}
+function B1() {
+>B1 : Symbol(B1, Decl(genericClassExpressionInFunction.ts, 2, 1))
+>U : Symbol(U, Decl(genericClassExpressionInFunction.ts, 3, 12))
+
+ // class expression can use T
+ return class extends A { }
+>A : Symbol(A, Decl(genericClassExpressionInFunction.ts, 0, 0))
+>U : Symbol(U, Decl(genericClassExpressionInFunction.ts, 3, 12))
+}
+class B2 {
+>B2 : Symbol(B2, Decl(genericClassExpressionInFunction.ts, 6, 1))
+>V : Symbol(V, Decl(genericClassExpressionInFunction.ts, 7, 9))
+
+ anon = class extends A { }
+>anon : Symbol(anon, Decl(genericClassExpressionInFunction.ts, 7, 13))
+>A : Symbol(A, Decl(genericClassExpressionInFunction.ts, 0, 0))
+>V : Symbol(V, Decl(genericClassExpressionInFunction.ts, 7, 9))
+}
+function B3() {
+>B3 : Symbol(B3, Decl(genericClassExpressionInFunction.ts, 9, 1))
+>W : Symbol(W, Decl(genericClassExpressionInFunction.ts, 10, 12))
+
+ return class Inner extends A { }
+>Inner : Symbol(Inner, Decl(genericClassExpressionInFunction.ts, 11, 10))
+>TInner : Symbol(TInner, Decl(genericClassExpressionInFunction.ts, 11, 23))
+>A : Symbol(A, Decl(genericClassExpressionInFunction.ts, 0, 0))
+>W : Symbol(W, Decl(genericClassExpressionInFunction.ts, 10, 12))
+}
+// extends can call B
+class K extends B1() {
+>K : Symbol(K, Decl(genericClassExpressionInFunction.ts, 12, 1))
+>B1 : Symbol(B1, Decl(genericClassExpressionInFunction.ts, 2, 1))
+
+ namae: string;
+>namae : Symbol(namae, Decl(genericClassExpressionInFunction.ts, 14, 30))
+}
+class C extends (new B2().anon) {
+>C : Symbol(C, Decl(genericClassExpressionInFunction.ts, 16, 1))
+>new B2().anon : Symbol(B2.anon, Decl(genericClassExpressionInFunction.ts, 7, 13))
+>B2 : Symbol(B2, Decl(genericClassExpressionInFunction.ts, 6, 1))
+>anon : Symbol(B2.anon, Decl(genericClassExpressionInFunction.ts, 7, 13))
+
+ name: string;
+>name : Symbol(name, Decl(genericClassExpressionInFunction.ts, 17, 41))
+}
+let b3Number = B3();
+>b3Number : Symbol(b3Number, Decl(genericClassExpressionInFunction.ts, 20, 3))
+>B3 : Symbol(B3, Decl(genericClassExpressionInFunction.ts, 9, 1))
+
+class S extends b3Number {
+>S : Symbol(S, Decl(genericClassExpressionInFunction.ts, 20, 28))
+>b3Number : Symbol(b3Number, Decl(genericClassExpressionInFunction.ts, 20, 3))
+
+ nom: string;
+>nom : Symbol(nom, Decl(genericClassExpressionInFunction.ts, 21, 34))
+}
+var c = new C();
+>c : Symbol(c, Decl(genericClassExpressionInFunction.ts, 24, 3))
+>C : Symbol(C, Decl(genericClassExpressionInFunction.ts, 16, 1))
+
+var k = new K();
+>k : Symbol(k, Decl(genericClassExpressionInFunction.ts, 25, 3))
+>K : Symbol(K, Decl(genericClassExpressionInFunction.ts, 12, 1))
+
+var s = new S();
+>s : Symbol(s, Decl(genericClassExpressionInFunction.ts, 26, 3))
+>S : Symbol(S, Decl(genericClassExpressionInFunction.ts, 20, 28))
+
+c.genericVar = 12;
+>c.genericVar : Symbol(A.genericVar, Decl(genericClassExpressionInFunction.ts, 0, 12))
+>c : Symbol(c, Decl(genericClassExpressionInFunction.ts, 24, 3))
+>genericVar : Symbol(A.genericVar, Decl(genericClassExpressionInFunction.ts, 0, 12))
+
+k.genericVar = 12;
+>k.genericVar : Symbol(A.genericVar, Decl(genericClassExpressionInFunction.ts, 0, 12))
+>k : Symbol(k, Decl(genericClassExpressionInFunction.ts, 25, 3))
+>genericVar : Symbol(A.genericVar, Decl(genericClassExpressionInFunction.ts, 0, 12))
+
+s.genericVar = 12;
+>s.genericVar : Symbol(A.genericVar, Decl(genericClassExpressionInFunction.ts, 0, 12))
+>s : Symbol(s, Decl(genericClassExpressionInFunction.ts, 26, 3))
+>genericVar : Symbol(A.genericVar, Decl(genericClassExpressionInFunction.ts, 0, 12))
+
diff --git a/tests/baselines/reference/genericClassExpressionInFunction.types b/tests/baselines/reference/genericClassExpressionInFunction.types
new file mode 100644
index 00000000000..943391fdd59
--- /dev/null
+++ b/tests/baselines/reference/genericClassExpressionInFunction.types
@@ -0,0 +1,108 @@
+=== tests/cases/conformance/classes/classExpressions/genericClassExpressionInFunction.ts ===
+class A {
+>A : A
+>T : T
+
+ genericVar: T
+>genericVar : T
+>T : T
+}
+function B1() {
+>B1 : () => typeof (Anonymous class)
+>U : U
+
+ // class expression can use T
+ return class extends A { }
+>class extends A { } : typeof (Anonymous class)
+>A : A
+>U : U
+}
+class B2 {
+>B2 : B2
+>V : V
+
+ anon = class extends A { }
+>anon : typeof (Anonymous class)
+>class extends A { } : typeof (Anonymous class)
+>A : A
+>V : V
+}
+function B3() {
+>B3 : () => typeof Inner
+>W : W
+
+ return class Inner extends A { }
+>class Inner extends A { } : typeof Inner
+>Inner : typeof Inner
+>TInner : TInner
+>A : A
+>W : W
+}
+// extends can call B
+class K extends B1() {
+>K : K
+>B1() : B1.(Anonymous class)
+>B1 : () => typeof (Anonymous class)
+
+ namae: string;
+>namae : string
+}
+class C extends (new B2().anon) {
+>C : C
+>(new B2().anon) : B2.(Anonymous class)
+>new B2().anon : typeof (Anonymous class)
+>new B2() : B2
+>B2 : typeof B2
+>anon : typeof (Anonymous class)
+
+ name: string;
+>name : string
+}
+let b3Number = B3();
+>b3Number : typeof Inner
+>B3() : typeof Inner
+>B3 : () => typeof Inner
+
+class S extends b3Number {
+>S : S
+>b3Number : B3.Inner
+
+ nom: string;
+>nom : string
+}
+var c = new C();
+>c : C
+>new C() : C
+>C : typeof C
+
+var k = new K();
+>k : K
+>new K() : K
+>K : typeof K
+
+var s = new S();
+>s : S
+>new S() : S
+>S : typeof S
+
+c.genericVar = 12;
+>c.genericVar = 12 : number
+>c.genericVar : number
+>c : C
+>genericVar : number
+>12 : number
+
+k.genericVar = 12;
+>k.genericVar = 12 : number
+>k.genericVar : number
+>k : K
+>genericVar : number
+>12 : number
+
+s.genericVar = 12;
+>s.genericVar = 12 : number
+>s.genericVar : number
+>s : S
+>genericVar : number
+>12 : number
+
diff --git a/tests/baselines/reference/literalsInComputedProperties1.errors.txt b/tests/baselines/reference/literalsInComputedProperties1.errors.txt
new file mode 100644
index 00000000000..e9972229f79
--- /dev/null
+++ b/tests/baselines/reference/literalsInComputedProperties1.errors.txt
@@ -0,0 +1,66 @@
+tests/cases/compiler/literalsInComputedProperties1.ts(40,5): error TS2452: An enum member cannot have a numeric name.
+tests/cases/compiler/literalsInComputedProperties1.ts(41,5): error TS2452: An enum member cannot have a numeric name.
+tests/cases/compiler/literalsInComputedProperties1.ts(42,5): error TS2452: An enum member cannot have a numeric name.
+tests/cases/compiler/literalsInComputedProperties1.ts(43,5): error TS2452: An enum member cannot have a numeric name.
+
+
+==== tests/cases/compiler/literalsInComputedProperties1.ts (4 errors) ====
+
+ let x = {
+ 1:1,
+ [2]:1,
+ "3":1,
+ ["4"]:1
+ }
+ x[1].toExponential();
+ x[2].toExponential();
+ x[3].toExponential();
+ x[4].toExponential();
+
+ interface A {
+ 1:number;
+ [2]:number;
+ "3":number;
+ ["4"]:number;
+ }
+
+ let y:A;
+ y[1].toExponential();
+ y[2].toExponential();
+ y[3].toExponential();
+ y[4].toExponential();
+
+ class C {
+ 1:number;
+ [2]:number;
+ "3":number;
+ ["4"]:number;
+ }
+
+ let z:C;
+ z[1].toExponential();
+ z[2].toExponential();
+ z[3].toExponential();
+ z[4].toExponential();
+
+ enum X {
+ 1 = 1,
+ ~
+!!! error TS2452: An enum member cannot have a numeric name.
+ [2] = 2,
+ ~~~
+!!! error TS2452: An enum member cannot have a numeric name.
+ "3" = 3,
+ ~~~
+!!! error TS2452: An enum member cannot have a numeric name.
+ ["4"] = 4,
+ ~~~~~
+!!! error TS2452: An enum member cannot have a numeric name.
+ "foo" = 5,
+ ["bar"] = 6
+ }
+
+ let a = X["foo"];
+ let a0 = X["bar"];
+
+ // TODO: make sure that enum still disallow template literals as member names
\ No newline at end of file
diff --git a/tests/baselines/reference/literalsInComputedProperties1.js b/tests/baselines/reference/literalsInComputedProperties1.js
new file mode 100644
index 00000000000..ef11dbff6ea
--- /dev/null
+++ b/tests/baselines/reference/literalsInComputedProperties1.js
@@ -0,0 +1,94 @@
+//// [literalsInComputedProperties1.ts]
+
+let x = {
+ 1:1,
+ [2]:1,
+ "3":1,
+ ["4"]:1
+}
+x[1].toExponential();
+x[2].toExponential();
+x[3].toExponential();
+x[4].toExponential();
+
+interface A {
+ 1:number;
+ [2]:number;
+ "3":number;
+ ["4"]:number;
+}
+
+let y:A;
+y[1].toExponential();
+y[2].toExponential();
+y[3].toExponential();
+y[4].toExponential();
+
+class C {
+ 1:number;
+ [2]:number;
+ "3":number;
+ ["4"]:number;
+}
+
+let z:C;
+z[1].toExponential();
+z[2].toExponential();
+z[3].toExponential();
+z[4].toExponential();
+
+enum X {
+ 1 = 1,
+ [2] = 2,
+ "3" = 3,
+ ["4"] = 4,
+ "foo" = 5,
+ ["bar"] = 6
+}
+
+let a = X["foo"];
+let a0 = X["bar"];
+
+// TODO: make sure that enum still disallow template literals as member names
+
+//// [literalsInComputedProperties1.js]
+var x = (_a = {
+ 1: 1
+ },
+ _a[2] = 1,
+ _a["3"] = 1,
+ _a["4"] = 1,
+ _a
+);
+x[1].toExponential();
+x[2].toExponential();
+x[3].toExponential();
+x[4].toExponential();
+var y;
+y[1].toExponential();
+y[2].toExponential();
+y[3].toExponential();
+y[4].toExponential();
+var C = (function () {
+ function C() {
+ }
+ return C;
+})();
+var z;
+z[1].toExponential();
+z[2].toExponential();
+z[3].toExponential();
+z[4].toExponential();
+var X;
+(function (X) {
+ X[X["1"] = 1] = "1";
+ X[X[2] = 2] = 2;
+ X[X["3"] = 3] = "3";
+ X[X["4"] = 4] = "4";
+ X[X["foo"] = 5] = "foo";
+ X[X["bar"] = 6] = "bar";
+})(X || (X = {}));
+var a = X["foo"];
+var a0 = X["bar"];
+var _a;
+// TODO: make sure that enum still disallow template literals as member names
diff --git a/tests/cases/compiler/computedPropertiesInDestructuring1.ts b/tests/cases/compiler/computedPropertiesInDestructuring1.ts
new file mode 100644
index 00000000000..d3ccaa57ad1
--- /dev/null
+++ b/tests/cases/compiler/computedPropertiesInDestructuring1.ts
@@ -0,0 +1,36 @@
+// destructuring in variable declarations
+let foo = "bar";
+let {[foo]: bar} = {bar: "bar"};
+
+let {["bar"]: bar2} = {bar: "bar"};
+
+let foo2 = () => "bar";
+let {[foo2()]: bar3} = {bar: "bar"};
+
+let [{[foo]: bar4}] = [{bar: "bar"}];
+let [{[foo2()]: bar5}] = [{bar: "bar"}];
+
+function f1({["bar"]: x}: { bar: number }) {}
+function f2({[foo]: x}: { bar: number }) {}
+function f3({[foo2()]: x}: { bar: number }) {}
+function f4([{[foo]: x}]: [{ bar: number }]) {}
+function f5([{[foo2()]: x}]: [{ bar: number }]) {}
+
+// report errors on type errors in computed properties used in destructuring
+let [{[foo()]: bar6}] = [{bar: "bar"}];
+let [{[foo.toExponential()]: bar7}] = [{bar: "bar"}];
+
+// destructuring assignment
+({[foo]: bar} = {bar: "bar"});
+
+({["bar"]: bar2} = {bar: "bar"});
+
+({[foo2()]: bar3} = {bar: "bar"});
+
+[{[foo]: bar4}] = [{bar: "bar"}];
+[{[foo2()]: bar5}] = [{bar: "bar"}];
+
+[{[foo()]: bar4}] = [{bar: "bar"}];
+[{[(1 + {})]: bar4}] = [{bar: "bar"}];
+
+
diff --git a/tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts b/tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts
new file mode 100644
index 00000000000..4951e474fdb
--- /dev/null
+++ b/tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts
@@ -0,0 +1,36 @@
+// @target: ES6
+// destructuring in variable declarations
+let foo = "bar";
+let {[foo]: bar} = {bar: "bar"};
+
+let {["bar"]: bar2} = {bar: "bar"};
+let {[11]: bar2_1} = {11: "bar"};
+
+let foo2 = () => "bar";
+let {[foo2()]: bar3} = {bar: "bar"};
+
+let [{[foo]: bar4}] = [{bar: "bar"}];
+let [{[foo2()]: bar5}] = [{bar: "bar"}];
+
+function f1({["bar"]: x}: { bar: number }) {}
+function f2({[foo]: x}: { bar: number }) {}
+function f3({[foo2()]: x}: { bar: number }) {}
+function f4([{[foo]: x}]: [{ bar: number }]) {}
+function f5([{[foo2()]: x}]: [{ bar: number }]) {}
+
+// report errors on type errors in computed properties used in destructuring
+let [{[foo()]: bar6}] = [{bar: "bar"}];
+let [{[foo.toExponential()]: bar7}] = [{bar: "bar"}];
+
+// destructuring assignment
+({[foo]: bar} = {bar: "bar"});
+
+({["bar"]: bar2} = {bar: "bar"});
+
+({[foo2()]: bar3} = {bar: "bar"});
+
+[{[foo]: bar4}] = [{bar: "bar"}];
+[{[foo2()]: bar5}] = [{bar: "bar"}];
+
+[{[foo()]: bar4}] = [{bar: "bar"}];
+[{[(1 + {})]: bar4}] = [{bar: "bar"}];
diff --git a/tests/cases/compiler/computedPropertiesInDestructuring2.ts b/tests/cases/compiler/computedPropertiesInDestructuring2.ts
new file mode 100644
index 00000000000..806c528c17c
--- /dev/null
+++ b/tests/cases/compiler/computedPropertiesInDestructuring2.ts
@@ -0,0 +1,2 @@
+let foo2 = () => "bar";
+let {[foo2()]: bar3} = {};
\ No newline at end of file
diff --git a/tests/cases/compiler/computedPropertiesInDestructuring2_ES6.ts b/tests/cases/compiler/computedPropertiesInDestructuring2_ES6.ts
new file mode 100644
index 00000000000..c21f86bed1c
--- /dev/null
+++ b/tests/cases/compiler/computedPropertiesInDestructuring2_ES6.ts
@@ -0,0 +1,4 @@
+// @target: ES6
+
+let foo2 = () => "bar";
+let {[foo2()]: bar3} = {};
\ No newline at end of file
diff --git a/tests/cases/compiler/literalsInComputedProperties1.ts b/tests/cases/compiler/literalsInComputedProperties1.ts
new file mode 100644
index 00000000000..e3fed5b80aa
--- /dev/null
+++ b/tests/cases/compiler/literalsInComputedProperties1.ts
@@ -0,0 +1,52 @@
+// @noImplicitAny: true
+
+let x = {
+ 1:1,
+ [2]:1,
+ "3":1,
+ ["4"]:1
+}
+x[1].toExponential();
+x[2].toExponential();
+x[3].toExponential();
+x[4].toExponential();
+
+interface A {
+ 1:number;
+ [2]:number;
+ "3":number;
+ ["4"]:number;
+}
+
+let y:A;
+y[1].toExponential();
+y[2].toExponential();
+y[3].toExponential();
+y[4].toExponential();
+
+class C {
+ 1:number;
+ [2]:number;
+ "3":number;
+ ["4"]:number;
+}
+
+let z:C;
+z[1].toExponential();
+z[2].toExponential();
+z[3].toExponential();
+z[4].toExponential();
+
+enum X {
+ 1 = 1,
+ [2] = 2,
+ "3" = 3,
+ ["4"] = 4,
+ "foo" = 5,
+ ["bar"] = 6
+}
+
+let a = X["foo"];
+let a0 = X["bar"];
+
+// TODO: make sure that enum still disallow template literals as member names
\ No newline at end of file
diff --git a/tests/cases/conformance/classes/classExpressions/genericClassExpressionInFunction.ts b/tests/cases/conformance/classes/classExpressions/genericClassExpressionInFunction.ts
new file mode 100644
index 00000000000..14885ca9905
--- /dev/null
+++ b/tests/cases/conformance/classes/classExpressions/genericClassExpressionInFunction.ts
@@ -0,0 +1,30 @@
+class A {
+ genericVar: T
+}
+function B1() {
+ // class expression can use T
+ return class extends A { }
+}
+class B2 {
+ anon = class extends A { }
+}
+function B3() {
+ return class Inner extends A { }
+}
+// extends can call B
+class K extends B1() {
+ namae: string;
+}
+class C extends (new B2().anon) {
+ name: string;
+}
+let b3Number = B3();
+class S extends b3Number {
+ nom: string;
+}
+var c = new C();
+var k = new K();
+var s = new S();
+c.genericVar = 12;
+k.genericVar = 12;
+s.genericVar = 12;
diff --git a/tests/cases/conformance/es6/classDeclaration/emitClassDeclarationWithGetterSetterInES6.ts b/tests/cases/conformance/es6/classDeclaration/emitClassDeclarationWithGetterSetterInES6.ts
index 70c0b35763e..54c95c95a37 100644
--- a/tests/cases/conformance/es6/classDeclaration/emitClassDeclarationWithGetterSetterInES6.ts
+++ b/tests/cases/conformance/es6/classDeclaration/emitClassDeclarationWithGetterSetterInES6.ts
@@ -10,16 +10,16 @@ class C {
static get ["computedname"]() {
return "";
}
- get ["computedname"]() {
+ get ["computedname1"]() {
return "";
}
- get ["computedname"]() {
+ get ["computedname2"]() {
return "";
}
- set ["computedname"](x: any) {
+ set ["computedname3"](x: any) {
}
- set ["computedname"](y: string) {
+ set ["computedname4"](y: string) {
}
set foo(a: string) { }
diff --git a/tests/cases/conformance/es6/classDeclaration/emitClassDeclarationWithMethodInES6.ts b/tests/cases/conformance/es6/classDeclaration/emitClassDeclarationWithMethodInES6.ts
index c5d95bc6cb1..b7399a3511c 100644
--- a/tests/cases/conformance/es6/classDeclaration/emitClassDeclarationWithMethodInES6.ts
+++ b/tests/cases/conformance/es6/classDeclaration/emitClassDeclarationWithMethodInES6.ts
@@ -2,18 +2,18 @@
class D {
_bar: string;
foo() { }
- ["computedName"]() { }
- ["computedName"](a: string) { }
- ["computedName"](a: string): number { return 1; }
+ ["computedName1"]() { }
+ ["computedName2"](a: string) { }
+ ["computedName3"](a: string): number { return 1; }
bar(): string {
return this._bar;
}
baz(a: any, x: string): string {
return "HELLO";
}
- static ["computedname"]() { }
- static ["computedname"](a: string) { }
- static ["computedname"](a: string): boolean { return true; }
+ static ["computedname4"]() { }
+ static ["computedname5"](a: string) { }
+ static ["computedname6"](a: string): boolean { return true; }
static staticMethod() {
var x = 1 + 2;
return x
diff --git a/tests/cases/fourslash/getJavaScriptSyntacticDiagnostics1.ts b/tests/cases/fourslash/getJavaScriptSyntacticDiagnostics1.ts
deleted file mode 100644
index e409029276b..00000000000
--- a/tests/cases/fourslash/getJavaScriptSyntacticDiagnostics1.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-///
-
-// @allowNonTsExtensions: true
-// @Filename: a.js
-//// /**
-//// * @type {number}
-//// * @type {string}
-//// */
-//// var v;
-
-verify.getSyntacticDiagnostics(`[
- {
- "message": "\'type\' tag already specified.",
- "start": 26,
- "length": 4,
- "category": "error",
- "code": 1223
- }
-]`);
\ No newline at end of file
diff --git a/tests/cases/fourslash/javaScriptModules12.ts b/tests/cases/fourslash/javaScriptModules12.ts
new file mode 100644
index 00000000000..c391f150963
--- /dev/null
+++ b/tests/cases/fourslash/javaScriptModules12.ts
@@ -0,0 +1,57 @@
+///
+
+// Invocations of 'require' stop top-level variables from becoming global
+
+// @allowNonTsExtensions: true
+
+// @Filename: mod1.js
+//// var x = require('fs');
+//// /*1*/
+
+// @Filename: mod2.js
+//// var y;
+//// if(true) {
+//// y = require('fs');
+//// }
+//// /*2*/
+
+// @Filename: glob1.js
+//// var a = require;
+//// /*3*/
+
+// @Filename: glob2.js
+//// var b = '';
+//// /*4*/
+
+// @Filename: consumer.js
+//// /*5*/
+
+goTo.marker('1');
+verify.completionListContains('x');
+verify.not.completionListContains('y');
+verify.completionListContains('a');
+verify.completionListContains('b');
+
+goTo.marker('2');
+verify.not.completionListContains('x');
+verify.completionListContains('y');
+verify.completionListContains('a');
+verify.completionListContains('b');
+
+goTo.marker('3');
+verify.not.completionListContains('x');
+verify.not.completionListContains('y');
+verify.completionListContains('a');
+verify.completionListContains('b');
+
+goTo.marker('4');
+verify.not.completionListContains('x');
+verify.not.completionListContains('y');
+verify.completionListContains('a');
+verify.completionListContains('b');
+
+goTo.marker('5');
+verify.not.completionListContains('x');
+verify.not.completionListContains('y');
+verify.completionListContains('a');
+verify.completionListContains('b');
diff --git a/tests/cases/fourslash/javaScriptModules13.ts b/tests/cases/fourslash/javaScriptModules13.ts
new file mode 100644
index 00000000000..8b22971009c
--- /dev/null
+++ b/tests/cases/fourslash/javaScriptModules13.ts
@@ -0,0 +1,26 @@
+///
+
+// Assignments to 'module.exports' create an external module
+
+// @allowNonTsExtensions: true
+// @Filename: myMod.js
+//// if (true) {
+//// module.exports = { a: 10 };
+//// }
+//// var invisible = true;
+
+// @Filename: isGlobal.js
+//// var y = 10;
+
+// @Filename: consumer.js
+//// var x = require('myMod');
+//// /**/;
+
+goTo.file('consumer.js');
+goTo.marker();
+
+verify.completionListContains('y');
+verify.not.completionListContains('invisible');
+
+edit.insert('x.');
+verify.completionListContains('a');
diff --git a/tests/cases/fourslash/javaScriptModules14.ts b/tests/cases/fourslash/javaScriptModules14.ts
new file mode 100644
index 00000000000..5434f94cf8d
--- /dev/null
+++ b/tests/cases/fourslash/javaScriptModules14.ts
@@ -0,0 +1,28 @@
+///
+
+// Assignments to 'exports.p' stop global variables from being visible in other files
+
+// @allowNonTsExtensions: true
+// @Filename: myMod.js
+//// if (true) {
+//// exports.b = true;
+//// } else {
+//// exports.n = 3;
+//// }
+//// function fn() {
+//// exports.s = 'foo';
+//// }
+//// var invisible = true;
+
+// @Filename: isGlobal.js
+//// var y = 10;
+
+// @Filename: consumer.js
+//// var x = require('myMod');
+//// /**/;
+
+goTo.file('consumer.js');
+goTo.marker();
+
+verify.completionListContains('y');
+verify.not.completionListContains('invisible');
diff --git a/tests/cases/fourslash/javaScriptModules15.ts b/tests/cases/fourslash/javaScriptModules15.ts
new file mode 100644
index 00000000000..ff888d99336
--- /dev/null
+++ b/tests/cases/fourslash/javaScriptModules15.ts
@@ -0,0 +1,27 @@
+///
+
+// Assignments to 'exports.p' define a property 'p' even if they're not at top-level
+
+// @allowNonTsExtensions: true
+// @Filename: myMod.js
+//// if (true) {
+//// exports.b = true;
+//// } else {
+//// exports.n = 3;
+//// }
+//// function fn() {
+//// exports.s = 'foo';
+//// }
+
+// @Filename: consumer.js
+//// var x = require('myMod');
+//// x/**/;
+
+goTo.file('consumer.js');
+goTo.marker();
+edit.insert('.');
+verify.completionListContains("n", /*displayText:*/ undefined, /*documentation*/ undefined, "property");
+verify.completionListContains("s", /*displayText:*/ undefined, /*documentation*/ undefined, "property");
+verify.completionListContains("b", /*displayText:*/ undefined, /*documentation*/ undefined, "property");
+edit.insert('n.');
+verify.completionListContains("toFixed", /*displayText:*/ undefined, /*documentation*/ undefined, "method");
diff --git a/tests/cases/fourslash/javaScriptModules16.ts b/tests/cases/fourslash/javaScriptModules16.ts
new file mode 100644
index 00000000000..c556f288145
--- /dev/null
+++ b/tests/cases/fourslash/javaScriptModules16.ts
@@ -0,0 +1,22 @@
+///
+
+// Assignments to 'exports.p' define a property 'p'
+
+// @allowNonTsExtensions: true
+// @Filename: myMod.js
+//// exports.n = 3;
+//// exports.s = 'foo';
+//// exports.b = true;
+
+// @Filename: consumer.js
+//// var x = require('myMod');
+//// x/**/;
+
+goTo.file('consumer.js');
+goTo.marker();
+edit.insert('.');
+verify.completionListContains("n", /*displayText:*/ undefined, /*documentation*/ undefined, "property");
+verify.completionListContains("s", /*displayText:*/ undefined, /*documentation*/ undefined, "property");
+verify.completionListContains("b", /*displayText:*/ undefined, /*documentation*/ undefined, "property");
+edit.insert('n.');
+verify.completionListContains("toFixed", /*displayText:*/ undefined, /*documentation*/ undefined, "method");
diff --git a/tests/cases/fourslash/javaScriptModules17.ts b/tests/cases/fourslash/javaScriptModules17.ts
new file mode 100644
index 00000000000..8514ed0ee18
--- /dev/null
+++ b/tests/cases/fourslash/javaScriptModules17.ts
@@ -0,0 +1,18 @@
+///
+
+// @allowNonTsExtensions: true
+// @Filename: myMod.js
+//// module.exports = { n: 3, s: 'foo', b: true };
+
+// @Filename: consumer.js
+//// var x = require('./myMod');
+//// x/**/;
+
+goTo.file('consumer.js');
+goTo.marker();
+edit.insert('.');
+verify.completionListContains("n", /*displayText:*/ undefined, /*documentation*/ undefined, "property");
+verify.completionListContains("s", /*displayText:*/ undefined, /*documentation*/ undefined, "property");
+verify.completionListContains("b", /*displayText:*/ undefined, /*documentation*/ undefined, "property");
+edit.insert('n.');
+verify.completionListContains("toFixed", /*displayText:*/ undefined, /*documentation*/ undefined, "method");
diff --git a/tests/cases/fourslash/javaScriptModules18.ts b/tests/cases/fourslash/javaScriptModules18.ts
new file mode 100644
index 00000000000..d3117f86b3f
--- /dev/null
+++ b/tests/cases/fourslash/javaScriptModules18.ts
@@ -0,0 +1,14 @@
+///
+
+// CommonJS modules should not pollute the global namespace
+
+// @allowNonTsExtensions: true
+// @Filename: myMod.js
+//// var x = require('fs');
+
+// @Filename: other.js
+//// /**/;
+
+goTo.file('other.js');
+
+verify.not.completionListContains('x');
diff --git a/tests/cases/unittests/moduleResolution.ts b/tests/cases/unittests/moduleResolution.ts
index a76428a62a1..c53cad5725a 100644
--- a/tests/cases/unittests/moduleResolution.ts
+++ b/tests/cases/unittests/moduleResolution.ts
@@ -95,8 +95,8 @@ module ts {
let resolution = nodeModuleNameResolver(moduleName, containingFile.name, createModuleResolutionHost(containingFile, packageJson, moduleFile));
assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
assert.equal(!!resolution.resolvedModule.isExternalLibraryImport, false);
- // expect three failed lookup location - attempt to load module as file with all supported extensions
- assert.equal(resolution.failedLookupLocations.length, 3);
+ // expect five failed lookup location - attempt to load module as file with all supported extensions
+ assert.equal(resolution.failedLookupLocations.length, 5);
}
it("module name as directory - load from typings", () => {
@@ -117,6 +117,8 @@ module ts {
"/a/b/foo.ts",
"/a/b/foo.tsx",
"/a/b/foo.d.ts",
+ "/a/b/foo.js",
+ "/a/b/foo.jsx",
"/a/b/foo/index.ts",
"/a/b/foo/index.tsx",
]);
@@ -143,7 +145,7 @@ module ts {
"/a/b/c/node_modules/foo/package.json",
"/a/b/c/node_modules/foo/index.ts",
"/a/b/c/node_modules/foo/index.tsx",
- "/a/b/c/node_modules/foo/index.d.ts"
+ "/a/b/c/node_modules/foo/index.d.ts",
])
});
diff --git a/tests/cases/unittests/services/preProcessFile.ts b/tests/cases/unittests/services/preProcessFile.ts
index a3f8db5528f..d9ddaf0f256 100644
--- a/tests/cases/unittests/services/preProcessFile.ts
+++ b/tests/cases/unittests/services/preProcessFile.ts
@@ -2,8 +2,8 @@
///
describe('PreProcessFile:', function () {
- function test(sourceText: string, readImportFile: boolean, expectedPreProcess: ts.PreProcessedFileInfo): void {
- var resultPreProcess = ts.preProcessFile(sourceText, readImportFile);
+ function test(sourceText: string, readImportFile: boolean, detectJavaScriptImports: boolean, expectedPreProcess: ts.PreProcessedFileInfo): void {
+ var resultPreProcess = ts.preProcessFile(sourceText, readImportFile, detectJavaScriptImports);
var resultIsLibFile = resultPreProcess.isLibFile;
var resultImportedFiles = resultPreProcess.importedFiles;
@@ -45,7 +45,9 @@ describe('PreProcessFile:', function () {
}
describe("Test preProcessFiles,", function () {
it("Correctly return referenced files from triple slash", function () {
- test("///" + "\n" + "///" + "\n" + "///" + "\n" + "///", true,
+ test("///" + "\n" + "///" + "\n" + "///" + "\n" + "///",
+ /* readImports */true,
+ /* detectJavaScriptImports */ false,
{
referencedFiles: [{ fileName: "refFile1.ts", pos: 0, end: 37 }, { fileName: "refFile2.ts", pos: 38, end: 73 },
{ fileName: "refFile3.ts", pos: 74, end: 109 }, { fileName: "..\\refFile4d.ts", pos: 110, end: 150 }],
@@ -56,7 +58,9 @@ describe('PreProcessFile:', function () {
}),
it("Do not return reference path because of invalid triple-slash syntax", function () {
- test("///" + "\n" + "///" + "\n" + "///" + "\n" + "///", true,
+ test("///" + "\n" + "///" + "\n" + "///" + "\n" + "///",
+ /* readImports */true,
+ /* detectJavaScriptImports */ false,
{
referencedFiles: [],
importedFiles: [],
@@ -66,7 +70,9 @@ describe('PreProcessFile:', function () {
}),
it("Correctly return imported files", function () {
- test("import i1 = require(\"r1.ts\"); import i2 =require(\"r2.ts\"); import i3= require(\"r3.ts\"); import i4=require(\"r4.ts\"); import i5 = require (\"r5.ts\");", true,
+ test("import i1 = require(\"r1.ts\"); import i2 =require(\"r2.ts\"); import i3= require(\"r3.ts\"); import i4=require(\"r4.ts\"); import i5 = require (\"r5.ts\");",
+ /* readImports */true,
+ /* detectJavaScriptImports */ false,
{
referencedFiles: [],
importedFiles: [{ fileName: "r1.ts", pos: 20, end: 25 }, { fileName: "r2.ts", pos: 49, end: 54 }, { fileName: "r3.ts", pos: 78, end: 83 },
@@ -77,7 +83,9 @@ describe('PreProcessFile:', function () {
}),
it("Do not return imported files if readImportFiles argument is false", function () {
- test("import i1 = require(\"r1.ts\"); import i2 =require(\"r2.ts\"); import i3= require(\"r3.ts\"); import i4=require(\"r4.ts\"); import i5 = require (\"r5.ts\");", false,
+ test("import i1 = require(\"r1.ts\"); import i2 =require(\"r2.ts\"); import i3= require(\"r3.ts\"); import i4=require(\"r4.ts\"); import i5 = require (\"r5.ts\");",
+ /* readImports */ false,
+ /* detectJavaScriptImports */ false,
{
referencedFiles: [],
importedFiles: [],
@@ -87,7 +95,9 @@ describe('PreProcessFile:', function () {
}),
it("Do not return import path because of invalid import syntax", function () {
- test("import i1 require(\"r1.ts\"); import = require(\"r2.ts\") import i3= require(\"r3.ts\"); import i5", true,
+ test("import i1 require(\"r1.ts\"); import = require(\"r2.ts\") import i3= require(\"r3.ts\"); import i5",
+ /* readImports */true,
+ /* detectJavaScriptImports */ false,
{
referencedFiles: [],
importedFiles: [{ fileName: "r3.ts", pos: 73, end: 78 }],
@@ -97,7 +107,9 @@ describe('PreProcessFile:', function () {
}),
it("Correctly return referenced files and import files", function () {
- test("///" + "\n" + "///" + "\n" + "import i1 = require(\"r1.ts\"); import i2 =require(\"r2.ts\");", true,
+ test("///" + "\n" + "///" + "\n" + "import i1 = require(\"r1.ts\"); import i2 =require(\"r2.ts\");",
+ /* readImports */true,
+ /* detectJavaScriptImports */ false,
{
referencedFiles: [{ fileName: "refFile1.ts", pos: 0, end: 35 }, { fileName: "refFile2.ts", pos: 36, end: 71 }],
importedFiles: [{ fileName: "r1.ts", pos: 92, end: 97 }, { fileName: "r2.ts", pos: 121, end: 126 }],
@@ -107,7 +119,9 @@ describe('PreProcessFile:', function () {
}),
it("Correctly return referenced files and import files even with some invalid syntax", function () {
- test("///" + "\n" + "///" + "\n" + "import i1 = require(\"r1.ts\"); import = require(\"r2.ts\"); import i2 = require(\"r3.ts\");", true,
+ test("///" + "\n" + "///" + "\n" + "import i1 = require(\"r1.ts\"); import = require(\"r2.ts\"); import i2 = require(\"r3.ts\");",
+ /* readImports */true,
+ /* detectJavaScriptImports */ false,
{
referencedFiles: [{ fileName: "refFile1.ts", pos: 0, end: 35 }],
importedFiles: [{ fileName: "r1.ts", pos: 91, end: 96 }, { fileName: "r3.ts", pos: 148, end: 153 }],
@@ -124,7 +138,8 @@ describe('PreProcessFile:', function () {
"import {a as A} from \"m5\";" + "\n" +
"import {a as A, b, c as C} from \"m6\";" + "\n" +
"import def , {a, b, c as C} from \"m7\";" + "\n",
- true,
+ /* readImports */true,
+ /* detectJavaScriptImports */ false,
{
referencedFiles: [],
importedFiles: [
@@ -146,7 +161,8 @@ describe('PreProcessFile:', function () {
"export {a} from \"m2\";" + "\n" +
"export {a as A} from \"m3\";" + "\n" +
"export {a as A, b, c as C} from \"m4\";" + "\n",
- true,
+ /* readImports */true,
+ /* detectJavaScriptImports */ false,
{
referencedFiles: [],
importedFiles: [
@@ -166,7 +182,11 @@ describe('PreProcessFile:', function () {
declare module "B" {}
function foo() {
}
- `, false, {
+ `,
+ /* readImports */ false,
+ /* detectJavaScriptImports */ false,
+
+ {
referencedFiles: [],
importedFiles: [],
ambientExternalModules: ["B"],
@@ -176,7 +196,8 @@ describe('PreProcessFile:', function () {
it("Correctly handles export import declarations", function () {
test("export import a = require(\"m1\");",
- true,
+ /* readImports */true,
+ /* detectJavaScriptImports */ false,
{
referencedFiles: [],
importedFiles: [
@@ -186,7 +207,61 @@ describe('PreProcessFile:', function () {
isLibFile: false
})
});
-
+ it("Correctly handles export require calls in JavaScript files", function () {
+ test(`
+ export import a = require("m1");
+ var x = require('m2');
+ foo(require('m3'));
+ var z = { f: require('m4') }
+ `,
+ /* readImports */true,
+ /* detectJavaScriptImports */ true,
+ {
+ referencedFiles: [],
+ importedFiles: [
+ { fileName: "m1", pos: 39, end: 41 },
+ { fileName: "m2", pos: 74, end: 76 },
+ { fileName: "m3", pos: 105, end: 107 },
+ { fileName: "m4", pos: 146, end: 148 },
+ ],
+ ambientExternalModules: undefined,
+ isLibFile: false
+ })
+ });
+ it("Correctly handles dependency lists in define([deplist]) calls in JavaScript files", function () {
+ test(`
+ define(["mod1", "mod2"], (m1, m2) => {
+ });
+ `,
+ /* readImports */true,
+ /* detectJavaScriptImports */ true,
+ {
+ referencedFiles: [],
+ importedFiles: [
+ { fileName: "mod1", pos: 21, end: 25 },
+ { fileName: "mod2", pos: 29, end: 33 },
+ ],
+ ambientExternalModules: undefined,
+ isLibFile: false
+ })
+ });
+ it("Correctly handles dependency lists in define(modName, [deplist]) calls in JavaScript files", function () {
+ test(`
+ define("mod", ["mod1", "mod2"], (m1, m2) => {
+ });
+ `,
+ /* readImports */true,
+ /* detectJavaScriptImports */ true,
+ {
+ referencedFiles: [],
+ importedFiles: [
+ { fileName: "mod1", pos: 28, end: 32 },
+ { fileName: "mod2", pos: 36, end: 40 },
+ ],
+ ambientExternalModules: undefined,
+ isLibFile: false
+ })
+ });
});
});
diff --git a/tests/webTestServer.ts b/tests/webTestServer.ts
index 6ddc18f1344..6bd15359e3f 100644
--- a/tests/webTestServer.ts
+++ b/tests/webTestServer.ts
@@ -5,7 +5,7 @@ import fs = require("fs");
import path = require("path");
import url = require("url");
import child_process = require("child_process");
-import os = require('os');
+import os = require("os");
/// Command line processing ///
@@ -276,7 +276,6 @@ if ((browser && browser === 'chrome')) {
console.log(`default Chrome location is unknown for platform '${os.platform()}'`);
break;
}
-
if (fs.existsSync(defaultChromePath)) {
browserPath = defaultChromePath;
} else {