Merge branch 'master' into watchImprovements
This commit is contained in:
commit
898559b4e5
|
@ -1272,8 +1272,10 @@ namespace ts {
|
||||||
case SyntaxKind.PropertyAccessExpression:
|
case SyntaxKind.PropertyAccessExpression:
|
||||||
return node.parent ? getEntityNameForExtendingInterface(node.parent) : undefined;
|
return node.parent ? getEntityNameForExtendingInterface(node.parent) : undefined;
|
||||||
case SyntaxKind.ExpressionWithTypeArguments:
|
case SyntaxKind.ExpressionWithTypeArguments:
|
||||||
Debug.assert(isEntityNameExpression((<ExpressionWithTypeArguments>node).expression));
|
if (isEntityNameExpression((<ExpressionWithTypeArguments>node).expression)) {
|
||||||
return <EntityNameExpression>(<ExpressionWithTypeArguments>node).expression;
|
return <EntityNameExpression>(<ExpressionWithTypeArguments>node).expression;
|
||||||
|
}
|
||||||
|
// falls through
|
||||||
default:
|
default:
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
@ -4917,6 +4919,8 @@ namespace ts {
|
||||||
*/
|
*/
|
||||||
function getBaseConstructorTypeOfClass(type: InterfaceType): Type {
|
function getBaseConstructorTypeOfClass(type: InterfaceType): Type {
|
||||||
if (!type.resolvedBaseConstructorType) {
|
if (!type.resolvedBaseConstructorType) {
|
||||||
|
const decl = <ClassLikeDeclaration>type.symbol.valueDeclaration;
|
||||||
|
const extended = getClassExtendsHeritageClauseElement(decl);
|
||||||
const baseTypeNode = getBaseTypeNodeOfClass(type);
|
const baseTypeNode = getBaseTypeNodeOfClass(type);
|
||||||
if (!baseTypeNode) {
|
if (!baseTypeNode) {
|
||||||
return type.resolvedBaseConstructorType = undefinedType;
|
return type.resolvedBaseConstructorType = undefinedType;
|
||||||
|
@ -4925,6 +4929,10 @@ namespace ts {
|
||||||
return unknownType;
|
return unknownType;
|
||||||
}
|
}
|
||||||
const baseConstructorType = checkExpression(baseTypeNode.expression);
|
const baseConstructorType = checkExpression(baseTypeNode.expression);
|
||||||
|
if (extended && baseTypeNode !== extended) {
|
||||||
|
Debug.assert(!extended.typeArguments); // Because this is in a JS file, and baseTypeNode is in an @extends tag
|
||||||
|
checkExpression(extended.expression);
|
||||||
|
}
|
||||||
if (baseConstructorType.flags & (TypeFlags.Object | TypeFlags.Intersection)) {
|
if (baseConstructorType.flags & (TypeFlags.Object | TypeFlags.Intersection)) {
|
||||||
// Resolving the members of a class requires us to resolve the base class of that class.
|
// Resolving the members of a class requires us to resolve the base class of that class.
|
||||||
// We force resolution here such that we catch circularities now.
|
// We force resolution here such that we catch circularities now.
|
||||||
|
@ -14866,6 +14874,7 @@ namespace ts {
|
||||||
|
|
||||||
function getSuggestionForNonexistentSymbol(location: Node, name: __String, meaning: SymbolFlags): string {
|
function getSuggestionForNonexistentSymbol(location: Node, name: __String, meaning: SymbolFlags): string {
|
||||||
const result = resolveNameHelper(location, name, meaning, /*nameNotFoundMessage*/ undefined, name, /*isUse*/ false, (symbols, name, meaning) => {
|
const result = resolveNameHelper(location, name, meaning, /*nameNotFoundMessage*/ undefined, name, /*isUse*/ false, (symbols, name, meaning) => {
|
||||||
|
// `name` from the callback === the outer `name`
|
||||||
const symbol = getSymbol(symbols, name, meaning);
|
const symbol = getSymbol(symbols, name, meaning);
|
||||||
// Sometimes the symbol is found when location is a return type of a function: `typeof x` and `x` is declared in the body of the function
|
// Sometimes the symbol is found when location is a return type of a function: `typeof x` and `x` is declared in the body of the function
|
||||||
// So the table *contains* `x` but `x` isn't actually in scope.
|
// So the table *contains* `x` but `x` isn't actually in scope.
|
||||||
|
@ -19792,7 +19801,7 @@ namespace ts {
|
||||||
if (!getParameterSymbolFromJSDoc(node)) {
|
if (!getParameterSymbolFromJSDoc(node)) {
|
||||||
error(node.name,
|
error(node.name,
|
||||||
Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name,
|
Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name,
|
||||||
unescapeLeadingUnderscores((node.name.kind === SyntaxKind.QualifiedName ? node.name.right : node.name).escapedText));
|
idText(node.name.kind === SyntaxKind.QualifiedName ? node.name.right : node.name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19808,9 +19817,7 @@ namespace ts {
|
||||||
if (extend) {
|
if (extend) {
|
||||||
const className = getIdentifierFromEntityNameExpression(extend.expression);
|
const className = getIdentifierFromEntityNameExpression(extend.expression);
|
||||||
if (className && name.escapedText !== className.escapedText) {
|
if (className && name.escapedText !== className.escapedText) {
|
||||||
error(name, Diagnostics.JSDoc_augments_0_does_not_match_the_extends_1_clause,
|
error(name, Diagnostics.JSDoc_augments_0_does_not_match_the_extends_1_clause, idText(name), idText(className));
|
||||||
unescapeLeadingUnderscores(name.escapedText),
|
|
||||||
unescapeLeadingUnderscores(className.escapedText));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -378,7 +378,7 @@ namespace ts {
|
||||||
const catchVariable = getGeneratedNameForNode(errorRecord);
|
const catchVariable = getGeneratedNameForNode(errorRecord);
|
||||||
const returnMethod = createTempVariable(/*recordTempVariable*/ undefined);
|
const returnMethod = createTempVariable(/*recordTempVariable*/ undefined);
|
||||||
const callValues = createAsyncValuesHelper(context, expression, /*location*/ node.expression);
|
const callValues = createAsyncValuesHelper(context, expression, /*location*/ node.expression);
|
||||||
const callNext = createCall(createPropertyAccess(iterator, "next" ), /*typeArguments*/ undefined, []);
|
const callNext = createCall(createPropertyAccess(iterator, "next"), /*typeArguments*/ undefined, []);
|
||||||
const getDone = createPropertyAccess(result, "done");
|
const getDone = createPropertyAccess(result, "done");
|
||||||
const getValue = createPropertyAccess(result, "value");
|
const getValue = createPropertyAccess(result, "value");
|
||||||
const callReturn = createFunctionCall(returnMethod, iterator, []);
|
const callReturn = createFunctionCall(returnMethod, iterator, []);
|
||||||
|
|
|
@ -2824,7 +2824,7 @@ Actual: ${stringify(fullActual)}`);
|
||||||
const refactors = this.languageService.getApplicableRefactors(this.activeFile.fileName, range);
|
const refactors = this.languageService.getApplicableRefactors(this.activeFile.fileName, range);
|
||||||
const refactor = refactors.find(r => r.name === refactorName);
|
const refactor = refactors.find(r => r.name === refactorName);
|
||||||
if (!refactor) {
|
if (!refactor) {
|
||||||
this.raiseError(`The expected refactor: ${refactorName} is not available at the marker location.`);
|
this.raiseError(`The expected refactor: ${refactorName} is not available at the marker location.\nAvailable refactors: ${refactors.map(r => r.name)}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const action = refactor.actions.find(a => a.name === actionName);
|
const action = refactor.actions.find(a => a.name === actionName);
|
||||||
|
|
|
@ -109,16 +109,6 @@ namespace ts {
|
||||||
return C.foo();|]
|
return C.foo();|]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}`);
|
|
||||||
testExtractFunction("extractFunction8",
|
|
||||||
`namespace A {
|
|
||||||
let x = 1;
|
|
||||||
namespace B {
|
|
||||||
function a() {
|
|
||||||
let a1 = 1;
|
|
||||||
return 1 + [#|a1 + x|] + 100;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}`);
|
}`);
|
||||||
testExtractFunction("extractFunction9",
|
testExtractFunction("extractFunction9",
|
||||||
`namespace A {
|
`namespace A {
|
||||||
|
|
|
@ -152,18 +152,6 @@ namespace ts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`);
|
`);
|
||||||
testExtractRange(`
|
|
||||||
function f() {
|
|
||||||
return [$|1 + [#|2 + 3|]|];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`);
|
|
||||||
testExtractRange(`
|
|
||||||
function f() {
|
|
||||||
return [$|1 + 2 + [#|3 + 4|]|];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
testExtractRangeFailed("extractRangeFailed1",
|
testExtractRangeFailed("extractRangeFailed1",
|
||||||
|
@ -311,7 +299,18 @@ switch (x) {
|
||||||
testExtractRangeFailed("extractRangeFailed9",
|
testExtractRangeFailed("extractRangeFailed9",
|
||||||
`var x = ([#||]1 + 2);`,
|
`var x = ([#||]1 + 2);`,
|
||||||
[
|
[
|
||||||
"Cannot extract empty range."
|
refactor.extractSymbol.Messages.CannotExtractEmpty.message
|
||||||
|
]);
|
||||||
|
|
||||||
|
testExtractRangeFailed("extractRangeFailed10",
|
||||||
|
`
|
||||||
|
function f() {
|
||||||
|
return 1 + [#|2 + 3|];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
[
|
||||||
|
refactor.extractSymbol.Messages.CannotExtractRange.message
|
||||||
]);
|
]);
|
||||||
|
|
||||||
testExtractRangeFailed("extract-method-not-for-token-expression-statement", `[#|a|]`, [refactor.extractSymbol.Messages.CannotExtractIdentifier.message]);
|
testExtractRangeFailed("extract-method-not-for-token-expression-statement", `[#|a|]`, [refactor.extractSymbol.Messages.CannotExtractIdentifier.message]);
|
||||||
|
|
|
@ -4874,7 +4874,7 @@ namespace ts.projectSystem {
|
||||||
};
|
};
|
||||||
const openFiles = [commonFile1.path];
|
const openFiles = [commonFile1.path];
|
||||||
const host = createServerHost([commonFile1, libFile, configFile]);
|
const host = createServerHost([commonFile1, libFile, configFile]);
|
||||||
const { verifyProjectsUpdatedInBackgroundEventHandler, verifyInitialOpen } = createSession(host, );
|
const { verifyProjectsUpdatedInBackgroundEventHandler, verifyInitialOpen } = createSession(host);
|
||||||
verifyInitialOpen(commonFile1);
|
verifyInitialOpen(commonFile1);
|
||||||
|
|
||||||
host.reloadFS([commonFile1, libFile, configFile, commonFile2]);
|
host.reloadFS([commonFile1, libFile, configFile, commonFile2]);
|
||||||
|
|
2
src/lib/es2015.core.d.ts
vendored
2
src/lib/es2015.core.d.ts
vendored
|
@ -162,7 +162,7 @@ interface Math {
|
||||||
* If any argument is NaN, the result is NaN.
|
* If any argument is NaN, the result is NaN.
|
||||||
* If all arguments are either +0 or −0, the result is +0.
|
* If all arguments are either +0 or −0, the result is +0.
|
||||||
*/
|
*/
|
||||||
hypot(...values: number[] ): number;
|
hypot(...values: number[]): number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the integral part of the a numeric expression, x, removing any fractional digits.
|
* Returns the integral part of the a numeric expression, x, removing any fractional digits.
|
||||||
|
|
|
@ -976,9 +976,10 @@ namespace ts.server {
|
||||||
// unknown version - return everything
|
// unknown version - return everything
|
||||||
const projectFileNames = this.getFileNames();
|
const projectFileNames = this.getFileNames();
|
||||||
const externalFiles = this.getExternalFiles().map(f => toNormalizedPath(f));
|
const externalFiles = this.getExternalFiles().map(f => toNormalizedPath(f));
|
||||||
this.lastReportedFileNames = arrayToSet(projectFileNames.concat(externalFiles));
|
const allFiles = projectFileNames.concat(externalFiles);
|
||||||
|
this.lastReportedFileNames = arrayToSet(allFiles);
|
||||||
this.lastReportedVersion = this.projectStructureVersion;
|
this.lastReportedVersion = this.projectStructureVersion;
|
||||||
return { info, files: projectFileNames, projectErrors: this.getGlobalProjectErrors() };
|
return { info, files: allFiles, projectErrors: this.getGlobalProjectErrors() };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,38 +6,20 @@ namespace ts.formatting {
|
||||||
public map: RulesBucket[];
|
public map: RulesBucket[];
|
||||||
public mapRowLength: number;
|
public mapRowLength: number;
|
||||||
|
|
||||||
constructor() {
|
constructor(rules: ReadonlyArray<Rule>) {
|
||||||
this.map = [];
|
|
||||||
this.mapRowLength = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static create(rules: Rule[]): RulesMap {
|
|
||||||
const result = new RulesMap();
|
|
||||||
result.Initialize(rules);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Initialize(rules: Rule[]) {
|
|
||||||
this.mapRowLength = SyntaxKind.LastToken + 1;
|
this.mapRowLength = SyntaxKind.LastToken + 1;
|
||||||
this.map = <any>new Array(this.mapRowLength * this.mapRowLength); // new Array<RulesBucket>(this.mapRowLength * this.mapRowLength);
|
this.map = new Array<RulesBucket>(this.mapRowLength * this.mapRowLength);
|
||||||
|
|
||||||
// This array is used only during construction of the rulesbucket in the map
|
// This array is used only during construction of the rulesbucket in the map
|
||||||
const rulesBucketConstructionStateList: RulesBucketConstructionState[] = <any>new Array(this.map.length); // new Array<RulesBucketConstructionState>(this.map.length);
|
const rulesBucketConstructionStateList: RulesBucketConstructionState[] = new Array<RulesBucketConstructionState>(this.map.length);
|
||||||
|
for (const rule of rules) {
|
||||||
this.FillRules(rules, rulesBucketConstructionStateList);
|
|
||||||
return this.map;
|
|
||||||
}
|
|
||||||
|
|
||||||
public FillRules(rules: Rule[], rulesBucketConstructionStateList: RulesBucketConstructionState[]): void {
|
|
||||||
rules.forEach((rule) => {
|
|
||||||
this.FillRule(rule, rulesBucketConstructionStateList);
|
this.FillRule(rule, rulesBucketConstructionStateList);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private GetRuleBucketIndex(row: number, column: number): number {
|
private GetRuleBucketIndex(row: number, column: number): number {
|
||||||
Debug.assert(row <= SyntaxKind.LastKeyword && column <= SyntaxKind.LastKeyword, "Must compute formatting context from tokens");
|
Debug.assert(row <= SyntaxKind.LastKeyword && column <= SyntaxKind.LastKeyword, "Must compute formatting context from tokens");
|
||||||
const rulesBucketIndex = (row * this.mapRowLength) + column;
|
return (row * this.mapRowLength) + column;
|
||||||
return rulesBucketIndex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private FillRule(rule: Rule, rulesBucketConstructionStateList: RulesBucketConstructionState[]): void {
|
private FillRule(rule: Rule, rulesBucketConstructionStateList: RulesBucketConstructionState[]): void {
|
||||||
|
@ -57,7 +39,7 @@ namespace ts.formatting {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public GetRule(context: FormattingContext): Rule {
|
public GetRule(context: FormattingContext): Rule | undefined {
|
||||||
const bucketIndex = this.GetRuleBucketIndex(context.currentTokenSpan.kind, context.nextTokenSpan.kind);
|
const bucketIndex = this.GetRuleBucketIndex(context.currentTokenSpan.kind, context.nextTokenSpan.kind);
|
||||||
const bucket = this.map[bucketIndex];
|
const bucket = this.map[bucketIndex];
|
||||||
if (bucket) {
|
if (bucket) {
|
||||||
|
@ -74,7 +56,7 @@ namespace ts.formatting {
|
||||||
const MaskBitSize = 5;
|
const MaskBitSize = 5;
|
||||||
const Mask = 0x1f;
|
const Mask = 0x1f;
|
||||||
|
|
||||||
export enum RulesPosition {
|
enum RulesPosition {
|
||||||
IgnoreRulesSpecific = 0,
|
IgnoreRulesSpecific = 0,
|
||||||
IgnoreRulesAny = MaskBitSize * 1,
|
IgnoreRulesAny = MaskBitSize * 1,
|
||||||
ContextRulesSpecific = MaskBitSize * 2,
|
ContextRulesSpecific = MaskBitSize * 2,
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace ts.formatting {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.globalRules = new Rules();
|
this.globalRules = new Rules();
|
||||||
const activeRules = this.globalRules.HighPriorityCommonRules.concat(this.globalRules.UserConfigurableRules).concat(this.globalRules.LowPriorityCommonRules);
|
const activeRules = this.globalRules.HighPriorityCommonRules.concat(this.globalRules.UserConfigurableRules).concat(this.globalRules.LowPriorityCommonRules);
|
||||||
this.rulesMap = RulesMap.create(activeRules);
|
this.rulesMap = new RulesMap(activeRules);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getRulesMap() {
|
public getRulesMap() {
|
||||||
|
|
|
@ -201,9 +201,9 @@ namespace ts.refactor.extractSymbol {
|
||||||
|
|
||||||
// Walk up starting from the the start position until we find a non-SourceFile node that subsumes the selected span.
|
// Walk up starting from the the start position until we find a non-SourceFile node that subsumes the selected span.
|
||||||
// This may fail (e.g. you select two statements in the root of a source file)
|
// This may fail (e.g. you select two statements in the root of a source file)
|
||||||
let start = getParentNodeInSpan(getTokenAtPosition(sourceFile, span.start, /*includeJsDocComment*/ false), sourceFile, span);
|
const start = getParentNodeInSpan(getTokenAtPosition(sourceFile, span.start, /*includeJsDocComment*/ false), sourceFile, span);
|
||||||
// Do the same for the ending position
|
// Do the same for the ending position
|
||||||
let end = getParentNodeInSpan(findTokenOnLeftOfPosition(sourceFile, textSpanEnd(span)), sourceFile, span);
|
const end = getParentNodeInSpan(findTokenOnLeftOfPosition(sourceFile, textSpanEnd(span)), sourceFile, span);
|
||||||
|
|
||||||
const declarations: Symbol[] = [];
|
const declarations: Symbol[] = [];
|
||||||
|
|
||||||
|
@ -217,31 +217,10 @@ namespace ts.refactor.extractSymbol {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (start.parent !== end.parent) {
|
if (start.parent !== end.parent) {
|
||||||
// handle cases like 1 + [2 + 3] + 4
|
// start and end nodes belong to different subtrees
|
||||||
// user selection is marked with [].
|
return { errors: [createFileDiagnostic(sourceFile, span.start, length, Messages.CannotExtractRange)] };
|
||||||
// in this case 2 + 3 does not belong to the same tree node
|
|
||||||
// instead the shape of the tree looks like this:
|
|
||||||
// +
|
|
||||||
// / \
|
|
||||||
// + 4
|
|
||||||
// / \
|
|
||||||
// + 3
|
|
||||||
// / \
|
|
||||||
// 1 2
|
|
||||||
// in this case there is no such one node that covers ends of selection and is located inside the selection
|
|
||||||
// to handle this we check if both start and end of the selection belong to some binary operation
|
|
||||||
// and start node is parented by the parent of the end node
|
|
||||||
// if this is the case - expand the selection to the entire parent of end node (in this case it will be [1 + 2 + 3] + 4)
|
|
||||||
const startParent = skipParentheses(start.parent);
|
|
||||||
const endParent = skipParentheses(end.parent);
|
|
||||||
if (isBinaryExpression(startParent) && isBinaryExpression(endParent) && isNodeDescendantOf(startParent, endParent)) {
|
|
||||||
start = end = endParent;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// start and end nodes belong to different subtrees
|
|
||||||
return { errors: [createFileDiagnostic(sourceFile, span.start, length, Messages.CannotExtractRange)] };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (start !== end) {
|
if (start !== end) {
|
||||||
// start and end should be statements and parent should be either block or a source file
|
// start and end should be statements and parent should be either block or a source file
|
||||||
if (!isBlockLike(start.parent)) {
|
if (!isBlockLike(start.parent)) {
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
tests/cases/compiler/classExtendsInterface_not.ts(1,20): error TS2339: Property 'bogus' does not exist on type '""'.
|
||||||
|
|
||||||
|
|
||||||
|
==== tests/cases/compiler/classExtendsInterface_not.ts (1 errors) ====
|
||||||
|
class C extends "".bogus {}
|
||||||
|
~~~~~
|
||||||
|
!!! error TS2339: Property 'bogus' does not exist on type '""'.
|
||||||
|
|
22
tests/baselines/reference/classExtendsInterface_not.js
Normal file
22
tests/baselines/reference/classExtendsInterface_not.js
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
//// [classExtendsInterface_not.ts]
|
||||||
|
class C extends "".bogus {}
|
||||||
|
|
||||||
|
|
||||||
|
//// [classExtendsInterface_not.js]
|
||||||
|
var __extends = (this && this.__extends) || (function () {
|
||||||
|
var extendStatics = Object.setPrototypeOf ||
|
||||||
|
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||||
|
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||||
|
return function (d, b) {
|
||||||
|
extendStatics(d, b);
|
||||||
|
function __() { this.constructor = d; }
|
||||||
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
var C = /** @class */ (function (_super) {
|
||||||
|
__extends(C, _super);
|
||||||
|
function C() {
|
||||||
|
return _super !== null && _super.apply(this, arguments) || this;
|
||||||
|
}
|
||||||
|
return C;
|
||||||
|
}("".bogus));
|
|
@ -0,0 +1,4 @@
|
||||||
|
=== tests/cases/compiler/classExtendsInterface_not.ts ===
|
||||||
|
class C extends "".bogus {}
|
||||||
|
>C : Symbol(C, Decl(classExtendsInterface_not.ts, 0, 0))
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
=== tests/cases/compiler/classExtendsInterface_not.ts ===
|
||||||
|
class C extends "".bogus {}
|
||||||
|
>C : C
|
||||||
|
>"".bogus : any
|
||||||
|
>"" : ""
|
||||||
|
>bogus : any
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
// ==ORIGINAL==
|
|
||||||
namespace A {
|
|
||||||
let x = 1;
|
|
||||||
namespace B {
|
|
||||||
function a() {
|
|
||||||
let a1 = 1;
|
|
||||||
return 1 + a1 + x + 100;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ==SCOPE::Extract to inner function in function 'a'==
|
|
||||||
namespace A {
|
|
||||||
let x = 1;
|
|
||||||
namespace B {
|
|
||||||
function a() {
|
|
||||||
let a1 = 1;
|
|
||||||
return /*RENAME*/newFunction() + 100;
|
|
||||||
|
|
||||||
function newFunction() {
|
|
||||||
return 1 + a1 + x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ==SCOPE::Extract to function in namespace 'B'==
|
|
||||||
namespace A {
|
|
||||||
let x = 1;
|
|
||||||
namespace B {
|
|
||||||
function a() {
|
|
||||||
let a1 = 1;
|
|
||||||
return /*RENAME*/newFunction(a1) + 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
function newFunction(a1: number) {
|
|
||||||
return 1 + a1 + x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ==SCOPE::Extract to function in namespace 'A'==
|
|
||||||
namespace A {
|
|
||||||
let x = 1;
|
|
||||||
namespace B {
|
|
||||||
function a() {
|
|
||||||
let a1 = 1;
|
|
||||||
return /*RENAME*/newFunction(a1) + 100;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function newFunction(a1: number) {
|
|
||||||
return 1 + a1 + x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ==SCOPE::Extract to function in global scope==
|
|
||||||
namespace A {
|
|
||||||
let x = 1;
|
|
||||||
namespace B {
|
|
||||||
function a() {
|
|
||||||
let a1 = 1;
|
|
||||||
return /*RENAME*/newFunction(a1, x) + 100;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function newFunction(a1: number, x: number) {
|
|
||||||
return 1 + a1 + x;
|
|
||||||
}
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
/a.js(3,17): error TS2304: Cannot find name 'err'.
|
||||||
|
|
||||||
|
|
||||||
|
==== /a.js (1 errors) ====
|
||||||
|
class A {}
|
||||||
|
/** @augments A */
|
||||||
|
class B extends err() {}
|
||||||
|
~~~
|
||||||
|
!!! error TS2304: Cannot find name 'err'.
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
=== /a.js ===
|
||||||
|
class A {}
|
||||||
|
>A : Symbol(A, Decl(a.js, 0, 0))
|
||||||
|
|
||||||
|
/** @augments A */
|
||||||
|
class B extends err() {}
|
||||||
|
>B : Symbol(B, Decl(a.js, 0, 10))
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
=== /a.js ===
|
||||||
|
class A {}
|
||||||
|
>A : A
|
||||||
|
|
||||||
|
/** @augments A */
|
||||||
|
class B extends err() {}
|
||||||
|
>B : B
|
||||||
|
>err() : A
|
||||||
|
>err : any
|
||||||
|
|
1
tests/cases/compiler/classExtendsInterface_not.ts
Normal file
1
tests/cases/compiler/classExtendsInterface_not.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
class C extends "".bogus {}
|
|
@ -0,0 +1,8 @@
|
||||||
|
// @allowJs: true
|
||||||
|
// @checkJs: true
|
||||||
|
// @noEmit: true
|
||||||
|
|
||||||
|
// @Filename: /a.js
|
||||||
|
class A {}
|
||||||
|
/** @augments A */
|
||||||
|
class B extends err() {}
|
|
@ -41,6 +41,7 @@
|
||||||
"avoid-escape"
|
"avoid-escape"
|
||||||
],
|
],
|
||||||
"semicolon": [true, "always", "ignore-bound-class-methods"],
|
"semicolon": [true, "always", "ignore-bound-class-methods"],
|
||||||
|
"space-within-parens": true,
|
||||||
"triple-equals": true,
|
"triple-equals": true,
|
||||||
"type-operator-spacing": true,
|
"type-operator-spacing": true,
|
||||||
"typedef-whitespace": [
|
"typedef-whitespace": [
|
||||||
|
|
Loading…
Reference in a new issue