mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge remote-tracking branch 'Microsoft/master' into tsconfigpath
This commit is contained in:
+53
-50
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 {
|
||||
|
||||
@@ -2076,6 +2076,7 @@ namespace ts {
|
||||
AMD = 2,
|
||||
UMD = 3,
|
||||
System = 4,
|
||||
ES6 = 5,
|
||||
}
|
||||
|
||||
export const enum JsxEmit {
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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";
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user