Merge remote-tracking branch 'Microsoft/master' into tsconfigpath

This commit is contained in:
SaschaNaz
2015-10-05 04:55:31 +09:00
136 changed files with 2622 additions and 685 deletions
+53 -50
View File
@@ -44,6 +44,7 @@ namespace ts {
let compilerOptions = host.getCompilerOptions();
let languageVersion = compilerOptions.target || ScriptTarget.ES3;
let modulekind = compilerOptions.module ? compilerOptions.module : languageVersion === ScriptTarget.ES6 ? ModuleKind.ES6 : ModuleKind.None;
let emitResolver = createResolver();
@@ -2293,10 +2294,17 @@ namespace ts {
return type && (type.flags & TypeFlags.Any) !== 0;
}
// Return the type of a binding element parent. We check SymbolLinks first to see if a type has been
// assigned by contextual typing.
function getTypeForBindingElementParent(node: VariableLikeDeclaration) {
let symbol = getSymbolOfNode(node);
return symbol && getSymbolLinks(symbol).type || getTypeForVariableLikeDeclaration(node);
}
// Return the inferred type for a binding element
function getTypeForBindingElement(declaration: BindingElement): Type {
let pattern = <BindingPattern>declaration.parent;
let parentType = getTypeForVariableLikeDeclaration(<VariableLikeDeclaration>pattern.parent);
let parentType = getTypeForBindingElementParent(<VariableLikeDeclaration>pattern.parent);
// If parent has the unknown (error) type, then so does this binding element
if (parentType === unknownType) {
return unknownType;
@@ -9162,10 +9170,24 @@ namespace ts {
}
}
// When contextual typing assigns a type to a parameter that contains a binding pattern, we also need to push
// the destructured type into the contained binding elements.
function assignBindingElementTypes(node: VariableLikeDeclaration) {
if (isBindingPattern(node.name)) {
for (let element of (<BindingPattern>node.name).elements) {
if (element.kind !== SyntaxKind.OmittedExpression) {
getSymbolLinks(getSymbolOfNode(element)).type = getTypeForBindingElement(element);
assignBindingElementTypes(element);
}
}
}
}
function assignTypeToParameterAndFixTypeParameters(parameter: Symbol, contextualType: Type, mapper: TypeMapper) {
let links = getSymbolLinks(parameter);
if (!links.type) {
links.type = instantiateType(contextualType, mapper);
assignBindingElementTypes(<ParameterDeclaration>parameter.valueDeclaration);
}
else if (isInferentialContext(mapper)) {
// Even if the parameter already has a type, it might be because it was given a type while
@@ -12940,26 +12962,41 @@ namespace ts {
if (!(nodeLinks.flags & NodeCheckFlags.EnumValuesComputed)) {
let enumSymbol = getSymbolOfNode(node);
let enumType = getDeclaredTypeOfSymbol(enumSymbol);
let autoValue = 0;
let autoValue = 0; // set to undefined when enum member is non-constant
let ambient = isInAmbientContext(node);
let enumIsConst = isConst(node);
forEach(node.members, member => {
if (member.name.kind !== SyntaxKind.ComputedPropertyName && isNumericLiteralName((<Identifier>member.name).text)) {
for (const member of node.members) {
if (member.name.kind === SyntaxKind.ComputedPropertyName) {
error(member.name, Diagnostics.Computed_property_names_are_not_allowed_in_enums);
}
else if (isNumericLiteralName((<Identifier>member.name).text)) {
error(member.name, Diagnostics.An_enum_member_cannot_have_a_numeric_name);
}
const previousEnumMemberIsNonConstant = autoValue === undefined;
let initializer = member.initializer;
if (initializer) {
autoValue = computeConstantValueForEnumMemberInitializer(initializer, enumType, enumIsConst, ambient);
}
else if (ambient && !enumIsConst) {
// In ambient enum declarations that specify no const modifier, enum member declarations
// that omit a value are considered computed members (as opposed to having auto-incremented values assigned).
autoValue = undefined;
}
else if (previousEnumMemberIsNonConstant) {
// If the member declaration specifies no value, the member is considered a constant enum member.
// If the member is the first member in the enum declaration, it is assigned the value zero.
// Otherwise, it is assigned the value of the immediately preceding member plus one,
// and an error occurs if the immediately preceding member is not a constant enum member
error(member.name, Diagnostics.Enum_member_must_have_initializer);
}
if (autoValue !== undefined) {
getNodeLinks(member).enumMemberValue = autoValue++;
}
});
}
nodeLinks.flags |= NodeCheckFlags.EnumValuesComputed;
}
@@ -12975,11 +13012,11 @@ namespace ts {
if (enumIsConst) {
error(initializer, Diagnostics.In_const_enum_declarations_member_initializer_must_be_constant_expression);
}
else if (!ambient) {
else if (ambient) {
error(initializer, Diagnostics.In_ambient_enum_declarations_member_initializer_must_be_constant_expression);
}
else {
// Only here do we need to check that the initializer is assignable to the enum type.
// If it is a constant value (not undefined), it is syntactically constrained to be a number.
// Also, we do not need to check this for ambients because there is already
// a syntax error if it is not a constant.
checkTypeAssignableTo(checkExpression(initializer), enumType, initializer, /*headMessage*/ undefined);
}
}
@@ -13119,7 +13156,7 @@ namespace ts {
}
// Grammar checking
checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarEnumDeclaration(node);
checkGrammarDecorators(node) || checkGrammarModifiers(node);
checkTypeNameIsReserved(node.name, Diagnostics.Enum_name_cannot_be_0);
checkCollisionWithCapturedThisVariable(node, node.name);
@@ -13379,9 +13416,9 @@ namespace ts {
}
}
else {
if (languageVersion >= ScriptTarget.ES6 && !isInAmbientContext(node)) {
if (modulekind === ModuleKind.ES6 && !isInAmbientContext(node)) {
// Import equals declaration is deprecated in es6 or above
grammarErrorOnNode(node, Diagnostics.Import_assignment_cannot_be_used_when_targeting_ECMAScript_6_or_higher_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_or_import_d_from_mod_instead);
grammarErrorOnNode(node, Diagnostics.Import_assignment_cannot_be_used_when_targeting_ECMAScript_6_modules_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_import_d_from_mod_or_another_module_format_instead);
}
}
}
@@ -13456,11 +13493,11 @@ namespace ts {
checkExternalModuleExports(<SourceFile | ModuleDeclaration>container);
if (node.isExportEquals && !isInAmbientContext(node)) {
if (languageVersion >= ScriptTarget.ES6) {
// export assignment is deprecated in es6 or above
grammarErrorOnNode(node, Diagnostics.Export_assignment_cannot_be_used_when_targeting_ECMAScript_6_or_higher_Consider_using_export_default_instead);
if (modulekind === ModuleKind.ES6) {
// export assignment is not supported in es6 modules
grammarErrorOnNode(node, Diagnostics.Export_assignment_cannot_be_used_when_targeting_ECMAScript_6_modules_Consider_using_export_default_or_another_module_format_instead);
}
else if (compilerOptions.module === ModuleKind.System) {
else if (modulekind === ModuleKind.System) {
// system modules does not support export assignment
grammarErrorOnNode(node, Diagnostics.Export_assignment_is_not_supported_when_module_flag_is_system);
}
@@ -15619,40 +15656,6 @@ namespace ts {
return false;
}
function checkGrammarEnumDeclaration(enumDecl: EnumDeclaration): boolean {
let enumIsConst = (enumDecl.flags & NodeFlags.Const) !== 0;
let hasError = false;
// skip checks below for const enums - they allow arbitrary initializers as long as they can be evaluated to constant expressions.
// since all values are known in compile time - it is not necessary to check that constant enum section precedes computed enum members.
if (!enumIsConst) {
let inConstantEnumMemberSection = true;
let inAmbientContext = isInAmbientContext(enumDecl);
for (let node of enumDecl.members) {
// Do not use hasDynamicName here, because that returns false for well known symbols.
// We want to perform checkComputedPropertyName for all computed properties, including
// well known symbols.
if (node.name.kind === SyntaxKind.ComputedPropertyName) {
hasError = grammarErrorOnNode(node.name, Diagnostics.Computed_property_names_are_not_allowed_in_enums);
}
else if (inAmbientContext) {
if (node.initializer && !isIntegerLiteral(node.initializer)) {
hasError = grammarErrorOnNode(node.name, Diagnostics.Ambient_enum_elements_can_only_have_integer_literal_initializers) || hasError;
}
}
else if (node.initializer) {
inConstantEnumMemberSection = isIntegerLiteral(node.initializer);
}
else if (!inConstantEnumMemberSection) {
hasError = grammarErrorOnNode(node.name, Diagnostics.Enum_member_must_have_initializer) || hasError;
}
}
}
return hasError;
}
function hasParseDiagnostics(sourceFile: SourceFile): boolean {
return sourceFile.parseDiagnostics.length > 0;
}
+3 -2
View File
@@ -76,10 +76,11 @@ namespace ts {
"amd": ModuleKind.AMD,
"system": ModuleKind.System,
"umd": ModuleKind.UMD,
"es6": ModuleKind.ES6,
},
description: Diagnostics.Specify_module_code_generation_Colon_commonjs_amd_system_or_umd,
description: Diagnostics.Specify_module_code_generation_Colon_commonjs_amd_system_umd_or_es6,
paramType: Diagnostics.KIND,
error: Diagnostics.Argument_for_module_option_must_be_commonjs_amd_system_or_umd
error: Diagnostics.Argument_for_module_option_must_be_commonjs_amd_system_umd_or_es6
},
{
name: "newLine",
+6 -6
View File
@@ -195,7 +195,7 @@
"category": "Error",
"code": 1063
},
"Ambient enum elements can only have integer literal initializers.": {
"In ambient enum declarations member initializer must be constant expression.": {
"category": "Error",
"code": 1066
},
@@ -619,15 +619,15 @@
"category": "Error",
"code": 1200
},
"Import assignment cannot be used when targeting ECMAScript 6 or higher. Consider using 'import * as ns from \"mod\"', 'import {a} from \"mod\"' or 'import d from \"mod\"' instead.": {
"Import assignment cannot be used when targeting ECMAScript 6 modules. Consider using 'import * as ns from \"mod\"', 'import {a} from \"mod\"', 'import d from \"mod\"', or another module format instead.": {
"category": "Error",
"code": 1202
},
"Export assignment cannot be used when targeting ECMAScript 6 or higher. Consider using 'export default' instead.": {
"Export assignment cannot be used when targeting ECMAScript 6 modules. Consider using 'export default' or another module format instead.": {
"category": "Error",
"code": 1203
},
"Cannot compile modules into 'commonjs', 'amd', 'system' or 'umd' when targeting 'ES6' or higher.": {
"Cannot compile modules into 'es6' when targeting 'ES5' or lower.": {
"category": "Error",
"code": 1204
},
@@ -2109,7 +2109,7 @@
"category": "Message",
"code": 6015
},
"Specify module code generation: 'commonjs', 'amd', 'system' or 'umd'": {
"Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es6'": {
"category": "Message",
"code": 6016
},
@@ -2193,7 +2193,7 @@
"category": "Error",
"code": 6045
},
"Argument for '--module' option must be 'commonjs', 'amd', 'system' or 'umd'.": {
"Argument for '--module' option must be 'commonjs', 'amd', 'system', 'umd', or 'es6'.": {
"category": "Error",
"code": 6046
},
+79 -56
View File
@@ -64,6 +64,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
let compilerOptions = host.getCompilerOptions();
let languageVersion = compilerOptions.target || ScriptTarget.ES3;
let modulekind = compilerOptions.module ? compilerOptions.module : languageVersion === ScriptTarget.ES6 ? ModuleKind.ES6 : ModuleKind.None;
let sourceMapDataList: SourceMapData[] = compilerOptions.sourceMap || compilerOptions.inlineSourceMap ? [] : undefined;
let diagnostics: Diagnostic[] = [];
let newLine = host.getNewLine();
@@ -188,6 +189,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
/** If removeComments is true, no leading-comments needed to be emitted **/
let emitLeadingCommentsOfPosition = compilerOptions.removeComments ? function (pos: number) { } : emitLeadingCommentsOfPositionWorker;
let moduleEmitDelegates: Map<(node: SourceFile, startIndex: number) => void> = {
[ModuleKind.ES6]: emitES6Module,
[ModuleKind.AMD]: emitAMDModule,
[ModuleKind.System]: emitSystemModule,
[ModuleKind.UMD]: emitUMDModule,
[ModuleKind.CommonJS]: emitCommonJSModule,
};
if (compilerOptions.sourceMap || compilerOptions.inlineSourceMap) {
initializeEmitterWithSourceMaps();
@@ -1425,6 +1434,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
let parent = node.parent;
switch (parent.kind) {
case SyntaxKind.ArrayLiteralExpression:
case SyntaxKind.AsExpression:
case SyntaxKind.BinaryExpression:
case SyntaxKind.CallExpression:
case SyntaxKind.CaseClause:
@@ -1493,7 +1503,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
if (container) {
if (container.kind === SyntaxKind.SourceFile) {
// Identifier references module export
if (languageVersion < ScriptTarget.ES6 && compilerOptions.module !== ModuleKind.System) {
if (modulekind !== ModuleKind.ES6 && modulekind !== ModuleKind.System) {
write("exports.");
}
}
@@ -1503,7 +1513,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
write(".");
}
}
else if (languageVersion < ScriptTarget.ES6) {
else if (modulekind !== ModuleKind.ES6) {
let declaration = resolver.getReferencedImportDeclaration(node);
if (declaration) {
if (declaration.kind === SyntaxKind.ImportClause) {
@@ -3056,7 +3066,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
write(getGeneratedNameForNode(container));
write(".");
}
else if (languageVersion < ScriptTarget.ES6 && compilerOptions.module !== ModuleKind.System) {
else if (modulekind !== ModuleKind.ES6 && modulekind !== ModuleKind.System) {
write("exports.");
}
}
@@ -3076,7 +3086,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
if (node.parent.kind === SyntaxKind.SourceFile) {
Debug.assert(!!(node.flags & NodeFlags.Default) || node.kind === SyntaxKind.ExportAssignment);
// only allow export default at a source file level
if (compilerOptions.module === ModuleKind.CommonJS || compilerOptions.module === ModuleKind.AMD || compilerOptions.module === ModuleKind.UMD) {
if (modulekind === ModuleKind.CommonJS || modulekind === ModuleKind.AMD || modulekind === ModuleKind.UMD) {
if (!currentSourceFile.symbol.exports["___esModule"]) {
if (languageVersion === ScriptTarget.ES5) {
// default value of configurable, enumerable, writable are `false`.
@@ -3098,7 +3108,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
emitStart(node);
// emit call to exporter only for top level nodes
if (compilerOptions.module === ModuleKind.System && node.parent === currentSourceFile) {
if (modulekind === ModuleKind.System && node.parent === currentSourceFile) {
// emit export default <smth> as
// export("default", <smth>)
write(`${exportFunctionForFile}("`);
@@ -3134,7 +3144,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
}
function emitExportMemberAssignments(name: Identifier) {
if (compilerOptions.module === ModuleKind.System) {
if (modulekind === ModuleKind.System) {
return;
}
@@ -3154,7 +3164,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
}
function emitExportSpecifierInSystemModule(specifier: ExportSpecifier): void {
Debug.assert(compilerOptions.module === ModuleKind.System);
Debug.assert(modulekind === ModuleKind.System);
if (!resolver.getReferencedValueDeclaration(specifier.propertyName || specifier.name) && !resolver.isValueAliasDeclaration(specifier) ) {
return;
@@ -3491,7 +3501,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
function isES6ExportedDeclaration(node: Node) {
return !!(node.flags & NodeFlags.Export) &&
languageVersion >= ScriptTarget.ES6 &&
modulekind === ModuleKind.ES6 &&
node.parent.kind === SyntaxKind.SourceFile;
}
@@ -4520,8 +4530,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
write("class");
// check if this is an "export default class" as it may not have a name. Do not emit the name if the class is decorated.
if ((node.name || !(node.flags & NodeFlags.Default)) && !thisNodeIsDecorated) {
// emit name if
// - node has a name
// - this is default export and target is not ES6 (for ES6 `export default` does not need to be compiled downlevel)
if ((node.name || (node.flags & NodeFlags.Default && languageVersion < ScriptTarget.ES6)) && !thisNodeIsDecorated) {
write(" ");
emitDeclarationName(node);
}
@@ -5257,7 +5269,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
write(";");
}
if (languageVersion < ScriptTarget.ES6 && node.parent === currentSourceFile) {
if (compilerOptions.module === ModuleKind.System && (node.flags & NodeFlags.Export)) {
if (modulekind === ModuleKind.System && (node.flags & NodeFlags.Export)) {
// write the call to exporter for enum
writeLine();
write(`${exportFunctionForFile}("`);
@@ -5379,7 +5391,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
write(" = {}));");
emitEnd(node);
if (!isES6ExportedDeclaration(node) && node.name.kind === SyntaxKind.Identifier && node.parent === currentSourceFile) {
if (compilerOptions.module === ModuleKind.System && (node.flags & NodeFlags.Export)) {
if (modulekind === ModuleKind.System && (node.flags & NodeFlags.Export)) {
writeLine();
write(`${exportFunctionForFile}("`);
emitDeclarationName(node);
@@ -5443,7 +5455,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
}
function emitImportDeclaration(node: ImportDeclaration) {
if (languageVersion < ScriptTarget.ES6) {
if (modulekind !== ModuleKind.ES6) {
return emitExternalImportDeclaration(node);
}
@@ -5494,7 +5506,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
let isExportedImport = node.kind === SyntaxKind.ImportEqualsDeclaration && (node.flags & NodeFlags.Export) !== 0;
let namespaceDeclaration = getNamespaceDeclarationNode(node);
if (compilerOptions.module !== ModuleKind.AMD) {
if (modulekind !== ModuleKind.AMD) {
emitLeadingComments(node);
emitStart(node);
if (namespaceDeclaration && !isDefaultImport(node)) {
@@ -5606,15 +5618,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
}
function emitExportDeclaration(node: ExportDeclaration) {
Debug.assert(compilerOptions.module !== ModuleKind.System);
Debug.assert(modulekind !== ModuleKind.System);
if (languageVersion < ScriptTarget.ES6) {
if (modulekind !== ModuleKind.ES6) {
if (node.moduleSpecifier && (!node.exportClause || resolver.isValueAliasDeclaration(node))) {
emitStart(node);
let generatedName = getGeneratedNameForNode(node);
if (node.exportClause) {
// export { x, y, ... } from "foo"
if (compilerOptions.module !== ModuleKind.AMD) {
if (modulekind !== ModuleKind.AMD) {
write("var ");
write(generatedName);
write(" = ");
@@ -5641,7 +5653,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
// export * from "foo"
writeLine();
write("__export(");
if (compilerOptions.module !== ModuleKind.AMD) {
if (modulekind !== ModuleKind.AMD) {
emitRequire(getExternalModuleName(node));
}
else {
@@ -5674,7 +5686,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
}
function emitExportOrImportSpecifierList(specifiers: ImportOrExportSpecifier[], shouldEmit: (node: Node) => boolean) {
Debug.assert(languageVersion >= ScriptTarget.ES6);
Debug.assert(modulekind === ModuleKind.ES6);
let needsComma = false;
for (let specifier of specifiers) {
@@ -5694,7 +5706,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
function emitExportAssignment(node: ExportAssignment) {
if (!node.isExportEquals && resolver.isValueAliasDeclaration(node)) {
if (languageVersion >= ScriptTarget.ES6) {
if (modulekind === ModuleKind.ES6) {
writeLine();
emitStart(node);
write("export default ");
@@ -5709,7 +5721,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
else {
writeLine();
emitStart(node);
if (compilerOptions.module === ModuleKind.System) {
if (modulekind === ModuleKind.System) {
write(`${exportFunctionForFile}("default",`);
emit(node.expression);
write(")");
@@ -6155,7 +6167,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
}
function isCurrentFileSystemExternalModule() {
return compilerOptions.module === ModuleKind.System && isExternalModule(currentSourceFile);
return modulekind === ModuleKind.System && isExternalModule(currentSourceFile);
}
function emitSystemModuleBody(node: SourceFile, dependencyGroups: DependencyGroup[], startIndex: number): void {
@@ -6395,19 +6407,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
write("});");
}
function emitAMDDependencies(node: SourceFile, includeNonAmdDependencies: boolean) {
// An AMD define function has the following shape:
// define(id?, dependencies?, factory);
//
// This has the shape of
// define(name, ["module1", "module2"], function (module1Alias) {
// The location of the alias in the parameter list in the factory function needs to
// match the position of the module name in the dependency list.
//
// To ensure this is true in cases of modules with no aliases, e.g.:
// `import "module"` or `<amd-dependency path= "a.css" />`
// we need to add modules without alias names to the end of the dependencies list
interface AMDDependencyNames {
aliasedModuleNames: string[];
unaliasedModuleNames: string[];
importAliasNames: string[];
}
function getAMDDependencyNames(node: SourceFile, includeNonAmdDependencies: boolean): AMDDependencyNames {
// names of modules with corresponding parameter in the factory function
let aliasedModuleNames: string[] = [];
// names of modules with no corresponding parameters in factory function
@@ -6442,6 +6448,29 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
}
}
return { aliasedModuleNames, unaliasedModuleNames, importAliasNames };
}
function emitAMDDependencies(node: SourceFile, includeNonAmdDependencies: boolean) {
// An AMD define function has the following shape:
// define(id?, dependencies?, factory);
//
// This has the shape of
// define(name, ["module1", "module2"], function (module1Alias) {
// The location of the alias in the parameter list in the factory function needs to
// match the position of the module name in the dependency list.
//
// To ensure this is true in cases of modules with no aliases, e.g.:
// `import "module"` or `<amd-dependency path= "a.css" />`
// we need to add modules without alias names to the end of the dependencies list
let dependencyNames = getAMDDependencyNames(node, includeNonAmdDependencies);
emitAMDDependencyList(dependencyNames);
write(", ");
emitAMDFactoryHeader(dependencyNames);
}
function emitAMDDependencyList({ aliasedModuleNames, unaliasedModuleNames }: AMDDependencyNames) {
write("[\"require\", \"exports\"");
if (aliasedModuleNames.length) {
write(", ");
@@ -6451,11 +6480,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
write(", ");
write(unaliasedModuleNames.join(", "));
}
write("], function (require, exports");
write("]");
}
function emitAMDFactoryHeader({ importAliasNames }: AMDDependencyNames) {
write("function (require, exports");
if (importAliasNames.length) {
write(", ");
write(importAliasNames.join(", "));
}
write(") {");
}
function emitAMDModule(node: SourceFile, startIndex: number) {
@@ -6468,7 +6502,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
write("\"" + node.moduleName + "\", ");
}
emitAMDDependencies(node, /*includeNonAmdDependencies*/ true);
write(") {");
increaseIndent();
emitExportStarHelper();
emitCaptureThisForNodeIfNecessary(node);
@@ -6494,17 +6527,20 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
emitEmitHelpers(node);
collectExternalModuleInfo(node);
let dependencyNames = getAMDDependencyNames(node, /*includeNonAmdDependencies*/ false);
// Module is detected first to support Browserify users that load into a browser with an AMD loader
writeLines(`(function (deps, factory) {
writeLines(`(function (factory) {
if (typeof module === 'object' && typeof module.exports === 'object') {
var v = factory(require, exports); if (v !== undefined) module.exports = v;
}
else if (typeof define === 'function' && define.amd) {
define(deps, factory);
}
define(`);
emitAMDDependencyList(dependencyNames);
write(", factory);");
writeLines(` }
})(`);
emitAMDDependencies(node, false);
write(") {");
emitAMDFactoryHeader(dependencyNames);
increaseIndent();
emitExportStarHelper();
emitCaptureThisForNodeIfNecessary(node);
@@ -6713,21 +6749,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
let startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ false);
if (isExternalModule(node) || compilerOptions.isolatedModules) {
if (languageVersion >= ScriptTarget.ES6) {
emitES6Module(node, startIndex);
}
else if (compilerOptions.module === ModuleKind.AMD) {
emitAMDModule(node, startIndex);
}
else if (compilerOptions.module === ModuleKind.System) {
emitSystemModule(node, startIndex);
}
else if (compilerOptions.module === ModuleKind.UMD) {
emitUMDModule(node, startIndex);
}
else {
emitCommonJSModule(node, startIndex);
}
let emitModule = moduleEmitDelegates[modulekind] || moduleEmitDelegates[ModuleKind.CommonJS];
emitModule(node, startIndex);
}
else {
externalImports = undefined;
+17 -2
View File
@@ -4809,7 +4809,7 @@ namespace ts {
node.decorators = decorators;
setModifiers(node, modifiers);
parseExpected(SyntaxKind.ClassKeyword);
node.name = parseOptionalIdentifier();
node.name = parseNameOfClassDeclarationOrExpression();
node.typeParameters = parseTypeParameters();
node.heritageClauses = parseHeritageClauses(/*isClassHeritageClause*/ true);
@@ -4825,7 +4825,22 @@ namespace ts {
return finishNode(node);
}
function parseNameOfClassDeclarationOrExpression(): Identifier {
// implements is a future reserved word so
// 'class implements' might mean either
// - class expression with omitted name, 'implements' starts heritage clause
// - class with name 'implements'
// 'isImplementsClause' helps to disambiguate between these two cases
return isIdentifier() && !isImplementsClause()
? parseIdentifier()
: undefined;
}
function isImplementsClause() {
return token === SyntaxKind.ImplementsKeyword && lookAhead(nextTokenIsIdentifierOrKeyword)
}
function parseHeritageClauses(isClassHeritageClause: boolean): NodeArray<HeritageClause> {
// ClassTail[Yield,Await] : (Modified) See 14.5
// ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt }
+55 -51
View File
@@ -568,7 +568,9 @@ namespace ts {
}
function getSourceFile(fileName: string) {
return filesByName.get(fileName);
// first try to use file name as is to find file
// then try to convert relative file name to absolute and use it to retrieve source file
return filesByName.get(fileName) || filesByName.get(getNormalizedAbsolutePath(fileName, host.getCurrentDirectory()));
}
function getDiagnosticsHelper(
@@ -775,60 +777,62 @@ namespace ts {
// Get source file from normalized fileName
function findSourceFile(fileName: string, isDefaultLib: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number): SourceFile {
let canonicalName = host.getCanonicalFileName(normalizeSlashes(fileName));
if (filesByName.contains(canonicalName)) {
if (filesByName.contains(fileName)) {
// We've already looked for this file, use cached result
return getSourceFileFromCache(fileName, canonicalName, /*useAbsolutePath*/ false);
return getSourceFileFromCache(fileName, /*useAbsolutePath*/ false);
}
else {
let normalizedAbsolutePath = getNormalizedAbsolutePath(fileName, host.getCurrentDirectory());
let canonicalAbsolutePath = host.getCanonicalFileName(normalizedAbsolutePath);
if (filesByName.contains(canonicalAbsolutePath)) {
return getSourceFileFromCache(normalizedAbsolutePath, canonicalAbsolutePath, /*useAbsolutePath*/ true);
}
// We haven't looked for this file, do so now and cache result
let file = host.getSourceFile(fileName, options.target, hostErrorMessage => {
if (refFile !== undefined && refPos !== undefined && refEnd !== undefined) {
fileProcessingDiagnostics.add(createFileDiagnostic(refFile, refPos, refEnd - refPos,
Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage));
}
else {
fileProcessingDiagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage));
}
});
filesByName.set(canonicalName, file);
if (file) {
skipDefaultLib = skipDefaultLib || file.hasNoDefaultLib;
// Set the source file for normalized absolute path
filesByName.set(canonicalAbsolutePath, file);
let basePath = getDirectoryPath(fileName);
if (!options.noResolve) {
processReferencedFiles(file, basePath);
}
// always process imported modules to record module name resolutions
processImportedModules(file, basePath);
if (isDefaultLib) {
file.isDefaultLib = true;
files.unshift(file);
}
else {
files.push(file);
}
}
let normalizedAbsolutePath = getNormalizedAbsolutePath(fileName, host.getCurrentDirectory());
if (filesByName.contains(normalizedAbsolutePath)) {
const file = getSourceFileFromCache(normalizedAbsolutePath, /*useAbsolutePath*/ true);
// we don't have resolution for this relative file name but the match was found by absolute file name
// store resolution for relative name as well
filesByName.set(fileName, file);
return file;
}
function getSourceFileFromCache(fileName: string, canonicalName: string, useAbsolutePath: boolean): SourceFile {
let file = filesByName.get(canonicalName);
// We haven't looked for this file, do so now and cache result
let file = host.getSourceFile(fileName, options.target, hostErrorMessage => {
if (refFile !== undefined && refPos !== undefined && refEnd !== undefined) {
fileProcessingDiagnostics.add(createFileDiagnostic(refFile, refPos, refEnd - refPos,
Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage));
}
else {
fileProcessingDiagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage));
}
});
filesByName.set(fileName, file);
if (file) {
skipDefaultLib = skipDefaultLib || file.hasNoDefaultLib;
// Set the source file for normalized absolute path
filesByName.set(normalizedAbsolutePath, file);
let basePath = getDirectoryPath(fileName);
if (!options.noResolve) {
processReferencedFiles(file, basePath);
}
// always process imported modules to record module name resolutions
processImportedModules(file, basePath);
if (isDefaultLib) {
file.isDefaultLib = true;
files.unshift(file);
}
else {
files.push(file);
}
}
return file;
function getSourceFileFromCache(fileName: string, useAbsolutePath: boolean): SourceFile {
let file = filesByName.get(fileName);
if (file && host.useCaseSensitiveFileNames()) {
let sourceFileName = useAbsolutePath ? getNormalizedAbsolutePath(file.fileName, host.getCurrentDirectory()) : file.fileName;
if (canonicalName !== sourceFileName) {
if (normalizeSlashes(fileName) !== normalizeSlashes(sourceFileName)) {
if (refFile !== undefined && refPos !== undefined && refEnd !== undefined) {
fileProcessingDiagnostics.add(createFileDiagnostic(refFile, refPos, refEnd - refPos,
Diagnostics.File_name_0_differs_from_already_included_file_name_1_only_in_casing, fileName, sourceFileName));
@@ -1022,9 +1026,9 @@ namespace ts {
programDiagnostics.add(createFileDiagnostic(firstExternalModuleSourceFile, span.start, span.length, Diagnostics.Cannot_compile_modules_unless_the_module_flag_is_provided));
}
// Cannot specify module gen target when in es6 or above
if (options.module && languageVersion >= ScriptTarget.ES6) {
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_compile_modules_into_commonjs_amd_system_or_umd_when_targeting_ES6_or_higher));
// Cannot specify module gen target of es6 when below es6
if (options.module === ModuleKind.ES6 && languageVersion < ScriptTarget.ES6) {
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_compile_modules_into_es6_when_targeting_ES5_or_lower));
}
// there has to be common source directory if user specified --outdir || --sourceRoot
+7 -19
View File
@@ -739,18 +739,6 @@ namespace ts {
}
}
function isIdentifierStart(ch: number): boolean {
return ch >= CharacterCodes.A && ch <= CharacterCodes.Z || ch >= CharacterCodes.a && ch <= CharacterCodes.z ||
ch === CharacterCodes.$ || ch === CharacterCodes._ ||
ch > CharacterCodes.maxAsciiCharacter && isUnicodeIdentifierStart(ch, languageVersion);
}
function isIdentifierPart(ch: number): boolean {
return ch >= CharacterCodes.A && ch <= CharacterCodes.Z || ch >= CharacterCodes.a && ch <= CharacterCodes.z ||
ch >= CharacterCodes._0 && ch <= CharacterCodes._9 || ch === CharacterCodes.$ || ch === CharacterCodes._ ||
ch > CharacterCodes.maxAsciiCharacter && isUnicodeIdentifierPart(ch, languageVersion);
}
function scanNumber(): number {
let start = pos;
while (isDigit(text.charCodeAt(pos))) pos++;
@@ -1064,12 +1052,12 @@ namespace ts {
let start = pos;
while (pos < end) {
let ch = text.charCodeAt(pos);
if (isIdentifierPart(ch)) {
if (isIdentifierPart(ch, languageVersion)) {
pos++;
}
else if (ch === CharacterCodes.backslash) {
ch = peekUnicodeEscape();
if (!(ch >= 0 && isIdentifierPart(ch))) {
if (!(ch >= 0 && isIdentifierPart(ch, languageVersion))) {
break;
}
result += text.substring(start, pos);
@@ -1439,7 +1427,7 @@ namespace ts {
return pos++, token = SyntaxKind.AtToken;
case CharacterCodes.backslash:
let cookedChar = peekUnicodeEscape();
if (cookedChar >= 0 && isIdentifierStart(cookedChar)) {
if (cookedChar >= 0 && isIdentifierStart(cookedChar, languageVersion)) {
pos += 6;
tokenValue = String.fromCharCode(cookedChar) + scanIdentifierParts();
return token = getIdentifierToken();
@@ -1447,9 +1435,9 @@ namespace ts {
error(Diagnostics.Invalid_character);
return pos++, token = SyntaxKind.Unknown;
default:
if (isIdentifierStart(ch)) {
if (isIdentifierStart(ch, languageVersion)) {
pos++;
while (pos < end && isIdentifierPart(ch = text.charCodeAt(pos))) pos++;
while (pos < end && isIdentifierPart(ch = text.charCodeAt(pos), languageVersion)) pos++;
tokenValue = text.substring(tokenPos, pos);
if (ch === CharacterCodes.backslash) {
tokenValue += scanIdentifierParts();
@@ -1536,7 +1524,7 @@ namespace ts {
p++;
}
while (p < end && isIdentifierPart(text.charCodeAt(p))) {
while (p < end && isIdentifierPart(text.charCodeAt(p), languageVersion)) {
p++;
}
pos = p;
@@ -1599,7 +1587,7 @@ namespace ts {
let firstCharPosition = pos;
while (pos < end) {
let ch = text.charCodeAt(pos);
if (ch === CharacterCodes.minus || ((firstCharPosition === pos) ? isIdentifierStart(ch) : isIdentifierPart(ch))) {
if (ch === CharacterCodes.minus || ((firstCharPosition === pos) ? isIdentifierStart(ch, languageVersion) : isIdentifierPart(ch, languageVersion))) {
pos++;
}
else {
+1
View File
@@ -2076,6 +2076,7 @@ namespace ts {
AMD = 2,
UMD = 3,
System = 4,
ES6 = 5,
}
export const enum JsxEmit {
+1 -1
View File
@@ -621,7 +621,7 @@ namespace ts {
return node && (node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression);
}
export function isFunctionLike(node: Node): boolean {
export function isFunctionLike(node: Node): node is FunctionLikeDeclaration {
if (node) {
switch (node.kind) {
case SyntaxKind.Constructor:
+8 -1
View File
@@ -1908,7 +1908,7 @@ module FourSlash {
}
if (actual.newText !== expected.newText) {
this.raiseError(name + ' failed - expected insertion:\n' + expected.newText + '\nactual insertion:\n' + actual.newText);
this.raiseError(name + ' failed - expected insertion:\n' + this.clarifyNewlines(expected.newText) + '\nactual insertion:\n' + this.clarifyNewlines(actual.newText));
}
if (actual.caretOffset !== expected.caretOffset) {
@@ -1917,6 +1917,13 @@ module FourSlash {
}
}
private clarifyNewlines(str: string) {
return str.replace(/\r?\n/g, lineEnding => {
const representation = lineEnding === "\r\n" ? "CRLF" : "LF";
return "# - " + representation + lineEnding;
});
}
public verifyMatchingBracePosition(bracePosition: number, expectedMatchPosition: number) {
this.taoInvalidReason = "verifyMatchingBracePosition NYI";
+19 -2
View File
@@ -3,8 +3,14 @@
/* @internal */
namespace ts.formatting {
let scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false);
const standardScanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false, LanguageVariant.Standard);
const jsxScanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false, LanguageVariant.JSX);
/**
* Scanner that is currently used for formatting
*/
let scanner: Scanner;
export interface FormattingScanner {
advance(): void;
isOnToken(): boolean;
@@ -22,6 +28,8 @@ namespace ts.formatting {
}
export function getFormattingScanner(sourceFile: SourceFile, startPos: number, endPos: number): FormattingScanner {
Debug.assert(scanner === undefined);
scanner = sourceFile.languageVariant === LanguageVariant.JSX ? jsxScanner : standardScanner;
scanner.setText(sourceFile.text);
scanner.setTextPos(startPos);
@@ -40,12 +48,17 @@ namespace ts.formatting {
isOnToken: isOnToken,
lastTrailingTriviaWasNewLine: () => wasNewLine,
close: () => {
Debug.assert(scanner !== undefined);
lastTokenInfo = undefined;
scanner.setText(undefined);
scanner = undefined;
}
}
function advance(): void {
Debug.assert(scanner !== undefined);
lastTokenInfo = undefined;
let isStarted = scanner.getStartPos() !== startPos;
@@ -138,6 +151,8 @@ namespace ts.formatting {
}
function readTokenInfo(n: Node): TokenInfo {
Debug.assert(scanner !== undefined);
if (!isOnToken()) {
// scanner is not on the token (either advance was not called yet or scanner is already past the end position)
return {
@@ -245,6 +260,8 @@ namespace ts.formatting {
}
function isOnToken(): boolean {
Debug.assert(scanner !== undefined);
let current = (lastTokenInfo && lastTokenInfo.token.kind) || scanner.getToken();
let startPos = (lastTokenInfo && lastTokenInfo.token.pos) || scanner.getStartPos();
return startPos < endPos && current !== SyntaxKind.EndOfFileToken && !isTrivia(current);
+91 -11
View File
@@ -3549,6 +3549,9 @@ namespace ts {
if (parent && (parent.kind === SyntaxKind.JsxSelfClosingElement || parent.kind === SyntaxKind.JsxOpeningElement)) {
return <JsxOpeningLikeElement>parent;
}
else if (parent.kind === SyntaxKind.JsxAttribute) {
return <JsxOpeningLikeElement>parent.parent;
}
break;
// The context token is the closing } or " of an attribute, which means
@@ -6997,8 +7000,12 @@ namespace ts {
* Checks if position points to a valid position to add JSDoc comments, and if so,
* returns the appropriate template. Otherwise returns an empty string.
* Valid positions are
* - outside of comments, statements, and expressions, and
* - preceding a function declaration.
* - outside of comments, statements, and expressions, and
* - preceding a:
* - function/constructor/method declaration
* - class declarations
* - variable statements
* - namespace declarations
*
* Hosts should ideally check that:
* - The line is all whitespace up to 'position' before performing the insertion.
@@ -7025,16 +7032,37 @@ namespace ts {
}
// TODO: add support for:
// - methods
// - constructors
// - class decls
let containingFunction = <FunctionDeclaration>getAncestor(tokenAtPos, SyntaxKind.FunctionDeclaration);
// - enums/enum members
// - interfaces
// - property declarations
// - potentially property assignments
let commentOwner: Node;
findOwner: for (commentOwner = tokenAtPos; commentOwner; commentOwner = commentOwner.parent) {
switch (commentOwner.kind) {
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.MethodDeclaration:
case SyntaxKind.Constructor:
case SyntaxKind.ClassDeclaration:
case SyntaxKind.VariableStatement:
break findOwner;
case SyntaxKind.SourceFile:
return undefined;
case SyntaxKind.ModuleDeclaration:
// If in walking up the tree, we hit a a nested namespace declaration,
// then we must be somewhere within a dotted namespace name; however we don't
// want to give back a JSDoc template for the 'b' or 'c' in 'namespace a.b.c { }'.
if (commentOwner.parent.kind === SyntaxKind.ModuleDeclaration) {
return undefined;
}
break findOwner;
}
}
if (!containingFunction || containingFunction.getStart() < position) {
if (!commentOwner || commentOwner.getStart() < position) {
return undefined;
}
let parameters = containingFunction.parameters;
let parameters = getParametersForJsDocOwningNode(commentOwner);
let posLineAndChar = sourceFile.getLineAndCharacterOfPosition(position);
let lineStart = sourceFile.getLineStarts()[posLineAndChar.line];
@@ -7043,9 +7071,15 @@ namespace ts {
// TODO: call a helper method instead once PR #4133 gets merged in.
const newLine = host.getNewLine ? host.getNewLine() : "\r\n";
let docParams = parameters.reduce((prev, cur, index) =>
prev +
indentationStr + " * @param " + (cur.name.kind === SyntaxKind.Identifier ? (<Identifier>cur.name).text : "param" + index) + newLine, "");
let docParams = "";
for (let i = 0, numParams = parameters.length; i < numParams; i++) {
const currentName = parameters[i].name;
const paramName = currentName.kind === SyntaxKind.Identifier ?
(<Identifier>currentName).text :
"param" + i;
docParams += `${indentationStr} * @param ${paramName}${newLine}`;
}
// A doc comment consists of the following
// * The opening comment line
@@ -7065,6 +7099,52 @@ namespace ts {
return { newText: result, caretOffset: preamble.length };
}
function getParametersForJsDocOwningNode(commentOwner: Node): ParameterDeclaration[] {
if (isFunctionLike(commentOwner)) {
return commentOwner.parameters;
}
if (commentOwner.kind === SyntaxKind.VariableStatement) {
const varStatement = <VariableStatement>commentOwner;
const varDeclarations = varStatement.declarationList.declarations;
if (varDeclarations.length === 1 && varDeclarations[0].initializer) {
return getParametersFromRightHandSideOfAssignment(varDeclarations[0].initializer);
}
}
return emptyArray;
}
/**
* Digs into an an initializer or RHS operand of an assignment operation
* to get the parameters of an apt signature corresponding to a
* function expression or a class expression.
*
* @param rightHandSide the expression which may contain an appropriate set of parameters
* @returns the parameters of a signature found on the RHS if one exists; otherwise 'emptyArray'.
*/
function getParametersFromRightHandSideOfAssignment(rightHandSide: Expression): ParameterDeclaration[] {
while (rightHandSide.kind === SyntaxKind.ParenthesizedExpression) {
rightHandSide = (<ParenthesizedExpression>rightHandSide).expression;
}
switch (rightHandSide.kind) {
case SyntaxKind.FunctionExpression:
case SyntaxKind.ArrowFunction:
return (<FunctionExpression>rightHandSide).parameters;
case SyntaxKind.ClassExpression:
for (let member of (<ClassExpression>rightHandSide).members) {
if (member.kind === SyntaxKind.Constructor) {
return (<ConstructorDeclaration>member).parameters;
}
}
break;
}
return emptyArray;
}
function getTodoComments(fileName: string, descriptors: TodoCommentDescriptor[]): TodoComment[] {
// Note: while getting todo comments seems like a syntactic operation, we actually
// treat it as a semantic operation here. This is because we expect our host to call