mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into release-2.1
This commit is contained in:
+14
-6
@@ -4612,8 +4612,8 @@ namespace ts {
|
||||
// the modifiers type is T. Otherwise, the modifiers type is {}.
|
||||
const declaredType = <MappedType>getTypeFromMappedTypeNode(type.declaration);
|
||||
const constraint = getConstraintTypeFromMappedType(declaredType);
|
||||
const extendedConstraint = constraint.flags & TypeFlags.TypeParameter ? getConstraintOfTypeParameter(<TypeParameter>constraint) : constraint;
|
||||
type.modifiersType = extendedConstraint.flags & TypeFlags.Index ? instantiateType((<IndexType>extendedConstraint).type, type.mapper || identityMapper) : emptyObjectType;
|
||||
const extendedConstraint = constraint && constraint.flags & TypeFlags.TypeParameter ? getConstraintOfTypeParameter(<TypeParameter>constraint) : constraint;
|
||||
type.modifiersType = extendedConstraint && extendedConstraint.flags & TypeFlags.Index ? instantiateType((<IndexType>extendedConstraint).type, type.mapper || identityMapper) : emptyObjectType;
|
||||
}
|
||||
}
|
||||
return type.modifiersType;
|
||||
@@ -7730,8 +7730,11 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (relation !== identityRelation && isEmptyObjectType(resolveStructuredTypeMembers(<ObjectType>target))) {
|
||||
return Ternary.True;
|
||||
else if (relation !== identityRelation) {
|
||||
const resolved = resolveStructuredTypeMembers(<ObjectType>target);
|
||||
if (isEmptyObjectType(resolved) || resolved.stringIndexInfo && resolved.stringIndexInfo.type.flags & TypeFlags.Any) {
|
||||
return Ternary.True;
|
||||
}
|
||||
}
|
||||
return Ternary.False;
|
||||
}
|
||||
@@ -21845,8 +21848,13 @@ namespace ts {
|
||||
|
||||
function checkGrammarNumericLiteral(node: NumericLiteral): boolean {
|
||||
// Grammar checking
|
||||
if (node.isOctalLiteral && languageVersion >= ScriptTarget.ES5) {
|
||||
return grammarErrorOnNode(node, Diagnostics.Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher);
|
||||
if (node.isOctalLiteral) {
|
||||
if (languageVersion >= ScriptTarget.ES5) {
|
||||
return grammarErrorOnNode(node, Diagnostics.Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher_Use_the_syntax_0o_0, node.text);
|
||||
}
|
||||
if (isChildOfLiteralType(node)) {
|
||||
return grammarErrorOnNode(node, Diagnostics.Octal_literal_types_must_use_ES2015_syntax_Use_the_syntax_0o_0, node.text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -572,7 +572,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function parseCommandLine(commandLine: string[], readFile?: (path: string) => string): ParsedCommandLine {
|
||||
const options: CompilerOptions = {};
|
||||
const fileNames: string[] = [];
|
||||
|
||||
@@ -227,7 +227,7 @@
|
||||
"category": "Error",
|
||||
"code": 1084
|
||||
},
|
||||
"Octal literals are not available when targeting ECMAScript 5 and higher.": {
|
||||
"Octal literals are not available when targeting ECMAScript 5 and higher. Use the syntax '0o{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 1085
|
||||
},
|
||||
@@ -2685,6 +2685,10 @@
|
||||
"category": "Message",
|
||||
"code": 6080
|
||||
},
|
||||
"File '{0}' has an unsupported extension, so skipping it.": {
|
||||
"category": "Message",
|
||||
"code": 6081
|
||||
},
|
||||
"Only 'amd' and 'system' modules are supported alongside --{0}.": {
|
||||
"category": "Error",
|
||||
"code": 6082
|
||||
@@ -2945,6 +2949,10 @@
|
||||
"category": "Message",
|
||||
"code": 6146
|
||||
},
|
||||
"Resolution for module '{0}' was found in cache": {
|
||||
"category": "Message",
|
||||
"code": 6147
|
||||
},
|
||||
"Variable '{0}' implicitly has an '{1}' type.": {
|
||||
"category": "Error",
|
||||
"code": 7005
|
||||
@@ -3234,5 +3242,9 @@
|
||||
"Add {0} to existing import declaration from {1}": {
|
||||
"category": "Message",
|
||||
"code": 90015
|
||||
},
|
||||
"Octal literal types must use ES2015 syntax. Use the syntax '0o{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 8017
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,11 +47,6 @@ namespace ts {
|
||||
return resolved.path;
|
||||
}
|
||||
|
||||
/** Create Resolved from a file with unknown extension. */
|
||||
function resolvedFromAnyFile(path: string): Resolved | undefined {
|
||||
return { path, extension: extensionFromPath(path) };
|
||||
}
|
||||
|
||||
/** Adds `isExernalLibraryImport` to a Resolved to get a ResolvedModule. */
|
||||
function resolvedModuleFromResolved({ path, extension }: Resolved, isExternalLibraryImport: boolean): ResolvedModuleFull {
|
||||
return { resolvedFileName: path, extension, isExternalLibraryImport };
|
||||
@@ -71,7 +66,8 @@ namespace ts {
|
||||
traceEnabled: boolean;
|
||||
}
|
||||
|
||||
function tryReadTypesSection(extensions: Extensions, packageJsonPath: string, baseDirectory: string, state: ModuleResolutionState): string {
|
||||
/** Reads from "main" or "types"/"typings" depending on `extensions`. */
|
||||
function tryReadPackageJsonMainOrTypes(extensions: Extensions, packageJsonPath: string, baseDirectory: string, state: ModuleResolutionState): string {
|
||||
const jsonContent = readJson(packageJsonPath, state.host);
|
||||
|
||||
switch (extensions) {
|
||||
@@ -293,33 +289,69 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
export function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations {
|
||||
/**
|
||||
* Cached module resolutions per containing directory.
|
||||
* This assumes that any module id will have the same resolution for sibling files located in the same folder.
|
||||
*/
|
||||
export interface ModuleResolutionCache {
|
||||
getOrCreateCacheForDirectory(directoryName: string): Map<ResolvedModuleWithFailedLookupLocations>;
|
||||
}
|
||||
|
||||
export function createModuleResolutionCache(currentDirectory: string, getCanonicalFileName: (s: string) => string) {
|
||||
const map = createFileMap<Map<ResolvedModuleWithFailedLookupLocations>>();
|
||||
|
||||
return { getOrCreateCacheForDirectory };
|
||||
|
||||
function getOrCreateCacheForDirectory(directoryName: string) {
|
||||
const path = toPath(directoryName, currentDirectory, getCanonicalFileName);
|
||||
let perFolderCache = map.get(path);
|
||||
if (!perFolderCache) {
|
||||
perFolderCache = createMap<ResolvedModuleWithFailedLookupLocations>();
|
||||
map.set(path, perFolderCache);
|
||||
}
|
||||
return perFolderCache;
|
||||
}
|
||||
}
|
||||
|
||||
export function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations {
|
||||
const traceEnabled = isTraceEnabled(compilerOptions, host);
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Resolving_module_0_from_1, moduleName, containingFile);
|
||||
}
|
||||
const perFolderCache = cache && cache.getOrCreateCacheForDirectory(getDirectoryPath(containingFile));
|
||||
let result = perFolderCache && perFolderCache[moduleName];
|
||||
|
||||
let moduleResolution = compilerOptions.moduleResolution;
|
||||
if (moduleResolution === undefined) {
|
||||
moduleResolution = getEmitModuleKind(compilerOptions) === ModuleKind.CommonJS ? ModuleResolutionKind.NodeJs : ModuleResolutionKind.Classic;
|
||||
if (result) {
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Module_resolution_kind_is_not_specified_using_0, ModuleResolutionKind[moduleResolution]);
|
||||
trace(host, Diagnostics.Resolution_for_module_0_was_found_in_cache, moduleName);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Explicitly_specified_module_resolution_kind_Colon_0, ModuleResolutionKind[moduleResolution]);
|
||||
let moduleResolution = compilerOptions.moduleResolution;
|
||||
if (moduleResolution === undefined) {
|
||||
moduleResolution = getEmitModuleKind(compilerOptions) === ModuleKind.CommonJS ? ModuleResolutionKind.NodeJs : ModuleResolutionKind.Classic;
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Module_resolution_kind_is_not_specified_using_0, ModuleResolutionKind[moduleResolution]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Explicitly_specified_module_resolution_kind_Colon_0, ModuleResolutionKind[moduleResolution]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let result: ResolvedModuleWithFailedLookupLocations;
|
||||
switch (moduleResolution) {
|
||||
case ModuleResolutionKind.NodeJs:
|
||||
result = nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host);
|
||||
break;
|
||||
case ModuleResolutionKind.Classic:
|
||||
result = classicNameResolver(moduleName, containingFile, compilerOptions, host);
|
||||
break;
|
||||
switch (moduleResolution) {
|
||||
case ModuleResolutionKind.NodeJs:
|
||||
result = nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host);
|
||||
break;
|
||||
case ModuleResolutionKind.Classic:
|
||||
result = classicNameResolver(moduleName, containingFile, compilerOptions, host);
|
||||
break;
|
||||
}
|
||||
|
||||
if (perFolderCache) {
|
||||
perFolderCache[moduleName] = result;
|
||||
}
|
||||
}
|
||||
|
||||
if (traceEnabled) {
|
||||
@@ -678,18 +710,21 @@ namespace ts {
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.Found_package_json_at_0, packageJsonPath);
|
||||
}
|
||||
const typesFile = tryReadTypesSection(extensions, packageJsonPath, candidate, state);
|
||||
if (typesFile) {
|
||||
const onlyRecordFailures = !directoryProbablyExists(getDirectoryPath(typesFile), state.host);
|
||||
const mainOrTypesFile = tryReadPackageJsonMainOrTypes(extensions, packageJsonPath, candidate, state);
|
||||
if (mainOrTypesFile) {
|
||||
const onlyRecordFailures = !directoryProbablyExists(getDirectoryPath(mainOrTypesFile), state.host);
|
||||
// A package.json "typings" may specify an exact filename, or may choose to omit an extension.
|
||||
const fromFile = tryFile(typesFile, failedLookupLocations, onlyRecordFailures, state);
|
||||
if (fromFile) {
|
||||
// Note: this would allow a package.json to specify a ".js" file as typings. Maybe that should be forbidden.
|
||||
return resolvedFromAnyFile(fromFile);
|
||||
const fromExactFile = tryFile(mainOrTypesFile, failedLookupLocations, onlyRecordFailures, state);
|
||||
if (fromExactFile) {
|
||||
const resolved = fromExactFile && resolvedIfExtensionMatches(extensions, fromExactFile);
|
||||
if (resolved) {
|
||||
return resolved;
|
||||
}
|
||||
trace(state.host, Diagnostics.File_0_has_an_unsupported_extension_so_skipping_it, fromExactFile);
|
||||
}
|
||||
const x = tryAddingExtensions(typesFile, Extensions.TypeScript, failedLookupLocations, onlyRecordFailures, state);
|
||||
if (x) {
|
||||
return x;
|
||||
const resolved = tryAddingExtensions(mainOrTypesFile, Extensions.TypeScript, failedLookupLocations, onlyRecordFailures, state);
|
||||
if (resolved) {
|
||||
return resolved;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -709,6 +744,24 @@ namespace ts {
|
||||
return loadModuleFromFile(extensions, combinePaths(candidate, "index"), failedLookupLocations, !directoryExists, state);
|
||||
}
|
||||
|
||||
/** Resolve from an arbitrarily specified file. Return `undefined` if it has an unsupported extension. */
|
||||
function resolvedIfExtensionMatches(extensions: Extensions, path: string): Resolved | undefined {
|
||||
const extension = tryGetExtensionFromPath(path);
|
||||
return extension !== undefined && extensionIsOk(extensions, extension) ? { path, extension } : undefined;
|
||||
}
|
||||
|
||||
/** True if `extension` is one of the supported `extensions`. */
|
||||
function extensionIsOk(extensions: Extensions, extension: Extension): boolean {
|
||||
switch (extensions) {
|
||||
case Extensions.JavaScript:
|
||||
return extension === Extension.Js || extension === Extension.Jsx;
|
||||
case Extensions.TypeScript:
|
||||
return extension === Extension.Ts || extension === Extension.Tsx || extension === Extension.Dts;
|
||||
case Extensions.DtsOnly:
|
||||
return extension === Extension.Dts;
|
||||
}
|
||||
}
|
||||
|
||||
function pathToPackageJson(directory: string): string {
|
||||
return combinePaths(directory, "package.json");
|
||||
}
|
||||
|
||||
@@ -325,6 +325,7 @@ namespace ts {
|
||||
// Map storing if there is emit blocking diagnostics for given input
|
||||
const hasEmitBlockingDiagnostics = createFileMap<boolean>(getCanonicalFileName);
|
||||
|
||||
let moduleResolutionCache: ModuleResolutionCache;
|
||||
let resolveModuleNamesWorker: (moduleNames: string[], containingFile: string) => ResolvedModuleFull[];
|
||||
if (host.resolveModuleNames) {
|
||||
resolveModuleNamesWorker = (moduleNames, containingFile) => host.resolveModuleNames(moduleNames, containingFile).map(resolved => {
|
||||
@@ -338,7 +339,8 @@ namespace ts {
|
||||
});
|
||||
}
|
||||
else {
|
||||
const loader = (moduleName: string, containingFile: string) => resolveModuleName(moduleName, containingFile, options, host).resolvedModule;
|
||||
moduleResolutionCache = createModuleResolutionCache(currentDirectory, x => host.getCanonicalFileName(x));
|
||||
const loader = (moduleName: string, containingFile: string) => resolveModuleName(moduleName, containingFile, options, host, moduleResolutionCache).resolvedModule;
|
||||
resolveModuleNamesWorker = (moduleNames, containingFile) => loadWithLocalCache(moduleNames, containingFile, loader);
|
||||
}
|
||||
|
||||
@@ -391,6 +393,9 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
// unconditionally set moduleResolutionCache to undefined to avoid unnecessary leaks
|
||||
moduleResolutionCache = undefined;
|
||||
|
||||
// unconditionally set oldProgram to undefined to prevent it from being captured in closure
|
||||
oldProgram = undefined;
|
||||
|
||||
|
||||
@@ -2290,7 +2290,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
startLexicalEnvironment();
|
||||
let loopBody = visitNode(node.statement, visitor, isStatement);
|
||||
let loopBody = visitNode(node.statement, visitor, isStatement, /*optional*/ false, liftToBlock);
|
||||
const lexicalEnvironment = endLexicalEnvironment();
|
||||
|
||||
const currentState = convertedLoopState;
|
||||
@@ -2305,7 +2305,10 @@ namespace ts {
|
||||
loopBody = createBlock(statements, /*location*/ undefined, /*multiline*/ true);
|
||||
}
|
||||
|
||||
if (!isBlock(loopBody)) {
|
||||
if (isBlock(loopBody)) {
|
||||
loopBody.multiLine = true;
|
||||
}
|
||||
else {
|
||||
loopBody = createBlock([loopBody], /*location*/ undefined, /*multiline*/ true);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,20 @@ namespace ts {
|
||||
* @param context Context and state information for the transformation.
|
||||
*/
|
||||
export function transformES5(context: TransformationContext) {
|
||||
const compilerOptions = context.getCompilerOptions();
|
||||
|
||||
// enable emit notification only if using --jsx preserve
|
||||
let previousOnEmitNode: (emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) => void;
|
||||
let noSubstitution: boolean[];
|
||||
if (compilerOptions.jsx === JsxEmit.Preserve) {
|
||||
previousOnEmitNode = context.onEmitNode;
|
||||
context.onEmitNode = onEmitNode;
|
||||
context.enableEmitNotification(SyntaxKind.JsxOpeningElement);
|
||||
context.enableEmitNotification(SyntaxKind.JsxClosingElement);
|
||||
context.enableEmitNotification(SyntaxKind.JsxSelfClosingElement);
|
||||
noSubstitution = [];
|
||||
}
|
||||
|
||||
const previousOnSubstituteNode = context.onSubstituteNode;
|
||||
context.onSubstituteNode = onSubstituteNode;
|
||||
context.enableSubstitution(SyntaxKind.PropertyAccessExpression);
|
||||
@@ -24,6 +38,24 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the printer just before a node is printed.
|
||||
*
|
||||
* @param node The node to be printed.
|
||||
*/
|
||||
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.JsxOpeningElement:
|
||||
case SyntaxKind.JsxClosingElement:
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
const tagName = (<JsxOpeningElement | JsxClosingElement | JsxSelfClosingElement>node).tagName;
|
||||
noSubstitution[getOriginalNodeId(tagName)] = true;
|
||||
break;
|
||||
}
|
||||
|
||||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks node substitutions.
|
||||
*
|
||||
@@ -31,6 +63,10 @@ namespace ts {
|
||||
* @param node The node to substitute.
|
||||
*/
|
||||
function onSubstituteNode(emitContext: EmitContext, node: Node) {
|
||||
if (node.id && noSubstitution && noSubstitution[node.id]) {
|
||||
return previousOnSubstituteNode(emitContext, node);
|
||||
}
|
||||
|
||||
node = previousOnSubstituteNode(emitContext, node);
|
||||
if (isPropertyAccessExpression(node)) {
|
||||
return substitutePropertyAccessExpression(node);
|
||||
|
||||
@@ -732,6 +732,16 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
export function isChildOfLiteralType(node: Node): boolean {
|
||||
while (node) {
|
||||
if (node.kind === SyntaxKind.LiteralType) {
|
||||
return true;
|
||||
}
|
||||
node = node.parent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Warning: This has the same semantics as the forEach family of functions,
|
||||
// in that traversal terminates in the event that 'visitor' supplies a truthy value.
|
||||
export function forEachReturnStatement<T>(body: Block, visitor: (stmt: ReturnStatement) => T): T {
|
||||
|
||||
@@ -341,6 +341,7 @@ namespace FourSlash {
|
||||
insertSpaceAfterCommaDelimiter: true,
|
||||
insertSpaceAfterSemicolonInForStatements: true,
|
||||
insertSpaceBeforeAndAfterBinaryOperators: true,
|
||||
insertSpaceAfterConstructor: false,
|
||||
insertSpaceAfterKeywordsInControlFlowStatements: true,
|
||||
insertSpaceAfterFunctionKeywordForAnonymousFunctions: false,
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false,
|
||||
|
||||
@@ -2209,12 +2209,14 @@ namespace ts.server.protocol {
|
||||
insertSpaceAfterCommaDelimiter?: boolean;
|
||||
insertSpaceAfterSemicolonInForStatements?: boolean;
|
||||
insertSpaceBeforeAndAfterBinaryOperators?: boolean;
|
||||
insertSpaceAfterConstructor?: boolean;
|
||||
insertSpaceAfterKeywordsInControlFlowStatements?: boolean;
|
||||
insertSpaceAfterFunctionKeywordForAnonymousFunctions?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces?: boolean;
|
||||
insertSpaceBeforeFunctionParenthesis?: boolean;
|
||||
placeOpenBraceOnNewLineForFunctions?: boolean;
|
||||
placeOpenBraceOnNewLineForControlBlocks?: boolean;
|
||||
}
|
||||
|
||||
@@ -78,6 +78,7 @@ namespace ts.server {
|
||||
newLineCharacter: host.newLine || "\n",
|
||||
convertTabsToSpaces: true,
|
||||
indentStyle: ts.IndentStyle.Smart,
|
||||
insertSpaceAfterConstructor: false,
|
||||
insertSpaceAfterCommaDelimiter: true,
|
||||
insertSpaceAfterSemicolonInForStatements: true,
|
||||
insertSpaceBeforeAndAfterBinaryOperators: true,
|
||||
@@ -87,6 +88,7 @@ namespace ts.server {
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false,
|
||||
insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false,
|
||||
insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false,
|
||||
insertSpaceBeforeFunctionParenthesis: false,
|
||||
placeOpenBraceOnNewLineForFunctions: false,
|
||||
placeOpenBraceOnNewLineForControlBlocks: false,
|
||||
};
|
||||
|
||||
@@ -87,6 +87,7 @@ namespace ts.formatting {
|
||||
public SpaceAfterLetConstInVariableDeclaration: Rule;
|
||||
public NoSpaceBeforeOpenParenInFuncCall: Rule;
|
||||
public SpaceAfterFunctionInFuncDecl: Rule;
|
||||
public SpaceBeforeOpenParenInFuncDecl: Rule;
|
||||
public NoSpaceBeforeOpenParenInFuncDecl: Rule;
|
||||
public SpaceAfterVoidOperator: Rule;
|
||||
|
||||
@@ -112,6 +113,7 @@ namespace ts.formatting {
|
||||
// TypeScript-specific rules
|
||||
|
||||
// Treat constructor as an identifier in a function declaration, and remove spaces between constructor and following left parentheses
|
||||
public SpaceAfterConstructor: Rule;
|
||||
public NoSpaceAfterConstructor: Rule;
|
||||
|
||||
// Use of module as a function call. e.g.: import m2 = module("m2");
|
||||
@@ -329,6 +331,7 @@ namespace ts.formatting {
|
||||
this.SpaceAfterLetConstInVariableDeclaration = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.LetKeyword, SyntaxKind.ConstKeyword]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsStartOfVariableDeclarationList), RuleAction.Space));
|
||||
this.NoSpaceBeforeOpenParenInFuncCall = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsFunctionCallOrNewContext, Rules.IsPreviousTokenNotComma), RuleAction.Delete));
|
||||
this.SpaceAfterFunctionInFuncDecl = new Rule(RuleDescriptor.create3(SyntaxKind.FunctionKeyword, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsFunctionDeclContext), RuleAction.Space));
|
||||
this.SpaceBeforeOpenParenInFuncDecl = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsFunctionDeclContext), RuleAction.Space));
|
||||
this.NoSpaceBeforeOpenParenInFuncDecl = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsFunctionDeclContext), RuleAction.Delete));
|
||||
this.SpaceAfterVoidOperator = new Rule(RuleDescriptor.create3(SyntaxKind.VoidKeyword, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsVoidOpContext), RuleAction.Space));
|
||||
|
||||
@@ -352,13 +355,14 @@ namespace ts.formatting {
|
||||
// TypeScript-specific higher priority rules
|
||||
|
||||
// Treat constructor as an identifier in a function declaration, and remove spaces between constructor and following left parentheses
|
||||
this.SpaceAfterConstructor = new Rule(RuleDescriptor.create1(SyntaxKind.ConstructorKeyword, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
|
||||
this.NoSpaceAfterConstructor = new Rule(RuleDescriptor.create1(SyntaxKind.ConstructorKeyword, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
|
||||
|
||||
// Use of module as a function call. e.g.: import m2 = module("m2");
|
||||
this.NoSpaceAfterModuleImport = new Rule(RuleDescriptor.create2(Shared.TokenRange.FromTokens([SyntaxKind.ModuleKeyword, SyntaxKind.RequireKeyword]), SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
|
||||
|
||||
// Add a space around certain TypeScript keywords
|
||||
this.SpaceAfterCertainTypeScriptKeywords = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.AbstractKeyword, SyntaxKind.ClassKeyword, SyntaxKind.DeclareKeyword, SyntaxKind.DefaultKeyword, SyntaxKind.EnumKeyword, SyntaxKind.ExportKeyword, SyntaxKind.ExtendsKeyword, SyntaxKind.GetKeyword, SyntaxKind.ImplementsKeyword, SyntaxKind.ImportKeyword, SyntaxKind.InterfaceKeyword, SyntaxKind.ModuleKeyword, SyntaxKind.NamespaceKeyword, SyntaxKind.PrivateKeyword, SyntaxKind.PublicKeyword, SyntaxKind.ProtectedKeyword, SyntaxKind.SetKeyword, SyntaxKind.StaticKeyword, SyntaxKind.TypeKeyword, SyntaxKind.FromKeyword]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
|
||||
this.SpaceAfterCertainTypeScriptKeywords = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.AbstractKeyword, SyntaxKind.ClassKeyword, SyntaxKind.DeclareKeyword, SyntaxKind.DefaultKeyword, SyntaxKind.EnumKeyword, SyntaxKind.ExportKeyword, SyntaxKind.ExtendsKeyword, SyntaxKind.GetKeyword, SyntaxKind.ImplementsKeyword, SyntaxKind.ImportKeyword, SyntaxKind.InterfaceKeyword, SyntaxKind.ModuleKeyword, SyntaxKind.NamespaceKeyword, SyntaxKind.PrivateKeyword, SyntaxKind.PublicKeyword, SyntaxKind.ProtectedKeyword, SyntaxKind.ReadonlyKeyword, SyntaxKind.SetKeyword, SyntaxKind.StaticKeyword, SyntaxKind.TypeKeyword, SyntaxKind.FromKeyword]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
|
||||
this.SpaceBeforeCertainTypeScriptKeywords = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.FromTokens([SyntaxKind.ExtendsKeyword, SyntaxKind.ImplementsKeyword, SyntaxKind.FromKeyword])), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
|
||||
|
||||
// Treat string literals in module names as identifiers, and add a space between the literal and the opening Brace braces, e.g.: module "m2" {
|
||||
@@ -437,7 +441,7 @@ namespace ts.formatting {
|
||||
this.NoSpaceBeforeEqualInJsxAttribute, this.NoSpaceAfterEqualInJsxAttribute,
|
||||
|
||||
// TypeScript-specific rules
|
||||
this.NoSpaceAfterConstructor, this.NoSpaceAfterModuleImport,
|
||||
this.NoSpaceAfterModuleImport,
|
||||
this.SpaceAfterCertainTypeScriptKeywords, this.SpaceBeforeCertainTypeScriptKeywords,
|
||||
this.SpaceAfterModuleName,
|
||||
this.SpaceBeforeArrow, this.SpaceAfterArrow,
|
||||
@@ -462,7 +466,6 @@ namespace ts.formatting {
|
||||
this.NoSpaceBeforeOpenBracket,
|
||||
this.NoSpaceAfterCloseBracket,
|
||||
this.SpaceAfterSemicolon,
|
||||
this.NoSpaceBeforeOpenParenInFuncDecl,
|
||||
this.SpaceBetweenStatements, this.SpaceAfterTryFinally
|
||||
];
|
||||
|
||||
|
||||
@@ -38,6 +38,13 @@ namespace ts.formatting {
|
||||
private createActiveRules(options: ts.FormatCodeSettings): Rule[] {
|
||||
let rules = this.globalRules.HighPriorityCommonRules.slice(0);
|
||||
|
||||
if (options.insertSpaceAfterConstructor) {
|
||||
rules.push(this.globalRules.SpaceAfterConstructor);
|
||||
}
|
||||
else {
|
||||
rules.push(this.globalRules.NoSpaceAfterConstructor);
|
||||
}
|
||||
|
||||
if (options.insertSpaceAfterCommaDelimiter) {
|
||||
rules.push(this.globalRules.SpaceAfterComma);
|
||||
}
|
||||
@@ -128,6 +135,13 @@ namespace ts.formatting {
|
||||
rules.push(this.globalRules.NoSpaceAfterBinaryOperator);
|
||||
}
|
||||
|
||||
if (options.insertSpaceBeforeFunctionParenthesis) {
|
||||
rules.push(this.globalRules.SpaceBeforeOpenParenInFuncDecl);
|
||||
}
|
||||
else {
|
||||
rules.push(this.globalRules.NoSpaceBeforeOpenParenInFuncDecl);
|
||||
}
|
||||
|
||||
if (options.placeOpenBraceOnNewLineForControlBlocks) {
|
||||
rules.push(this.globalRules.NewLineBeforeOpenBraceInControl);
|
||||
}
|
||||
|
||||
@@ -420,6 +420,7 @@ namespace ts {
|
||||
InsertSpaceAfterCommaDelimiter: boolean;
|
||||
InsertSpaceAfterSemicolonInForStatements: boolean;
|
||||
InsertSpaceBeforeAndAfterBinaryOperators: boolean;
|
||||
InsertSpaceAfterConstructor?: boolean;
|
||||
InsertSpaceAfterKeywordsInControlFlowStatements: boolean;
|
||||
InsertSpaceAfterFunctionKeywordForAnonymousFunctions: boolean;
|
||||
InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: boolean;
|
||||
@@ -428,6 +429,7 @@ namespace ts {
|
||||
InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: boolean;
|
||||
InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces?: boolean;
|
||||
InsertSpaceAfterTypeAssertion?: boolean;
|
||||
InsertSpaceBeforeFunctionParenthesis?: boolean;
|
||||
PlaceOpenBraceOnNewLineForFunctions: boolean;
|
||||
PlaceOpenBraceOnNewLineForControlBlocks: boolean;
|
||||
}
|
||||
@@ -436,6 +438,7 @@ namespace ts {
|
||||
insertSpaceAfterCommaDelimiter?: boolean;
|
||||
insertSpaceAfterSemicolonInForStatements?: boolean;
|
||||
insertSpaceBeforeAndAfterBinaryOperators?: boolean;
|
||||
insertSpaceAfterConstructor?: boolean;
|
||||
insertSpaceAfterKeywordsInControlFlowStatements?: boolean;
|
||||
insertSpaceAfterFunctionKeywordForAnonymousFunctions?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis?: boolean;
|
||||
@@ -444,6 +447,7 @@ namespace ts {
|
||||
insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces?: boolean;
|
||||
insertSpaceAfterTypeAssertion?: boolean;
|
||||
insertSpaceBeforeFunctionParenthesis?: boolean;
|
||||
placeOpenBraceOnNewLineForFunctions?: boolean;
|
||||
placeOpenBraceOnNewLineForControlBlocks?: boolean;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user