mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into js-object-literal-assignments-as-declarations
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
workflows:
|
||||
version: 2
|
||||
main:
|
||||
jobs:
|
||||
- node9:
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- release-2.5
|
||||
- release-2.6
|
||||
- release-2.7
|
||||
- circleci
|
||||
- node8:
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- release-2.5
|
||||
- release-2.6
|
||||
- release-2.7
|
||||
- circleci
|
||||
- node6:
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- release-2.5
|
||||
- release-2.6
|
||||
- release-2.7
|
||||
- circleci
|
||||
nightly:
|
||||
triggers:
|
||||
- schedule:
|
||||
cron: "0 8 * * *"
|
||||
filters:
|
||||
branches:
|
||||
only: master
|
||||
jobs:
|
||||
- node9:
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- release-2.5
|
||||
- release-2.6
|
||||
- release-2.7
|
||||
- circleci
|
||||
context: nightlies
|
||||
- node8:
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- release-2.5
|
||||
- release-2.6
|
||||
- release-2.7
|
||||
- circleci
|
||||
context: nightlies
|
||||
- node6:
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- release-2.5
|
||||
- release-2.6
|
||||
- release-2.7
|
||||
- circleci
|
||||
context: nightlies
|
||||
|
||||
base: &base
|
||||
environment:
|
||||
- workerCount: 4
|
||||
steps:
|
||||
- checkout
|
||||
- run: |
|
||||
npm uninstall typescript --no-save
|
||||
npm uninstall tslint --no-save
|
||||
npm install
|
||||
#npm update Appeared in Jenkins only
|
||||
npm test
|
||||
|
||||
version: 2
|
||||
jobs:
|
||||
node9:
|
||||
docker:
|
||||
- image: circleci/node:9
|
||||
<<: *base
|
||||
node8:
|
||||
docker:
|
||||
- image: circleci/node:8
|
||||
<<: *base
|
||||
node6:
|
||||
docker:
|
||||
- image: circleci/node:6
|
||||
<<: *base
|
||||
+5
-9
@@ -53,7 +53,6 @@ const cmdLineOptions = minimist(process.argv.slice(2), {
|
||||
"ru": "runners", "runner": "runners",
|
||||
"r": "reporter",
|
||||
"c": "colors", "color": "colors",
|
||||
"f": "files", "file": "files",
|
||||
"w": "workers",
|
||||
},
|
||||
default: {
|
||||
@@ -69,7 +68,6 @@ const cmdLineOptions = minimist(process.argv.slice(2), {
|
||||
light: process.env.light === undefined || process.env.light !== "false",
|
||||
reporter: process.env.reporter || process.env.r,
|
||||
lint: process.env.lint || true,
|
||||
files: process.env.f || process.env.file || process.env.files || "",
|
||||
workers: process.env.workerCount || os.cpus().length,
|
||||
}
|
||||
});
|
||||
@@ -1112,13 +1110,11 @@ function spawnLintWorker(files: {path: string}[], callback: (failures: number) =
|
||||
|
||||
gulp.task("lint", "Runs tslint on the compiler sources. Optional arguments are: --f[iles]=regex", ["build-rules"], () => {
|
||||
if (fold.isTravis()) console.log(fold.start("lint"));
|
||||
const fileMatcher = cmdLineOptions.files;
|
||||
const files = fileMatcher
|
||||
? `src/**/${fileMatcher}`
|
||||
: `Gulpfile.ts "scripts/generateLocalizedDiagnosticMessages.ts" "scripts/tslint/**/*.ts" "src/**/*.ts" --exclude "src/lib/*.d.ts"`;
|
||||
const cmd = `node node_modules/tslint/bin/tslint ${files} --formatters-dir ./built/local/tslint/formatters --format autolinkableStylish`;
|
||||
console.log("Linting: " + cmd);
|
||||
child_process.execSync(cmd, { stdio: [0, 1, 2] });
|
||||
for (const project of ["scripts/tslint/tsconfig.json", "src/tsconfig-base.json"]) {
|
||||
const cmd = `node node_modules/tslint/bin/tslint --project ${project} --formatters-dir ./built/local/tslint/formatters --format autolinkableStylish`;
|
||||
console.log("Linting: " + cmd);
|
||||
child_process.execSync(cmd, { stdio: [0, 1, 2] });
|
||||
}
|
||||
if (fold.isTravis()) console.log(fold.end("lint"));
|
||||
});
|
||||
|
||||
|
||||
+8
-9
@@ -141,6 +141,7 @@ var harnessSources = harnessCoreSources.concat([
|
||||
"typingsInstaller.ts",
|
||||
"projectErrors.ts",
|
||||
"matchFiles.ts",
|
||||
"organizeImports.ts",
|
||||
"initializeTSConfig.ts",
|
||||
"extractConstants.ts",
|
||||
"extractFunctions.ts",
|
||||
@@ -1301,15 +1302,13 @@ function spawnLintWorker(files, callback) {
|
||||
desc("Runs tslint on the compiler sources. Optional arguments are: f[iles]=regex");
|
||||
task("lint", ["build-rules"], () => {
|
||||
if (fold.isTravis()) console.log(fold.start("lint"));
|
||||
const fileMatcher = process.env.f || process.env.file || process.env.files;
|
||||
|
||||
const files = fileMatcher
|
||||
? `src/**/${fileMatcher}`
|
||||
: `Gulpfile.ts scripts/generateLocalizedDiagnosticMessages.ts "scripts/tslint/**/*.ts" "src/**/*.ts" --exclude "src/lib/*.d.ts"`;
|
||||
const cmd = `node node_modules/tslint/bin/tslint ${files} --formatters-dir ./built/local/tslint/formatters --format autolinkableStylish`;
|
||||
console.log("Linting: " + cmd);
|
||||
jake.exec([cmd], { interactive: true, windowsVerbatimArguments: true }, () => {
|
||||
function lint(project, cb) {
|
||||
const cmd = `node node_modules/tslint/bin/tslint --project ${project} --formatters-dir ./built/local/tslint/formatters --format autolinkableStylish`;
|
||||
console.log("Linting: " + cmd);
|
||||
jake.exec([cmd], { interactive: true, windowsVerbatimArguments: true }, cb);
|
||||
}
|
||||
lint("scripts/tslint/tsconfig.json", () => lint("src/tsconfig-base.json", () => {
|
||||
if (fold.isTravis()) console.log(fold.end("lint"));
|
||||
complete();
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
@@ -27,7 +27,7 @@ function walk(ctx: Lint.WalkContext<void>): void {
|
||||
/** Skip certain function/method names whose parameter names are not informative. */
|
||||
function shouldIgnoreCalledExpression(expression: ts.Expression): boolean {
|
||||
if (expression.kind === ts.SyntaxKind.PropertyAccessExpression) {
|
||||
const methodName = (expression as ts.PropertyAccessExpression).name.text as string;
|
||||
const methodName = (expression as ts.PropertyAccessExpression).name.text;
|
||||
if (methodName.indexOf("set") === 0) {
|
||||
return true;
|
||||
}
|
||||
@@ -45,7 +45,7 @@ function walk(ctx: Lint.WalkContext<void>): void {
|
||||
}
|
||||
}
|
||||
else if (expression.kind === ts.SyntaxKind.Identifier) {
|
||||
const functionName = (expression as ts.Identifier).text as string;
|
||||
const functionName = (expression as ts.Identifier).text;
|
||||
if (functionName.indexOf("set") === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2016 Palantir Technologies, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import * as ts from "typescript";
|
||||
import * as Lint from "tslint";
|
||||
|
||||
export class Rule extends Lint.Rules.TypedRule {
|
||||
/* tslint:disable:object-literal-sort-keys */
|
||||
public static metadata: Lint.IRuleMetadata = {
|
||||
ruleName: "no-unnecessary-type-assertion",
|
||||
description: "Warns if a type assertion does not change the type of an expression.",
|
||||
options: {
|
||||
type: "list",
|
||||
listType: {
|
||||
type: "array",
|
||||
items: { type: "string" },
|
||||
},
|
||||
},
|
||||
optionsDescription: "A list of whitelisted assertion types to ignore",
|
||||
type: "typescript",
|
||||
hasFix: true,
|
||||
typescriptOnly: true,
|
||||
requiresTypeInfo: true,
|
||||
};
|
||||
/* tslint:enable:object-literal-sort-keys */
|
||||
|
||||
public static FAILURE_STRING = "This assertion is unnecessary since it does not change the type of the expression.";
|
||||
|
||||
public applyWithProgram(sourceFile: ts.SourceFile, program: ts.Program): Lint.RuleFailure[] {
|
||||
return this.applyWithWalker(new Walker(sourceFile, this.ruleName, this.ruleArguments, program.getTypeChecker()));
|
||||
}
|
||||
}
|
||||
|
||||
class Walker extends Lint.AbstractWalker<string[]> {
|
||||
constructor(sourceFile: ts.SourceFile, ruleName: string, options: string[], private readonly checker: ts.TypeChecker) {
|
||||
super(sourceFile, ruleName, options);
|
||||
}
|
||||
|
||||
public walk(sourceFile: ts.SourceFile) {
|
||||
const cb = (node: ts.Node): void => {
|
||||
switch (node.kind) {
|
||||
case ts.SyntaxKind.TypeAssertionExpression:
|
||||
case ts.SyntaxKind.AsExpression:
|
||||
this.verifyCast(node as ts.TypeAssertion | ts.AsExpression);
|
||||
}
|
||||
|
||||
return ts.forEachChild(node, cb);
|
||||
};
|
||||
|
||||
return ts.forEachChild(sourceFile, cb);
|
||||
}
|
||||
|
||||
private verifyCast(node: ts.TypeAssertion | ts.NonNullExpression | ts.AsExpression) {
|
||||
if (ts.isAssertionExpression(node) && this.options.indexOf(node.type.getText(this.sourceFile)) !== -1) {
|
||||
return;
|
||||
}
|
||||
const castType = this.checker.getTypeAtLocation(node);
|
||||
if (castType === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.kind !== ts.SyntaxKind.NonNullExpression &&
|
||||
(castType.flags & ts.TypeFlags.Literal ||
|
||||
castType.flags & ts.TypeFlags.Object &&
|
||||
(castType as ts.ObjectType).objectFlags & ts.ObjectFlags.Tuple) ||
|
||||
// Sometimes tuple types don't have ObjectFlags.Tuple set, like when
|
||||
// they're being matched against an inferred type. So, in addition,
|
||||
// check if any properties are numbers, which implies that this is
|
||||
// likely a tuple type.
|
||||
(castType.getProperties().some((symbol) => !isNaN(Number(symbol.name))))) {
|
||||
|
||||
// It's not always safe to remove a cast to a literal type or tuple
|
||||
// type, as those types are sometimes widened without the cast.
|
||||
return;
|
||||
}
|
||||
|
||||
const uncastType = this.checker.getTypeAtLocation(node.expression);
|
||||
if (uncastType === castType) {
|
||||
this.addFailureAtNode(node, Rule.FAILURE_STRING, node.kind === ts.SyntaxKind.TypeAssertionExpression
|
||||
? Lint.Replacement.deleteFromTo(node.getStart(), node.expression.getStart())
|
||||
: Lint.Replacement.deleteFromTo(node.expression.getEnd(), node.getEnd()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["es6"],
|
||||
"noImplicitAny": true,
|
||||
"noImplicitReturns": true,
|
||||
"noImplicitThis": true,
|
||||
|
||||
+12
-15
@@ -264,7 +264,7 @@ namespace ts {
|
||||
return (isGlobalScopeAugmentation(<ModuleDeclaration>node) ? "__global" : `"${moduleName}"`) as __String;
|
||||
}
|
||||
if (name.kind === SyntaxKind.ComputedPropertyName) {
|
||||
const nameExpression = (<ComputedPropertyName>name).expression;
|
||||
const nameExpression = name.expression;
|
||||
// treat computed property names where expression is string/numeric literal as just string/numeric literal
|
||||
if (isStringOrNumericLiteral(nameExpression)) {
|
||||
return escapeLeadingUnderscores(nameExpression.text);
|
||||
@@ -459,10 +459,7 @@ namespace ts {
|
||||
// and this case is specially handled. Module augmentations should only be merged with original module definition
|
||||
// and should never be merged directly with other augmentation, and the latter case would be possible if automatic merge is allowed.
|
||||
if (node.kind === SyntaxKind.JSDocTypedefTag) Debug.assert(isInJavaScriptFile(node)); // We shouldn't add symbols for JSDoc nodes if not in a JS file.
|
||||
const isJSDocTypedefInJSDocNamespace = node.kind === SyntaxKind.JSDocTypedefTag &&
|
||||
(node as JSDocTypedefTag).name &&
|
||||
(node as JSDocTypedefTag).name.kind === SyntaxKind.Identifier &&
|
||||
((node as JSDocTypedefTag).name as Identifier).isInJSDocNamespace;
|
||||
const isJSDocTypedefInJSDocNamespace = isJSDocTypedefTag(node) && node.name && node.name.kind === SyntaxKind.Identifier && node.name.isInJSDocNamespace;
|
||||
if ((!isAmbientModule(node) && (hasExportModifier || container.flags & NodeFlags.ExportContext)) || isJSDocTypedefInJSDocNamespace) {
|
||||
const exportKind = symbolFlags & SymbolFlags.Value ? SymbolFlags.ExportValue : 0;
|
||||
const local = declareSymbol(container.locals, /*parent*/ undefined, node, exportKind, symbolExcludes);
|
||||
@@ -527,7 +524,7 @@ namespace ts {
|
||||
if (!isIIFE) {
|
||||
currentFlow = { flags: FlowFlags.Start };
|
||||
if (containerFlags & (ContainerFlags.IsFunctionExpression | ContainerFlags.IsObjectLiteralOrClassExpressionMethod)) {
|
||||
(<FlowStart>currentFlow).container = <FunctionExpression | ArrowFunction | MethodDeclaration>node;
|
||||
currentFlow.container = <FunctionExpression | ArrowFunction | MethodDeclaration>node;
|
||||
}
|
||||
}
|
||||
// We create a return control flow graph for IIFEs and constructors. For constructors
|
||||
@@ -997,7 +994,7 @@ namespace ts {
|
||||
addAntecedent(postLoopLabel, currentFlow);
|
||||
bind(node.initializer);
|
||||
if (node.initializer.kind !== SyntaxKind.VariableDeclarationList) {
|
||||
bindAssignmentTargetFlow(<Expression>node.initializer);
|
||||
bindAssignmentTargetFlow(node.initializer);
|
||||
}
|
||||
bindIterativeStatement(node.statement, postLoopLabel, preLoopLabel);
|
||||
addAntecedent(preLoopLabel, currentFlow);
|
||||
@@ -1170,7 +1167,7 @@ namespace ts {
|
||||
i++;
|
||||
}
|
||||
const preCaseLabel = createBranchLabel();
|
||||
addAntecedent(preCaseLabel, createFlowSwitchClause(preSwitchCaseFlow, <SwitchStatement>node.parent, clauseStart, i + 1));
|
||||
addAntecedent(preCaseLabel, createFlowSwitchClause(preSwitchCaseFlow, node.parent, clauseStart, i + 1));
|
||||
addAntecedent(preCaseLabel, fallthroughFlow);
|
||||
currentFlow = finishFlowLabel(preCaseLabel);
|
||||
const clause = clauses[i];
|
||||
@@ -1251,13 +1248,13 @@ namespace ts {
|
||||
else if (node.kind === SyntaxKind.ObjectLiteralExpression) {
|
||||
for (const p of (<ObjectLiteralExpression>node).properties) {
|
||||
if (p.kind === SyntaxKind.PropertyAssignment) {
|
||||
bindDestructuringTargetFlow((<PropertyAssignment>p).initializer);
|
||||
bindDestructuringTargetFlow(p.initializer);
|
||||
}
|
||||
else if (p.kind === SyntaxKind.ShorthandPropertyAssignment) {
|
||||
bindAssignmentTargetFlow((<ShorthandPropertyAssignment>p).name);
|
||||
bindAssignmentTargetFlow(p.name);
|
||||
}
|
||||
else if (p.kind === SyntaxKind.SpreadAssignment) {
|
||||
bindAssignmentTargetFlow((<SpreadAssignment>p).expression);
|
||||
bindAssignmentTargetFlow(p.expression);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1572,7 +1569,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function hasExportDeclarations(node: ModuleDeclaration | SourceFile): boolean {
|
||||
const body = node.kind === SyntaxKind.SourceFile ? node : (<ModuleDeclaration>node).body;
|
||||
const body = node.kind === SyntaxKind.SourceFile ? node : node.body;
|
||||
if (body && (body.kind === SyntaxKind.SourceFile || body.kind === SyntaxKind.ModuleBlock)) {
|
||||
for (const stat of (<BlockLike>body).statements) {
|
||||
if (stat.kind === SyntaxKind.ExportDeclaration || stat.kind === SyntaxKind.ExportAssignment) {
|
||||
@@ -2210,7 +2207,7 @@ namespace ts {
|
||||
function checkTypePredicate(node: TypePredicateNode) {
|
||||
const { parameterName, type } = node;
|
||||
if (parameterName && parameterName.kind === SyntaxKind.Identifier) {
|
||||
checkStrictModeIdentifier(parameterName as Identifier);
|
||||
checkStrictModeIdentifier(parameterName);
|
||||
}
|
||||
if (parameterName && parameterName.kind === SyntaxKind.ThisType) {
|
||||
seenThisKeyword = true;
|
||||
@@ -2565,13 +2562,13 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
checkStrictModeFunctionName(<FunctionDeclaration>node);
|
||||
checkStrictModeFunctionName(node);
|
||||
if (inStrictMode) {
|
||||
checkStrictModeFunctionDeclaration(node);
|
||||
bindBlockScopedDeclaration(node, SymbolFlags.Function, SymbolFlags.FunctionExcludes);
|
||||
}
|
||||
else {
|
||||
declareSymbolAndAddToSymbolTable(<Declaration>node, SymbolFlags.Function, SymbolFlags.FunctionExcludes);
|
||||
declareSymbolAndAddToSymbolTable(node, SymbolFlags.Function, SymbolFlags.FunctionExcludes);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -228,7 +228,7 @@ namespace ts {
|
||||
host = oldProgramOrHost as CompilerHost;
|
||||
}
|
||||
else {
|
||||
newProgram = newProgramOrRootNames as Program;
|
||||
newProgram = newProgramOrRootNames;
|
||||
host = hostOrOptions as BuilderProgramHost;
|
||||
oldProgram = oldProgramOrHost as BuilderProgram;
|
||||
}
|
||||
|
||||
+197
-198
File diff suppressed because it is too large
Load Diff
@@ -1438,6 +1438,14 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function group<T>(values: ReadonlyArray<T>, getGroupId: (value: T) => string): ReadonlyArray<ReadonlyArray<T>> {
|
||||
const groupIdToGroup = createMultiMap<T>();
|
||||
for (const value of values) {
|
||||
groupIdToGroup.add(getGroupId(value), value);
|
||||
}
|
||||
return arrayFrom(groupIdToGroup.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether a value is an array.
|
||||
*/
|
||||
@@ -1897,6 +1905,11 @@ namespace ts {
|
||||
Comparison.EqualTo;
|
||||
}
|
||||
|
||||
/** True is greater than false. */
|
||||
export function compareBooleans(a: boolean, b: boolean): Comparison {
|
||||
return compareValues(a ? 1 : 0, b ? 1 : 0);
|
||||
}
|
||||
|
||||
function compareMessageText(text1: string | DiagnosticMessageChain, text2: string | DiagnosticMessageChain): Comparison {
|
||||
while (text1 && text2) {
|
||||
// We still have both chains.
|
||||
|
||||
@@ -350,8 +350,8 @@ namespace ts {
|
||||
// and also for non-optional initialized parameters that aren't a parameter property
|
||||
// these types may need to add `undefined`.
|
||||
const shouldUseResolverType = declaration.kind === SyntaxKind.Parameter &&
|
||||
(resolver.isRequiredInitializedParameter(declaration as ParameterDeclaration) ||
|
||||
resolver.isOptionalUninitializedParameterProperty(declaration as ParameterDeclaration));
|
||||
(resolver.isRequiredInitializedParameter(declaration) ||
|
||||
resolver.isOptionalUninitializedParameterProperty(declaration));
|
||||
if (type && !shouldUseResolverType) {
|
||||
// Write the type
|
||||
emitType(type);
|
||||
@@ -839,10 +839,10 @@ namespace ts {
|
||||
function isVisibleNamedBinding(namedBindings: NamespaceImport | NamedImports): boolean {
|
||||
if (namedBindings) {
|
||||
if (namedBindings.kind === SyntaxKind.NamespaceImport) {
|
||||
return resolver.isDeclarationVisible(<NamespaceImport>namedBindings);
|
||||
return resolver.isDeclarationVisible(namedBindings);
|
||||
}
|
||||
else {
|
||||
return forEach((<NamedImports>namedBindings).elements, namedImport => resolver.isDeclarationVisible(namedImport));
|
||||
return namedBindings.elements.some(namedImport => resolver.isDeclarationVisible(namedImport));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -865,11 +865,11 @@ namespace ts {
|
||||
}
|
||||
if (node.importClause.namedBindings.kind === SyntaxKind.NamespaceImport) {
|
||||
write("* as ");
|
||||
writeTextOfNode(currentText, (<NamespaceImport>node.importClause.namedBindings).name);
|
||||
writeTextOfNode(currentText, node.importClause.namedBindings.name);
|
||||
}
|
||||
else {
|
||||
write("{ ");
|
||||
emitCommaList((<NamedImports>node.importClause.namedBindings).elements, emitImportOrExportSpecifier, resolver.isDeclarationVisible);
|
||||
emitCommaList(node.importClause.namedBindings.elements, emitImportOrExportSpecifier, resolver.isDeclarationVisible);
|
||||
write(" }");
|
||||
}
|
||||
}
|
||||
@@ -886,18 +886,8 @@ namespace ts {
|
||||
// external modules since they are indistinguishable from script files with ambient modules. To fix this in such d.ts files we'll emit top level 'export {}'
|
||||
// so compiler will treat them as external modules.
|
||||
resultHasExternalModuleIndicator = resultHasExternalModuleIndicator || parent.kind !== SyntaxKind.ModuleDeclaration;
|
||||
let moduleSpecifier: Node;
|
||||
if (parent.kind === SyntaxKind.ImportEqualsDeclaration) {
|
||||
const node = parent as ImportEqualsDeclaration;
|
||||
moduleSpecifier = getExternalModuleImportEqualsDeclarationExpression(node);
|
||||
}
|
||||
else if (parent.kind === SyntaxKind.ModuleDeclaration) {
|
||||
moduleSpecifier = (<ModuleDeclaration>parent).name;
|
||||
}
|
||||
else {
|
||||
const node = parent as (ImportDeclaration | ExportDeclaration);
|
||||
moduleSpecifier = node.moduleSpecifier;
|
||||
}
|
||||
const moduleSpecifier = parent.kind === SyntaxKind.ImportEqualsDeclaration ? getExternalModuleImportEqualsDeclarationExpression(parent) :
|
||||
parent.kind === SyntaxKind.ModuleDeclaration ? parent.name : parent.moduleSpecifier;
|
||||
|
||||
if (moduleSpecifier.kind === SyntaxKind.StringLiteral && isBundledEmit && (compilerOptions.out || compilerOptions.outFile)) {
|
||||
const moduleName = getExternalModuleNameFromDeclaration(host, resolver, parent);
|
||||
@@ -1293,7 +1283,7 @@ namespace ts {
|
||||
// so there is no check needed to see if declaration is visible
|
||||
if (node.kind !== SyntaxKind.VariableDeclaration || isVariableDeclarationVisible(node)) {
|
||||
if (isBindingPattern(node.name)) {
|
||||
emitBindingPattern(<BindingPattern>node.name);
|
||||
emitBindingPattern(node.name);
|
||||
}
|
||||
else {
|
||||
writeNameOfDeclaration(node, getVariableDeclarationTypeVisibilityError);
|
||||
@@ -1301,7 +1291,7 @@ namespace ts {
|
||||
// If optional property emit ? but in the case of parameterProperty declaration with "?" indicating optional parameter for the constructor
|
||||
// we don't want to emit property declaration with "?"
|
||||
if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature ||
|
||||
(node.kind === SyntaxKind.Parameter && !isParameterPropertyDeclaration(<ParameterDeclaration>node))) && hasQuestionToken(node)) {
|
||||
(node.kind === SyntaxKind.Parameter && !isParameterPropertyDeclaration(node))) && hasQuestionToken(node)) {
|
||||
write("?");
|
||||
}
|
||||
if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature) && node.parent.kind === SyntaxKind.TypeLiteral) {
|
||||
@@ -1389,7 +1379,7 @@ namespace ts {
|
||||
|
||||
if (bindingElement.name) {
|
||||
if (isBindingPattern(bindingElement.name)) {
|
||||
emitBindingPattern(<BindingPattern>bindingElement.name);
|
||||
emitBindingPattern(bindingElement.name);
|
||||
}
|
||||
else {
|
||||
writeTextOfNode(currentText, bindingElement.name);
|
||||
@@ -1782,7 +1772,7 @@ namespace ts {
|
||||
// For bindingPattern, we can't simply writeTextOfNode from the source file
|
||||
// because we want to omit the initializer and using writeTextOfNode will result in initializer get emitted.
|
||||
// Therefore, we will have to recursively emit each element in the bindingPattern.
|
||||
emitBindingPattern(<BindingPattern>node.name);
|
||||
emitBindingPattern(node.name);
|
||||
}
|
||||
else {
|
||||
writeTextOfNode(currentText, node.name);
|
||||
@@ -1921,7 +1911,7 @@ namespace ts {
|
||||
// emit : declare function foo([a, [[b]], c]: [number, [[string]], number]): void;
|
||||
// original with rest: function foo([a, ...c]) {}
|
||||
// emit : declare function foo([a, ...c]): void;
|
||||
emitBindingPattern(<BindingPattern>bindingElement.name);
|
||||
emitBindingPattern(bindingElement.name);
|
||||
}
|
||||
else {
|
||||
Debug.assert(bindingElement.name.kind === SyntaxKind.Identifier);
|
||||
|
||||
@@ -951,7 +951,7 @@ namespace ts {
|
||||
|
||||
function emitEntityName(node: EntityName) {
|
||||
if (node.kind === SyntaxKind.Identifier) {
|
||||
emitExpression(<Identifier>node);
|
||||
emitExpression(node);
|
||||
}
|
||||
else {
|
||||
emit(node);
|
||||
@@ -1709,7 +1709,7 @@ namespace ts {
|
||||
emit(node);
|
||||
}
|
||||
else {
|
||||
emitExpression(<Expression>node);
|
||||
emitExpression(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2068,7 +2068,7 @@ namespace ts {
|
||||
|
||||
function emitModuleReference(node: ModuleReference) {
|
||||
if (node.kind === SyntaxKind.Identifier) {
|
||||
emitExpression(<Identifier>node);
|
||||
emitExpression(node);
|
||||
}
|
||||
else {
|
||||
emit(node);
|
||||
@@ -2472,12 +2472,12 @@ namespace ts {
|
||||
|
||||
function emitPrologueDirectivesIfNeeded(sourceFileOrBundle: Bundle | SourceFile) {
|
||||
if (isSourceFile(sourceFileOrBundle)) {
|
||||
setSourceFile(sourceFileOrBundle as SourceFile);
|
||||
emitPrologueDirectives((sourceFileOrBundle as SourceFile).statements);
|
||||
setSourceFile(sourceFileOrBundle);
|
||||
emitPrologueDirectives(sourceFileOrBundle.statements);
|
||||
}
|
||||
else {
|
||||
const seenPrologueDirectives = createMap<true>();
|
||||
for (const sourceFile of (sourceFileOrBundle as Bundle).sourceFiles) {
|
||||
for (const sourceFile of sourceFileOrBundle.sourceFiles) {
|
||||
setSourceFile(sourceFile);
|
||||
emitPrologueDirectives(sourceFile.statements, /*startWithNewLine*/ true, seenPrologueDirectives);
|
||||
}
|
||||
|
||||
+25
-25
@@ -644,7 +644,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray<TypeParameterDeclaration> | undefined, parameters: NodeArray<ParameterDeclaration>, type: TypeNode | undefined) {
|
||||
return <FunctionTypeNode>updateSignatureDeclaration(node, typeParameters, parameters, type);
|
||||
return updateSignatureDeclaration(node, typeParameters, parameters, type);
|
||||
}
|
||||
|
||||
export function createConstructorTypeNode(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined) {
|
||||
@@ -652,7 +652,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function updateConstructorTypeNode(node: ConstructorTypeNode, typeParameters: NodeArray<TypeParameterDeclaration> | undefined, parameters: NodeArray<ParameterDeclaration>, type: TypeNode | undefined) {
|
||||
return <ConstructorTypeNode>updateSignatureDeclaration(node, typeParameters, parameters, type);
|
||||
return updateSignatureDeclaration(node, typeParameters, parameters, type);
|
||||
}
|
||||
|
||||
export function createTypeQueryNode(exprName: EntityName) {
|
||||
@@ -1285,7 +1285,7 @@ namespace ts {
|
||||
export function createYield(asteriskTokenOrExpression?: AsteriskToken | Expression, expression?: Expression) {
|
||||
const node = <YieldExpression>createSynthesizedNode(SyntaxKind.YieldExpression);
|
||||
node.asteriskToken = asteriskTokenOrExpression && asteriskTokenOrExpression.kind === SyntaxKind.AsteriskToken ? <AsteriskToken>asteriskTokenOrExpression : undefined;
|
||||
node.expression = asteriskTokenOrExpression && asteriskTokenOrExpression.kind !== SyntaxKind.AsteriskToken ? <Expression>asteriskTokenOrExpression : expression;
|
||||
node.expression = asteriskTokenOrExpression && asteriskTokenOrExpression.kind !== SyntaxKind.AsteriskToken ? asteriskTokenOrExpression : expression;
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -3415,13 +3415,13 @@ namespace ts {
|
||||
switch (property.kind) {
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
return createExpressionForAccessorDeclaration(node.properties, <AccessorDeclaration>property, receiver, node.multiLine);
|
||||
return createExpressionForAccessorDeclaration(node.properties, property, receiver, node.multiLine);
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
return createExpressionForPropertyAssignment(<PropertyAssignment>property, receiver);
|
||||
return createExpressionForPropertyAssignment(property, receiver);
|
||||
case SyntaxKind.ShorthandPropertyAssignment:
|
||||
return createExpressionForShorthandPropertyAssignment(<ShorthandPropertyAssignment>property, receiver);
|
||||
return createExpressionForShorthandPropertyAssignment(property, receiver);
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
return createExpressionForMethodDeclaration(<MethodDeclaration>property, receiver);
|
||||
return createExpressionForMethodDeclaration(property, receiver);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4065,13 +4065,13 @@ namespace ts {
|
||||
|
||||
export function parenthesizePostfixOperand(operand: Expression) {
|
||||
return isLeftHandSideExpression(operand)
|
||||
? <LeftHandSideExpression>operand
|
||||
? operand
|
||||
: setTextRange(createParen(operand), operand);
|
||||
}
|
||||
|
||||
export function parenthesizePrefixOperand(operand: Expression) {
|
||||
return isUnaryExpression(operand)
|
||||
? <UnaryExpression>operand
|
||||
? operand
|
||||
: setTextRange(createParen(operand), operand);
|
||||
}
|
||||
|
||||
@@ -4203,7 +4203,7 @@ namespace ts {
|
||||
|
||||
export function parenthesizeConciseBody(body: ConciseBody): ConciseBody {
|
||||
if (!isBlock(body) && getLeftmostExpression(body, /*stopAtCallExpressions*/ false).kind === SyntaxKind.ObjectLiteralExpression) {
|
||||
return setTextRange(createParen(<Expression>body), body);
|
||||
return setTextRange(createParen(body), body);
|
||||
}
|
||||
|
||||
return body;
|
||||
@@ -4360,10 +4360,10 @@ namespace ts {
|
||||
const name = namespaceDeclaration.name;
|
||||
return isGeneratedIdentifier(name) ? name : createIdentifier(getSourceTextOfNodeFromSourceFile(sourceFile, name) || idText(name));
|
||||
}
|
||||
if (node.kind === SyntaxKind.ImportDeclaration && (<ImportDeclaration>node).importClause) {
|
||||
if (node.kind === SyntaxKind.ImportDeclaration && node.importClause) {
|
||||
return getGeneratedNameForNode(node);
|
||||
}
|
||||
if (node.kind === SyntaxKind.ExportDeclaration && (<ExportDeclaration>node).moduleSpecifier) {
|
||||
if (node.kind === SyntaxKind.ExportDeclaration && node.moduleSpecifier) {
|
||||
return getGeneratedNameForNode(node);
|
||||
}
|
||||
return undefined;
|
||||
@@ -4484,7 +4484,7 @@ namespace ts {
|
||||
// `{a}` in `let [{a} = 1] = ...`
|
||||
// `[a]` in `let [[a]] = ...`
|
||||
// `[a]` in `let [[a] = 1] = ...`
|
||||
return <ObjectBindingPattern | ArrayBindingPattern | Identifier>bindingElement.name;
|
||||
return bindingElement.name;
|
||||
}
|
||||
|
||||
if (isObjectLiteralElementLike(bindingElement)) {
|
||||
@@ -4546,12 +4546,12 @@ namespace ts {
|
||||
case SyntaxKind.Parameter:
|
||||
case SyntaxKind.BindingElement:
|
||||
// `...` in `let [...a] = ...`
|
||||
return (<ParameterDeclaration | BindingElement>bindingElement).dotDotDotToken;
|
||||
return bindingElement.dotDotDotToken;
|
||||
|
||||
case SyntaxKind.SpreadElement:
|
||||
case SyntaxKind.SpreadAssignment:
|
||||
// `...` in `[...a] = ...`
|
||||
return <SpreadElement | SpreadAssignment>bindingElement;
|
||||
return bindingElement;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
@@ -4567,8 +4567,8 @@ namespace ts {
|
||||
// `[a]` in `let { [a]: b } = ...`
|
||||
// `"a"` in `let { "a": b } = ...`
|
||||
// `1` in `let { 1: b } = ...`
|
||||
if ((<BindingElement>bindingElement).propertyName) {
|
||||
const propertyName = (<BindingElement>bindingElement).propertyName;
|
||||
if (bindingElement.propertyName) {
|
||||
const propertyName = bindingElement.propertyName;
|
||||
return isComputedPropertyName(propertyName) && isStringOrNumericLiteral(propertyName.expression)
|
||||
? propertyName.expression
|
||||
: propertyName;
|
||||
@@ -4581,8 +4581,8 @@ namespace ts {
|
||||
// `[a]` in `({ [a]: b } = ...)`
|
||||
// `"a"` in `({ "a": b } = ...)`
|
||||
// `1` in `({ 1: b } = ...)`
|
||||
if ((<PropertyAssignment>bindingElement).name) {
|
||||
const propertyName = (<PropertyAssignment>bindingElement).name;
|
||||
if (bindingElement.name) {
|
||||
const propertyName = bindingElement.name;
|
||||
return isComputedPropertyName(propertyName) && isStringOrNumericLiteral(propertyName.expression)
|
||||
? propertyName.expression
|
||||
: propertyName;
|
||||
@@ -4592,7 +4592,7 @@ namespace ts {
|
||||
|
||||
case SyntaxKind.SpreadAssignment:
|
||||
// `a` in `({ ...a } = ...)`
|
||||
return (<SpreadAssignment>bindingElement).name;
|
||||
return bindingElement.name;
|
||||
}
|
||||
|
||||
const target = getTargetOfBindingOrAssignmentElement(bindingElement);
|
||||
@@ -4629,7 +4629,7 @@ namespace ts {
|
||||
Debug.assertNode(element.name, isIdentifier);
|
||||
return setOriginalNode(setTextRange(createSpread(<Identifier>element.name), element), element);
|
||||
}
|
||||
const expression = convertToAssignmentElementTarget(<ObjectBindingPattern | ArrayBindingPattern | Identifier>element.name);
|
||||
const expression = convertToAssignmentElementTarget(element.name);
|
||||
return element.initializer
|
||||
? setOriginalNode(
|
||||
setTextRange(
|
||||
@@ -4651,7 +4651,7 @@ namespace ts {
|
||||
return setOriginalNode(setTextRange(createSpreadAssignment(<Identifier>element.name), element), element);
|
||||
}
|
||||
if (element.propertyName) {
|
||||
const expression = convertToAssignmentElementTarget(<ObjectBindingPattern | ArrayBindingPattern | Identifier>element.name);
|
||||
const expression = convertToAssignmentElementTarget(element.name);
|
||||
return setOriginalNode(setTextRange(createPropertyAssignment(element.propertyName, element.initializer ? createAssignment(expression, element.initializer) : expression), element), element);
|
||||
}
|
||||
Debug.assertNode(element.name, isIdentifier);
|
||||
@@ -4684,7 +4684,7 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
Debug.assertNode(node, isObjectLiteralExpression);
|
||||
return <ObjectLiteralExpression>node;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function convertToArrayAssignmentPattern(node: ArrayBindingOrAssignmentPattern) {
|
||||
@@ -4698,7 +4698,7 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
Debug.assertNode(node, isArrayLiteralExpression);
|
||||
return <ArrayLiteralExpression>node;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function convertToAssignmentElementTarget(node: BindingOrAssignmentElementTarget): Expression {
|
||||
@@ -4707,6 +4707,6 @@ namespace ts {
|
||||
}
|
||||
|
||||
Debug.assertNode(node, isExpression);
|
||||
return <Expression>node;
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -690,7 +690,7 @@ namespace ts {
|
||||
// Prime the scanner.
|
||||
nextToken();
|
||||
if (token() === SyntaxKind.EndOfFileToken) {
|
||||
sourceFile.endOfFileToken = <EndOfFileToken>parseTokenNode();
|
||||
sourceFile.endOfFileToken = parseTokenNode<EndOfFileToken>();
|
||||
}
|
||||
else if (token() === SyntaxKind.OpenBraceToken ||
|
||||
lookAhead(() => token() === SyntaxKind.StringLiteral)) {
|
||||
@@ -773,7 +773,7 @@ namespace ts {
|
||||
|
||||
sourceFile.statements = parseList(ParsingContext.SourceElements, parseStatement);
|
||||
Debug.assert(token() === SyntaxKind.EndOfFileToken);
|
||||
sourceFile.endOfFileToken = addJSDocComment(parseTokenNode() as EndOfFileToken);
|
||||
sourceFile.endOfFileToken = addJSDocComment(parseTokenNode());
|
||||
|
||||
setExternalModuleIndicator(sourceFile);
|
||||
|
||||
@@ -1794,7 +1794,7 @@ namespace ts {
|
||||
// into an actual .ConstructorDeclaration.
|
||||
const methodDeclaration = <MethodDeclaration>node;
|
||||
const nameIsConstructor = methodDeclaration.name.kind === SyntaxKind.Identifier &&
|
||||
(<Identifier>methodDeclaration.name).originalKeywordKind === SyntaxKind.ConstructorKeyword;
|
||||
methodDeclaration.name.originalKeywordKind === SyntaxKind.ConstructorKeyword;
|
||||
|
||||
return !nameIsConstructor;
|
||||
}
|
||||
@@ -3175,7 +3175,7 @@ namespace ts {
|
||||
// Note: we call reScanGreaterToken so that we get an appropriately merged token
|
||||
// for cases like `> > =` becoming `>>=`
|
||||
if (isLeftHandSideExpression(expr) && isAssignmentOperator(reScanGreaterToken())) {
|
||||
return makeBinaryExpression(expr, <BinaryOperatorToken>parseTokenNode(), parseAssignmentExpressionOrHigher());
|
||||
return makeBinaryExpression(expr, parseTokenNode(), parseAssignmentExpressionOrHigher());
|
||||
}
|
||||
|
||||
// It wasn't an assignment or a lambda. This is a conditional expression:
|
||||
@@ -3624,7 +3624,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else {
|
||||
leftOperand = makeBinaryExpression(leftOperand, <BinaryOperatorToken>parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence));
|
||||
leftOperand = makeBinaryExpression(leftOperand, parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4079,7 +4079,7 @@ namespace ts {
|
||||
else {
|
||||
Debug.assert(opening.kind === SyntaxKind.JsxSelfClosingElement);
|
||||
// Nothing else to do for self-closing elements
|
||||
result = <JsxSelfClosingElement>opening;
|
||||
result = opening;
|
||||
}
|
||||
|
||||
// If the user writes the invalid code '<div></div><div></div>' in an expression context (i.e. not wrapped in
|
||||
@@ -4097,7 +4097,7 @@ namespace ts {
|
||||
badNode.end = invalidElement.end;
|
||||
badNode.left = result;
|
||||
badNode.right = invalidElement;
|
||||
badNode.operatorToken = <BinaryOperatorToken>createMissingNode(SyntaxKind.CommaToken, /*reportAtCurrentPosition*/ false, /*diagnosticMessage*/ undefined);
|
||||
badNode.operatorToken = createMissingNode(SyntaxKind.CommaToken, /*reportAtCurrentPosition*/ false, /*diagnosticMessage*/ undefined);
|
||||
badNode.operatorToken.pos = badNode.operatorToken.end = badNode.right.pos;
|
||||
return <JsxElement><Node>badNode;
|
||||
}
|
||||
@@ -5253,7 +5253,7 @@ namespace ts {
|
||||
if (node.decorators || node.modifiers) {
|
||||
// We reached this point because we encountered decorators and/or modifiers and assumed a declaration
|
||||
// would follow. For recovery and error reporting purposes, return an incomplete declaration.
|
||||
const missing = <Statement>createMissingNode(SyntaxKind.MissingDeclaration, /*reportAtCurrentPosition*/ true, Diagnostics.Declaration_expected);
|
||||
const missing = createMissingNode<Statement>(SyntaxKind.MissingDeclaration, /*reportAtCurrentPosition*/ true, Diagnostics.Declaration_expected);
|
||||
missing.pos = node.pos;
|
||||
missing.decorators = node.decorators;
|
||||
missing.modifiers = node.modifiers;
|
||||
|
||||
@@ -812,7 +812,7 @@ namespace ts {
|
||||
if (!result) {
|
||||
// There were no unresolved/ambient resolutions.
|
||||
Debug.assert(resolutions.length === moduleNames.length);
|
||||
return <ResolvedModuleFull[]>resolutions;
|
||||
return resolutions;
|
||||
}
|
||||
|
||||
let j = 0;
|
||||
|
||||
@@ -1995,7 +1995,7 @@ namespace ts {
|
||||
// If we are here it is because this is a destructuring assignment.
|
||||
if (isDestructuringAssignment(node)) {
|
||||
return flattenDestructuringAssignment(
|
||||
<DestructuringAssignment>node,
|
||||
node,
|
||||
visitor,
|
||||
context,
|
||||
FlattenLevel.All,
|
||||
@@ -2023,7 +2023,7 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
else {
|
||||
assignment = createBinary(<Identifier>decl.name, SyntaxKind.EqualsToken, visitNode(decl.initializer, visitor, isExpression));
|
||||
assignment = createBinary(decl.name, SyntaxKind.EqualsToken, visitNode(decl.initializer, visitor, isExpression));
|
||||
setTextRange(assignment, decl);
|
||||
}
|
||||
|
||||
@@ -2632,10 +2632,10 @@ namespace ts {
|
||||
|
||||
function visit(node: Identifier | BindingPattern) {
|
||||
if (node.kind === SyntaxKind.Identifier) {
|
||||
state.hoistedLocalVariables.push((<Identifier>node));
|
||||
state.hoistedLocalVariables.push(node);
|
||||
}
|
||||
else {
|
||||
for (const element of (<BindingPattern>node).elements) {
|
||||
for (const element of node.elements) {
|
||||
if (!isOmittedExpression(element)) {
|
||||
visit(element.name);
|
||||
}
|
||||
@@ -2716,7 +2716,7 @@ namespace ts {
|
||||
convertedLoopState = outerConvertedLoopState;
|
||||
|
||||
if (loopOutParameters.length || lexicalEnvironment) {
|
||||
const statements = isBlock(loopBody) ? (<Block>loopBody).statements.slice() : [loopBody];
|
||||
const statements = isBlock(loopBody) ? loopBody.statements.slice() : [loopBody];
|
||||
if (loopOutParameters.length) {
|
||||
copyOutParameters(loopOutParameters, CopyDirection.ToOutParameter, statements);
|
||||
}
|
||||
@@ -2856,7 +2856,7 @@ namespace ts {
|
||||
loop = convert(node, outermostLabeledStatement, convertedLoopBodyStatements);
|
||||
}
|
||||
else {
|
||||
let clone = <IterationStatement>getMutableClone(node);
|
||||
let clone = getMutableClone(node);
|
||||
// clean statement part
|
||||
clone.statement = undefined;
|
||||
// visit childnodes to transform initializer/condition/incrementor parts
|
||||
@@ -3039,7 +3039,7 @@ namespace ts {
|
||||
switch (property.kind) {
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
const accessors = getAllAccessorDeclarations(node.properties, <AccessorDeclaration>property);
|
||||
const accessors = getAllAccessorDeclarations(node.properties, property);
|
||||
if (property === accessors.firstAccessor) {
|
||||
expressions.push(transformAccessorsToExpression(receiver, accessors, node, node.multiLine));
|
||||
}
|
||||
@@ -3047,15 +3047,15 @@ namespace ts {
|
||||
break;
|
||||
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
expressions.push(transformObjectLiteralMethodDeclarationToExpression(<MethodDeclaration>property, receiver, node, node.multiLine));
|
||||
expressions.push(transformObjectLiteralMethodDeclarationToExpression(property, receiver, node, node.multiLine));
|
||||
break;
|
||||
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
expressions.push(transformPropertyAssignmentToExpression(<PropertyAssignment>property, receiver, node.multiLine));
|
||||
expressions.push(transformPropertyAssignmentToExpression(property, receiver, node.multiLine));
|
||||
break;
|
||||
|
||||
case SyntaxKind.ShorthandPropertyAssignment:
|
||||
expressions.push(transformShorthandPropertyAssignmentToExpression(<ShorthandPropertyAssignment>property, receiver, node.multiLine));
|
||||
expressions.push(transformShorthandPropertyAssignmentToExpression(property, receiver, node.multiLine));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -183,7 +183,7 @@ namespace ts {
|
||||
: visitNode(node.initializer, visitor, isForInitializer),
|
||||
visitNode(node.condition, visitor, isExpression),
|
||||
visitNode(node.incrementor, visitor, isExpression),
|
||||
visitNode((<ForStatement>node).statement, asyncBodyVisitor, isStatement, liftToBlock)
|
||||
visitNode(node.statement, asyncBodyVisitor, isStatement, liftToBlock)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -167,7 +167,7 @@ namespace ts {
|
||||
objects.push(createObjectLiteral(chunkObject));
|
||||
chunkObject = undefined;
|
||||
}
|
||||
const target = (e as SpreadAssignment).expression;
|
||||
const target = e.expression;
|
||||
objects.push(visitNode(target, visitor, isExpression));
|
||||
}
|
||||
else {
|
||||
@@ -175,8 +175,7 @@ namespace ts {
|
||||
chunkObject = [];
|
||||
}
|
||||
if (e.kind === SyntaxKind.PropertyAssignment) {
|
||||
const p = e as PropertyAssignment;
|
||||
chunkObject.push(createPropertyAssignment(p.name, visitNode(p.initializer, visitor, isExpression)));
|
||||
chunkObject.push(createPropertyAssignment(e.name, visitNode(e.initializer, visitor, isExpression)));
|
||||
}
|
||||
else {
|
||||
chunkObject.push(visitNode(e, visitor, isObjectLiteralElementLike));
|
||||
|
||||
@@ -1771,16 +1771,15 @@ namespace ts {
|
||||
for (let i = clausesWritten; i < numClauses; i++) {
|
||||
const clause = caseBlock.clauses[i];
|
||||
if (clause.kind === SyntaxKind.CaseClause) {
|
||||
const caseClause = <CaseClause>clause;
|
||||
if (containsYield(caseClause.expression) && pendingClauses.length > 0) {
|
||||
if (containsYield(clause.expression) && pendingClauses.length > 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
pendingClauses.push(
|
||||
createCaseClause(
|
||||
visitNode(caseClause.expression, visitor, isExpression),
|
||||
visitNode(clause.expression, visitor, isExpression),
|
||||
[
|
||||
createInlineBreak(clauseLabels[i], /*location*/ caseClause.expression)
|
||||
createInlineBreak(clauseLabels[i], /*location*/ clause.expression)
|
||||
]
|
||||
)
|
||||
);
|
||||
|
||||
@@ -57,19 +57,19 @@ namespace ts {
|
||||
function transformJsxChildToExpression(node: JsxChild): Expression {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.JsxText:
|
||||
return visitJsxText(<JsxText>node);
|
||||
return visitJsxText(node);
|
||||
|
||||
case SyntaxKind.JsxExpression:
|
||||
return visitJsxExpression(<JsxExpression>node);
|
||||
return visitJsxExpression(node);
|
||||
|
||||
case SyntaxKind.JsxElement:
|
||||
return visitJsxElement(<JsxElement>node, /*isChild*/ true);
|
||||
return visitJsxElement(node, /*isChild*/ true);
|
||||
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
return visitJsxSelfClosingElement(<JsxSelfClosingElement>node, /*isChild*/ true);
|
||||
return visitJsxSelfClosingElement(node, /*isChild*/ true);
|
||||
|
||||
case SyntaxKind.JsxFragment:
|
||||
return visitJsxFragment(<JsxFragment>node, /*isChild*/ true);
|
||||
return visitJsxFragment(node, /*isChild*/ true);
|
||||
|
||||
default:
|
||||
Debug.failBadSyntaxKind(node);
|
||||
@@ -171,15 +171,15 @@ namespace ts {
|
||||
else if (node.kind === SyntaxKind.StringLiteral) {
|
||||
// Always recreate the literal to escape any escape sequences or newlines which may be in the original jsx string and which
|
||||
// Need to be escaped to be handled correctly in a normal string
|
||||
const literal = createLiteral(tryDecodeEntities((<StringLiteral>node).text) || (<StringLiteral>node).text);
|
||||
literal.singleQuote = (node as StringLiteral).singleQuote !== undefined ? (node as StringLiteral).singleQuote : !isStringDoubleQuoted(node as StringLiteral, currentSourceFile);
|
||||
const literal = createLiteral(tryDecodeEntities(node.text) || node.text);
|
||||
literal.singleQuote = node.singleQuote !== undefined ? node.singleQuote : !isStringDoubleQuoted(node, currentSourceFile);
|
||||
return setTextRange(literal, node);
|
||||
}
|
||||
else if (node.kind === SyntaxKind.JsxExpression) {
|
||||
if (node.expression === undefined) {
|
||||
return createTrue();
|
||||
}
|
||||
return visitJsxExpression(<JsxExpression>node);
|
||||
return visitJsxExpression(node);
|
||||
}
|
||||
else {
|
||||
Debug.failBadSyntaxKind(node);
|
||||
@@ -279,10 +279,10 @@ namespace ts {
|
||||
|
||||
function getTagName(node: JsxElement | JsxOpeningLikeElement): Expression {
|
||||
if (node.kind === SyntaxKind.JsxElement) {
|
||||
return getTagName((<JsxElement>node).openingElement);
|
||||
return getTagName(node.openingElement);
|
||||
}
|
||||
else {
|
||||
const name = (<JsxOpeningLikeElement>node).tagName;
|
||||
const name = node.tagName;
|
||||
if (isIdentifier(name) && isIntrinsicJsxName(name.escapedText)) {
|
||||
return createLiteral(idText(name));
|
||||
}
|
||||
|
||||
@@ -533,7 +533,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (isImportCall(node)) {
|
||||
return visitImportCallExpression(<ImportCall>node);
|
||||
return visitImportCallExpression(node);
|
||||
}
|
||||
else {
|
||||
return visitEachChild(node, importCallExpressionVisitor, context);
|
||||
|
||||
@@ -343,13 +343,12 @@ namespace ts {
|
||||
continue;
|
||||
}
|
||||
|
||||
const exportDecl = <ExportDeclaration>externalImport;
|
||||
if (!exportDecl.exportClause) {
|
||||
if (!externalImport.exportClause) {
|
||||
// export * from ...
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const element of exportDecl.exportClause.elements) {
|
||||
for (const element of externalImport.exportClause.elements) {
|
||||
// write name of indirectly exported entry, i.e. 'export {x} from ...'
|
||||
exportedNames.push(
|
||||
createPropertyAssignment(
|
||||
@@ -472,7 +471,7 @@ namespace ts {
|
||||
const importVariableName = getLocalNameForExternalImport(entry, currentSourceFile);
|
||||
switch (entry.kind) {
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
if (!(<ImportDeclaration>entry).importClause) {
|
||||
if (!entry.importClause) {
|
||||
// 'import "..."' case
|
||||
// module is imported only for side-effects, no emit required
|
||||
break;
|
||||
@@ -491,7 +490,7 @@ namespace ts {
|
||||
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
Debug.assert(importVariableName !== undefined);
|
||||
if ((<ExportDeclaration>entry).exportClause) {
|
||||
if (entry.exportClause) {
|
||||
// export {a, b as c} from 'foo'
|
||||
//
|
||||
// emit as:
|
||||
@@ -501,7 +500,7 @@ namespace ts {
|
||||
// "c": _["b"]
|
||||
// });
|
||||
const properties: PropertyAssignment[] = [];
|
||||
for (const e of (<ExportDeclaration>entry).exportClause.elements) {
|
||||
for (const e of entry.exportClause.elements) {
|
||||
properties.push(
|
||||
createPropertyAssignment(
|
||||
createLiteral(idText(e.name)),
|
||||
|
||||
@@ -242,13 +242,13 @@ namespace ts {
|
||||
}
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
return visitImportDeclaration(<ImportDeclaration>node);
|
||||
return visitImportDeclaration(node);
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
return visitImportEqualsDeclaration(<ImportEqualsDeclaration>node);
|
||||
return visitImportEqualsDeclaration(node);
|
||||
case SyntaxKind.ExportAssignment:
|
||||
return visitExportAssignment(<ExportAssignment>node);
|
||||
return visitExportAssignment(node);
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
return visitExportDeclaration(<ExportDeclaration>node);
|
||||
return visitExportDeclaration(node);
|
||||
default:
|
||||
Debug.fail("Unhandled ellided statement");
|
||||
}
|
||||
@@ -2010,7 +2010,7 @@ namespace ts {
|
||||
case SyntaxKind.Identifier:
|
||||
// Create a clone of the name with a new parent, and treat it as if it were
|
||||
// a source tree node for the purposes of the checker.
|
||||
const name = getMutableClone(<Identifier>node);
|
||||
const name = getMutableClone(node);
|
||||
name.flags &= ~NodeFlags.Synthesized;
|
||||
name.original = undefined;
|
||||
name.parent = getParseTreeNode(currentScope); // ensure the parent is set to a parse tree node.
|
||||
@@ -2027,7 +2027,7 @@ namespace ts {
|
||||
return name;
|
||||
|
||||
case SyntaxKind.QualifiedName:
|
||||
return serializeQualifiedNameAsExpression(<QualifiedName>node, useFallback);
|
||||
return serializeQualifiedNameAsExpression(node, useFallback);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2091,9 +2091,9 @@ namespace ts {
|
||||
function getExpressionForPropertyName(member: ClassElement | EnumMember, generateNameForComputedPropertyName: boolean): Expression {
|
||||
const name = member.name;
|
||||
if (isComputedPropertyName(name)) {
|
||||
return generateNameForComputedPropertyName && !isSimpleInlineableExpression((<ComputedPropertyName>name).expression)
|
||||
return generateNameForComputedPropertyName && !isSimpleInlineableExpression(name.expression)
|
||||
? getGeneratedNameForNode(name)
|
||||
: (<ComputedPropertyName>name).expression;
|
||||
: name.expression;
|
||||
}
|
||||
else if (isIdentifier(name)) {
|
||||
return createLiteral(idText(name));
|
||||
@@ -2961,7 +2961,7 @@ namespace ts {
|
||||
const body = node.body;
|
||||
if (body.kind === SyntaxKind.ModuleBlock) {
|
||||
saveStateAndInvoke(body, body => addRange(statements, visitNodes((<ModuleBlock>body).statements, namespaceElementVisitor, isStatement)));
|
||||
statementsLocation = (<ModuleBlock>body).statements;
|
||||
statementsLocation = body.statements;
|
||||
blockLocation = body;
|
||||
}
|
||||
else {
|
||||
@@ -3547,9 +3547,7 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return isPropertyAccessExpression(node) || isElementAccessExpression(node)
|
||||
? resolver.getConstantValue(<PropertyAccessExpression | ElementAccessExpression>node)
|
||||
: undefined;
|
||||
return isPropertyAccessExpression(node) || isElementAccessExpression(node) ? resolver.getConstantValue(node) : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2835,6 +2835,8 @@ namespace ts {
|
||||
getAugmentedPropertiesOfType(type: Type): Symbol[];
|
||||
getRootSymbols(symbol: Symbol): Symbol[];
|
||||
getContextualType(node: Expression): Type | undefined;
|
||||
/* @internal */ getContextualTypeForArgumentAtIndex(call: CallLikeExpression, argIndex: number): Type;
|
||||
/* @internal */ getContextualTypeForJsxAttribute(attribute: JsxAttribute | JsxSpreadAttribute): Type | undefined;
|
||||
/* @internal */ isContextSensitive(node: Expression | MethodDeclaration | ObjectLiteralElementLike | JsxAttributeLike): boolean;
|
||||
|
||||
/**
|
||||
@@ -3307,7 +3309,7 @@ namespace ts {
|
||||
/* @internal */ parent?: Symbol; // Parent symbol
|
||||
/* @internal */ exportSymbol?: Symbol; // Exported symbol associated with this symbol
|
||||
/* @internal */ constEnumOnlyModule?: boolean; // True if module contains only const enums or other modules with only const enums
|
||||
/* @internal */ isReferenced?: boolean; // True if the symbol is referenced elsewhere
|
||||
/* @internal */ isReferenced?: SymbolFlags; // True if the symbol is referenced elsewhere. Keeps track of the meaning of a reference in case a symbol is both a type parameter and parameter.
|
||||
/* @internal */ isReplaceableByMethod?: boolean; // Can this Javascript class property be replaced by a method symbol?
|
||||
/* @internal */ isAssigned?: boolean; // True if the symbol is a parameter with assignments
|
||||
}
|
||||
|
||||
+35
-39
@@ -570,17 +570,15 @@ namespace ts {
|
||||
export function getTextOfPropertyName(name: PropertyName): __String {
|
||||
switch (name.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
return (<Identifier>name).escapedText;
|
||||
return name.escapedText;
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
return escapeLeadingUnderscores((<LiteralExpression>name).text);
|
||||
return escapeLeadingUnderscores(name.text);
|
||||
case SyntaxKind.ComputedPropertyName:
|
||||
if (isStringOrNumericLiteral((<ComputedPropertyName>name).expression)) {
|
||||
return escapeLeadingUnderscores((<LiteralExpression>(<ComputedPropertyName>name).expression).text);
|
||||
}
|
||||
return isStringOrNumericLiteral(name.expression) ? escapeLeadingUnderscores(name.expression.text) : undefined;
|
||||
default:
|
||||
Debug.assertNever(name);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function entityNameToString(name: EntityNameOrEntityNameExpression): string {
|
||||
@@ -906,11 +904,10 @@ namespace ts {
|
||||
return;
|
||||
default:
|
||||
if (isFunctionLike(node)) {
|
||||
const name = (<FunctionLikeDeclaration>node).name;
|
||||
if (name && name.kind === SyntaxKind.ComputedPropertyName) {
|
||||
if (node.name && node.name.kind === SyntaxKind.ComputedPropertyName) {
|
||||
// Note that we will not include methods/accessors of a class because they would require
|
||||
// first descending into the class. This is by design.
|
||||
traverse((<ComputedPropertyName>name).expression);
|
||||
traverse(node.name.expression);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1221,15 +1218,15 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function getInvokedExpression(node: CallLikeExpression): Expression {
|
||||
if (node.kind === SyntaxKind.TaggedTemplateExpression) {
|
||||
return (<TaggedTemplateExpression>node).tag;
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.TaggedTemplateExpression:
|
||||
return node.tag;
|
||||
case SyntaxKind.JsxOpeningElement:
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
return node.tagName;
|
||||
default:
|
||||
return node.expression;
|
||||
}
|
||||
else if (isJsxOpeningLikeElement(node)) {
|
||||
return node.tagName;
|
||||
}
|
||||
|
||||
// Will either be a CallExpression, NewExpression, or Decorator.
|
||||
return (<CallExpression | Decorator>node).expression;
|
||||
}
|
||||
|
||||
export function nodeCanBeDecorated(node: ClassDeclaration): true;
|
||||
@@ -1628,7 +1625,7 @@ namespace ts {
|
||||
if (node.kind === SyntaxKind.ImportEqualsDeclaration) {
|
||||
const reference = (<ImportEqualsDeclaration>node).moduleReference;
|
||||
if (reference.kind === SyntaxKind.ExternalModuleReference) {
|
||||
return (<ExternalModuleReference>reference).expression;
|
||||
return reference.expression;
|
||||
}
|
||||
}
|
||||
if (node.kind === SyntaxKind.ExportDeclaration) {
|
||||
@@ -1640,20 +1637,20 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function getNamespaceDeclarationNode(node: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration): ImportEqualsDeclaration | NamespaceImport {
|
||||
if (node.kind === SyntaxKind.ImportEqualsDeclaration) {
|
||||
return <ImportEqualsDeclaration>node;
|
||||
}
|
||||
|
||||
const importClause = (<ImportDeclaration>node).importClause;
|
||||
if (importClause && importClause.namedBindings && importClause.namedBindings.kind === SyntaxKind.NamespaceImport) {
|
||||
return <NamespaceImport>importClause.namedBindings;
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
return node.importClause && tryCast(node.importClause.namedBindings, isNamespaceImport);
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
return node;
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
return undefined;
|
||||
default:
|
||||
return Debug.assertNever(node);
|
||||
}
|
||||
}
|
||||
|
||||
export function isDefaultImport(node: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration) {
|
||||
return node.kind === SyntaxKind.ImportDeclaration
|
||||
&& (<ImportDeclaration>node).importClause
|
||||
&& !!(<ImportDeclaration>node).importClause.name;
|
||||
return node.kind === SyntaxKind.ImportDeclaration && node.importClause && !!node.importClause.name;
|
||||
}
|
||||
|
||||
export function hasQuestionToken(node: Node) {
|
||||
@@ -2217,8 +2214,8 @@ namespace ts {
|
||||
|
||||
export function isDynamicName(name: DeclarationName): boolean {
|
||||
return name.kind === SyntaxKind.ComputedPropertyName &&
|
||||
!isStringOrNumericLiteral((<ComputedPropertyName>name).expression) &&
|
||||
!isWellKnownSymbolSyntactically((<ComputedPropertyName>name).expression);
|
||||
!isStringOrNumericLiteral(name.expression) &&
|
||||
!isWellKnownSymbolSyntactically(name.expression);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2258,7 +2255,7 @@ namespace ts {
|
||||
if (node.kind === SyntaxKind.StringLiteral ||
|
||||
node.kind === SyntaxKind.NumericLiteral) {
|
||||
|
||||
return (node as LiteralLikeNode).text;
|
||||
return node.text;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2273,7 +2270,7 @@ namespace ts {
|
||||
if (node.kind === SyntaxKind.StringLiteral ||
|
||||
node.kind === SyntaxKind.NumericLiteral) {
|
||||
|
||||
return escapeLeadingUnderscores((node as LiteralLikeNode).text);
|
||||
return escapeLeadingUnderscores(node.text);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4348,13 +4345,12 @@ namespace ts {
|
||||
// Covers remaining cases
|
||||
switch (hostNode.kind) {
|
||||
case SyntaxKind.VariableStatement:
|
||||
if ((hostNode as VariableStatement).declarationList &&
|
||||
(hostNode as VariableStatement).declarationList.declarations[0]) {
|
||||
return getDeclarationIdentifier((hostNode as VariableStatement).declarationList.declarations[0]);
|
||||
if (hostNode.declarationList && hostNode.declarationList.declarations[0]) {
|
||||
return getDeclarationIdentifier(hostNode.declarationList.declarations[0]);
|
||||
}
|
||||
return undefined;
|
||||
case SyntaxKind.ExpressionStatement:
|
||||
const expr = (hostNode as ExpressionStatement).expression;
|
||||
const expr = hostNode.expression;
|
||||
switch (expr.kind) {
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
return (expr as PropertyAccessExpression).name;
|
||||
@@ -4387,7 +4383,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function getNameOfJSDocTypedef(declaration: JSDocTypedefTag): Identifier | undefined {
|
||||
return declaration.name || nameForNamelessJSDocTypedef(declaration as JSDocTypedefTag);
|
||||
return declaration.name || nameForNamelessJSDocTypedef(declaration);
|
||||
}
|
||||
|
||||
export function getNameOfDeclaration(declaration: Declaration | Expression): DeclarationName | undefined {
|
||||
@@ -4443,7 +4439,7 @@ namespace ts {
|
||||
export function getJSDocParameterTags(param: ParameterDeclaration): ReadonlyArray<JSDocParameterTag> | undefined {
|
||||
if (param.name && isIdentifier(param.name)) {
|
||||
const name = param.name.escapedText;
|
||||
return getJSDocTags(param.parent).filter((tag): tag is JSDocParameterTag => isJSDocParameterTag(tag) && isIdentifier(tag.name) && tag.name.escapedText === name) as JSDocParameterTag[];
|
||||
return getJSDocTags(param.parent).filter((tag): tag is JSDocParameterTag => isJSDocParameterTag(tag) && isIdentifier(tag.name) && tag.name.escapedText === name);
|
||||
}
|
||||
// a binding pattern doesn't have a name, so it's not possible to match it a JSDoc parameter, which is identified by name
|
||||
return undefined;
|
||||
|
||||
@@ -1621,7 +1621,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
const diagnostics = ts.getPreEmitDiagnostics(this.languageService.getProgram());
|
||||
for (const diagnostic of diagnostics) {
|
||||
if (!ts.isString(diagnostic.messageText)) {
|
||||
let chainedMessage = <ts.DiagnosticMessageChain>diagnostic.messageText;
|
||||
let chainedMessage = diagnostic.messageText;
|
||||
let indentation = " ";
|
||||
while (chainedMessage) {
|
||||
resultString += indentation + chainedMessage.messageText + Harness.IO.newLine();
|
||||
@@ -3170,24 +3170,23 @@ Actual: ${stringify(fullActual)}`);
|
||||
}
|
||||
|
||||
private findFile(indexOrName: string | number) {
|
||||
let result: FourSlashFile;
|
||||
if (typeof indexOrName === "number") {
|
||||
const index = <number>indexOrName;
|
||||
const index = indexOrName;
|
||||
if (index >= this.testData.files.length) {
|
||||
throw new Error(`File index (${index}) in openFile was out of range. There are only ${this.testData.files.length} files in this test.`);
|
||||
}
|
||||
else {
|
||||
result = this.testData.files[index];
|
||||
return this.testData.files[index];
|
||||
}
|
||||
}
|
||||
else if (ts.isString(indexOrName)) {
|
||||
let name = <string>indexOrName;
|
||||
let name = indexOrName;
|
||||
|
||||
// names are stored in the compiler with this relative path, this allows people to use goTo.file on just the fileName
|
||||
name = name.indexOf("/") === -1 ? (this.basePath + "/" + name) : name;
|
||||
|
||||
const availableNames: string[] = [];
|
||||
result = ts.forEach(this.testData.files, file => {
|
||||
const result = ts.forEach(this.testData.files, file => {
|
||||
const fn = file.fileName;
|
||||
if (fn) {
|
||||
if (fn === name) {
|
||||
@@ -3200,12 +3199,11 @@ Actual: ${stringify(fullActual)}`);
|
||||
if (!result) {
|
||||
throw new Error(`No test file named "${name}" exists. Available file names are: ${availableNames.join(", ")}`);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
throw new Error("Unknown argument type");
|
||||
return ts.Debug.assertNever(indexOrName);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private getLineColStringAtPosition(position: number) {
|
||||
|
||||
@@ -57,7 +57,7 @@ var assert: typeof _chai.assert = _chai.assert;
|
||||
}
|
||||
|
||||
declare var __dirname: string; // Node-specific
|
||||
var global: NodeJS.Global = <any>Function("return this").call(undefined);
|
||||
var global: NodeJS.Global = Function("return this").call(undefined);
|
||||
|
||||
declare var window: {};
|
||||
declare var XMLHttpRequest: {
|
||||
@@ -767,10 +767,9 @@ namespace Harness {
|
||||
return ts.matchFiles(path, extension, exclude, include, useCaseSensitiveFileNames(), getCurrentDirectory(), depth, path => {
|
||||
const entry = fs.traversePath(path);
|
||||
if (entry && entry.isDirectory()) {
|
||||
const directory = <Utils.VirtualDirectory>entry;
|
||||
return {
|
||||
files: ts.map(directory.getFiles(), f => f.name),
|
||||
directories: ts.map(directory.getDirectories(), d => d.name)
|
||||
files: ts.map(entry.getFiles(), f => f.name),
|
||||
directories: ts.map(entry.getDirectories(), d => d.name)
|
||||
};
|
||||
}
|
||||
return { files: [], directories: [] };
|
||||
|
||||
@@ -143,7 +143,7 @@ namespace Harness.LanguageService {
|
||||
|
||||
public getScriptInfo(fileName: string): ScriptInfo {
|
||||
const fileEntry = this.virtualFileSystem.traversePath(fileName);
|
||||
return fileEntry && fileEntry.isFile() ? (<Utils.VirtualFile>fileEntry).content : undefined;
|
||||
return fileEntry && fileEntry.isFile() ? fileEntry.content : undefined;
|
||||
}
|
||||
|
||||
public addScript(fileName: string, content: string, isRootFile: boolean): void {
|
||||
@@ -522,6 +522,9 @@ namespace Harness.LanguageService {
|
||||
getApplicableRefactors(): ts.ApplicableRefactorInfo[] {
|
||||
throw new Error("Not supported on the shim.");
|
||||
}
|
||||
organizeImports(_scope: ts.OrganizeImportsScope, _formatOptions: ts.FormatCodeSettings): ReadonlyArray<ts.FileTextChanges> {
|
||||
throw new Error("Not supported on the shim.");
|
||||
}
|
||||
getEmitOutput(fileName: string): ts.EmitOutput {
|
||||
return unwrapJSONCallResult(this.shim.getEmitOutput(fileName));
|
||||
}
|
||||
|
||||
@@ -117,6 +117,7 @@
|
||||
"./unittests/tsserverProjectSystem.ts",
|
||||
"./unittests/tscWatchMode.ts",
|
||||
"./unittests/matchFiles.ts",
|
||||
"./unittests/organizeImports.ts",
|
||||
"./unittests/initializeTSConfig.ts",
|
||||
"./unittests/compileOnSave.ts",
|
||||
"./unittests/typingsInstaller.ts",
|
||||
|
||||
@@ -0,0 +1,384 @@
|
||||
/// <reference path="..\..\..\src\harness\harness.ts" />
|
||||
/// <reference path="..\..\..\src\harness\virtualFileSystem.ts" />
|
||||
|
||||
|
||||
namespace ts {
|
||||
describe("Organize imports", () => {
|
||||
describe("Sort imports", () => {
|
||||
it("Sort - non-relative vs non-relative", () => {
|
||||
assertSortsBefore(
|
||||
`import y from "lib1";`,
|
||||
`import x from "lib2";`);
|
||||
});
|
||||
|
||||
it("Sort - relative vs relative", () => {
|
||||
assertSortsBefore(
|
||||
`import y from "./lib1";`,
|
||||
`import x from "./lib2";`);
|
||||
});
|
||||
|
||||
it("Sort - relative vs non-relative", () => {
|
||||
assertSortsBefore(
|
||||
`import y from "lib";`,
|
||||
`import x from "./lib";`);
|
||||
});
|
||||
|
||||
function assertSortsBefore(importString1: string, importString2: string) {
|
||||
const [{moduleSpecifier: moduleSpecifier1}, {moduleSpecifier: moduleSpecifier2}] = parseImports(importString1, importString2);
|
||||
assert.equal(OrganizeImports.compareModuleSpecifiers(moduleSpecifier1, moduleSpecifier2), Comparison.LessThan);
|
||||
assert.equal(OrganizeImports.compareModuleSpecifiers(moduleSpecifier2, moduleSpecifier1), Comparison.GreaterThan);
|
||||
}
|
||||
});
|
||||
|
||||
describe("Coalesce imports", () => {
|
||||
it("No imports", () => {
|
||||
assert.isEmpty(OrganizeImports.coalesceImports([]));
|
||||
});
|
||||
|
||||
it("Sort specifiers", () => {
|
||||
const sortedImports = parseImports(`import { default as m, a as n, b, y, z as o } from "lib";`);
|
||||
const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports);
|
||||
const expectedCoalescedImports = parseImports(`import { a as n, b, default as m, y, z as o } from "lib";`);
|
||||
assertListEqual(actualCoalescedImports, expectedCoalescedImports);
|
||||
});
|
||||
|
||||
it("Combine side-effect-only imports", () => {
|
||||
const sortedImports = parseImports(
|
||||
`import "lib";`,
|
||||
`import "lib";`);
|
||||
const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports);
|
||||
const expectedCoalescedImports = parseImports(`import "lib";`);
|
||||
assertListEqual(actualCoalescedImports, expectedCoalescedImports);
|
||||
});
|
||||
|
||||
it("Combine namespace imports", () => {
|
||||
const sortedImports = parseImports(
|
||||
`import * as x from "lib";`,
|
||||
`import * as y from "lib";`);
|
||||
const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports);
|
||||
const expectedCoalescedImports = sortedImports;
|
||||
assertListEqual(actualCoalescedImports, expectedCoalescedImports);
|
||||
});
|
||||
|
||||
it("Combine default imports", () => {
|
||||
const sortedImports = parseImports(
|
||||
`import x from "lib";`,
|
||||
`import y from "lib";`);
|
||||
const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports);
|
||||
const expectedCoalescedImports = parseImports(`import { default as x, default as y } from "lib";`);
|
||||
assertListEqual(actualCoalescedImports, expectedCoalescedImports);
|
||||
});
|
||||
|
||||
it("Combine property imports", () => {
|
||||
const sortedImports = parseImports(
|
||||
`import { x } from "lib";`,
|
||||
`import { y as z } from "lib";`);
|
||||
const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports);
|
||||
const expectedCoalescedImports = parseImports(`import { x, y as z } from "lib";`);
|
||||
assertListEqual(actualCoalescedImports, expectedCoalescedImports);
|
||||
});
|
||||
|
||||
it("Combine side-effect-only import with namespace import", () => {
|
||||
const sortedImports = parseImports(
|
||||
`import "lib";`,
|
||||
`import * as x from "lib";`);
|
||||
const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports);
|
||||
const expectedCoalescedImports = sortedImports;
|
||||
assertListEqual(actualCoalescedImports, expectedCoalescedImports);
|
||||
});
|
||||
|
||||
it("Combine side-effect-only import with default import", () => {
|
||||
const sortedImports = parseImports(
|
||||
`import "lib";`,
|
||||
`import x from "lib";`);
|
||||
const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports);
|
||||
const expectedCoalescedImports = sortedImports;
|
||||
assertListEqual(actualCoalescedImports, expectedCoalescedImports);
|
||||
});
|
||||
|
||||
it("Combine side-effect-only import with property import", () => {
|
||||
const sortedImports = parseImports(
|
||||
`import "lib";`,
|
||||
`import { x } from "lib";`);
|
||||
const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports);
|
||||
const expectedCoalescedImports = sortedImports;
|
||||
assertListEqual(actualCoalescedImports, expectedCoalescedImports);
|
||||
});
|
||||
|
||||
it("Combine namespace import with default import", () => {
|
||||
const sortedImports = parseImports(
|
||||
`import * as x from "lib";`,
|
||||
`import y from "lib";`);
|
||||
const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports);
|
||||
const expectedCoalescedImports = parseImports(
|
||||
`import y, * as x from "lib";`);
|
||||
assertListEqual(actualCoalescedImports, expectedCoalescedImports);
|
||||
});
|
||||
|
||||
it("Combine namespace import with property import", () => {
|
||||
const sortedImports = parseImports(
|
||||
`import * as x from "lib";`,
|
||||
`import { y } from "lib";`);
|
||||
const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports);
|
||||
const expectedCoalescedImports = sortedImports;
|
||||
assertListEqual(actualCoalescedImports, expectedCoalescedImports);
|
||||
});
|
||||
|
||||
it("Combine default import with property import", () => {
|
||||
const sortedImports = parseImports(
|
||||
`import x from "lib";`,
|
||||
`import { y } from "lib";`);
|
||||
const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports);
|
||||
const expectedCoalescedImports = parseImports(
|
||||
`import x, { y } from "lib";`);
|
||||
assertListEqual(actualCoalescedImports, expectedCoalescedImports);
|
||||
});
|
||||
|
||||
it("Combine many imports", () => {
|
||||
const sortedImports = parseImports(
|
||||
`import "lib";`,
|
||||
`import * as y from "lib";`,
|
||||
`import w from "lib";`,
|
||||
`import { b } from "lib";`,
|
||||
`import "lib";`,
|
||||
`import * as x from "lib";`,
|
||||
`import z from "lib";`,
|
||||
`import { a } from "lib";`);
|
||||
const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports);
|
||||
const expectedCoalescedImports = parseImports(
|
||||
`import "lib";`,
|
||||
`import * as x from "lib";`,
|
||||
`import * as y from "lib";`,
|
||||
`import { a, b, default as w, default as z } from "lib";`);
|
||||
assertListEqual(actualCoalescedImports, expectedCoalescedImports);
|
||||
});
|
||||
|
||||
// This is descriptive, rather than normative
|
||||
it("Combine two namespace imports with one default import", () => {
|
||||
const sortedImports = parseImports(
|
||||
`import * as x from "lib";`,
|
||||
`import * as y from "lib";`,
|
||||
`import z from "lib";`);
|
||||
const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports);
|
||||
const expectedCoalescedImports = sortedImports;
|
||||
assertListEqual(actualCoalescedImports, expectedCoalescedImports);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Baselines", () => {
|
||||
|
||||
const libFile = {
|
||||
path: "/lib.ts",
|
||||
content: `
|
||||
export function F1();
|
||||
export default function F2();
|
||||
`,
|
||||
};
|
||||
|
||||
// Don't bother to actually emit a baseline for this.
|
||||
it("NoImports", () => {
|
||||
const testFile = {
|
||||
path: "/a.ts",
|
||||
content: "function F() { }",
|
||||
};
|
||||
const languageService = makeLanguageService(testFile);
|
||||
const changes = languageService.organizeImports({ type: "file", fileName: testFile.path }, testFormatOptions);
|
||||
assert.isEmpty(changes);
|
||||
});
|
||||
|
||||
testOrganizeImports("Simple",
|
||||
{
|
||||
path: "/test.ts",
|
||||
content: `
|
||||
import { F1, F2 } from "lib";
|
||||
import * as NS from "lib";
|
||||
import D from "lib";
|
||||
|
||||
NS.F1();
|
||||
D();
|
||||
F1();
|
||||
F2();
|
||||
`,
|
||||
},
|
||||
libFile);
|
||||
|
||||
testOrganizeImports("MoveToTop",
|
||||
{
|
||||
path: "/test.ts",
|
||||
content: `
|
||||
import { F1, F2 } from "lib";
|
||||
F1();
|
||||
F2();
|
||||
import * as NS from "lib";
|
||||
NS.F1();
|
||||
import D from "lib";
|
||||
D();
|
||||
`,
|
||||
},
|
||||
libFile);
|
||||
|
||||
// tslint:disable no-invalid-template-strings
|
||||
testOrganizeImports("MoveToTop_Invalid",
|
||||
{
|
||||
path: "/test.ts",
|
||||
content: `
|
||||
import { F1, F2 } from "lib";
|
||||
F1();
|
||||
F2();
|
||||
import * as NS from "lib";
|
||||
NS.F1();
|
||||
import b from ${"`${'lib'}`"};
|
||||
import a from ${"`${'lib'}`"};
|
||||
import D from "lib";
|
||||
D();
|
||||
`,
|
||||
},
|
||||
libFile);
|
||||
// tslint:enable no-invalid-template-strings
|
||||
|
||||
testOrganizeImports("CoalesceMultipleModules",
|
||||
{
|
||||
path: "/test.ts",
|
||||
content: `
|
||||
import { d } from "lib1";
|
||||
import { b } from "lib1";
|
||||
import { c } from "lib2";
|
||||
import { a } from "lib2";
|
||||
`,
|
||||
},
|
||||
{ path: "/lib1.ts", content: "" },
|
||||
{ path: "/lib2.ts", content: "" });
|
||||
|
||||
testOrganizeImports("CoalesceTrivia",
|
||||
{
|
||||
path: "/test.ts",
|
||||
content: `
|
||||
/*A*/import /*B*/ { /*C*/ F2 /*D*/ } /*E*/ from /*F*/ "lib" /*G*/;/*H*/ //I
|
||||
/*J*/import /*K*/ { /*L*/ F1 /*M*/ } /*N*/ from /*O*/ "lib" /*P*/;/*Q*/ //R
|
||||
|
||||
F1();
|
||||
F2();
|
||||
`,
|
||||
},
|
||||
libFile);
|
||||
|
||||
testOrganizeImports("SortTrivia",
|
||||
{
|
||||
path: "/test.ts",
|
||||
content: `
|
||||
/*A*/import /*B*/ "lib2" /*C*/;/*D*/ //E
|
||||
/*F*/import /*G*/ "lib1" /*H*/;/*I*/ //J
|
||||
`,
|
||||
},
|
||||
{ path: "/lib1.ts", content: "" },
|
||||
{ path: "/lib2.ts", content: "" });
|
||||
|
||||
function testOrganizeImports(testName: string, testFile: TestFSWithWatch.FileOrFolder, ...otherFiles: TestFSWithWatch.FileOrFolder[]) {
|
||||
it(testName, () => runBaseline(`organizeImports/${testName}.ts`, testFile, ...otherFiles));
|
||||
}
|
||||
|
||||
function runBaseline(baselinePath: string, testFile: TestFSWithWatch.FileOrFolder, ...otherFiles: TestFSWithWatch.FileOrFolder[]) {
|
||||
const { path: testPath, content: testContent } = testFile;
|
||||
const languageService = makeLanguageService(testFile, ...otherFiles);
|
||||
const changes = languageService.organizeImports({ type: "file", fileName: testPath }, testFormatOptions);
|
||||
assert.equal(changes.length, 1);
|
||||
assert.equal(changes[0].fileName, testPath);
|
||||
|
||||
Harness.Baseline.runBaseline(baselinePath, () => {
|
||||
const newText = textChanges.applyChanges(testContent, changes[0].textChanges);
|
||||
return [
|
||||
"// ==ORIGINAL==",
|
||||
testContent,
|
||||
"// ==ORGANIZED==",
|
||||
newText,
|
||||
].join(newLineCharacter);
|
||||
});
|
||||
}
|
||||
|
||||
function makeLanguageService(...files: TestFSWithWatch.FileOrFolder[]) {
|
||||
const host = projectSystem.createServerHost(files);
|
||||
const projectService = projectSystem.createProjectService(host, { useSingleInferredProject: true });
|
||||
files.forEach(f => projectService.openClientFile(f.path));
|
||||
return projectService.inferredProjects[0].getLanguageService();
|
||||
}
|
||||
});
|
||||
|
||||
function parseImports(...importStrings: string[]): ReadonlyArray<ImportDeclaration> {
|
||||
const sourceFile = createSourceFile("a.ts", importStrings.join("\n"), ScriptTarget.ES2015, /*setParentNodes*/ true, ScriptKind.TS);
|
||||
const imports = filter(sourceFile.statements, isImportDeclaration);
|
||||
assert.equal(imports.length, importStrings.length);
|
||||
return imports;
|
||||
}
|
||||
|
||||
function assertEqual(node1?: Node, node2?: Node) {
|
||||
if (node1 === undefined) {
|
||||
assert.isUndefined(node2);
|
||||
return;
|
||||
}
|
||||
else if (node2 === undefined) {
|
||||
assert.isUndefined(node1); // Guaranteed to fail
|
||||
return;
|
||||
}
|
||||
|
||||
assert.equal(node1.kind, node2.kind);
|
||||
|
||||
switch (node1.kind) {
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
const decl1 = node1 as ImportDeclaration;
|
||||
const decl2 = node2 as ImportDeclaration;
|
||||
assertEqual(decl1.importClause, decl2.importClause);
|
||||
assertEqual(decl1.moduleSpecifier, decl2.moduleSpecifier);
|
||||
break;
|
||||
case SyntaxKind.ImportClause:
|
||||
const clause1 = node1 as ImportClause;
|
||||
const clause2 = node2 as ImportClause;
|
||||
assertEqual(clause1.name, clause2.name);
|
||||
assertEqual(clause1.namedBindings, clause2.namedBindings);
|
||||
break;
|
||||
case SyntaxKind.NamespaceImport:
|
||||
const nsi1 = node1 as NamespaceImport;
|
||||
const nsi2 = node2 as NamespaceImport;
|
||||
assertEqual(nsi1.name, nsi2.name);
|
||||
break;
|
||||
case SyntaxKind.NamedImports:
|
||||
const ni1 = node1 as NamedImports;
|
||||
const ni2 = node2 as NamedImports;
|
||||
assertListEqual(ni1.elements, ni2.elements);
|
||||
break;
|
||||
case SyntaxKind.ImportSpecifier:
|
||||
const is1 = node1 as ImportSpecifier;
|
||||
const is2 = node2 as ImportSpecifier;
|
||||
assertEqual(is1.name, is2.name);
|
||||
assertEqual(is1.propertyName, is2.propertyName);
|
||||
break;
|
||||
case SyntaxKind.Identifier:
|
||||
const id1 = node1 as Identifier;
|
||||
const id2 = node2 as Identifier;
|
||||
assert.equal(id1.text, id2.text);
|
||||
break;
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||
const sl1 = node1 as LiteralLikeNode;
|
||||
const sl2 = node2 as LiteralLikeNode;
|
||||
assert.equal(sl1.text, sl2.text);
|
||||
break;
|
||||
default:
|
||||
assert.equal(node1.getText(), node2.getText());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function assertListEqual(list1: ReadonlyArray<Node>, list2: ReadonlyArray<Node>) {
|
||||
if (list1 === undefined || list2 === undefined) {
|
||||
assert.isUndefined(list1);
|
||||
assert.isUndefined(list2);
|
||||
return;
|
||||
}
|
||||
|
||||
assert.equal(list1.length, list2.length);
|
||||
for (let i = 0; i < list1.length; i++) {
|
||||
assertEqual(list1[i], list2[i]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -165,7 +165,7 @@ namespace ts {
|
||||
|
||||
export function updateProgram(oldProgram: ProgramWithSourceTexts, rootNames: ReadonlyArray<string>, options: CompilerOptions, updater: (files: NamedSourceText[]) => void, newTexts?: NamedSourceText[]) {
|
||||
if (!newTexts) {
|
||||
newTexts = (<ProgramWithSourceTexts>oldProgram).sourceTexts.slice(0);
|
||||
newTexts = oldProgram.sourceTexts.slice(0);
|
||||
}
|
||||
updater(newTexts);
|
||||
const host = createTestCompilerHost(newTexts, options.target, oldProgram);
|
||||
|
||||
@@ -262,6 +262,8 @@ namespace ts.server {
|
||||
CommandNames.GetApplicableRefactors,
|
||||
CommandNames.GetEditsForRefactor,
|
||||
CommandNames.GetEditsForRefactorFull,
|
||||
CommandNames.OrganizeImports,
|
||||
CommandNames.OrganizeImportsFull,
|
||||
];
|
||||
|
||||
it("should not throw when commands are executed with invalid arguments", () => {
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace ts {
|
||||
Harness.Baseline.runBaseline(`textChanges/${caption}.js`, () => {
|
||||
const sourceFile = createSourceFile("source.ts", text, ScriptTarget.ES2015, /*setParentNodes*/ true);
|
||||
const rulesProvider = getRuleProvider(placeOpenBraceOnNewLineForFunctions);
|
||||
const changeTracker = new textChanges.ChangeTracker(printerOptions.newLine, rulesProvider, validateNodes ? verifyPositions : undefined);
|
||||
const changeTracker = new textChanges.ChangeTracker(newLineCharacter, rulesProvider, validateNodes ? verifyPositions : undefined);
|
||||
testBlock(sourceFile, changeTracker);
|
||||
const changes = changeTracker.getChanges();
|
||||
assert.equal(changes.length, 1);
|
||||
@@ -91,7 +91,7 @@ namespace M
|
||||
}
|
||||
}`;
|
||||
runSingleFileTest("extractMethodLike", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
const statements = (<Block>(<FunctionDeclaration>findChild("foo", sourceFile)).body).statements.slice(1);
|
||||
const statements = (<FunctionDeclaration>findChild("foo", sourceFile)).body.statements.slice(1);
|
||||
const newFunction = createFunctionDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
|
||||
@@ -2560,7 +2560,7 @@ namespace ts.projectSystem {
|
||||
}
|
||||
assert.equal(e.eventName, server.ProjectLanguageServiceStateEvent);
|
||||
assert.equal(e.data.project.getProjectName(), config.path, "project name");
|
||||
lastEvent = <server.ProjectLanguageServiceStateEvent>e;
|
||||
lastEvent = e;
|
||||
}
|
||||
});
|
||||
session.executeCommand(<protocol.OpenRequest>{
|
||||
|
||||
@@ -42,12 +42,12 @@ namespace Utils {
|
||||
|
||||
getDirectory(name: string): VirtualDirectory {
|
||||
const entry = this.getFileSystemEntry(name);
|
||||
return entry.isDirectory() ? <VirtualDirectory>entry : undefined;
|
||||
return entry.isDirectory() ? entry : undefined;
|
||||
}
|
||||
|
||||
getFile(name: string): VirtualFile {
|
||||
const entry = this.getFileSystemEntry(name);
|
||||
return entry.isFile() ? <VirtualFile>entry : undefined;
|
||||
return entry.isFile() ? entry : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace Utils {
|
||||
return directory;
|
||||
}
|
||||
else if (entry.isDirectory()) {
|
||||
return <VirtualDirectory>entry;
|
||||
return entry;
|
||||
}
|
||||
else {
|
||||
return undefined;
|
||||
@@ -149,7 +149,7 @@ namespace Utils {
|
||||
return undefined;
|
||||
}
|
||||
else if (entry.isDirectory()) {
|
||||
directory = <VirtualDirectory>entry;
|
||||
directory = entry;
|
||||
}
|
||||
else {
|
||||
return entry;
|
||||
@@ -167,10 +167,9 @@ namespace Utils {
|
||||
getAccessibleFileSystemEntries(path: string) {
|
||||
const entry = this.traversePath(path);
|
||||
if (entry && entry.isDirectory()) {
|
||||
const directory = <VirtualDirectory>entry;
|
||||
return {
|
||||
files: ts.map(directory.getFiles(), f => f.name),
|
||||
directories: ts.map(directory.getDirectories(), d => d.name)
|
||||
files: ts.map(entry.getFiles(), f => f.name),
|
||||
directories: ts.map(entry.getDirectories(), d => d.name)
|
||||
};
|
||||
}
|
||||
return { files: [], directories: [] };
|
||||
|
||||
Vendored
+409
-393
File diff suppressed because it is too large
Load Diff
Vendored
+53
-45
@@ -128,7 +128,9 @@ interface SyncEventInit extends ExtendableEventInit {
|
||||
lastChance?: boolean;
|
||||
}
|
||||
|
||||
type EventListener = (evt: Event) => void | { handleEvent(evt: Event): void; };
|
||||
interface EventListener {
|
||||
(evt: Event): void;
|
||||
}
|
||||
|
||||
interface AudioBuffer {
|
||||
readonly duration: number;
|
||||
@@ -390,9 +392,9 @@ declare var Event: {
|
||||
};
|
||||
|
||||
interface EventTarget {
|
||||
addEventListener(type: string, listener: EventListener, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
dispatchEvent(evt: Event): boolean;
|
||||
removeEventListener(type: string, listener: EventListener, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var EventTarget: {
|
||||
@@ -430,9 +432,9 @@ interface FileReader extends EventTarget, MSBaseReader {
|
||||
readAsDataURL(blob: Blob): void;
|
||||
readAsText(blob: Blob, encoding?: string): void;
|
||||
addEventListener<K extends keyof MSBaseReaderEventMap>(type: K, listener: (this: FileReader, ev: MSBaseReaderEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListener, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof MSBaseReaderEventMap>(type: K, listener: (this: FileReader, ev: MSBaseReaderEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListener, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var FileReader: {
|
||||
@@ -515,9 +517,9 @@ interface IDBDatabase extends EventTarget {
|
||||
addEventListener(type: "versionchange", listener: (this: IDBDatabase, ev: IDBVersionChangeEvent) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener(type: "versionchange", listener: (this: IDBDatabase, ev: IDBVersionChangeEvent) => any, options?: boolean | EventListenerOptions): void;
|
||||
addEventListener<K extends keyof IDBDatabaseEventMap>(type: K, listener: (this: IDBDatabase, ev: IDBDatabaseEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListener, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof IDBDatabaseEventMap>(type: K, listener: (this: IDBDatabase, ev: IDBDatabaseEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListener, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var IDBDatabase: {
|
||||
@@ -602,9 +604,9 @@ interface IDBOpenDBRequest extends IDBRequest {
|
||||
onblocked: (this: IDBOpenDBRequest, ev: Event) => any;
|
||||
onupgradeneeded: (this: IDBOpenDBRequest, ev: IDBVersionChangeEvent) => any;
|
||||
addEventListener<K extends keyof IDBOpenDBRequestEventMap>(type: K, listener: (this: IDBOpenDBRequest, ev: IDBOpenDBRequestEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListener, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof IDBOpenDBRequestEventMap>(type: K, listener: (this: IDBOpenDBRequest, ev: IDBOpenDBRequestEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListener, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var IDBOpenDBRequest: {
|
||||
@@ -626,9 +628,9 @@ interface IDBRequest extends EventTarget {
|
||||
source: IDBObjectStore | IDBIndex | IDBCursor;
|
||||
readonly transaction: IDBTransaction;
|
||||
addEventListener<K extends keyof IDBRequestEventMap>(type: K, listener: (this: IDBRequest, ev: IDBRequestEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListener, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof IDBRequestEventMap>(type: K, listener: (this: IDBRequest, ev: IDBRequestEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListener, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var IDBRequest: {
|
||||
@@ -655,9 +657,9 @@ interface IDBTransaction extends EventTarget {
|
||||
readonly READ_WRITE: string;
|
||||
readonly VERSION_CHANGE: string;
|
||||
addEventListener<K extends keyof IDBTransactionEventMap>(type: K, listener: (this: IDBTransaction, ev: IDBTransactionEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListener, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof IDBTransactionEventMap>(type: K, listener: (this: IDBTransaction, ev: IDBTransactionEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListener, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var IDBTransaction: {
|
||||
@@ -723,9 +725,9 @@ interface MessagePort extends EventTarget {
|
||||
postMessage(message?: any, transfer?: any[]): void;
|
||||
start(): void;
|
||||
addEventListener<K extends keyof MessagePortEventMap>(type: K, listener: (this: MessagePort, ev: MessagePortEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListener, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof MessagePortEventMap>(type: K, listener: (this: MessagePort, ev: MessagePortEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListener, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var MessagePort: {
|
||||
@@ -754,9 +756,9 @@ interface Notification extends EventTarget {
|
||||
readonly title: string;
|
||||
close(): void;
|
||||
addEventListener<K extends keyof NotificationEventMap>(type: K, listener: (this: Notification, ev: NotificationEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListener, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof NotificationEventMap>(type: K, listener: (this: Notification, ev: NotificationEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListener, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var Notification: {
|
||||
@@ -985,9 +987,9 @@ interface ServiceWorker extends EventTarget, AbstractWorker {
|
||||
readonly state: ServiceWorkerState;
|
||||
postMessage(message: any, transfer?: any[]): void;
|
||||
addEventListener<K extends keyof ServiceWorkerEventMap>(type: K, listener: (this: ServiceWorker, ev: ServiceWorkerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListener, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof ServiceWorkerEventMap>(type: K, listener: (this: ServiceWorker, ev: ServiceWorkerEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListener, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var ServiceWorker: {
|
||||
@@ -1012,9 +1014,9 @@ interface ServiceWorkerRegistration extends EventTarget {
|
||||
unregister(): Promise<boolean>;
|
||||
update(): Promise<void>;
|
||||
addEventListener<K extends keyof ServiceWorkerRegistrationEventMap>(type: K, listener: (this: ServiceWorkerRegistration, ev: ServiceWorkerRegistrationEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListener, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof ServiceWorkerRegistrationEventMap>(type: K, listener: (this: ServiceWorkerRegistration, ev: ServiceWorkerRegistrationEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListener, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var ServiceWorkerRegistration: {
|
||||
@@ -1080,9 +1082,9 @@ interface WebSocket extends EventTarget {
|
||||
readonly CONNECTING: number;
|
||||
readonly OPEN: number;
|
||||
addEventListener<K extends keyof WebSocketEventMap>(type: K, listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListener, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof WebSocketEventMap>(type: K, listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListener, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var WebSocket: {
|
||||
@@ -1103,9 +1105,9 @@ interface Worker extends EventTarget, AbstractWorker {
|
||||
postMessage(message: any, transfer?: any[]): void;
|
||||
terminate(): void;
|
||||
addEventListener<K extends keyof WorkerEventMap>(type: K, listener: (this: Worker, ev: WorkerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListener, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof WorkerEventMap>(type: K, listener: (this: Worker, ev: WorkerEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListener, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var Worker: {
|
||||
@@ -1146,9 +1148,9 @@ interface XMLHttpRequest extends EventTarget, XMLHttpRequestEventTarget {
|
||||
readonly OPENED: number;
|
||||
readonly UNSENT: number;
|
||||
addEventListener<K extends keyof XMLHttpRequestEventMap>(type: K, listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListener, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof XMLHttpRequestEventMap>(type: K, listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListener, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var XMLHttpRequest: {
|
||||
@@ -1163,9 +1165,9 @@ declare var XMLHttpRequest: {
|
||||
|
||||
interface XMLHttpRequestUpload extends EventTarget, XMLHttpRequestEventTarget {
|
||||
addEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListener, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListener, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var XMLHttpRequestUpload: {
|
||||
@@ -1180,9 +1182,9 @@ interface AbstractWorkerEventMap {
|
||||
interface AbstractWorker {
|
||||
onerror: (this: AbstractWorker, ev: ErrorEvent) => any;
|
||||
addEventListener<K extends keyof AbstractWorkerEventMap>(type: K, listener: (this: AbstractWorker, ev: AbstractWorkerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListener, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof AbstractWorkerEventMap>(type: K, listener: (this: AbstractWorker, ev: AbstractWorkerEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListener, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
interface Body {
|
||||
@@ -1220,9 +1222,9 @@ interface MSBaseReader {
|
||||
readonly EMPTY: number;
|
||||
readonly LOADING: number;
|
||||
addEventListener<K extends keyof MSBaseReaderEventMap>(type: K, listener: (this: MSBaseReader, ev: MSBaseReaderEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListener, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof MSBaseReaderEventMap>(type: K, listener: (this: MSBaseReader, ev: MSBaseReaderEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListener, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
interface NavigatorBeacon {
|
||||
@@ -1277,9 +1279,9 @@ interface XMLHttpRequestEventTarget {
|
||||
onprogress: (this: XMLHttpRequest, ev: ProgressEvent) => any;
|
||||
ontimeout: (this: XMLHttpRequest, ev: ProgressEvent) => any;
|
||||
addEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestEventTarget, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListener, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestEventTarget, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListener, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
interface Client {
|
||||
@@ -1315,9 +1317,9 @@ interface DedicatedWorkerGlobalScope extends WorkerGlobalScope {
|
||||
close(): void;
|
||||
postMessage(message: any, transfer?: any[]): void;
|
||||
addEventListener<K extends keyof DedicatedWorkerGlobalScopeEventMap>(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListener, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof DedicatedWorkerGlobalScopeEventMap>(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListener, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var DedicatedWorkerGlobalScope: {
|
||||
@@ -1428,9 +1430,9 @@ interface ServiceWorkerGlobalScope extends WorkerGlobalScope {
|
||||
readonly registration: ServiceWorkerRegistration;
|
||||
skipWaiting(): Promise<void>;
|
||||
addEventListener<K extends keyof ServiceWorkerGlobalScopeEventMap>(type: K, listener: (this: ServiceWorkerGlobalScope, ev: ServiceWorkerGlobalScopeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListener, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof ServiceWorkerGlobalScopeEventMap>(type: K, listener: (this: ServiceWorkerGlobalScope, ev: ServiceWorkerGlobalScopeEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListener, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var ServiceWorkerGlobalScope: {
|
||||
@@ -1475,9 +1477,9 @@ interface WorkerGlobalScope extends EventTarget, WorkerUtils, WindowConsole, Glo
|
||||
createImageBitmap(image: ImageBitmap | ImageData | Blob, options?: ImageBitmapOptions): Promise<ImageBitmap>;
|
||||
createImageBitmap(image: ImageBitmap | ImageData | Blob, sx: number, sy: number, sw: number, sh: number, options?: ImageBitmapOptions): Promise<ImageBitmap>;
|
||||
addEventListener<K extends keyof WorkerGlobalScopeEventMap>(type: K, listener: (this: WorkerGlobalScope, ev: WorkerGlobalScopeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListener, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof WorkerGlobalScopeEventMap>(type: K, listener: (this: WorkerGlobalScope, ev: WorkerGlobalScopeEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListener, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var WorkerGlobalScope: {
|
||||
@@ -1535,9 +1537,9 @@ interface BroadcastChannel extends EventTarget {
|
||||
close(): void;
|
||||
postMessage(message: any): void;
|
||||
addEventListener<K extends keyof BroadcastChannelEventMap>(type: K, listener: (this: BroadcastChannel, ev: BroadcastChannelEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListener, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof BroadcastChannelEventMap>(type: K, listener: (this: BroadcastChannel, ev: BroadcastChannelEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListener, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var BroadcastChannel: {
|
||||
@@ -1617,6 +1619,10 @@ interface FilePropertyBag extends BlobPropertyBag {
|
||||
lastModified?: number;
|
||||
}
|
||||
|
||||
interface EventListenerObject {
|
||||
handleEvent(evt: Event): void;
|
||||
}
|
||||
|
||||
interface ProgressEventInit extends EventInit {
|
||||
lengthComputable?: boolean;
|
||||
loaded?: number;
|
||||
@@ -1843,6 +1849,8 @@ interface EventSourceInit {
|
||||
readonly withCredentials: boolean;
|
||||
}
|
||||
|
||||
declare type EventListenerOrEventListenerObject = EventListener | EventListenerObject;
|
||||
|
||||
interface DecodeErrorCallback {
|
||||
(error: DOMException): void;
|
||||
}
|
||||
@@ -1899,9 +1907,9 @@ declare var console: Console;
|
||||
declare function fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;
|
||||
declare function dispatchEvent(evt: Event): boolean;
|
||||
declare function addEventListener<K extends keyof DedicatedWorkerGlobalScopeEventMap>(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
declare function addEventListener(type: string, listener: EventListener, options?: boolean | AddEventListenerOptions): void;
|
||||
declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
declare function removeEventListener<K extends keyof DedicatedWorkerGlobalScopeEventMap>(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
declare function removeEventListener(type: string, listener: EventListener, options?: boolean | EventListenerOptions): void;
|
||||
declare function removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
type AlgorithmIdentifier = string | Algorithm;
|
||||
type BodyInit = Blob | BufferSource | FormData | string;
|
||||
type IDBKeyPath = string;
|
||||
|
||||
@@ -3021,6 +3021,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Enum_declarations_can_only_merge_with_namespace_or_other_enum_declarations_2567" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Enum declarations can only merge with namespace or other enum declarations.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[È possibile unire dichiarazioni di enumerazione solo con lo spazio dei nomi o altre dichiarazioni di enumerazione.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Enum_declarations_must_all_be_const_or_non_const_2473" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Enum declarations must all be const or non-const.]]></Val>
|
||||
|
||||
@@ -3011,6 +3011,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Enum_declarations_can_only_merge_with_namespace_or_other_enum_declarations_2567" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Enum declarations can only merge with namespace or other enum declarations.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Deklaracje wyliczeń można scalać tylko z przestrzeniami nazw lub innymi deklaracjami wyliczeń.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Enum_declarations_must_all_be_const_or_non_const_2473" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Enum declarations must all be const or non-const.]]></Val>
|
||||
|
||||
@@ -629,6 +629,10 @@ namespace ts.server {
|
||||
};
|
||||
}
|
||||
|
||||
organizeImports(_scope: OrganizeImportsScope, _formatOptions: FormatCodeSettings): ReadonlyArray<FileTextChanges> {
|
||||
return notImplemented();
|
||||
}
|
||||
|
||||
private convertCodeEditsToTextChanges(edits: protocol.FileCodeEdits[]): FileTextChanges[] {
|
||||
return edits.map(edit => {
|
||||
const fileName = edit.fileName;
|
||||
|
||||
@@ -2026,7 +2026,7 @@ namespace ts.server {
|
||||
}
|
||||
else {
|
||||
configFileErrors = project.getAllProjectErrors();
|
||||
this.sendConfigFileDiagEvent(project as ConfiguredProject, fileName);
|
||||
this.sendConfigFileDiagEvent(project, fileName);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -113,6 +113,10 @@ namespace ts.server.protocol {
|
||||
/* @internal */
|
||||
GetEditsForRefactorFull = "getEditsForRefactor-full",
|
||||
|
||||
OrganizeImports = "organizeImports",
|
||||
/* @internal */
|
||||
OrganizeImportsFull = "organizeImports-full",
|
||||
|
||||
// NOTE: If updating this, be sure to also update `allCommandNames` in `harness/unittests/session.ts`.
|
||||
}
|
||||
|
||||
@@ -547,6 +551,27 @@ namespace ts.server.protocol {
|
||||
renameFilename?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Organize imports by:
|
||||
* 1) Removing unused imports
|
||||
* 2) Coalescing imports from the same module
|
||||
* 3) Sorting imports
|
||||
*/
|
||||
export interface OrganizeImportsRequest extends Request {
|
||||
command: CommandTypes.OrganizeImports;
|
||||
arguments: OrganizeImportsRequestArgs;
|
||||
}
|
||||
|
||||
export type OrganizeImportsScope = GetCombinedCodeFixScope;
|
||||
|
||||
export interface OrganizeImportsRequestArgs {
|
||||
scope: OrganizeImportsScope;
|
||||
}
|
||||
|
||||
export interface OrganizeImportsResponse extends Response {
|
||||
edits: ReadonlyArray<FileCodeEdits>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request for the available codefixes at a specific position.
|
||||
*/
|
||||
|
||||
@@ -680,7 +680,7 @@ namespace ts.server {
|
||||
|
||||
// Skipped all children
|
||||
const { leaf } = this.lineNumberToInfo(this.lineCount(), 0);
|
||||
return { oneBasedLine: this.lineCount(), zeroBasedColumn: leaf.charCount(), lineText: undefined };
|
||||
return { oneBasedLine: this.lineCount(), zeroBasedColumn: leaf ? leaf.charCount() : 0, lineText: undefined };
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -765,13 +765,13 @@ namespace ts.server {
|
||||
for (let i = 0; i < splitNodeCount; i++) {
|
||||
splitNodes[i] = new LineNode();
|
||||
}
|
||||
let splitNode = <LineNode>splitNodes[0];
|
||||
let splitNode = splitNodes[0];
|
||||
while (nodeIndex < nodeCount) {
|
||||
splitNode.add(nodes[nodeIndex]);
|
||||
nodeIndex++;
|
||||
if (splitNode.children.length === lineCollectionCapacity) {
|
||||
splitNodeIndex++;
|
||||
splitNode = <LineNode>splitNodes[splitNodeIndex];
|
||||
splitNode = splitNodes[splitNodeIndex];
|
||||
}
|
||||
}
|
||||
for (let i = splitNodes.length - 1; i >= 0; i--) {
|
||||
@@ -785,7 +785,7 @@ namespace ts.server {
|
||||
}
|
||||
this.updateCounts();
|
||||
for (let i = 0; i < splitNodeCount; i++) {
|
||||
(<LineNode>splitNodes[i]).updateCounts();
|
||||
splitNodes[i].updateCounts();
|
||||
}
|
||||
return splitNodes;
|
||||
}
|
||||
|
||||
@@ -1597,6 +1597,19 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
private organizeImports({ scope }: protocol.OrganizeImportsRequestArgs, simplifiedResult: boolean): ReadonlyArray<protocol.FileCodeEdits> | ReadonlyArray<FileTextChanges> {
|
||||
Debug.assert(scope.type === "file");
|
||||
const { file, project } = this.getFileAndProject(scope.args);
|
||||
const formatOptions = this.projectService.getFormatCodeOptions(file);
|
||||
const changes = project.getLanguageService().organizeImports({ type: "file", fileName: file }, formatOptions);
|
||||
if (simplifiedResult) {
|
||||
return this.mapTextChangesToCodeEdits(project, changes);
|
||||
}
|
||||
else {
|
||||
return changes;
|
||||
}
|
||||
}
|
||||
|
||||
private getCodeFixes(args: protocol.CodeFixRequestArgs, simplifiedResult: boolean): ReadonlyArray<protocol.CodeAction> | ReadonlyArray<CodeAction> {
|
||||
if (args.errorCodes.length === 0) {
|
||||
return undefined;
|
||||
@@ -2041,6 +2054,12 @@ namespace ts.server {
|
||||
},
|
||||
[CommandNames.GetEditsForRefactorFull]: (request: protocol.GetEditsForRefactorRequest) => {
|
||||
return this.requiredResponse(this.getEditsForRefactor(request.arguments, /*simplifiedResult*/ false));
|
||||
},
|
||||
[CommandNames.OrganizeImports]: (request: protocol.OrganizeImportsRequest) => {
|
||||
return this.requiredResponse(this.organizeImports(request.arguments, /*simplifiedResult*/ true));
|
||||
},
|
||||
[CommandNames.OrganizeImportsFull]: (request: protocol.OrganizeImportsRequest) => {
|
||||
return this.requiredResponse(this.organizeImports(request.arguments, /*simplifiedResult*/ false));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/// <reference path="typingsInstaller.ts"/>
|
||||
/// <reference types="node" />
|
||||
|
||||
namespace ts.server.typingsInstaller {
|
||||
|
||||
@@ -12,6 +12,18 @@
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
"../../compiler/types.ts",
|
||||
"../../compiler/performance.ts",
|
||||
"../../compiler/core.ts",
|
||||
"../../compiler/sys.ts",
|
||||
"../../compiler/diagnosticInformationMap.generated.ts",
|
||||
"../../compiler/utilities.ts",
|
||||
"../../compiler/scanner.ts",
|
||||
"../../compiler/parser.ts",
|
||||
"../../compiler/commandLineParser.ts",
|
||||
"../../compiler/moduleNameResolver.ts",
|
||||
"../../services/semver.ts",
|
||||
"../../services/jsTyping.ts",
|
||||
"../types.ts",
|
||||
"../shared.ts",
|
||||
"typingsInstaller.ts",
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
/// <reference path="../../compiler/core.ts" />
|
||||
/// <reference path="../../compiler/moduleNameResolver.ts" />
|
||||
/// <reference path="../../services/jsTyping.ts"/>
|
||||
/// <reference path="../../services/semver.ts"/>
|
||||
/// <reference path="../types.ts"/>
|
||||
/// <reference path="../shared.ts"/>
|
||||
|
||||
namespace ts.server.typingsInstaller {
|
||||
interface NpmConfig {
|
||||
devDependencies: MapLike<any>;
|
||||
@@ -413,4 +406,4 @@ namespace ts.server.typingsInstaller {
|
||||
}
|
||||
|
||||
const latestDistTag = "latest";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -390,7 +390,7 @@ namespace ts.BreakpointResolver {
|
||||
|
||||
// If this is a destructuring pattern, set breakpoint in binding pattern
|
||||
if (isBindingPattern(variableDeclaration.name)) {
|
||||
return spanInBindingPattern(<BindingPattern>variableDeclaration.name);
|
||||
return spanInBindingPattern(variableDeclaration.name);
|
||||
}
|
||||
|
||||
// Breakpoint is possible in variableDeclaration only if there is initialization
|
||||
@@ -420,7 +420,7 @@ namespace ts.BreakpointResolver {
|
||||
function spanInParameterDeclaration(parameter: ParameterDeclaration): TextSpan {
|
||||
if (isBindingPattern(parameter.name)) {
|
||||
// Set breakpoint in binding pattern
|
||||
return spanInBindingPattern(<BindingPattern>parameter.name);
|
||||
return spanInBindingPattern(parameter.name);
|
||||
}
|
||||
else if (canHaveSpanInParameterDeclaration(parameter)) {
|
||||
return textSpan(parameter);
|
||||
@@ -540,10 +540,7 @@ namespace ts.BreakpointResolver {
|
||||
|
||||
function spanInArrayLiteralOrObjectLiteralDestructuringPattern(node: DestructuringPattern): TextSpan {
|
||||
Debug.assert(node.kind !== SyntaxKind.ArrayBindingPattern && node.kind !== SyntaxKind.ObjectBindingPattern);
|
||||
const elements: NodeArray<Expression | ObjectLiteralElement> =
|
||||
node.kind === SyntaxKind.ArrayLiteralExpression ?
|
||||
(<ArrayLiteralExpression>node).elements :
|
||||
(<ObjectLiteralExpression>node).properties;
|
||||
const elements: NodeArray<Expression | ObjectLiteralElement> = node.kind === SyntaxKind.ArrayLiteralExpression ? node.elements : (node as ObjectLiteralExpression).properties;
|
||||
|
||||
const firstBindingElement = forEach(elements,
|
||||
element => element.kind !== SyntaxKind.OmittedExpression ? element : undefined);
|
||||
|
||||
@@ -195,7 +195,7 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
function tryDeleteNamedImportBinding(changes: textChanges.ChangeTracker, sourceFile: SourceFile, namedBindings: NamedImportBindings): void {
|
||||
if ((<ImportClause>namedBindings.parent).name) {
|
||||
if (namedBindings.parent.name) {
|
||||
// Delete named imports while preserving the default import
|
||||
// import d|, * as ns| from './file'
|
||||
// import d|, { a }| from './file'
|
||||
@@ -229,7 +229,7 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
case SyntaxKind.ForOfStatement:
|
||||
const forOfStatement = <ForOfStatement>varDecl.parent.parent;
|
||||
const forOfStatement = varDecl.parent.parent;
|
||||
Debug.assert(forOfStatement.initializer.kind === SyntaxKind.VariableDeclarationList);
|
||||
const forOfInitializer = <VariableDeclarationList>forOfStatement.initializer;
|
||||
changes.replaceNode(sourceFile, forOfInitializer.declarations[0], createObjectLiteral());
|
||||
@@ -240,7 +240,7 @@ namespace ts.codefix {
|
||||
break;
|
||||
|
||||
default:
|
||||
const variableStatement = <VariableStatement>varDecl.parent.parent;
|
||||
const variableStatement = varDecl.parent.parent;
|
||||
if (variableStatement.declarationList.declarations.length === 1) {
|
||||
changes.deleteNode(sourceFile, variableStatement);
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace ts.codefix {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const declaration = declarations[0] as Declaration;
|
||||
const declaration = declarations[0];
|
||||
// Clone name to remove leading trivia.
|
||||
const name = getSynthesizedDeepClone(getNameOfDeclaration(declaration)) as PropertyName;
|
||||
const visibilityModifier = createVisibilityModifier(getModifierFlags(declaration));
|
||||
|
||||
@@ -140,7 +140,7 @@ namespace ts.codefix {
|
||||
case SyntaxKind.Constructor:
|
||||
return true;
|
||||
case SyntaxKind.FunctionExpression:
|
||||
return !!(declaration as FunctionExpression).name;
|
||||
return !!declaration.name;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -497,7 +497,7 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
function inferTypeFromSwitchStatementLabelContext(parent: CaseOrDefaultClause, checker: TypeChecker, usageContext: UsageContext): void {
|
||||
addCandidateType(usageContext, checker.getTypeAtLocation((<SwitchStatement>parent.parent.parent).expression));
|
||||
addCandidateType(usageContext, checker.getTypeAtLocation(parent.parent.parent.expression));
|
||||
}
|
||||
|
||||
function inferTypeFromCallExpressionContext(parent: CallExpression | NewExpression, checker: TypeChecker, usageContext: UsageContext): void {
|
||||
|
||||
+35
-21
@@ -657,8 +657,8 @@ namespace ts.Completions {
|
||||
None,
|
||||
}
|
||||
|
||||
function getRecommendedCompletion(currentToken: Node, checker: TypeChecker): Symbol | undefined {
|
||||
const ty = getContextualType(currentToken, checker);
|
||||
function getRecommendedCompletion(currentToken: Node, position: number, sourceFile: SourceFile, checker: TypeChecker): Symbol | undefined {
|
||||
const ty = getContextualType(currentToken, position, sourceFile, checker);
|
||||
const symbol = ty && ty.symbol;
|
||||
// Don't include make a recommended completion for an abstract class
|
||||
return symbol && (symbol.flags & SymbolFlags.Enum || symbol.flags & SymbolFlags.Class && !isAbstractConstructorSymbol(symbol))
|
||||
@@ -666,23 +666,37 @@ namespace ts.Completions {
|
||||
: undefined;
|
||||
}
|
||||
|
||||
function getContextualType(currentToken: Node, checker: ts.TypeChecker): Type | undefined {
|
||||
function getContextualType(currentToken: Node, position: number, sourceFile: SourceFile, checker: TypeChecker): Type | undefined {
|
||||
const { parent } = currentToken;
|
||||
switch (currentToken.kind) {
|
||||
case ts.SyntaxKind.Identifier:
|
||||
return getContextualTypeFromParent(currentToken as ts.Identifier, checker);
|
||||
case ts.SyntaxKind.EqualsToken:
|
||||
return ts.isVariableDeclaration(parent) ? checker.getContextualType(parent.initializer) :
|
||||
ts.isBinaryExpression(parent) ? checker.getTypeAtLocation(parent.left) : undefined;
|
||||
case ts.SyntaxKind.NewKeyword:
|
||||
return checker.getContextualType(parent as ts.Expression);
|
||||
case ts.SyntaxKind.CaseKeyword:
|
||||
return getSwitchedType(cast(currentToken.parent, isCaseClause), checker);
|
||||
case SyntaxKind.Identifier:
|
||||
return getContextualTypeFromParent(currentToken as Identifier, checker);
|
||||
case SyntaxKind.EqualsToken:
|
||||
switch (parent.kind) {
|
||||
case ts.SyntaxKind.VariableDeclaration:
|
||||
return checker.getContextualType((parent as VariableDeclaration).initializer);
|
||||
case ts.SyntaxKind.BinaryExpression:
|
||||
return checker.getTypeAtLocation((parent as BinaryExpression).left);
|
||||
case ts.SyntaxKind.JsxAttribute:
|
||||
return checker.getContextualTypeForJsxAttribute(parent as JsxAttribute);
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
case SyntaxKind.NewKeyword:
|
||||
return checker.getContextualType(parent as Expression);
|
||||
case SyntaxKind.CaseKeyword:
|
||||
return getSwitchedType(cast(parent, isCaseClause), checker);
|
||||
case SyntaxKind.OpenBraceToken:
|
||||
return isJsxExpression(parent) && parent.parent.kind !== SyntaxKind.JsxElement ? checker.getContextualTypeForJsxAttribute(parent.parent) : undefined;
|
||||
default:
|
||||
return isEqualityOperatorKind(currentToken.kind) && ts.isBinaryExpression(parent) && isEqualityOperatorKind(parent.operatorToken.kind)
|
||||
const argInfo = SignatureHelp.getImmediatelyContainingArgumentInfo(currentToken, position, sourceFile);
|
||||
return argInfo
|
||||
// At `,`, treat this as the next argument after the comma.
|
||||
? checker.getContextualTypeForArgumentAtIndex(argInfo.invocation, argInfo.argumentIndex + (currentToken.kind === SyntaxKind.CommaToken ? 1 : 0))
|
||||
: isEqualityOperatorKind(currentToken.kind) && isBinaryExpression(parent) && isEqualityOperatorKind(parent.operatorToken.kind)
|
||||
// completion at `x ===/**/` should be for the right side
|
||||
? checker.getTypeAtLocation(parent.left)
|
||||
: checker.getContextualType(currentToken as ts.Expression);
|
||||
: checker.getContextualType(currentToken as Expression);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -956,7 +970,7 @@ namespace ts.Completions {
|
||||
|
||||
log("getCompletionData: Semantic work: " + (timestamp() - semanticStart));
|
||||
|
||||
const recommendedCompletion = previousToken && getRecommendedCompletion(previousToken, typeChecker);
|
||||
const recommendedCompletion = previousToken && getRecommendedCompletion(previousToken, position, sourceFile, typeChecker);
|
||||
return { kind: CompletionDataKind.Data, symbols, completionKind, propertyAccessToConvert, isNewIdentifierLocation, location, keywordFilters, symbolToOriginInfoMap, recommendedCompletion, previousToken, isJsxInitializer };
|
||||
|
||||
type JSDocTagWithTypeExpression = JSDocParameterTag | JSDocPropertyTag | JSDocReturnTag | JSDocTypeTag | JSDocTypedefTag;
|
||||
@@ -1068,10 +1082,10 @@ namespace ts.Completions {
|
||||
let attrsType: Type;
|
||||
if ((jsxContainer.kind === SyntaxKind.JsxSelfClosingElement) || (jsxContainer.kind === SyntaxKind.JsxOpeningElement)) {
|
||||
// Cursor is inside a JSX self-closing element or opening element
|
||||
attrsType = typeChecker.getAllAttributesTypeFromJsxOpeningLikeElement(<JsxOpeningLikeElement>jsxContainer);
|
||||
attrsType = typeChecker.getAllAttributesTypeFromJsxOpeningLikeElement(jsxContainer);
|
||||
|
||||
if (attrsType) {
|
||||
symbols = filterJsxAttributes(typeChecker.getPropertiesOfType(attrsType), (<JsxOpeningLikeElement>jsxContainer).attributes.properties);
|
||||
symbols = filterJsxAttributes(typeChecker.getPropertiesOfType(attrsType), jsxContainer.attributes.properties);
|
||||
completionKind = CompletionKind.MemberLike;
|
||||
isNewIdentifierLocation = false;
|
||||
return true;
|
||||
@@ -1429,10 +1443,10 @@ namespace ts.Completions {
|
||||
// We are completing on contextual types, but may also include properties
|
||||
// other than those within the declared type.
|
||||
isNewIdentifierLocation = true;
|
||||
const typeForObject = typeChecker.getContextualType(<ObjectLiteralExpression>objectLikeContainer);
|
||||
const typeForObject = typeChecker.getContextualType(objectLikeContainer);
|
||||
if (!typeForObject) return false;
|
||||
typeMembers = getPropertiesForCompletion(typeForObject, typeChecker, /*isForAccess*/ false);
|
||||
existingMembers = (<ObjectLiteralExpression>objectLikeContainer).properties;
|
||||
existingMembers = objectLikeContainer.properties;
|
||||
}
|
||||
else {
|
||||
Debug.assert(objectLikeContainer.kind === SyntaxKind.ObjectBindingPattern);
|
||||
@@ -1461,7 +1475,7 @@ namespace ts.Completions {
|
||||
if (!typeForObject) return false;
|
||||
// In a binding pattern, get only known properties. Everywhere else we will get all possible properties.
|
||||
typeMembers = typeChecker.getPropertiesOfType(typeForObject).filter((symbol) => !(getDeclarationModifierFlagsFromSymbol(symbol) & ModifierFlags.NonPublicAccessibilityModifier));
|
||||
existingMembers = (<ObjectBindingPattern>objectLikeContainer).elements;
|
||||
existingMembers = objectLikeContainer.elements;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2073,7 +2087,7 @@ namespace ts.Completions {
|
||||
}
|
||||
|
||||
if (attr.kind === SyntaxKind.JsxAttribute) {
|
||||
seenNames.set((<JsxAttribute>attr).name.escapedText, true);
|
||||
seenNames.set(attr.name.escapedText, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -356,7 +356,7 @@ namespace ts.FindAllReferences.Core {
|
||||
|
||||
/** Core find-all-references algorithm for a normal symbol. */
|
||||
function getReferencedSymbolsForSymbol(symbol: Symbol, node: Node, sourceFiles: ReadonlyArray<SourceFile>, checker: TypeChecker, cancellationToken: CancellationToken, options: Options): SymbolAndEntries[] {
|
||||
symbol = skipPastExportOrImportSpecifierOrUnion(symbol, node, checker);
|
||||
symbol = skipPastExportOrImportSpecifierOrUnion(symbol, node, checker) || symbol;
|
||||
|
||||
// Compute the meaning from the location and the symbol it references
|
||||
const searchMeaning = getIntersectingMeaningFromDeclarations(getMeaningFromLocation(node), symbol.declarations);
|
||||
@@ -405,7 +405,7 @@ namespace ts.FindAllReferences.Core {
|
||||
}
|
||||
|
||||
/** Handle a few special cases relating to export/import specifiers. */
|
||||
function skipPastExportOrImportSpecifierOrUnion(symbol: Symbol, node: Node, checker: TypeChecker): Symbol {
|
||||
function skipPastExportOrImportSpecifierOrUnion(symbol: Symbol, node: Node, checker: TypeChecker): Symbol | undefined {
|
||||
const { parent } = node;
|
||||
if (isExportSpecifier(parent)) {
|
||||
return getLocalSymbolForExportSpecifier(node as Identifier, symbol, parent, checker);
|
||||
@@ -425,7 +425,7 @@ namespace ts.FindAllReferences.Core {
|
||||
return isTypeLiteralNode(decl.parent) && isUnionTypeNode(decl.parent.parent)
|
||||
? checker.getPropertyOfType(checker.getTypeFromTypeNode(decl.parent.parent), symbol.name)
|
||||
: undefined;
|
||||
}) || symbol;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -912,7 +912,7 @@ namespace ts.FindAllReferences.Core {
|
||||
|
||||
// For `export { foo as bar }`, rename `foo`, but not `bar`.
|
||||
if (!(referenceLocation === propertyName && state.options.isForRename)) {
|
||||
const exportKind = (referenceLocation as Identifier).originalKeywordKind === ts.SyntaxKind.DefaultKeyword ? ExportKind.Default : ExportKind.Named;
|
||||
const exportKind = referenceLocation.originalKeywordKind === ts.SyntaxKind.DefaultKeyword ? ExportKind.Default : ExportKind.Named;
|
||||
const exportInfo = getExportInfo(referenceSymbol, exportKind, state.checker);
|
||||
Debug.assert(!!exportInfo);
|
||||
searchForImportsOfExport(referenceLocation, referenceSymbol, exportInfo, state);
|
||||
@@ -1125,7 +1125,7 @@ namespace ts.FindAllReferences.Core {
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (isImplementationExpression(<Expression>body)) {
|
||||
else if (isImplementationExpression(body)) {
|
||||
addReference(body);
|
||||
}
|
||||
}
|
||||
@@ -1647,10 +1647,10 @@ namespace ts.FindAllReferences.Core {
|
||||
|
||||
function getNameFromObjectLiteralElement(node: ObjectLiteralElement): string {
|
||||
if (node.name.kind === SyntaxKind.ComputedPropertyName) {
|
||||
const nameExpression = (<ComputedPropertyName>node.name).expression;
|
||||
const nameExpression = node.name.expression;
|
||||
// treat computed property names where expression is string/numeric literal as just string/numeric literal
|
||||
if (isStringOrNumericLiteral(nameExpression)) {
|
||||
return (<LiteralExpression>nameExpression).text;
|
||||
return nameExpression.text;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
@@ -1728,7 +1728,7 @@ namespace ts.FindAllReferences.Core {
|
||||
function getParentStatementOfVariableDeclaration(node: VariableDeclaration): VariableStatement {
|
||||
if (node.parent && node.parent.parent && node.parent.parent.kind === SyntaxKind.VariableStatement) {
|
||||
Debug.assert(node.parent.kind === SyntaxKind.VariableDeclarationList);
|
||||
return <VariableStatement>node.parent.parent;
|
||||
return node.parent.parent;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -200,7 +200,7 @@ namespace ts.formatting {
|
||||
return rangeContainsRange((<InterfaceDeclaration>parent).members, node);
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
const body = (<ModuleDeclaration>parent).body;
|
||||
return body && body.kind === SyntaxKind.ModuleBlock && rangeContainsRange((<ModuleBlock>body).statements, node);
|
||||
return body && body.kind === SyntaxKind.ModuleBlock && rangeContainsRange(body.statements, node);
|
||||
case SyntaxKind.SourceFile:
|
||||
case SyntaxKind.Block:
|
||||
case SyntaxKind.ModuleBlock:
|
||||
|
||||
@@ -383,9 +383,8 @@ namespace ts.formatting {
|
||||
return Value.Unknown;
|
||||
}
|
||||
|
||||
if (node.parent && isCallOrNewExpression(node.parent) && (<CallExpression>node.parent).expression !== node) {
|
||||
|
||||
const fullCallOrNewExpression = (<CallExpression | NewExpression>node.parent).expression;
|
||||
if (node.parent && isCallOrNewExpression(node.parent) && node.parent.expression !== node) {
|
||||
const fullCallOrNewExpression = node.parent.expression;
|
||||
const startingExpression = getStartingExpression(fullCallOrNewExpression);
|
||||
|
||||
if (fullCallOrNewExpression === startingExpression) {
|
||||
|
||||
@@ -629,7 +629,7 @@ namespace ts.FindAllReferences {
|
||||
// For `export { foo } from './bar", there's nothing to skip, because it does not create a new alias. But `export { foo } does.
|
||||
if (symbol.declarations) {
|
||||
for (const declaration of symbol.declarations) {
|
||||
if (isExportSpecifier(declaration) && !(declaration as ExportSpecifier).propertyName && !(declaration as ExportSpecifier).parent.parent.moduleSpecifier) {
|
||||
if (isExportSpecifier(declaration) && !declaration.propertyName && !declaration.parent.parent.moduleSpecifier) {
|
||||
return checker.getExportSpecifierLocalTargetSymbol(declaration);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ namespace ts.JsDoc {
|
||||
"see",
|
||||
"since",
|
||||
"static",
|
||||
"template",
|
||||
"throws",
|
||||
"type",
|
||||
"typedef",
|
||||
@@ -268,9 +269,7 @@ namespace ts.JsDoc {
|
||||
let docParams = "";
|
||||
for (let i = 0; i < parameters.length; i++) {
|
||||
const currentName = parameters[i].name;
|
||||
const paramName = currentName.kind === SyntaxKind.Identifier ?
|
||||
(<Identifier>currentName).escapedText :
|
||||
"param" + i;
|
||||
const paramName = currentName.kind === SyntaxKind.Identifier ? currentName.escapedText : "param" + i;
|
||||
if (isJavaScriptFile) {
|
||||
docParams += `${indentationStr} * @param {any} ${paramName}${newLine}`;
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ namespace ts.NavigateTo {
|
||||
containers.unshift(text);
|
||||
}
|
||||
else if (name.kind === SyntaxKind.ComputedPropertyName) {
|
||||
return tryAddComputedPropertyName((<ComputedPropertyName>name).expression, containers, /*includeLastPortion*/ true);
|
||||
return tryAddComputedPropertyName(name.expression, containers, /*includeLastPortion*/ true);
|
||||
}
|
||||
else {
|
||||
// Don't know how to add this.
|
||||
@@ -140,7 +140,7 @@ namespace ts.NavigateTo {
|
||||
// portion into the container array.
|
||||
const name = getNameOfDeclaration(declaration);
|
||||
if (name.kind === SyntaxKind.ComputedPropertyName) {
|
||||
if (!tryAddComputedPropertyName((<ComputedPropertyName>name).expression, containers, /*includeLastPortion*/ false)) {
|
||||
if (!tryAddComputedPropertyName(name.expression, containers, /*includeLastPortion*/ false)) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
@@ -181,7 +181,7 @@ namespace ts.NavigateTo {
|
||||
|
||||
function createNavigateToItem(rawItem: RawNavigateToItem): NavigateToItem {
|
||||
const declaration = rawItem.declaration;
|
||||
const container = <Declaration>getContainerNode(declaration);
|
||||
const container = getContainerNode(declaration);
|
||||
const containerName = container && getNameOfDeclaration(container);
|
||||
return {
|
||||
name: rawItem.name,
|
||||
|
||||
@@ -197,10 +197,10 @@ namespace ts.NavigationBar {
|
||||
const {namedBindings} = importClause;
|
||||
if (namedBindings) {
|
||||
if (namedBindings.kind === SyntaxKind.NamespaceImport) {
|
||||
addLeafNode(<NamespaceImport>namedBindings);
|
||||
addLeafNode(namedBindings);
|
||||
}
|
||||
else {
|
||||
for (const element of (<NamedImports>namedBindings).elements) {
|
||||
for (const element of namedBindings.elements) {
|
||||
addLeafNode(element);
|
||||
}
|
||||
}
|
||||
@@ -475,8 +475,8 @@ namespace ts.NavigationBar {
|
||||
else {
|
||||
const parentNode = node.parent && node.parent.parent;
|
||||
if (parentNode && parentNode.kind === SyntaxKind.VariableStatement) {
|
||||
if ((<VariableStatement>parentNode).declarationList.declarations.length > 0) {
|
||||
const nameIdentifier = (<VariableStatement>parentNode).declarationList.declarations[0].name;
|
||||
if (parentNode.declarationList.declarations.length > 0) {
|
||||
const nameIdentifier = parentNode.declarationList.declarations[0].name;
|
||||
if (nameIdentifier.kind === SyntaxKind.Identifier) {
|
||||
return nameIdentifier.text;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
/* @internal */
|
||||
namespace ts.OrganizeImports {
|
||||
export function organizeImports(
|
||||
sourceFile: SourceFile,
|
||||
formatContext: formatting.FormatContext,
|
||||
host: LanguageServiceHost) {
|
||||
|
||||
// TODO (https://github.com/Microsoft/TypeScript/issues/10020): sort *within* ambient modules (find using isAmbientModule)
|
||||
|
||||
// All of the old ImportDeclarations in the file, in syntactic order.
|
||||
const oldImportDecls = sourceFile.statements.filter(isImportDeclaration);
|
||||
|
||||
if (oldImportDecls.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const oldImportGroups = group(oldImportDecls, importDecl => getExternalModuleName(importDecl.moduleSpecifier));
|
||||
|
||||
const sortedImportGroups = stableSort(oldImportGroups, (group1, group2) =>
|
||||
compareModuleSpecifiers(group1[0].moduleSpecifier, group2[0].moduleSpecifier));
|
||||
|
||||
const newImportDecls = flatMap(sortedImportGroups, importGroup =>
|
||||
getExternalModuleName(importGroup[0].moduleSpecifier)
|
||||
? coalesceImports(removeUnusedImports(importGroup))
|
||||
: importGroup);
|
||||
|
||||
const changeTracker = textChanges.ChangeTracker.fromContext({ host, formatContext });
|
||||
|
||||
// Delete or replace the first import.
|
||||
if (newImportDecls.length === 0) {
|
||||
changeTracker.deleteNode(sourceFile, oldImportDecls[0]);
|
||||
}
|
||||
else {
|
||||
// Note: Delete the surrounding trivia because it will have been retained in newImportDecls.
|
||||
changeTracker.replaceNodeWithNodes(sourceFile, oldImportDecls[0], newImportDecls, {
|
||||
useNonAdjustedStartPosition: false,
|
||||
useNonAdjustedEndPosition: false,
|
||||
suffix: getNewLineOrDefaultFromHost(host, formatContext.options),
|
||||
});
|
||||
}
|
||||
|
||||
// Delete any subsequent imports.
|
||||
for (let i = 1; i < oldImportDecls.length; i++) {
|
||||
changeTracker.deleteNode(sourceFile, oldImportDecls[i]);
|
||||
}
|
||||
|
||||
return changeTracker.getChanges();
|
||||
}
|
||||
|
||||
function removeUnusedImports(oldImports: ReadonlyArray<ImportDeclaration>) {
|
||||
return oldImports; // TODO (https://github.com/Microsoft/TypeScript/issues/10020)
|
||||
}
|
||||
|
||||
function getExternalModuleName(specifier: Expression) {
|
||||
return isStringLiteral(specifier) || isNoSubstitutionTemplateLiteral(specifier)
|
||||
? specifier.text
|
||||
: undefined;
|
||||
}
|
||||
|
||||
/* @internal */ // Internal for testing
|
||||
/**
|
||||
* @param importGroup a list of ImportDeclarations, all with the same module name.
|
||||
*/
|
||||
export function coalesceImports(importGroup: ReadonlyArray<ImportDeclaration>) {
|
||||
if (importGroup.length === 0) {
|
||||
return importGroup;
|
||||
}
|
||||
|
||||
const { importWithoutClause, defaultImports, namespaceImports, namedImports } = getImportParts(importGroup);
|
||||
|
||||
const coalescedImports: ImportDeclaration[] = [];
|
||||
|
||||
if (importWithoutClause) {
|
||||
coalescedImports.push(importWithoutClause);
|
||||
}
|
||||
|
||||
// Normally, we don't combine default and namespace imports, but it would be silly to
|
||||
// produce two import declarations in this special case.
|
||||
if (defaultImports.length === 1 && namespaceImports.length === 1 && namedImports.length === 0) {
|
||||
// Add the namespace import to the existing default ImportDeclaration.
|
||||
const defaultImportClause = defaultImports[0].parent as ImportClause;
|
||||
coalescedImports.push(
|
||||
updateImportDeclarationAndClause(defaultImportClause, defaultImportClause.name, namespaceImports[0]));
|
||||
|
||||
return coalescedImports;
|
||||
}
|
||||
|
||||
const sortedNamespaceImports = stableSort(namespaceImports, (n1, n2) => compareIdentifiers(n1.name, n2.name));
|
||||
|
||||
for (const namespaceImport of sortedNamespaceImports) {
|
||||
// Drop the name, if any
|
||||
coalescedImports.push(
|
||||
updateImportDeclarationAndClause(namespaceImport.parent, /*name*/ undefined, namespaceImport));
|
||||
}
|
||||
|
||||
if (defaultImports.length === 0 && namedImports.length === 0) {
|
||||
return coalescedImports;
|
||||
}
|
||||
|
||||
let newDefaultImport: Identifier | undefined;
|
||||
const newImportSpecifiers: ImportSpecifier[] = [];
|
||||
if (defaultImports.length === 1) {
|
||||
newDefaultImport = defaultImports[0];
|
||||
}
|
||||
else {
|
||||
for (const defaultImport of defaultImports) {
|
||||
newImportSpecifiers.push(
|
||||
createImportSpecifier(createIdentifier("default"), defaultImport));
|
||||
}
|
||||
}
|
||||
|
||||
newImportSpecifiers.push(...flatMap(namedImports, n => n.elements));
|
||||
|
||||
const sortedImportSpecifiers = stableSort(newImportSpecifiers, (s1, s2) =>
|
||||
compareIdentifiers(s1.propertyName || s1.name, s2.propertyName || s2.name) ||
|
||||
compareIdentifiers(s1.name, s2.name));
|
||||
|
||||
const importClause = defaultImports.length > 0
|
||||
? defaultImports[0].parent as ImportClause
|
||||
: namedImports[0].parent;
|
||||
|
||||
const newNamedImports = sortedImportSpecifiers.length === 0
|
||||
? undefined
|
||||
: namedImports.length === 0
|
||||
? createNamedImports(sortedImportSpecifiers)
|
||||
: updateNamedImports(namedImports[0], sortedImportSpecifiers);
|
||||
|
||||
coalescedImports.push(
|
||||
updateImportDeclarationAndClause(importClause, newDefaultImport, newNamedImports));
|
||||
|
||||
return coalescedImports;
|
||||
|
||||
function getImportParts(importGroup: ReadonlyArray<ImportDeclaration>) {
|
||||
let importWithoutClause: ImportDeclaration | undefined;
|
||||
const defaultImports: Identifier[] = [];
|
||||
const namespaceImports: NamespaceImport[] = [];
|
||||
const namedImports: NamedImports[] = [];
|
||||
|
||||
for (const importDeclaration of importGroup) {
|
||||
if (importDeclaration.importClause === undefined) {
|
||||
// Only the first such import is interesting - the others are redundant.
|
||||
// Note: Unfortunately, we will lose trivia that was on this node.
|
||||
importWithoutClause = importWithoutClause || importDeclaration;
|
||||
continue;
|
||||
}
|
||||
|
||||
const { name, namedBindings } = importDeclaration.importClause;
|
||||
|
||||
if (name) {
|
||||
defaultImports.push(name);
|
||||
}
|
||||
|
||||
if (namedBindings) {
|
||||
if (isNamespaceImport(namedBindings)) {
|
||||
namespaceImports.push(namedBindings);
|
||||
}
|
||||
else {
|
||||
namedImports.push(namedBindings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
importWithoutClause,
|
||||
defaultImports,
|
||||
namespaceImports,
|
||||
namedImports,
|
||||
};
|
||||
}
|
||||
|
||||
function compareIdentifiers(s1: Identifier, s2: Identifier) {
|
||||
return compareStringsCaseSensitive(s1.text, s2.text);
|
||||
}
|
||||
|
||||
function updateImportDeclarationAndClause(
|
||||
importClause: ImportClause,
|
||||
name: Identifier | undefined,
|
||||
namedBindings: NamedImportBindings | undefined) {
|
||||
|
||||
const importDeclaration = importClause.parent;
|
||||
return updateImportDeclaration(
|
||||
importDeclaration,
|
||||
importDeclaration.decorators,
|
||||
importDeclaration.modifiers,
|
||||
updateImportClause(importClause, name, namedBindings),
|
||||
importDeclaration.moduleSpecifier);
|
||||
}
|
||||
}
|
||||
|
||||
/* internal */ // Exported for testing
|
||||
export function compareModuleSpecifiers(m1: Expression, m2: Expression) {
|
||||
const name1 = getExternalModuleName(m1);
|
||||
const name2 = getExternalModuleName(m2);
|
||||
return compareBooleans(name1 === undefined, name2 === undefined) ||
|
||||
compareBooleans(isExternalModuleNameRelative(name1), isExternalModuleNameRelative(name2)) ||
|
||||
compareStringsCaseSensitive(name1, name2);
|
||||
}
|
||||
}
|
||||
@@ -118,7 +118,7 @@ namespace ts.refactor.annotateWithTypeFromJSDoc {
|
||||
case SyntaxKind.Constructor:
|
||||
return createConstructor(decl.decorators, decl.modifiers, parameters, decl.body);
|
||||
case SyntaxKind.FunctionExpression:
|
||||
return createFunctionExpression(decl.modifiers, decl.asteriskToken, (decl as FunctionExpression).name, typeParameters, parameters, returnType, decl.body);
|
||||
return createFunctionExpression(decl.modifiers, decl.asteriskToken, decl.name, typeParameters, parameters, returnType, decl.body);
|
||||
case SyntaxKind.ArrowFunction:
|
||||
return createArrowFunction(decl.modifiers, typeParameters, parameters, returnType, decl.equalsGreaterThanToken, decl.body);
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
|
||||
@@ -180,8 +180,7 @@ namespace ts.refactor.convertFunctionToES6Class {
|
||||
}
|
||||
// case 2: () => [1,2,3]
|
||||
else {
|
||||
const expression = arrowFunctionBody as Expression;
|
||||
bodyBlock = createBlock([createReturn(expression)]);
|
||||
bodyBlock = createBlock([createReturn(arrowFunctionBody)]);
|
||||
}
|
||||
const fullModifiers = concatenate(modifiers, getModifierKindFromSource(arrowFunction, SyntaxKind.AsyncKeyword));
|
||||
const method = createMethod(/*decorators*/ undefined, fullModifiers, /*asteriskToken*/ undefined, memberDeclaration.name, /*questionToken*/ undefined,
|
||||
|
||||
@@ -194,7 +194,7 @@ namespace ts.refactor {
|
||||
}
|
||||
|
||||
function convertVariableStatement(sourceFile: SourceFile, statement: VariableStatement, changes: textChanges.ChangeTracker, checker: TypeChecker, identifiers: Identifiers, target: ScriptTarget): void {
|
||||
const { declarationList } = statement as VariableStatement;
|
||||
const { declarationList } = statement;
|
||||
let foundImport = false;
|
||||
const newNodes = flatMap(declarationList.declarations, decl => {
|
||||
const { name, initializer } = decl;
|
||||
@@ -290,14 +290,10 @@ namespace ts.refactor {
|
||||
case SyntaxKind.ShorthandPropertyAssignment:
|
||||
case SyntaxKind.SpreadAssignment:
|
||||
return undefined;
|
||||
case SyntaxKind.PropertyAssignment: {
|
||||
const { name, initializer } = prop as PropertyAssignment;
|
||||
return !isIdentifier(name) ? undefined : convertExportsDotXEquals(name.text, initializer);
|
||||
}
|
||||
case SyntaxKind.MethodDeclaration: {
|
||||
const m = prop as MethodDeclaration;
|
||||
return !isIdentifier(m.name) ? undefined : functionExpressionToDeclaration(m.name.text, [createToken(SyntaxKind.ExportKeyword)], m);
|
||||
}
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
return !isIdentifier(prop.name) ? undefined : convertExportsDotXEquals(prop.name.text, prop.initializer);
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
return !isIdentifier(prop.name) ? undefined : functionExpressionToDeclaration(prop.name.text, [createToken(SyntaxKind.ExportKeyword)], prop);
|
||||
default:
|
||||
Debug.assertNever(prop);
|
||||
}
|
||||
|
||||
@@ -223,7 +223,7 @@ namespace ts.refactor.extractSymbol {
|
||||
return { errors: [createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractRange)] };
|
||||
}
|
||||
const statements: Statement[] = [];
|
||||
for (const statement of (<BlockLike>start.parent).statements) {
|
||||
for (const statement of start.parent.statements) {
|
||||
if (statement === start || statements.length) {
|
||||
const errors = checkNode(statement);
|
||||
if (errors) {
|
||||
@@ -1476,7 +1476,7 @@ namespace ts.refactor.extractSymbol {
|
||||
}
|
||||
|
||||
const seenUsages = createMap<Usage>();
|
||||
const target = isReadonlyArray(targetRange.range) ? createBlock(<Statement[]>targetRange.range) : targetRange.range;
|
||||
const target = isReadonlyArray(targetRange.range) ? createBlock(targetRange.range) : targetRange.range;
|
||||
|
||||
const unmodifiedNode = isReadonlyArray(targetRange.range) ? first(targetRange.range) : targetRange.range;
|
||||
const inGenericContext = isInGenericContext(unmodifiedNode);
|
||||
@@ -1681,9 +1681,9 @@ namespace ts.refactor.extractSymbol {
|
||||
// if we get here this means that we are trying to handle 'write' and 'read' was already processed
|
||||
// walk scopes and update existing records.
|
||||
for (const perScope of usagesPerScope) {
|
||||
const prevEntry = perScope.usages.get(identifier.text as string);
|
||||
const prevEntry = perScope.usages.get(identifier.text);
|
||||
if (prevEntry) {
|
||||
perScope.usages.set(identifier.text as string, { usage, symbol, node: identifier });
|
||||
perScope.usages.set(identifier.text, { usage, symbol, node: identifier });
|
||||
}
|
||||
}
|
||||
return symbolId;
|
||||
@@ -1730,7 +1730,7 @@ namespace ts.refactor.extractSymbol {
|
||||
}
|
||||
}
|
||||
else {
|
||||
usagesPerScope[i].usages.set(identifier.text as string, { usage, symbol, node: identifier });
|
||||
usagesPerScope[i].usages.set(identifier.text, { usage, symbol, node: identifier });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+39
-87
@@ -14,6 +14,7 @@
|
||||
/// <reference path='jsTyping.ts' />
|
||||
/// <reference path='navigateTo.ts' />
|
||||
/// <reference path='navigationBar.ts' />
|
||||
/// <reference path='organizeImports.ts' />
|
||||
/// <reference path='outliningElementsCollector.ts' />
|
||||
/// <reference path='patternMatcher.ts' />
|
||||
/// <reference path='preProcess.ts' />
|
||||
@@ -727,7 +728,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (name.kind === SyntaxKind.ComputedPropertyName) {
|
||||
const expr = (<ComputedPropertyName>name).expression;
|
||||
const expr = name.expression;
|
||||
if (expr.kind === SyntaxKind.PropertyAccessExpression) {
|
||||
return (<PropertyAccessExpression>expr).name.text;
|
||||
}
|
||||
@@ -831,10 +832,10 @@ namespace ts {
|
||||
// import {a, b as B} from "mod";
|
||||
if (importClause.namedBindings) {
|
||||
if (importClause.namedBindings.kind === SyntaxKind.NamespaceImport) {
|
||||
addDeclaration(<NamespaceImport>importClause.namedBindings);
|
||||
addDeclaration(importClause.namedBindings);
|
||||
}
|
||||
else {
|
||||
forEach((<NamedImports>importClause.namedBindings).elements, visit);
|
||||
forEach(importClause.namedBindings.elements, visit);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1567,17 +1568,17 @@ namespace ts {
|
||||
|
||||
/// References and Occurrences
|
||||
function getOccurrencesAtPosition(fileName: string, position: number): ReferenceEntry[] {
|
||||
let results = getOccurrencesAtPositionCore(fileName, position);
|
||||
|
||||
if (results) {
|
||||
const sourceFile = getCanonicalFileName(normalizeSlashes(fileName));
|
||||
|
||||
// Get occurrences only supports reporting occurrences for the file queried. So
|
||||
// filter down to that list.
|
||||
results = filter(results, r => getCanonicalFileName(ts.normalizeSlashes(r.fileName)) === sourceFile);
|
||||
}
|
||||
|
||||
return results;
|
||||
const canonicalFileName = getCanonicalFileName(normalizeSlashes(fileName));
|
||||
return flatMap(getDocumentHighlights(fileName, position, [fileName]), entry => entry.highlightSpans.map<ReferenceEntry>(highlightSpan => {
|
||||
Debug.assert(getCanonicalFileName(normalizeSlashes(entry.fileName)) === canonicalFileName); // Get occurrences only supports reporting occurrences for the file queried.
|
||||
return {
|
||||
fileName: entry.fileName,
|
||||
textSpan: highlightSpan.textSpan,
|
||||
isWriteAccess: highlightSpan.kind === HighlightSpanKind.writtenReference,
|
||||
isDefinition: false,
|
||||
isInString: highlightSpan.isInString,
|
||||
};
|
||||
}));
|
||||
}
|
||||
|
||||
function getDocumentHighlights(fileName: string, position: number, filesToSearch: ReadonlyArray<string>): DocumentHighlights[] {
|
||||
@@ -1587,31 +1588,6 @@ namespace ts {
|
||||
return DocumentHighlights.getDocumentHighlights(program, cancellationToken, sourceFile, position, sourceFilesToSearch);
|
||||
}
|
||||
|
||||
function getOccurrencesAtPositionCore(fileName: string, position: number): ReferenceEntry[] {
|
||||
return convertDocumentHighlights(getDocumentHighlights(fileName, position, [fileName]));
|
||||
|
||||
function convertDocumentHighlights(documentHighlights: DocumentHighlights[]): ReferenceEntry[] {
|
||||
if (!documentHighlights) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const result: ReferenceEntry[] = [];
|
||||
for (const entry of documentHighlights) {
|
||||
for (const highlightSpan of entry.highlightSpans) {
|
||||
result.push({
|
||||
fileName: entry.fileName,
|
||||
textSpan: highlightSpan.textSpan,
|
||||
isWriteAccess: highlightSpan.kind === HighlightSpanKind.writtenReference,
|
||||
isDefinition: false,
|
||||
isInString: highlightSpan.isInString,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
function findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): RenameLocation[] {
|
||||
return getReferences(fileName, position, { findInStrings, findInComments, isForRename: true });
|
||||
}
|
||||
@@ -1792,55 +1768,21 @@ namespace ts {
|
||||
return OutliningElementsCollector.collectElements(sourceFile, cancellationToken);
|
||||
}
|
||||
|
||||
function getBraceMatchingAtPosition(fileName: string, position: number) {
|
||||
const braceMatching = createMapFromTemplate({
|
||||
[SyntaxKind.OpenBraceToken]: SyntaxKind.CloseBraceToken,
|
||||
[SyntaxKind.OpenParenToken]: SyntaxKind.CloseParenToken,
|
||||
[SyntaxKind.OpenBracketToken]: SyntaxKind.CloseBracketToken,
|
||||
[SyntaxKind.GreaterThanToken]: SyntaxKind.LessThanToken,
|
||||
});
|
||||
braceMatching.forEach((value, key) => braceMatching.set(value.toString(), Number(key) as SyntaxKind));
|
||||
|
||||
function getBraceMatchingAtPosition(fileName: string, position: number): TextSpan[] {
|
||||
const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
|
||||
const result: TextSpan[] = [];
|
||||
|
||||
const token = getTouchingToken(sourceFile, position, /*includeJsDocComment*/ false);
|
||||
|
||||
if (token.getStart(sourceFile) === position) {
|
||||
const matchKind = getMatchingTokenKind(token);
|
||||
|
||||
// Ensure that there is a corresponding token to match ours.
|
||||
if (matchKind) {
|
||||
const parentElement = token.parent;
|
||||
|
||||
const childNodes = parentElement.getChildren(sourceFile);
|
||||
for (const current of childNodes) {
|
||||
if (current.kind === matchKind) {
|
||||
const range1 = createTextSpan(token.getStart(sourceFile), token.getWidth(sourceFile));
|
||||
const range2 = createTextSpan(current.getStart(sourceFile), current.getWidth(sourceFile));
|
||||
|
||||
// We want to order the braces when we return the result.
|
||||
if (range1.start < range2.start) {
|
||||
result.push(range1, range2);
|
||||
}
|
||||
else {
|
||||
result.push(range2, range1);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
function getMatchingTokenKind(token: Node): ts.SyntaxKind {
|
||||
switch (token.kind) {
|
||||
case ts.SyntaxKind.OpenBraceToken: return ts.SyntaxKind.CloseBraceToken;
|
||||
case ts.SyntaxKind.OpenParenToken: return ts.SyntaxKind.CloseParenToken;
|
||||
case ts.SyntaxKind.OpenBracketToken: return ts.SyntaxKind.CloseBracketToken;
|
||||
case ts.SyntaxKind.LessThanToken: return ts.SyntaxKind.GreaterThanToken;
|
||||
case ts.SyntaxKind.CloseBraceToken: return ts.SyntaxKind.OpenBraceToken;
|
||||
case ts.SyntaxKind.CloseParenToken: return ts.SyntaxKind.OpenParenToken;
|
||||
case ts.SyntaxKind.CloseBracketToken: return ts.SyntaxKind.OpenBracketToken;
|
||||
case ts.SyntaxKind.GreaterThanToken: return ts.SyntaxKind.LessThanToken;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
const matchKind = token.getStart(sourceFile) === position ? braceMatching.get(token.kind.toString()) : undefined;
|
||||
const match = matchKind && findChildOfKind(token.parent, matchKind, sourceFile);
|
||||
// We want to order the braces when we return the result.
|
||||
return match ? [createTextSpanFromNode(token, sourceFile), createTextSpanFromNode(match, sourceFile)].sort((a, b) => a.start - b.start) : emptyArray;
|
||||
}
|
||||
|
||||
function getIndentationAtPosition(fileName: string, position: number, editorOptions: EditorOptions | EditorSettings) {
|
||||
@@ -1907,6 +1849,15 @@ namespace ts {
|
||||
return codefix.getAllFixes({ fixId, sourceFile, program, host, cancellationToken, formatContext });
|
||||
}
|
||||
|
||||
function organizeImports(scope: OrganizeImportsScope, formatOptions: FormatCodeSettings): ReadonlyArray<FileTextChanges> {
|
||||
synchronizeHostData();
|
||||
Debug.assert(scope.type === "file");
|
||||
const sourceFile = getValidSourceFile(scope.fileName);
|
||||
const formatContext = formatting.getFormatContext(formatOptions);
|
||||
|
||||
return OrganizeImports.organizeImports(sourceFile, formatContext, host);
|
||||
}
|
||||
|
||||
function applyCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
|
||||
function applyCodeActionCommand(action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
|
||||
function applyCodeActionCommand(action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
|
||||
@@ -2202,6 +2153,7 @@ namespace ts {
|
||||
getCodeFixesAtPosition,
|
||||
getCombinedCodeFix,
|
||||
applyCodeActionCommand,
|
||||
organizeImports,
|
||||
getEmitOutput,
|
||||
getNonBoundSourceFile,
|
||||
getSourceFile,
|
||||
@@ -2266,7 +2218,7 @@ namespace ts {
|
||||
case SyntaxKind.Identifier:
|
||||
return isObjectLiteralElement(node.parent) &&
|
||||
(node.parent.parent.kind === SyntaxKind.ObjectLiteralExpression || node.parent.parent.kind === SyntaxKind.JsxAttributes) &&
|
||||
(<ObjectLiteralElement>node.parent).name === node ? node.parent as ObjectLiteralElement : undefined;
|
||||
node.parent.name === node ? node.parent : undefined;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -57,14 +57,9 @@ namespace ts.SignatureHelp {
|
||||
}
|
||||
|
||||
// See if we can find some symbol with the call expression name that has call signatures.
|
||||
const callExpression = <CallExpression>argumentInfo.invocation;
|
||||
const callExpression = argumentInfo.invocation;
|
||||
const expression = callExpression.expression;
|
||||
const name = expression.kind === SyntaxKind.Identifier
|
||||
? <Identifier>expression
|
||||
: expression.kind === SyntaxKind.PropertyAccessExpression
|
||||
? (<PropertyAccessExpression>expression).name
|
||||
: undefined;
|
||||
|
||||
const name = isIdentifier(expression) ? expression : isPropertyAccessExpression(expression) ? expression.name : undefined;
|
||||
if (!name || !name.escapedText) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -95,7 +90,7 @@ namespace ts.SignatureHelp {
|
||||
* Returns relevant information for the argument list and the current argument if we are
|
||||
* in the argument of an invocation; returns undefined otherwise.
|
||||
*/
|
||||
export function getImmediatelyContainingArgumentInfo(node: Node, position: number, sourceFile: SourceFile): ArgumentListInfo {
|
||||
export function getImmediatelyContainingArgumentInfo(node: Node, position: number, sourceFile: SourceFile): ArgumentListInfo | undefined {
|
||||
if (isCallOrNewExpression(node.parent)) {
|
||||
const invocation = node.parent;
|
||||
let list: Node;
|
||||
@@ -160,7 +155,7 @@ namespace ts.SignatureHelp {
|
||||
}
|
||||
else if (node.parent.kind === SyntaxKind.TemplateSpan && node.parent.parent.parent.kind === SyntaxKind.TaggedTemplateExpression) {
|
||||
const templateSpan = <TemplateSpan>node.parent;
|
||||
const templateExpression = <TemplateExpression>templateSpan.parent;
|
||||
const templateExpression = templateSpan.parent;
|
||||
const tagExpression = <TaggedTemplateExpression>templateExpression.parent;
|
||||
Debug.assert(templateExpression.kind === SyntaxKind.TemplateExpression);
|
||||
|
||||
@@ -207,8 +202,7 @@ namespace ts.SignatureHelp {
|
||||
// that trailing comma in the list, and we'll have generated the appropriate
|
||||
// arg index.
|
||||
let argumentIndex = 0;
|
||||
const listChildren = argumentsList.getChildren();
|
||||
for (const child of listChildren) {
|
||||
for (const child of argumentsList.getChildren()) {
|
||||
if (child === node) {
|
||||
break;
|
||||
}
|
||||
@@ -270,10 +264,7 @@ namespace ts.SignatureHelp {
|
||||
|
||||
function getArgumentListInfoForTemplate(tagExpression: TaggedTemplateExpression, argumentIndex: number, sourceFile: SourceFile): ArgumentListInfo {
|
||||
// argumentCount is either 1 or (numSpans + 1) to account for the template strings array argument.
|
||||
const argumentCount = tagExpression.template.kind === SyntaxKind.NoSubstitutionTemplateLiteral
|
||||
? 1
|
||||
: (<TemplateExpression>tagExpression.template).templateSpans.length + 1;
|
||||
|
||||
const argumentCount = isNoSubstitutionTemplateLiteral(tagExpression.template) ? 1 : tagExpression.template.templateSpans.length + 1;
|
||||
if (argumentIndex !== 0) {
|
||||
Debug.assertLessThan(argumentIndex, argumentCount);
|
||||
}
|
||||
@@ -314,7 +305,7 @@ namespace ts.SignatureHelp {
|
||||
// This is because a Missing node has no width. However, what we actually want is to include trivia
|
||||
// leading up to the next token in case the user is about to type in a TemplateMiddle or TemplateTail.
|
||||
if (template.kind === SyntaxKind.TemplateExpression) {
|
||||
const lastSpan = lastOrUndefined((<TemplateExpression>template).templateSpans);
|
||||
const lastSpan = lastOrUndefined(template.templateSpans);
|
||||
if (lastSpan.literal.getFullWidth() === 0) {
|
||||
applicableSpanEnd = skipTrivia(sourceFile.text, applicableSpanEnd, /*stopAfterLineBreak*/ false);
|
||||
}
|
||||
|
||||
@@ -146,13 +146,13 @@ namespace ts.SymbolDisplay {
|
||||
// try get the call/construct signature from the type if it matches
|
||||
let callExpressionLike: CallExpression | NewExpression | JsxOpeningLikeElement;
|
||||
if (isCallOrNewExpression(location)) {
|
||||
callExpressionLike = <CallExpression | NewExpression>location;
|
||||
callExpressionLike = location;
|
||||
}
|
||||
else if (isCallExpressionTarget(location) || isNewExpressionTarget(location)) {
|
||||
callExpressionLike = <CallExpression | NewExpression>location.parent;
|
||||
}
|
||||
else if (location.parent && isJsxOpeningLikeElement(location.parent) && isFunctionLike(symbol.valueDeclaration)) {
|
||||
callExpressionLike = <JsxOpeningLikeElement>location.parent;
|
||||
callExpressionLike = location.parent;
|
||||
}
|
||||
|
||||
if (callExpressionLike) {
|
||||
|
||||
+12
-34
@@ -197,13 +197,12 @@ namespace ts.textChanges {
|
||||
|
||||
export class ChangeTracker {
|
||||
private readonly changes: Change[] = [];
|
||||
private readonly newLineCharacter: string;
|
||||
private readonly deletedNodesInLists: true[] = []; // Stores ids of nodes in lists that we already deleted. Used to avoid deleting `, ` twice in `a, b`.
|
||||
// Map from class id to nodes to insert at the start
|
||||
private readonly nodesInsertedAtClassStarts = createMap<{ sourceFile: SourceFile, cls: ClassLikeDeclaration, members: ClassElement[] }>();
|
||||
|
||||
public static fromContext(context: TextChangesContext): ChangeTracker {
|
||||
return new ChangeTracker(getNewLineOrDefaultFromHost(context.host, context.formatContext.options) === "\n" ? NewLineKind.LineFeed : NewLineKind.CarriageReturnLineFeed, context.formatContext);
|
||||
return new ChangeTracker(getNewLineOrDefaultFromHost(context.host, context.formatContext.options), context.formatContext);
|
||||
}
|
||||
|
||||
public static with(context: TextChangesContext, cb: (tracker: ChangeTracker) => void): FileTextChanges[] {
|
||||
@@ -212,11 +211,11 @@ namespace ts.textChanges {
|
||||
return tracker.getChanges();
|
||||
}
|
||||
|
||||
/** Public for tests only. Other callers should use `ChangeTracker.with`. */
|
||||
constructor(
|
||||
private readonly newLine: NewLineKind,
|
||||
private readonly newLineCharacter: string,
|
||||
private readonly formatContext: ts.formatting.FormatContext,
|
||||
private readonly validator?: (text: NonFormattedText) => void) {
|
||||
this.newLineCharacter = getNewLineCharacter({ newLine });
|
||||
}
|
||||
|
||||
public deleteRange(sourceFile: SourceFile, range: TextRange) {
|
||||
@@ -593,32 +592,12 @@ namespace ts.textChanges {
|
||||
|
||||
public getChanges(): FileTextChanges[] {
|
||||
this.finishInsertNodeAtClassStart();
|
||||
|
||||
const changesPerFile = createMap<Change[]>();
|
||||
// group changes per file
|
||||
for (const c of this.changes) {
|
||||
let changesInFile = changesPerFile.get(c.sourceFile.path);
|
||||
if (!changesInFile) {
|
||||
changesPerFile.set(c.sourceFile.path, changesInFile = []);
|
||||
}
|
||||
changesInFile.push(c);
|
||||
}
|
||||
// convert changes
|
||||
const fileChangesList: FileTextChanges[] = [];
|
||||
changesPerFile.forEach(changesInFile => {
|
||||
return group(this.changes, c => c.sourceFile.path).map(changesInFile => {
|
||||
const sourceFile = changesInFile[0].sourceFile;
|
||||
const fileTextChanges: FileTextChanges = { fileName: sourceFile.fileName, textChanges: [] };
|
||||
for (const c of ChangeTracker.normalize(changesInFile)) {
|
||||
fileTextChanges.textChanges.push(createTextChange(this.computeSpan(c, sourceFile), this.computeNewText(c, sourceFile)));
|
||||
}
|
||||
fileChangesList.push(fileTextChanges);
|
||||
const textChanges = ChangeTracker.normalize(changesInFile).map(c =>
|
||||
createTextChange(createTextSpanFromRange(c.range), this.computeNewText(c, sourceFile)));
|
||||
return { fileName: sourceFile.fileName, textChanges };
|
||||
});
|
||||
|
||||
return fileChangesList;
|
||||
}
|
||||
|
||||
private computeSpan(change: Change, _sourceFile: SourceFile): TextSpan {
|
||||
return createTextSpanFromRange(change.range);
|
||||
}
|
||||
|
||||
private computeNewText(change: Change, sourceFile: SourceFile): string {
|
||||
@@ -651,7 +630,7 @@ namespace ts.textChanges {
|
||||
}
|
||||
|
||||
private getFormattedTextOfNode(node: Node, sourceFile: SourceFile, pos: number, options: ChangeNodeOptions): string {
|
||||
const nonformattedText = getNonformattedText(node, sourceFile, this.newLine);
|
||||
const nonformattedText = getNonformattedText(node, sourceFile, this.newLineCharacter);
|
||||
if (this.validator) {
|
||||
this.validator(nonformattedText);
|
||||
}
|
||||
@@ -675,7 +654,7 @@ namespace ts.textChanges {
|
||||
return applyFormatting(nonformattedText, sourceFile, initialIndentation, delta, this.formatContext);
|
||||
}
|
||||
|
||||
private static normalize(changes: Change[]): Change[] {
|
||||
private static normalize(changes: ReadonlyArray<Change>): ReadonlyArray<Change> {
|
||||
// order changes by start position
|
||||
const normalized = stableSort(changes, (a, b) => a.range.pos - b.range.pos);
|
||||
// verify that change intervals do not overlap, except possibly at end points.
|
||||
@@ -691,10 +670,9 @@ namespace ts.textChanges {
|
||||
readonly node: Node;
|
||||
}
|
||||
|
||||
function getNonformattedText(node: Node, sourceFile: SourceFile | undefined, newLine: NewLineKind): NonFormattedText {
|
||||
const options = { newLine, target: sourceFile && sourceFile.languageVersion };
|
||||
const writer = new Writer(getNewLineCharacter(options));
|
||||
const printer = createPrinter(options, writer);
|
||||
function getNonformattedText(node: Node, sourceFile: SourceFile | undefined, newLine: string): NonFormattedText {
|
||||
const writer = new Writer(newLine);
|
||||
const printer = createPrinter({ newLine: newLine === "\n" ? NewLineKind.LineFeed : NewLineKind.CarriageReturnLineFeed }, writer);
|
||||
printer.writeNode(EmitHint.Unspecified, node, sourceFile, writer);
|
||||
return { text: writer.getText(), node: assignPositionsToNode(node) };
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
"jsTyping.ts",
|
||||
"navigateTo.ts",
|
||||
"navigationBar.ts",
|
||||
"organizeImports.ts",
|
||||
"outliningElementsCollector.ts",
|
||||
"pathCompletions.ts",
|
||||
"patternMatcher.ts",
|
||||
|
||||
@@ -308,6 +308,7 @@ namespace ts {
|
||||
applyCodeActionCommand(fileName: string, action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
|
||||
getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[];
|
||||
getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined;
|
||||
organizeImports(scope: OrganizeImportsScope, formatOptions: FormatCodeSettings): ReadonlyArray<FileTextChanges>;
|
||||
|
||||
getEmitOutput(fileName: string, emitOnlyDtsFiles?: boolean): EmitOutput;
|
||||
|
||||
@@ -326,6 +327,8 @@ namespace ts {
|
||||
|
||||
export interface CombinedCodeFixScope { type: "file"; fileName: string; }
|
||||
|
||||
export type OrganizeImportsScope = CombinedCodeFixScope;
|
||||
|
||||
export interface GetCompletionsAtPositionOptions {
|
||||
includeExternalModuleExports: boolean;
|
||||
includeInsertTextCompletions: boolean;
|
||||
@@ -724,6 +727,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export interface CompletionInfo {
|
||||
/** Not true for all glboal completions. This will be true if the enclosing scope matches a few syntax kinds. See `isGlobalCompletionScope`. */
|
||||
isGlobalCompletion: boolean;
|
||||
isMemberCompletion: boolean;
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ namespace ts {
|
||||
while (node.parent.kind === SyntaxKind.QualifiedName) {
|
||||
node = node.parent;
|
||||
}
|
||||
return isInternalModuleImportEqualsDeclaration(node.parent) && (<ImportEqualsDeclaration>node.parent).moduleReference === node;
|
||||
return isInternalModuleImportEqualsDeclaration(node.parent) && node.parent.moduleReference === node;
|
||||
}
|
||||
|
||||
function isNamespaceReference(node: Node): boolean {
|
||||
|
||||
@@ -4135,6 +4135,7 @@ declare namespace ts {
|
||||
applyCodeActionCommand(fileName: string, action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
|
||||
getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[];
|
||||
getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined;
|
||||
organizeImports(scope: OrganizeImportsScope, formatOptions: FormatCodeSettings): ReadonlyArray<FileTextChanges>;
|
||||
getEmitOutput(fileName: string, emitOnlyDtsFiles?: boolean): EmitOutput;
|
||||
getProgram(): Program;
|
||||
dispose(): void;
|
||||
@@ -4143,6 +4144,7 @@ declare namespace ts {
|
||||
type: "file";
|
||||
fileName: string;
|
||||
}
|
||||
type OrganizeImportsScope = CombinedCodeFixScope;
|
||||
interface GetCompletionsAtPositionOptions {
|
||||
includeExternalModuleExports: boolean;
|
||||
includeInsertTextCompletions: boolean;
|
||||
@@ -4488,6 +4490,7 @@ declare namespace ts {
|
||||
argumentCount: number;
|
||||
}
|
||||
interface CompletionInfo {
|
||||
/** Not true for all glboal completions. This will be true if the enclosing scope matches a few syntax kinds. See `isGlobalCompletionScope`. */
|
||||
isGlobalCompletion: boolean;
|
||||
isMemberCompletion: boolean;
|
||||
/**
|
||||
@@ -5078,6 +5081,7 @@ declare namespace ts.server.protocol {
|
||||
GetSupportedCodeFixes = "getSupportedCodeFixes",
|
||||
GetApplicableRefactors = "getApplicableRefactors",
|
||||
GetEditsForRefactor = "getEditsForRefactor",
|
||||
OrganizeImports = "organizeImports",
|
||||
}
|
||||
/**
|
||||
* A TypeScript Server message
|
||||
@@ -5429,6 +5433,23 @@ declare namespace ts.server.protocol {
|
||||
renameLocation?: Location;
|
||||
renameFilename?: string;
|
||||
}
|
||||
/**
|
||||
* Organize imports by:
|
||||
* 1) Removing unused imports
|
||||
* 2) Coalescing imports from the same module
|
||||
* 3) Sorting imports
|
||||
*/
|
||||
interface OrganizeImportsRequest extends Request {
|
||||
command: CommandTypes.OrganizeImports;
|
||||
arguments: OrganizeImportsRequestArgs;
|
||||
}
|
||||
type OrganizeImportsScope = GetCombinedCodeFixScope;
|
||||
interface OrganizeImportsRequestArgs {
|
||||
scope: OrganizeImportsScope;
|
||||
}
|
||||
interface OrganizeImportsResponse extends Response {
|
||||
edits: ReadonlyArray<FileCodeEdits>;
|
||||
}
|
||||
/**
|
||||
* Request for the available codefixes at a specific position.
|
||||
*/
|
||||
@@ -7282,6 +7303,7 @@ declare namespace ts.server {
|
||||
private extractPositionAndRange(args, scriptInfo);
|
||||
private getApplicableRefactors(args);
|
||||
private getEditsForRefactor(args, simplifiedResult);
|
||||
private organizeImports({scope}, simplifiedResult);
|
||||
private getCodeFixes(args, simplifiedResult);
|
||||
private getCombinedCodeFix({scope, fixId}, simplifiedResult);
|
||||
private applyCodeActionCommand(args);
|
||||
|
||||
@@ -4387,6 +4387,7 @@ declare namespace ts {
|
||||
applyCodeActionCommand(fileName: string, action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
|
||||
getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[];
|
||||
getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined;
|
||||
organizeImports(scope: OrganizeImportsScope, formatOptions: FormatCodeSettings): ReadonlyArray<FileTextChanges>;
|
||||
getEmitOutput(fileName: string, emitOnlyDtsFiles?: boolean): EmitOutput;
|
||||
getProgram(): Program;
|
||||
dispose(): void;
|
||||
@@ -4395,6 +4396,7 @@ declare namespace ts {
|
||||
type: "file";
|
||||
fileName: string;
|
||||
}
|
||||
type OrganizeImportsScope = CombinedCodeFixScope;
|
||||
interface GetCompletionsAtPositionOptions {
|
||||
includeExternalModuleExports: boolean;
|
||||
includeInsertTextCompletions: boolean;
|
||||
@@ -4740,6 +4742,7 @@ declare namespace ts {
|
||||
argumentCount: number;
|
||||
}
|
||||
interface CompletionInfo {
|
||||
/** Not true for all glboal completions. This will be true if the enclosing scope matches a few syntax kinds. See `isGlobalCompletionScope`. */
|
||||
isGlobalCompletion: boolean;
|
||||
isMemberCompletion: boolean;
|
||||
/**
|
||||
|
||||
@@ -447,4 +447,34 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(275,43): error TS
|
||||
type A = Omit<{ a: void; b: never; }>; // 'a'
|
||||
type B = Omit2<{ a: void; b: never; }>; // 'a'
|
||||
}
|
||||
|
||||
// Repro from #21862
|
||||
|
||||
type OldDiff<T extends string, U extends string> = (
|
||||
& { [P in T]: P; }
|
||||
& { [P in U]: never; }
|
||||
& { [x: string]: never; }
|
||||
)[T];
|
||||
type NewDiff<T, U> = T extends U ? never : T;
|
||||
interface A {
|
||||
a: 'a';
|
||||
}
|
||||
interface B1 extends A {
|
||||
b: 'b';
|
||||
c: OldDiff<keyof this, keyof A>;
|
||||
}
|
||||
interface B2 extends A {
|
||||
b: 'b';
|
||||
c: NewDiff<keyof this, keyof A>;
|
||||
}
|
||||
type c1 = B1['c']; // 'c' | 'b'
|
||||
type c2 = B2['c']; // 'c' | 'b'
|
||||
|
||||
// Repro from #21929
|
||||
|
||||
type NonFooKeys1<T extends object> = OldDiff<keyof T, 'foo'>;
|
||||
type NonFooKeys2<T extends object> = Exclude<keyof T, 'foo'>;
|
||||
|
||||
type Test1 = NonFooKeys1<{foo: 1, bar: 2, baz: 3}>; // "bar" | "baz"
|
||||
type Test2 = NonFooKeys2<{foo: 1, bar: 2, baz: 3}>; // "bar" | "baz"
|
||||
|
||||
@@ -285,6 +285,36 @@ function f50() {
|
||||
type A = Omit<{ a: void; b: never; }>; // 'a'
|
||||
type B = Omit2<{ a: void; b: never; }>; // 'a'
|
||||
}
|
||||
|
||||
// Repro from #21862
|
||||
|
||||
type OldDiff<T extends string, U extends string> = (
|
||||
& { [P in T]: P; }
|
||||
& { [P in U]: never; }
|
||||
& { [x: string]: never; }
|
||||
)[T];
|
||||
type NewDiff<T, U> = T extends U ? never : T;
|
||||
interface A {
|
||||
a: 'a';
|
||||
}
|
||||
interface B1 extends A {
|
||||
b: 'b';
|
||||
c: OldDiff<keyof this, keyof A>;
|
||||
}
|
||||
interface B2 extends A {
|
||||
b: 'b';
|
||||
c: NewDiff<keyof this, keyof A>;
|
||||
}
|
||||
type c1 = B1['c']; // 'c' | 'b'
|
||||
type c2 = B2['c']; // 'c' | 'b'
|
||||
|
||||
// Repro from #21929
|
||||
|
||||
type NonFooKeys1<T extends object> = OldDiff<keyof T, 'foo'>;
|
||||
type NonFooKeys2<T extends object> = Exclude<keyof T, 'foo'>;
|
||||
|
||||
type Test1 = NonFooKeys1<{foo: 1, bar: 2, baz: 3}>; // "bar" | "baz"
|
||||
type Test2 = NonFooKeys2<{foo: 1, bar: 2, baz: 3}>; // "bar" | "baz"
|
||||
|
||||
|
||||
//// [conditionalTypes1.js]
|
||||
@@ -561,3 +591,36 @@ declare type T95<T> = T extends string ? boolean : number;
|
||||
declare const f44: <U>(value: T94<U>) => T95<U>;
|
||||
declare const f45: <U>(value: T95<U>) => T94<U>;
|
||||
declare function f50(): void;
|
||||
declare type OldDiff<T extends string, U extends string> = ({
|
||||
[P in T]: P;
|
||||
} & {
|
||||
[P in U]: never;
|
||||
} & {
|
||||
[x: string]: never;
|
||||
})[T];
|
||||
declare type NewDiff<T, U> = T extends U ? never : T;
|
||||
interface A {
|
||||
a: 'a';
|
||||
}
|
||||
interface B1 extends A {
|
||||
b: 'b';
|
||||
c: OldDiff<keyof this, keyof A>;
|
||||
}
|
||||
interface B2 extends A {
|
||||
b: 'b';
|
||||
c: NewDiff<keyof this, keyof A>;
|
||||
}
|
||||
declare type c1 = B1['c'];
|
||||
declare type c2 = B2['c'];
|
||||
declare type NonFooKeys1<T extends object> = OldDiff<keyof T, 'foo'>;
|
||||
declare type NonFooKeys2<T extends object> = Exclude<keyof T, 'foo'>;
|
||||
declare type Test1 = NonFooKeys1<{
|
||||
foo: 1;
|
||||
bar: 2;
|
||||
baz: 3;
|
||||
}>;
|
||||
declare type Test2 = NonFooKeys2<{
|
||||
foo: 1;
|
||||
bar: 2;
|
||||
baz: 3;
|
||||
}>;
|
||||
|
||||
@@ -1121,3 +1121,99 @@ function f50() {
|
||||
>b : Symbol(b, Decl(conditionalTypes1.ts, 284, 29))
|
||||
}
|
||||
|
||||
// Repro from #21862
|
||||
|
||||
type OldDiff<T extends string, U extends string> = (
|
||||
>OldDiff : Symbol(OldDiff, Decl(conditionalTypes1.ts, 285, 1))
|
||||
>T : Symbol(T, Decl(conditionalTypes1.ts, 289, 13))
|
||||
>U : Symbol(U, Decl(conditionalTypes1.ts, 289, 30))
|
||||
|
||||
& { [P in T]: P; }
|
||||
>P : Symbol(P, Decl(conditionalTypes1.ts, 290, 9))
|
||||
>T : Symbol(T, Decl(conditionalTypes1.ts, 289, 13))
|
||||
>P : Symbol(P, Decl(conditionalTypes1.ts, 290, 9))
|
||||
|
||||
& { [P in U]: never; }
|
||||
>P : Symbol(P, Decl(conditionalTypes1.ts, 291, 9))
|
||||
>U : Symbol(U, Decl(conditionalTypes1.ts, 289, 30))
|
||||
|
||||
& { [x: string]: never; }
|
||||
>x : Symbol(x, Decl(conditionalTypes1.ts, 292, 9))
|
||||
|
||||
)[T];
|
||||
>T : Symbol(T, Decl(conditionalTypes1.ts, 289, 13))
|
||||
|
||||
type NewDiff<T, U> = T extends U ? never : T;
|
||||
>NewDiff : Symbol(NewDiff, Decl(conditionalTypes1.ts, 293, 5))
|
||||
>T : Symbol(T, Decl(conditionalTypes1.ts, 294, 13))
|
||||
>U : Symbol(U, Decl(conditionalTypes1.ts, 294, 15))
|
||||
>T : Symbol(T, Decl(conditionalTypes1.ts, 294, 13))
|
||||
>U : Symbol(U, Decl(conditionalTypes1.ts, 294, 15))
|
||||
>T : Symbol(T, Decl(conditionalTypes1.ts, 294, 13))
|
||||
|
||||
interface A {
|
||||
>A : Symbol(A, Decl(conditionalTypes1.ts, 294, 45))
|
||||
|
||||
a: 'a';
|
||||
>a : Symbol(A.a, Decl(conditionalTypes1.ts, 295, 13))
|
||||
}
|
||||
interface B1 extends A {
|
||||
>B1 : Symbol(B1, Decl(conditionalTypes1.ts, 297, 1))
|
||||
>A : Symbol(A, Decl(conditionalTypes1.ts, 294, 45))
|
||||
|
||||
b: 'b';
|
||||
>b : Symbol(B1.b, Decl(conditionalTypes1.ts, 298, 24))
|
||||
|
||||
c: OldDiff<keyof this, keyof A>;
|
||||
>c : Symbol(B1.c, Decl(conditionalTypes1.ts, 299, 11))
|
||||
>OldDiff : Symbol(OldDiff, Decl(conditionalTypes1.ts, 285, 1))
|
||||
>A : Symbol(A, Decl(conditionalTypes1.ts, 294, 45))
|
||||
}
|
||||
interface B2 extends A {
|
||||
>B2 : Symbol(B2, Decl(conditionalTypes1.ts, 301, 1))
|
||||
>A : Symbol(A, Decl(conditionalTypes1.ts, 294, 45))
|
||||
|
||||
b: 'b';
|
||||
>b : Symbol(B2.b, Decl(conditionalTypes1.ts, 302, 24))
|
||||
|
||||
c: NewDiff<keyof this, keyof A>;
|
||||
>c : Symbol(B2.c, Decl(conditionalTypes1.ts, 303, 11))
|
||||
>NewDiff : Symbol(NewDiff, Decl(conditionalTypes1.ts, 293, 5))
|
||||
>A : Symbol(A, Decl(conditionalTypes1.ts, 294, 45))
|
||||
}
|
||||
type c1 = B1['c']; // 'c' | 'b'
|
||||
>c1 : Symbol(c1, Decl(conditionalTypes1.ts, 305, 1))
|
||||
>B1 : Symbol(B1, Decl(conditionalTypes1.ts, 297, 1))
|
||||
|
||||
type c2 = B2['c']; // 'c' | 'b'
|
||||
>c2 : Symbol(c2, Decl(conditionalTypes1.ts, 306, 18))
|
||||
>B2 : Symbol(B2, Decl(conditionalTypes1.ts, 301, 1))
|
||||
|
||||
// Repro from #21929
|
||||
|
||||
type NonFooKeys1<T extends object> = OldDiff<keyof T, 'foo'>;
|
||||
>NonFooKeys1 : Symbol(NonFooKeys1, Decl(conditionalTypes1.ts, 307, 18))
|
||||
>T : Symbol(T, Decl(conditionalTypes1.ts, 311, 17))
|
||||
>OldDiff : Symbol(OldDiff, Decl(conditionalTypes1.ts, 285, 1))
|
||||
>T : Symbol(T, Decl(conditionalTypes1.ts, 311, 17))
|
||||
|
||||
type NonFooKeys2<T extends object> = Exclude<keyof T, 'foo'>;
|
||||
>NonFooKeys2 : Symbol(NonFooKeys2, Decl(conditionalTypes1.ts, 311, 61))
|
||||
>T : Symbol(T, Decl(conditionalTypes1.ts, 312, 17))
|
||||
>Exclude : Symbol(Exclude, Decl(lib.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(conditionalTypes1.ts, 312, 17))
|
||||
|
||||
type Test1 = NonFooKeys1<{foo: 1, bar: 2, baz: 3}>; // "bar" | "baz"
|
||||
>Test1 : Symbol(Test1, Decl(conditionalTypes1.ts, 312, 61))
|
||||
>NonFooKeys1 : Symbol(NonFooKeys1, Decl(conditionalTypes1.ts, 307, 18))
|
||||
>foo : Symbol(foo, Decl(conditionalTypes1.ts, 314, 26))
|
||||
>bar : Symbol(bar, Decl(conditionalTypes1.ts, 314, 33))
|
||||
>baz : Symbol(baz, Decl(conditionalTypes1.ts, 314, 41))
|
||||
|
||||
type Test2 = NonFooKeys2<{foo: 1, bar: 2, baz: 3}>; // "bar" | "baz"
|
||||
>Test2 : Symbol(Test2, Decl(conditionalTypes1.ts, 314, 51))
|
||||
>NonFooKeys2 : Symbol(NonFooKeys2, Decl(conditionalTypes1.ts, 311, 61))
|
||||
>foo : Symbol(foo, Decl(conditionalTypes1.ts, 315, 26))
|
||||
>bar : Symbol(bar, Decl(conditionalTypes1.ts, 315, 33))
|
||||
>baz : Symbol(baz, Decl(conditionalTypes1.ts, 315, 41))
|
||||
|
||||
|
||||
@@ -1274,3 +1274,99 @@ function f50() {
|
||||
>b : never
|
||||
}
|
||||
|
||||
// Repro from #21862
|
||||
|
||||
type OldDiff<T extends string, U extends string> = (
|
||||
>OldDiff : ({ [P in T]: P; } & { [P in U]: never; } & { [x: string]: never; })[T]
|
||||
>T : T
|
||||
>U : U
|
||||
|
||||
& { [P in T]: P; }
|
||||
>P : P
|
||||
>T : T
|
||||
>P : P
|
||||
|
||||
& { [P in U]: never; }
|
||||
>P : P
|
||||
>U : U
|
||||
|
||||
& { [x: string]: never; }
|
||||
>x : string
|
||||
|
||||
)[T];
|
||||
>T : T
|
||||
|
||||
type NewDiff<T, U> = T extends U ? never : T;
|
||||
>NewDiff : NewDiff<T, U>
|
||||
>T : T
|
||||
>U : U
|
||||
>T : T
|
||||
>U : U
|
||||
>T : T
|
||||
|
||||
interface A {
|
||||
>A : A
|
||||
|
||||
a: 'a';
|
||||
>a : "a"
|
||||
}
|
||||
interface B1 extends A {
|
||||
>B1 : B1
|
||||
>A : A
|
||||
|
||||
b: 'b';
|
||||
>b : "b"
|
||||
|
||||
c: OldDiff<keyof this, keyof A>;
|
||||
>c : ({ [P in keyof this]: P; } & { a: never; } & { [x: string]: never; })[keyof this]
|
||||
>OldDiff : ({ [P in T]: P; } & { [P in U]: never; } & { [x: string]: never; })[T]
|
||||
>A : A
|
||||
}
|
||||
interface B2 extends A {
|
||||
>B2 : B2
|
||||
>A : A
|
||||
|
||||
b: 'b';
|
||||
>b : "b"
|
||||
|
||||
c: NewDiff<keyof this, keyof A>;
|
||||
>c : NewDiff<keyof this, "a">
|
||||
>NewDiff : NewDiff<T, U>
|
||||
>A : A
|
||||
}
|
||||
type c1 = B1['c']; // 'c' | 'b'
|
||||
>c1 : "b" | "c"
|
||||
>B1 : B1
|
||||
|
||||
type c2 = B2['c']; // 'c' | 'b'
|
||||
>c2 : "b" | "c"
|
||||
>B2 : B2
|
||||
|
||||
// Repro from #21929
|
||||
|
||||
type NonFooKeys1<T extends object> = OldDiff<keyof T, 'foo'>;
|
||||
>NonFooKeys1 : ({ [P in keyof T]: P; } & { foo: never; } & { [x: string]: never; })[keyof T]
|
||||
>T : T
|
||||
>OldDiff : ({ [P in T]: P; } & { [P in U]: never; } & { [x: string]: never; })[T]
|
||||
>T : T
|
||||
|
||||
type NonFooKeys2<T extends object> = Exclude<keyof T, 'foo'>;
|
||||
>NonFooKeys2 : Exclude<keyof T, "foo">
|
||||
>T : T
|
||||
>Exclude : Exclude<T, U>
|
||||
>T : T
|
||||
|
||||
type Test1 = NonFooKeys1<{foo: 1, bar: 2, baz: 3}>; // "bar" | "baz"
|
||||
>Test1 : "bar" | "baz"
|
||||
>NonFooKeys1 : ({ [P in keyof T]: P; } & { foo: never; } & { [x: string]: never; })[keyof T]
|
||||
>foo : 1
|
||||
>bar : 2
|
||||
>baz : 3
|
||||
|
||||
type Test2 = NonFooKeys2<{foo: 1, bar: 2, baz: 3}>; // "bar" | "baz"
|
||||
>Test2 : "bar" | "baz"
|
||||
>NonFooKeys2 : Exclude<keyof T, "foo">
|
||||
>foo : 1
|
||||
>bar : 2
|
||||
>baz : 3
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
tests/cases/compiler/noUnusedLocals_typeParameterMergedWithParameter.ts(1,18): error TS6133: 'T' is declared but its value is never read.
|
||||
tests/cases/compiler/noUnusedLocals_typeParameterMergedWithParameter.ts(1,21): error TS6133: 'T' is declared but its value is never read.
|
||||
tests/cases/compiler/noUnusedLocals_typeParameterMergedWithParameter.ts(3,19): error TS6133: 'T' is declared but its value is never read.
|
||||
tests/cases/compiler/noUnusedLocals_typeParameterMergedWithParameter.ts(7,26): error TS6133: 'T' is declared but its value is never read.
|
||||
|
||||
|
||||
==== tests/cases/compiler/noUnusedLocals_typeParameterMergedWithParameter.ts (4 errors) ====
|
||||
function useNone<T>(T: number) {}
|
||||
~
|
||||
!!! error TS6133: 'T' is declared but its value is never read.
|
||||
~
|
||||
!!! error TS6133: 'T' is declared but its value is never read.
|
||||
|
||||
function useParam<T>(T: number) {
|
||||
~
|
||||
!!! error TS6133: 'T' is declared but its value is never read.
|
||||
return T;
|
||||
}
|
||||
|
||||
function useTypeParam<T>(T: T) {}
|
||||
~
|
||||
!!! error TS6133: 'T' is declared but its value is never read.
|
||||
|
||||
function useBoth<T>(T: T) {
|
||||
return T;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
//// [noUnusedLocals_typeParameterMergedWithParameter.ts]
|
||||
function useNone<T>(T: number) {}
|
||||
|
||||
function useParam<T>(T: number) {
|
||||
return T;
|
||||
}
|
||||
|
||||
function useTypeParam<T>(T: T) {}
|
||||
|
||||
function useBoth<T>(T: T) {
|
||||
return T;
|
||||
}
|
||||
|
||||
|
||||
//// [noUnusedLocals_typeParameterMergedWithParameter.js]
|
||||
function useNone(T) { }
|
||||
function useParam(T) {
|
||||
return T;
|
||||
}
|
||||
function useTypeParam(T) { }
|
||||
function useBoth(T) {
|
||||
return T;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
=== tests/cases/compiler/noUnusedLocals_typeParameterMergedWithParameter.ts ===
|
||||
function useNone<T>(T: number) {}
|
||||
>useNone : Symbol(useNone, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 0, 17), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 0, 20))
|
||||
>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 0, 17), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 0, 20))
|
||||
|
||||
function useParam<T>(T: number) {
|
||||
>useParam : Symbol(useParam, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 0, 33))
|
||||
>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 2, 18), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 2, 21))
|
||||
>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 2, 18), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 2, 21))
|
||||
|
||||
return T;
|
||||
>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 2, 18), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 2, 21))
|
||||
}
|
||||
|
||||
function useTypeParam<T>(T: T) {}
|
||||
>useTypeParam : Symbol(useTypeParam, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 4, 1))
|
||||
>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 6, 22), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 6, 25))
|
||||
>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 6, 22), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 6, 25))
|
||||
>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 6, 22), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 6, 25))
|
||||
|
||||
function useBoth<T>(T: T) {
|
||||
>useBoth : Symbol(useBoth, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 6, 33))
|
||||
>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 8, 17), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 8, 20))
|
||||
>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 8, 17), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 8, 20))
|
||||
>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 8, 17), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 8, 20))
|
||||
|
||||
return T;
|
||||
>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 8, 17), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 8, 20))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
=== tests/cases/compiler/noUnusedLocals_typeParameterMergedWithParameter.ts ===
|
||||
function useNone<T>(T: number) {}
|
||||
>useNone : <T>(T: number) => void
|
||||
>T : T
|
||||
>T : number
|
||||
|
||||
function useParam<T>(T: number) {
|
||||
>useParam : <T>(T: number) => number
|
||||
>T : T
|
||||
>T : number
|
||||
|
||||
return T;
|
||||
>T : number
|
||||
}
|
||||
|
||||
function useTypeParam<T>(T: T) {}
|
||||
>useTypeParam : <T>(T: T) => void
|
||||
>T : T
|
||||
>T : T
|
||||
>T : T
|
||||
|
||||
function useBoth<T>(T: T) {
|
||||
>useBoth : <T>(T: T) => T
|
||||
>T : T
|
||||
>T : T
|
||||
>T : T
|
||||
|
||||
return T;
|
||||
>T : T
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
// ==ORIGINAL==
|
||||
|
||||
import { d } from "lib1";
|
||||
import { b } from "lib1";
|
||||
import { c } from "lib2";
|
||||
import { a } from "lib2";
|
||||
|
||||
// ==ORGANIZED==
|
||||
|
||||
import { b, d } from "lib1";
|
||||
import { a, c } from "lib2";
|
||||
@@ -0,0 +1,15 @@
|
||||
// ==ORIGINAL==
|
||||
|
||||
/*A*/import /*B*/ { /*C*/ F2 /*D*/ } /*E*/ from /*F*/ "lib" /*G*/;/*H*/ //I
|
||||
/*J*/import /*K*/ { /*L*/ F1 /*M*/ } /*N*/ from /*O*/ "lib" /*P*/;/*Q*/ //R
|
||||
|
||||
F1();
|
||||
F2();
|
||||
|
||||
// ==ORGANIZED==
|
||||
|
||||
/*A*/ import { /*L*/ F1 /*M*/, /*C*/ F2 /*D*/ } /*E*/ from "lib" /*G*/; /*H*/ //I
|
||||
|
||||
|
||||
F1();
|
||||
F2();
|
||||
@@ -0,0 +1,18 @@
|
||||
// ==ORIGINAL==
|
||||
|
||||
import { F1, F2 } from "lib";
|
||||
F1();
|
||||
F2();
|
||||
import * as NS from "lib";
|
||||
NS.F1();
|
||||
import D from "lib";
|
||||
D();
|
||||
|
||||
// ==ORGANIZED==
|
||||
|
||||
import * as NS from "lib";
|
||||
import D, { F1, F2 } from "lib";
|
||||
F1();
|
||||
F2();
|
||||
NS.F1();
|
||||
D();
|
||||
@@ -0,0 +1,22 @@
|
||||
// ==ORIGINAL==
|
||||
|
||||
import { F1, F2 } from "lib";
|
||||
F1();
|
||||
F2();
|
||||
import * as NS from "lib";
|
||||
NS.F1();
|
||||
import b from `${'lib'}`;
|
||||
import a from `${'lib'}`;
|
||||
import D from "lib";
|
||||
D();
|
||||
|
||||
// ==ORGANIZED==
|
||||
|
||||
import * as NS from "lib";
|
||||
import D, { F1, F2 } from "lib";
|
||||
import b from `${'lib'}`;
|
||||
import a from `${'lib'}`;
|
||||
F1();
|
||||
F2();
|
||||
NS.F1();
|
||||
D();
|
||||
@@ -0,0 +1,20 @@
|
||||
// ==ORIGINAL==
|
||||
|
||||
import { F1, F2 } from "lib";
|
||||
import * as NS from "lib";
|
||||
import D from "lib";
|
||||
|
||||
NS.F1();
|
||||
D();
|
||||
F1();
|
||||
F2();
|
||||
|
||||
// ==ORGANIZED==
|
||||
|
||||
import * as NS from "lib";
|
||||
import D, { F1, F2 } from "lib";
|
||||
|
||||
NS.F1();
|
||||
D();
|
||||
F1();
|
||||
F2();
|
||||
@@ -0,0 +1,10 @@
|
||||
// ==ORIGINAL==
|
||||
|
||||
/*A*/import /*B*/ "lib2" /*C*/;/*D*/ //E
|
||||
/*F*/import /*G*/ "lib1" /*H*/;/*I*/ //J
|
||||
|
||||
// ==ORGANIZED==
|
||||
|
||||
/*F*/ import "lib1" /*H*/; /*I*/ //J
|
||||
/*A*/ import "lib2" /*C*/; /*D*/ //E
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
// @noUnusedLocals: true
|
||||
// @noUnusedParameters: true
|
||||
|
||||
function useNone<T>(T: number) {}
|
||||
|
||||
function useParam<T>(T: number) {
|
||||
return T;
|
||||
}
|
||||
|
||||
function useTypeParam<T>(T: T) {}
|
||||
|
||||
function useBoth<T>(T: T) {
|
||||
return T;
|
||||
}
|
||||
@@ -287,3 +287,33 @@ function f50() {
|
||||
type A = Omit<{ a: void; b: never; }>; // 'a'
|
||||
type B = Omit2<{ a: void; b: never; }>; // 'a'
|
||||
}
|
||||
|
||||
// Repro from #21862
|
||||
|
||||
type OldDiff<T extends string, U extends string> = (
|
||||
& { [P in T]: P; }
|
||||
& { [P in U]: never; }
|
||||
& { [x: string]: never; }
|
||||
)[T];
|
||||
type NewDiff<T, U> = T extends U ? never : T;
|
||||
interface A {
|
||||
a: 'a';
|
||||
}
|
||||
interface B1 extends A {
|
||||
b: 'b';
|
||||
c: OldDiff<keyof this, keyof A>;
|
||||
}
|
||||
interface B2 extends A {
|
||||
b: 'b';
|
||||
c: NewDiff<keyof this, keyof A>;
|
||||
}
|
||||
type c1 = B1['c']; // 'c' | 'b'
|
||||
type c2 = B2['c']; // 'c' | 'b'
|
||||
|
||||
// Repro from #21929
|
||||
|
||||
type NonFooKeys1<T extends object> = OldDiff<keyof T, 'foo'>;
|
||||
type NonFooKeys2<T extends object> = Exclude<keyof T, 'foo'>;
|
||||
|
||||
type Test1 = NonFooKeys1<{foo: 1, bar: 2, baz: 3}>; // "bar" | "baz"
|
||||
type Test2 = NonFooKeys2<{foo: 1, bar: 2, baz: 3}>; // "bar" | "baz"
|
||||
|
||||
@@ -59,6 +59,7 @@ verify.completionListContains("constructor");
|
||||
verify.completionListContains("param");
|
||||
verify.completionListContains("type");
|
||||
verify.completionListContains("method");
|
||||
verify.completionListContains("template");
|
||||
|
||||
goTo.marker('2');
|
||||
verify.completionListContains("constructor");
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @jsx: preserve
|
||||
|
||||
// @Filename: /a.tsx
|
||||
////enum E {}
|
||||
////enum F {}
|
||||
////function f(e: E, f: F) {}
|
||||
////f(/*arg0*/, /*arg1*/);
|
||||
////
|
||||
////function tag(arr: TemplateStringsArray, x: E) {}
|
||||
////tag`${/*tag*/}`;
|
||||
////
|
||||
////declare function MainButton(props: { e: E }): any;
|
||||
////<MainButton e={/*jsx*/} />
|
||||
////<MainButton e=/*jsx2*/ />
|
||||
|
||||
recommended("arg0");
|
||||
recommended("arg1", "F");
|
||||
recommended("tag");
|
||||
recommended("jsx");
|
||||
recommended("jsx2");
|
||||
|
||||
function recommended(markerName: string, enumName = "E") {
|
||||
goTo.marker(markerName);
|
||||
verify.completionListContains(enumName, `enum ${enumName}`, "", "enum", undefined, undefined , { isRecommended: true });
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
////import { [|ab|] as [|cd|] } from "doesNotExist";
|
||||
|
||||
const [r0, r1] = test.ranges();
|
||||
verify.referencesOf(r0, [r1]);
|
||||
verify.referencesOf(r1, [r1]);
|
||||
@@ -27,5 +27,5 @@ verify.currentSignatureParameterCountIs(2);
|
||||
verify.currentSignatureHelpIs("f3(n: number, s: string): string");
|
||||
|
||||
verify.currentParameterHelpArgumentNameIs("s");
|
||||
verify.currentParameterSpanIs("s: string");
|
||||
verify.currentParameterSpanIs("s: string");
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
"extends": "tslint:latest",
|
||||
"rulesDirectory": "built/local/tslint/rules",
|
||||
"rules": {
|
||||
"no-unnecessary-type-assertion-2": true,
|
||||
|
||||
"array-type": [true, "array"],
|
||||
"ban-types": {
|
||||
"options": [
|
||||
|
||||
Reference in New Issue
Block a user