Completion list for a class extending another class should contain members from base class
Handles #7158
This commit is contained in:
parent
d483df94ef
commit
b3d793608d
9 changed files with 313 additions and 57 deletions
|
@ -679,10 +679,6 @@ namespace ts {
|
||||||
return type.flags & TypeFlags.Object ? (<ObjectType>type).objectFlags : 0;
|
return type.flags & TypeFlags.Object ? (<ObjectType>type).objectFlags : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCheckFlags(symbol: Symbol): CheckFlags {
|
|
||||||
return symbol.flags & SymbolFlags.Transient ? (<TransientSymbol>symbol).checkFlags : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
function isGlobalSourceFile(node: Node) {
|
function isGlobalSourceFile(node: Node) {
|
||||||
return node.kind === SyntaxKind.SourceFile && !isExternalOrCommonJsModule(<SourceFile>node);
|
return node.kind === SyntaxKind.SourceFile && !isExternalOrCommonJsModule(<SourceFile>node);
|
||||||
}
|
}
|
||||||
|
@ -13928,25 +13924,6 @@ namespace ts {
|
||||||
return s.valueDeclaration ? s.valueDeclaration.kind : SyntaxKind.PropertyDeclaration;
|
return s.valueDeclaration ? s.valueDeclaration.kind : SyntaxKind.PropertyDeclaration;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDeclarationModifierFlagsFromSymbol(s: Symbol): ModifierFlags {
|
|
||||||
if (s.valueDeclaration) {
|
|
||||||
const flags = getCombinedModifierFlags(s.valueDeclaration);
|
|
||||||
return s.parent && s.parent.flags & SymbolFlags.Class ? flags : flags & ~ModifierFlags.AccessibilityModifier;
|
|
||||||
}
|
|
||||||
if (getCheckFlags(s) & CheckFlags.Synthetic) {
|
|
||||||
const checkFlags = (<TransientSymbol>s).checkFlags;
|
|
||||||
const accessModifier = checkFlags & CheckFlags.ContainsPrivate ? ModifierFlags.Private :
|
|
||||||
checkFlags & CheckFlags.ContainsPublic ? ModifierFlags.Public :
|
|
||||||
ModifierFlags.Protected;
|
|
||||||
const staticModifier = checkFlags & CheckFlags.ContainsStatic ? ModifierFlags.Static : 0;
|
|
||||||
return accessModifier | staticModifier;
|
|
||||||
}
|
|
||||||
if (s.flags & SymbolFlags.Prototype) {
|
|
||||||
return ModifierFlags.Public | ModifierFlags.Static;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getDeclarationNodeFlagsFromSymbol(s: Symbol): NodeFlags {
|
function getDeclarationNodeFlagsFromSymbol(s: Symbol): NodeFlags {
|
||||||
return s.valueDeclaration ? getCombinedNodeFlags(s.valueDeclaration) : 0;
|
return s.valueDeclaration ? getCombinedNodeFlags(s.valueDeclaration) : 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4200,6 +4200,29 @@ namespace ts {
|
||||||
// Firefox has Object.prototype.watch
|
// Firefox has Object.prototype.watch
|
||||||
return options.watch && options.hasOwnProperty("watch");
|
return options.watch && options.hasOwnProperty("watch");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getCheckFlags(symbol: Symbol): CheckFlags {
|
||||||
|
return symbol.flags & SymbolFlags.Transient ? (<TransientSymbol>symbol).checkFlags : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getDeclarationModifierFlagsFromSymbol(s: Symbol): ModifierFlags {
|
||||||
|
if (s.valueDeclaration) {
|
||||||
|
const flags = getCombinedModifierFlags(s.valueDeclaration);
|
||||||
|
return s.parent && s.parent.flags & SymbolFlags.Class ? flags : flags & ~ModifierFlags.AccessibilityModifier;
|
||||||
|
}
|
||||||
|
if (getCheckFlags(s) & CheckFlags.Synthetic) {
|
||||||
|
const checkFlags = (<TransientSymbol>s).checkFlags;
|
||||||
|
const accessModifier = checkFlags & CheckFlags.ContainsPrivate ? ModifierFlags.Private :
|
||||||
|
checkFlags & CheckFlags.ContainsPublic ? ModifierFlags.Public :
|
||||||
|
ModifierFlags.Protected;
|
||||||
|
const staticModifier = checkFlags & CheckFlags.ContainsStatic ? ModifierFlags.Static : 0;
|
||||||
|
return accessModifier | staticModifier;
|
||||||
|
}
|
||||||
|
if (s.flags & SymbolFlags.Prototype) {
|
||||||
|
return ModifierFlags.Public | ModifierFlags.Static;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ts {
|
namespace ts {
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace ts.Completions {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, requestJsDocTagName, requestJsDocTag } = completionData;
|
const { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, requestJsDocTagName, requestJsDocTag, hasFilteredClassMemberKeywords } = completionData;
|
||||||
|
|
||||||
if (requestJsDocTagName) {
|
if (requestJsDocTagName) {
|
||||||
// If the current position is a jsDoc tag name, only tag names should be provided for completion
|
// If the current position is a jsDoc tag name, only tag names should be provided for completion
|
||||||
|
@ -52,7 +52,7 @@ namespace ts.Completions {
|
||||||
sortText: "0",
|
sortText: "0",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else if (!hasFilteredClassMemberKeywords) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,8 +60,11 @@ namespace ts.Completions {
|
||||||
getCompletionEntriesFromSymbols(symbols, entries, location, /*performCharacterChecks*/ true, typeChecker, compilerOptions.target, log);
|
getCompletionEntriesFromSymbols(symbols, entries, location, /*performCharacterChecks*/ true, typeChecker, compilerOptions.target, log);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasFilteredClassMemberKeywords) {
|
||||||
|
addRange(entries, classMemberKeywordCompletions);
|
||||||
|
}
|
||||||
// Add keywords if this is not a member completion list
|
// Add keywords if this is not a member completion list
|
||||||
if (!isMemberCompletion && !requestJsDocTag && !requestJsDocTagName) {
|
else if (!isMemberCompletion && !requestJsDocTag && !requestJsDocTagName) {
|
||||||
addRange(entries, keywordCompletions);
|
addRange(entries, keywordCompletions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -406,7 +409,7 @@ namespace ts.Completions {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (requestJsDocTagName || requestJsDocTag) {
|
if (requestJsDocTagName || requestJsDocTag) {
|
||||||
return { symbols: undefined, isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, location: undefined, isRightOfDot: false, requestJsDocTagName, requestJsDocTag };
|
return { symbols: undefined, isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, location: undefined, isRightOfDot: false, requestJsDocTagName, requestJsDocTag, hasFilteredClassMemberKeywords: false };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!insideJsDocTagExpression) {
|
if (!insideJsDocTagExpression) {
|
||||||
|
@ -505,6 +508,7 @@ namespace ts.Completions {
|
||||||
let isGlobalCompletion = false;
|
let isGlobalCompletion = false;
|
||||||
let isMemberCompletion: boolean;
|
let isMemberCompletion: boolean;
|
||||||
let isNewIdentifierLocation: boolean;
|
let isNewIdentifierLocation: boolean;
|
||||||
|
let hasFilteredClassMemberKeywords = false;
|
||||||
let symbols: Symbol[] = [];
|
let symbols: Symbol[] = [];
|
||||||
|
|
||||||
if (isRightOfDot) {
|
if (isRightOfDot) {
|
||||||
|
@ -542,7 +546,7 @@ namespace ts.Completions {
|
||||||
|
|
||||||
log("getCompletionData: Semantic work: " + (timestamp() - semanticStart));
|
log("getCompletionData: Semantic work: " + (timestamp() - semanticStart));
|
||||||
|
|
||||||
return { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), requestJsDocTagName, requestJsDocTag };
|
return { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), requestJsDocTagName, requestJsDocTag, hasFilteredClassMemberKeywords };
|
||||||
|
|
||||||
function getTypeScriptMemberSymbols(): void {
|
function getTypeScriptMemberSymbols(): void {
|
||||||
// Right of dot member completion list
|
// Right of dot member completion list
|
||||||
|
@ -599,6 +603,7 @@ namespace ts.Completions {
|
||||||
function tryGetGlobalSymbols(): boolean {
|
function tryGetGlobalSymbols(): boolean {
|
||||||
let objectLikeContainer: ObjectLiteralExpression | BindingPattern;
|
let objectLikeContainer: ObjectLiteralExpression | BindingPattern;
|
||||||
let namedImportsOrExports: NamedImportsOrExports;
|
let namedImportsOrExports: NamedImportsOrExports;
|
||||||
|
let classLikeContainer: ClassLikeDeclaration;
|
||||||
let jsxContainer: JsxOpeningLikeElement;
|
let jsxContainer: JsxOpeningLikeElement;
|
||||||
|
|
||||||
if (objectLikeContainer = tryGetObjectLikeCompletionContainer(contextToken)) {
|
if (objectLikeContainer = tryGetObjectLikeCompletionContainer(contextToken)) {
|
||||||
|
@ -611,6 +616,11 @@ namespace ts.Completions {
|
||||||
return tryGetImportOrExportClauseCompletionSymbols(namedImportsOrExports);
|
return tryGetImportOrExportClauseCompletionSymbols(namedImportsOrExports);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (classLikeContainer = tryGetClassLikeCompletionContainer(contextToken)) {
|
||||||
|
// cursor inside class declaration
|
||||||
|
return tryGetClassLikeCompletionSymbols(classLikeContainer);
|
||||||
|
}
|
||||||
|
|
||||||
if (jsxContainer = tryGetContainingJsxElement(contextToken)) {
|
if (jsxContainer = tryGetContainingJsxElement(contextToken)) {
|
||||||
let attrsType: Type;
|
let attrsType: Type;
|
||||||
if ((jsxContainer.kind === SyntaxKind.JsxSelfClosingElement) || (jsxContainer.kind === SyntaxKind.JsxOpeningElement)) {
|
if ((jsxContainer.kind === SyntaxKind.JsxSelfClosingElement) || (jsxContainer.kind === SyntaxKind.JsxOpeningElement)) {
|
||||||
|
@ -913,6 +923,31 @@ namespace ts.Completions {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aggregates relevant symbols for completion in class declaration
|
||||||
|
* Relevant symbols are stored in the captured 'symbols' variable.
|
||||||
|
*
|
||||||
|
* @returns true if 'symbols' was successfully populated; false otherwise.
|
||||||
|
*/
|
||||||
|
function tryGetClassLikeCompletionSymbols(classLikeDeclaration: ClassLikeDeclaration): boolean {
|
||||||
|
// We're looking up possible property names from parent type.
|
||||||
|
isMemberCompletion = true;
|
||||||
|
// Declaring new property/method/accessor
|
||||||
|
isNewIdentifierLocation = true;
|
||||||
|
// Has keywords for class elements
|
||||||
|
hasFilteredClassMemberKeywords = true;
|
||||||
|
|
||||||
|
const baseTypeNode = getClassExtendsHeritageClauseElement(classLikeDeclaration);
|
||||||
|
if (baseTypeNode) {
|
||||||
|
const baseType = typeChecker.getTypeAtLocation(baseTypeNode);
|
||||||
|
// List of property symbols of base type that are not private
|
||||||
|
symbols = filter(typeChecker.getPropertiesOfType(baseType),
|
||||||
|
baseProperty => !(getDeclarationModifierFlagsFromSymbol(baseProperty) & ModifierFlags.Private));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the immediate owning object literal or binding pattern of a context token,
|
* Returns the immediate owning object literal or binding pattern of a context token,
|
||||||
* on the condition that one exists and that the context implies completion should be given.
|
* on the condition that one exists and that the context implies completion should be given.
|
||||||
|
@ -953,6 +988,38 @@ namespace ts.Completions {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the immediate owning class declaration of a context token,
|
||||||
|
* on the condition that one exists and that the context implies completion should be given.
|
||||||
|
*/
|
||||||
|
function tryGetClassLikeCompletionContainer(contextToken: Node): ClassLikeDeclaration {
|
||||||
|
if (contextToken) {
|
||||||
|
switch (contextToken.kind) {
|
||||||
|
case SyntaxKind.OpenBraceToken: // class c { |
|
||||||
|
if (isClassLike(contextToken.parent)) {
|
||||||
|
return contextToken.parent;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// class c {getValue(): number; | }
|
||||||
|
case SyntaxKind.CommaToken:
|
||||||
|
case SyntaxKind.SemicolonToken:
|
||||||
|
// class c { method() { } | }
|
||||||
|
case SyntaxKind.CloseBraceToken:
|
||||||
|
if (isClassLike(location)) {
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// class c { method() { } | method2() { } }
|
||||||
|
if (location && location.kind === SyntaxKind.SyntaxList && isClassLike(location.parent)) {
|
||||||
|
return location.parent;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
function tryGetContainingJsxElement(contextToken: Node): JsxOpeningLikeElement {
|
function tryGetContainingJsxElement(contextToken: Node): JsxOpeningLikeElement {
|
||||||
if (contextToken) {
|
if (contextToken) {
|
||||||
const parent = contextToken.parent;
|
const parent = contextToken.parent;
|
||||||
|
@ -1306,6 +1373,21 @@ namespace ts.Completions {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const classMemberKeywordCompletions = filter(keywordCompletions, entry => {
|
||||||
|
switch (stringToToken(entry.name)) {
|
||||||
|
case SyntaxKind.PublicKeyword:
|
||||||
|
case SyntaxKind.ProtectedKeyword:
|
||||||
|
case SyntaxKind.PrivateKeyword:
|
||||||
|
case SyntaxKind.AbstractKeyword:
|
||||||
|
case SyntaxKind.StaticKeyword:
|
||||||
|
case SyntaxKind.ConstructorKeyword:
|
||||||
|
case SyntaxKind.ReadonlyKeyword:
|
||||||
|
case SyntaxKind.GetKeyword:
|
||||||
|
case SyntaxKind.SetKeyword:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
function isEqualityExpression(node: Node): node is BinaryExpression {
|
function isEqualityExpression(node: Node): node is BinaryExpression {
|
||||||
return isBinaryExpression(node) && isEqualityOperatorKind(node.operatorToken.kind);
|
return isBinaryExpression(node) && isEqualityOperatorKind(node.operatorToken.kind);
|
||||||
}
|
}
|
||||||
|
|
142
tests/cases/fourslash/completionEntryForClassMembers.ts
Normal file
142
tests/cases/fourslash/completionEntryForClassMembers.ts
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
///<reference path="fourslash.ts" />
|
||||||
|
|
||||||
|
////abstract class B {
|
||||||
|
//// abstract getValue(): number;
|
||||||
|
//// /*abstractClass*/
|
||||||
|
////}
|
||||||
|
////class C extends B {
|
||||||
|
//// /*classThatIsEmptyAndExtendingAnotherClass*/
|
||||||
|
////}
|
||||||
|
////class D extends B {
|
||||||
|
//// /*classThatHasAlreadyImplementedAnotherClassMethod*/
|
||||||
|
//// getValue() {
|
||||||
|
//// return 10;
|
||||||
|
//// }
|
||||||
|
//// /*classThatHasAlreadyImplementedAnotherClassMethodAfterMethod*/
|
||||||
|
////}
|
||||||
|
////class E {
|
||||||
|
//// /*classThatDoesNotExtendAnotherClass*/
|
||||||
|
////}
|
||||||
|
////class F extends B {
|
||||||
|
//// public /*classThatHasWrittenPublicKeyword*/
|
||||||
|
////}
|
||||||
|
////class G extends B {
|
||||||
|
//// static /*classElementContainingStatic*/
|
||||||
|
////}
|
||||||
|
////class H extends B {
|
||||||
|
//// prop/*classThatStartedWritingIdentifier*/
|
||||||
|
////}
|
||||||
|
////class I extends B {
|
||||||
|
//// prop0: number
|
||||||
|
//// /*propDeclarationWithoutSemicolon*/
|
||||||
|
//// prop: number;
|
||||||
|
//// /*propDeclarationWithSemicolon*/
|
||||||
|
//// prop1 = 10;
|
||||||
|
//// /*propAssignmentWithSemicolon*/
|
||||||
|
//// prop2 = 10
|
||||||
|
//// /*propAssignmentWithoutSemicolon*/
|
||||||
|
//// method(): number
|
||||||
|
//// /*methodSignatureWithoutSemicolon*/
|
||||||
|
//// method2(): number;
|
||||||
|
//// /*methodSignatureWithSemicolon*/
|
||||||
|
//// method3() {
|
||||||
|
//// /*InsideMethod*/
|
||||||
|
//// }
|
||||||
|
//// /*methodImplementation*/
|
||||||
|
//// get c()
|
||||||
|
//// /*accessorSignatureWithoutSemicolon*/
|
||||||
|
//// set c()
|
||||||
|
//// {
|
||||||
|
//// }
|
||||||
|
//// /*accessorSignatureImplementation*/
|
||||||
|
////}
|
||||||
|
////class J extends B {
|
||||||
|
//// get /*classThatHasWrittenGetKeyword*/
|
||||||
|
////}
|
||||||
|
////class K extends B {
|
||||||
|
//// set /*classThatHasWrittenSetKeyword*/
|
||||||
|
////}
|
||||||
|
////class J extends B {
|
||||||
|
//// get identi/*classThatStartedWritingIdentifierOfGetAccessor*/
|
||||||
|
////}
|
||||||
|
////class K extends B {
|
||||||
|
//// set identi/*classThatStartedWritingIdentifierOfSetAccessor*/
|
||||||
|
////}
|
||||||
|
////class L extends B {
|
||||||
|
//// public identi/*classThatStartedWritingIdentifierAfterModifier*/
|
||||||
|
////}
|
||||||
|
////class L extends B {
|
||||||
|
//// static identi/*classThatStartedWritingIdentifierAfterStaticModifier*/
|
||||||
|
////}
|
||||||
|
|
||||||
|
const allowedKeywords = [
|
||||||
|
"public",
|
||||||
|
"private",
|
||||||
|
"protected",
|
||||||
|
"static",
|
||||||
|
"abstract",
|
||||||
|
"readonly",
|
||||||
|
"get",
|
||||||
|
"set",
|
||||||
|
"constructor"
|
||||||
|
];
|
||||||
|
|
||||||
|
const allowedKeywordCount = allowedKeywords.length;
|
||||||
|
function verifyAllowedKeyWords() {
|
||||||
|
for (const keyword of allowedKeywords) {
|
||||||
|
verify.completionListContains(keyword, keyword, /*documentation*/ undefined, "keyword");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const nonClassElementMarkers = [
|
||||||
|
"InsideMethod"
|
||||||
|
];
|
||||||
|
for (const marker of nonClassElementMarkers) {
|
||||||
|
goTo.marker(marker);
|
||||||
|
verify.not.completionListContains("getValue");
|
||||||
|
verify.not.completionListIsEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only keywords allowed at this position since they dont extend the class
|
||||||
|
const onlyClassElementKeywordLocations = [
|
||||||
|
"abstractClass",
|
||||||
|
"classThatDoesNotExtendAnotherClass"
|
||||||
|
];
|
||||||
|
for (const marker of onlyClassElementKeywordLocations) {
|
||||||
|
goTo.marker(marker);
|
||||||
|
verifyAllowedKeyWords();
|
||||||
|
verify.completionListCount(allowedKeywordCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Base members and class member keywords allowed
|
||||||
|
const classElementCompletionLocations = [
|
||||||
|
"classThatIsEmptyAndExtendingAnotherClass",
|
||||||
|
"classThatHasAlreadyImplementedAnotherClassMethod",
|
||||||
|
"classThatHasAlreadyImplementedAnotherClassMethodAfterMethod",
|
||||||
|
// TODO should we give completion for these keywords
|
||||||
|
//"classThatHasWrittenPublicKeyword",
|
||||||
|
//"classElementContainingStatic",
|
||||||
|
"classThatStartedWritingIdentifier",
|
||||||
|
"propDeclarationWithoutSemicolon",
|
||||||
|
"propDeclarationWithSemicolon",
|
||||||
|
"propAssignmentWithSemicolon",
|
||||||
|
"propAssignmentWithoutSemicolon",
|
||||||
|
"methodSignatureWithoutSemicolon",
|
||||||
|
"methodSignatureWithSemicolon",
|
||||||
|
"methodImplementation",
|
||||||
|
"accessorSignatureWithoutSemicolon",
|
||||||
|
"accessorSignatureImplementation",
|
||||||
|
// TODO should we give completion for these keywords
|
||||||
|
//"classThatHasWrittenGetKeyword",
|
||||||
|
//"classThatHasWrittenSetKeyword",
|
||||||
|
//"classThatStartedWritingIdentifierOfGetAccessor",
|
||||||
|
//"classThatStartedWritingIdentifierOfSetAccessor",
|
||||||
|
//"classThatStartedWritingIdentifierAfterModifier",
|
||||||
|
//"classThatStartedWritingIdentifierAfterStaticModifier"
|
||||||
|
];
|
||||||
|
for (const marker of classElementCompletionLocations) {
|
||||||
|
goTo.marker(marker);
|
||||||
|
verify.completionListContains("getValue", "(method) B.getValue(): number", /*documentation*/ undefined, "method");
|
||||||
|
verifyAllowedKeyWords();
|
||||||
|
verify.completionListCount(allowedKeywordCount + 1);
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
///<reference path="fourslash.ts" />
|
///<reference path="fourslash.ts" />
|
||||||
|
|
||||||
//// var x = class myClass {
|
//// var x = class myClass {
|
||||||
//// getClassName (){
|
//// getClassName (){
|
||||||
|
@ -11,4 +11,4 @@ goTo.marker("0");
|
||||||
verify.completionListContains("myClass", "(local class) myClass", /*documentation*/ undefined, "local class");
|
verify.completionListContains("myClass", "(local class) myClass", /*documentation*/ undefined, "local class");
|
||||||
|
|
||||||
goTo.marker("1");
|
goTo.marker("1");
|
||||||
verify.completionListContains("myClass", "(local class) myClass", /*documentation*/ undefined, "local class");
|
verify.not.completionListContains("myClass", "(local class) myClass", /*documentation*/ undefined, "local class");
|
|
@ -1,4 +1,4 @@
|
||||||
///<reference path="fourslash.ts" />
|
///<reference path="fourslash.ts" />
|
||||||
|
|
||||||
//// class myClass { /*0*/ }
|
//// class myClass { /*0*/ }
|
||||||
//// /*1*/
|
//// /*1*/
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
//// }
|
//// }
|
||||||
|
|
||||||
goTo.marker("0");
|
goTo.marker("0");
|
||||||
verify.completionListContains("myClass", "class myClass", /*documentation*/ undefined, "class");
|
verify.not.completionListContains("myClass", "class myClass", /*documentation*/ undefined, "class");
|
||||||
verify.not.completionListContains("myClass", "(local class) myClass", /*documentation*/ undefined, "local class");
|
verify.not.completionListContains("myClass", "(local class) myClass", /*documentation*/ undefined, "local class");
|
||||||
|
|
||||||
goTo.marker("1");
|
goTo.marker("1");
|
||||||
|
@ -28,7 +28,7 @@ verify.completionListContains("myClass", "(local class) myClass", /*documentatio
|
||||||
verify.not.completionListContains("myClass", "class myClass", /*documentation*/ undefined, "class");
|
verify.not.completionListContains("myClass", "class myClass", /*documentation*/ undefined, "class");
|
||||||
|
|
||||||
goTo.marker("3");
|
goTo.marker("3");
|
||||||
verify.completionListContains("myClass", "(local class) myClass", /*documentation*/ undefined, "local class");
|
verify.not.completionListContains("myClass", "(local class) myClass", /*documentation*/ undefined, "local class");
|
||||||
verify.not.completionListContains("myClass", "class myClass", /*documentation*/ undefined, "class");
|
verify.not.completionListContains("myClass", "class myClass", /*documentation*/ undefined, "class");
|
||||||
|
|
||||||
goTo.marker("4");
|
goTo.marker("4");
|
||||||
|
@ -36,5 +36,5 @@ verify.completionListContains("myClass", "class myClass", /*documentation*/ unde
|
||||||
verify.not.completionListContains("myClass", "(local class) myClass", /*documentation*/ undefined, "local class");
|
verify.not.completionListContains("myClass", "(local class) myClass", /*documentation*/ undefined, "local class");
|
||||||
|
|
||||||
goTo.marker("5");
|
goTo.marker("5");
|
||||||
verify.completionListContains("myClass", "class myClass", /*documentation*/ undefined, "class");
|
verify.not.completionListContains("myClass", "class myClass", /*documentation*/ undefined, "class");
|
||||||
verify.not.completionListContains("myClass", "(local class) myClass", /*documentation*/ undefined, "local class");
|
verify.not.completionListContains("myClass", "(local class) myClass", /*documentation*/ undefined, "local class");
|
||||||
|
|
|
@ -53,7 +53,7 @@ verify.completionListIsGlobal(false);
|
||||||
goTo.marker("9");
|
goTo.marker("9");
|
||||||
verify.completionListIsGlobal(false);
|
verify.completionListIsGlobal(false);
|
||||||
goTo.marker("10");
|
goTo.marker("10");
|
||||||
verify.completionListIsGlobal(true);
|
verify.completionListIsGlobal(false);
|
||||||
goTo.marker("11");
|
goTo.marker("11");
|
||||||
verify.completionListIsGlobal(true);
|
verify.completionListIsGlobal(true);
|
||||||
goTo.marker("12");
|
goTo.marker("12");
|
||||||
|
|
|
@ -225,27 +225,28 @@
|
||||||
////
|
////
|
||||||
////var shwvar = 1;
|
////var shwvar = 1;
|
||||||
|
|
||||||
function goToMarkAndGeneralVerify(marker: string)
|
function goToMarkAndGeneralVerify(marker: string, isClassScope?: boolean)
|
||||||
{
|
{
|
||||||
goTo.marker(marker);
|
goTo.marker(marker);
|
||||||
|
|
||||||
verify.completionListContains('mod1var', 'var mod1var: number');
|
const verifyModule = isClassScope ? verify.not : verify;
|
||||||
verify.completionListContains('mod1fn', 'function mod1fn(): void');
|
verifyModule.completionListContains('mod1var', 'var mod1var: number');
|
||||||
verify.completionListContains('mod1cls', 'class mod1cls');
|
verifyModule.completionListContains('mod1fn', 'function mod1fn(): void');
|
||||||
verify.completionListContains('mod1int', 'interface mod1int');
|
verifyModule.completionListContains('mod1cls', 'class mod1cls');
|
||||||
verify.completionListContains('mod1mod', 'namespace mod1mod');
|
verifyModule.completionListContains('mod1int', 'interface mod1int');
|
||||||
verify.completionListContains('mod1evar', 'var mod1.mod1evar: number');
|
verifyModule.completionListContains('mod1mod', 'namespace mod1mod');
|
||||||
verify.completionListContains('mod1efn', 'function mod1.mod1efn(): void');
|
verifyModule.completionListContains('mod1evar', 'var mod1.mod1evar: number');
|
||||||
verify.completionListContains('mod1ecls', 'class mod1.mod1ecls');
|
verifyModule.completionListContains('mod1efn', 'function mod1.mod1efn(): void');
|
||||||
verify.completionListContains('mod1eint', 'interface mod1.mod1eint');
|
verifyModule.completionListContains('mod1ecls', 'class mod1.mod1ecls');
|
||||||
verify.completionListContains('mod1emod', 'namespace mod1.mod1emod');
|
verifyModule.completionListContains('mod1eint', 'interface mod1.mod1eint');
|
||||||
verify.completionListContains('mod1eexvar', 'var mod1.mod1eexvar: number');
|
verifyModule.completionListContains('mod1emod', 'namespace mod1.mod1emod');
|
||||||
verify.completionListContains('mod2', 'namespace mod2');
|
verifyModule.completionListContains('mod1eexvar', 'var mod1.mod1eexvar: number');
|
||||||
verify.completionListContains('mod3', 'namespace mod3');
|
verifyModule.completionListContains('mod2', 'namespace mod2');
|
||||||
verify.completionListContains('shwvar', 'var shwvar: number');
|
verifyModule.completionListContains('mod3', 'namespace mod3');
|
||||||
verify.completionListContains('shwfn', 'function shwfn(): void');
|
verifyModule.completionListContains('shwvar', 'var shwvar: number');
|
||||||
verify.completionListContains('shwcls', 'class shwcls');
|
verifyModule.completionListContains('shwfn', 'function shwfn(): void');
|
||||||
verify.completionListContains('shwint', 'interface shwint');
|
verifyModule.completionListContains('shwcls', 'class shwcls');
|
||||||
|
verifyModule.completionListContains('shwint', 'interface shwint');
|
||||||
|
|
||||||
verify.not.completionListContains('mod2var');
|
verify.not.completionListContains('mod2var');
|
||||||
verify.not.completionListContains('mod2fn');
|
verify.not.completionListContains('mod2fn');
|
||||||
|
@ -280,7 +281,7 @@ verify.completionListContains('bar', '(local var) bar: number');
|
||||||
verify.completionListContains('foob', '(local function) foob(): void');
|
verify.completionListContains('foob', '(local function) foob(): void');
|
||||||
|
|
||||||
// from class in mod1
|
// from class in mod1
|
||||||
goToMarkAndGeneralVerify('class');
|
goToMarkAndGeneralVerify('class', /*isClassScope*/ true);
|
||||||
//verify.not.completionListContains('ceFunc');
|
//verify.not.completionListContains('ceFunc');
|
||||||
//verify.not.completionListContains('ceVar');
|
//verify.not.completionListContains('ceVar');
|
||||||
|
|
||||||
|
@ -306,7 +307,7 @@ verify.completionListContains('bar', '(local var) bar: number');
|
||||||
verify.completionListContains('foob', '(local function) foob(): void');
|
verify.completionListContains('foob', '(local function) foob(): void');
|
||||||
|
|
||||||
// from exported class in mod1
|
// from exported class in mod1
|
||||||
goToMarkAndGeneralVerify('exportedClass');
|
goToMarkAndGeneralVerify('exportedClass', /*isClassScope*/ true);
|
||||||
//verify.not.completionListContains('ceFunc');
|
//verify.not.completionListContains('ceFunc');
|
||||||
//verify.not.completionListContains('ceVar');
|
//verify.not.completionListContains('ceVar');
|
||||||
|
|
||||||
|
|
|
@ -231,6 +231,39 @@
|
||||||
//// x: /*objectLiteral*/
|
//// x: /*objectLiteral*/
|
||||||
////}
|
////}
|
||||||
|
|
||||||
|
goTo.marker('extendedClass');
|
||||||
|
|
||||||
|
verify.not.completionListContains('mod1');
|
||||||
|
verify.not.completionListContains('mod2');
|
||||||
|
verify.not.completionListContains('mod3');
|
||||||
|
verify.not.completionListContains('shwvar', 'var shwvar: number');
|
||||||
|
verify.not.completionListContains('shwfn', 'function shwfn(): void');
|
||||||
|
verify.not.completionListContains('shwcls', 'class shwcls');
|
||||||
|
verify.not.completionListContains('shwint', 'interface shwint');
|
||||||
|
|
||||||
|
verify.not.completionListContains('mod2var');
|
||||||
|
verify.not.completionListContains('mod2fn');
|
||||||
|
verify.not.completionListContains('mod2cls');
|
||||||
|
verify.not.completionListContains('mod2int');
|
||||||
|
verify.not.completionListContains('mod2mod');
|
||||||
|
verify.not.completionListContains('mod2evar');
|
||||||
|
verify.not.completionListContains('mod2efn');
|
||||||
|
verify.not.completionListContains('mod2ecls');
|
||||||
|
verify.not.completionListContains('mod2eint');
|
||||||
|
verify.not.completionListContains('mod2emod');
|
||||||
|
verify.not.completionListContains('sfvar');
|
||||||
|
verify.not.completionListContains('sffn');
|
||||||
|
verify.not.completionListContains('scvar');
|
||||||
|
verify.not.completionListContains('scfn');
|
||||||
|
verify.completionListContains('scpfn');
|
||||||
|
verify.completionListContains('scpvar');
|
||||||
|
verify.not.completionListContains('scsvar');
|
||||||
|
verify.not.completionListContains('scsfn');
|
||||||
|
verify.not.completionListContains('sivar');
|
||||||
|
verify.not.completionListContains('sifn');
|
||||||
|
verify.not.completionListContains('mod1exvar');
|
||||||
|
verify.not.completionListContains('mod2eexvar');
|
||||||
|
|
||||||
function goToMarkerAndVerify(marker: string)
|
function goToMarkerAndVerify(marker: string)
|
||||||
{
|
{
|
||||||
goTo.marker(marker);
|
goTo.marker(marker);
|
||||||
|
@ -267,8 +300,6 @@ function goToMarkerAndVerify(marker: string)
|
||||||
verify.not.completionListContains('mod2eexvar');
|
verify.not.completionListContains('mod2eexvar');
|
||||||
}
|
}
|
||||||
|
|
||||||
goToMarkerAndVerify('extendedClass');
|
|
||||||
|
|
||||||
goToMarkerAndVerify('objectLiteral');
|
goToMarkerAndVerify('objectLiteral');
|
||||||
|
|
||||||
goTo.marker('localVar');
|
goTo.marker('localVar');
|
||||||
|
|
Loading…
Reference in a new issue