Filter symbols based on the meaning at the location

This commit is contained in:
Sheetal Nandi 2017-05-24 15:24:49 -07:00
parent 928da675ac
commit 893ba1de15
34 changed files with 558 additions and 256 deletions

View File

@ -954,7 +954,7 @@ var nodeServerInFile = "tests/webTestServer.ts";
compileFile(nodeServerOutFile, [nodeServerInFile], [builtLocalDirectory, tscFile], [], /*useBuiltCompiler:*/ true, { noOutFile: true, lib: "es6" });
desc("Runs browserify on run.js to produce a file suitable for running tests in the browser");
task("browserify", ["tests", builtLocalDirectory, nodeServerOutFile], function() {
task("browserify", ["tests", run, builtLocalDirectory, nodeServerOutFile], function() {
var cmd = 'browserify built/local/run.js -t ./scripts/browserify-optional -d -o built/local/bundle.js';
exec(cmd);
}, { async: true });

View File

@ -14554,12 +14554,31 @@ namespace ts {
? (<PropertyAccessExpression>node).expression
: (<QualifiedName>node).left;
const type = checkExpression(left);
return isValidPropertyAccessWithType(node, left, propertyName, getWidenedType(checkExpression(left)));
}
function isValidPropertyAccessWithType(
node: PropertyAccessExpression | QualifiedName,
left: LeftHandSideExpression | QualifiedName,
propertyName: string,
type: Type): boolean {
if (type !== unknownType && !isTypeAny(type)) {
const prop = getPropertyOfType(getWidenedType(type), propertyName);
const prop = getPropertyOfType(type, propertyName);
if (prop) {
return checkPropertyAccessibility(node, left, type, prop);
}
// In js files properties of unions are allowed in completion
if (isInJavaScriptFile(left) && (type.flags & TypeFlags.Union)) {
for (const elementType of (<UnionType>type).types) {
if (isValidPropertyAccessWithType(node, left, propertyName, elementType)) {
return true;
}
}
}
return false;
}
return true;
}

View File

@ -559,6 +559,9 @@ namespace ts.Completions {
isMemberCompletion = true;
isNewIdentifierLocation = false;
// Since this is qualified name check its a type node location
const isTypeLocation = isPartOfTypeNode(node.parent);
const isRhsOfImportDeclaration = isInRightSideOfInternalImportEqualsDeclaration(node);
if (node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.QualifiedName || node.kind === SyntaxKind.PropertyAccessExpression) {
let symbol = typeChecker.getSymbolAtLocation(node);
@ -570,16 +573,24 @@ namespace ts.Completions {
if (symbol && symbol.flags & SymbolFlags.HasExports) {
// Extract module or enum members
const exportedSymbols = typeChecker.getExportsOfModule(symbol);
const isValidValueAccess = (symbol: Symbol) => typeChecker.isValidPropertyAccess(<PropertyAccessExpression>(node.parent), symbol.name);
const isValidTypeAccess = (symbol: Symbol) => symbolCanbeReferencedAtTypeLocation(symbol);
const isValidAccess = isRhsOfImportDeclaration ?
// Any kind is allowed when dotting off namespace in internal import equals declaration
(symbol: Symbol) => isValidTypeAccess(symbol) || isValidValueAccess(symbol) :
isTypeLocation ? isValidTypeAccess : isValidValueAccess;
forEach(exportedSymbols, symbol => {
if (typeChecker.isValidPropertyAccess(<PropertyAccessExpression>(node.parent), symbol.name)) {
if (isValidAccess(symbol)) {
symbols.push(symbol);
}
});
}
}
const type = typeChecker.getTypeAtLocation(node);
addTypeProperties(type);
if (!isTypeLocation) {
const type = typeChecker.getTypeAtLocation(node);
addTypeProperties(type);
}
}
function addTypeProperties(type: Type) {
@ -687,13 +698,88 @@ namespace ts.Completions {
isStatement(scopeNode);
}
/// TODO filter meaning based on the current context
const symbolMeanings = SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace | SymbolFlags.Alias;
symbols = typeChecker.getSymbolsInScope(scopeNode, symbolMeanings);
symbols = filterGlobalCompletion(typeChecker.getSymbolsInScope(scopeNode, symbolMeanings));
return true;
}
function filterGlobalCompletion(symbols: Symbol[]) {
return filter(symbols, symbol => {
if (!isSourceFile(location)) {
// export = /**/ here we want to get all meanings, so any symbol is ok
if (isExportAssignment(location.parent)) {
return true;
}
// This is an alias, follow what it aliases
if (symbol && symbol.flags & SymbolFlags.Alias) {
symbol = typeChecker.getAliasedSymbol(symbol);
}
// import m = /**/ <-- It can only access namespace (if typing import = x. this would get member symbols and not namespace)
if (isInRightSideOfInternalImportEqualsDeclaration(location)) {
return !!(symbol.flags & SymbolFlags.Namespace);
}
if (!isContextTokenValueLocation(contextToken) &&
(isPartOfTypeNode(location) || isContextTokenTypeLocation(contextToken))) {
// Its a type, but you can reach it by namespace.type as well
return symbolCanbeReferencedAtTypeLocation(symbol);
}
}
// expressions are value space (which includes the value namespaces)
return !!(symbol.flags & SymbolFlags.Value);
});
}
function isContextTokenValueLocation(contextToken: Node) {
if (contextToken) {
const parentKind = contextToken.parent.kind;
switch (contextToken.kind) {
case SyntaxKind.TypeOfKeyword:
return parentKind === SyntaxKind.TypeQuery;
}
}
}
function isContextTokenTypeLocation(contextToken: Node) {
if (contextToken) {
const parentKind = contextToken.parent.kind;
switch (contextToken.kind) {
case SyntaxKind.ColonToken:
return parentKind === SyntaxKind.PropertyDeclaration ||
parentKind === SyntaxKind.PropertySignature ||
parentKind === SyntaxKind.Parameter ||
parentKind === SyntaxKind.VariableDeclaration ||
isFunctionLikeKind(parentKind);
case SyntaxKind.EqualsToken:
return parentKind === SyntaxKind.TypeAliasDeclaration;
case SyntaxKind.AsKeyword:
return parentKind === SyntaxKind.AsExpression;
}
}
}
function symbolCanbeReferencedAtTypeLocation(symbol: Symbol): boolean {
// This is an alias, follow what it aliases
if (symbol && symbol.flags & SymbolFlags.Alias) {
symbol = typeChecker.getAliasedSymbol(symbol);
}
if (symbol.flags & (SymbolFlags.ValueModule | SymbolFlags.NamespaceModule)) {
const exportedSymbols = typeChecker.getExportsOfModule(symbol);
// If the exported symbols contains type,
// symbol can be referenced at locations where type is allowed
return forEach(exportedSymbols, symbolCanbeReferencedAtTypeLocation);
}
return !!(symbol.flags & (SymbolFlags.NamespaceModule | SymbolFlags.Type));
}
/**
* Finds the first node that "embraces" the position, so that one may
* accurately aggregate locals from the closest containing scope.
@ -1126,21 +1212,6 @@ namespace ts.Completions {
return undefined;
}
function isFunction(kind: SyntaxKind): boolean {
if (!isFunctionLikeKind(kind)) {
return false;
}
switch (kind) {
case SyntaxKind.Constructor:
case SyntaxKind.ConstructorType:
case SyntaxKind.FunctionType:
return false;
default:
return true;
}
}
/**
* @returns true if we are certain that the currently edited location must define a new location; false otherwise.
*/
@ -1152,7 +1223,7 @@ namespace ts.Completions {
containingNodeKind === SyntaxKind.VariableDeclarationList ||
containingNodeKind === SyntaxKind.VariableStatement ||
containingNodeKind === SyntaxKind.EnumDeclaration || // enum a { foo, |
isFunction(containingNodeKind) ||
isFunctionLikeButNotConstructor(containingNodeKind) ||
containingNodeKind === SyntaxKind.ClassDeclaration || // class A<T, |
containingNodeKind === SyntaxKind.ClassExpression || // var C = class D<T, |
containingNodeKind === SyntaxKind.InterfaceDeclaration || // interface A<T, |
@ -1170,7 +1241,7 @@ namespace ts.Completions {
case SyntaxKind.OpenParenToken:
return containingNodeKind === SyntaxKind.CatchClause ||
isFunction(containingNodeKind);
isFunctionLikeButNotConstructor(containingNodeKind);
case SyntaxKind.OpenBraceToken:
return containingNodeKind === SyntaxKind.EnumDeclaration || // enum a { |
@ -1188,7 +1259,7 @@ namespace ts.Completions {
containingNodeKind === SyntaxKind.ClassExpression || // var C = class D< |
containingNodeKind === SyntaxKind.InterfaceDeclaration || // interface A< |
containingNodeKind === SyntaxKind.TypeAliasDeclaration || // type List< |
isFunction(containingNodeKind);
isFunctionLikeKind(containingNodeKind);
case SyntaxKind.StaticKeyword:
return containingNodeKind === SyntaxKind.PropertyDeclaration && !isClassLike(contextToken.parent.parent);
@ -1257,6 +1328,10 @@ namespace ts.Completions {
return false;
}
function isFunctionLikeButNotConstructor(kind: SyntaxKind) {
return isFunctionLikeKind(kind) && kind !== SyntaxKind.Constructor;
}
function isDotOfNumericLiteral(contextToken: Node): boolean {
if (contextToken.kind === SyntaxKind.NumericLiteral) {
const text = contextToken.getFullText();

View File

@ -82,7 +82,7 @@ namespace ts {
else if (node.parent.kind === SyntaxKind.ExportAssignment) {
return SemanticMeaning.All;
}
else if (isInRightSideOfImport(node)) {
else if (isInRightSideOfInternalImportEqualsDeclaration(node)) {
return getMeaningFromRightHandSideOfImportEquals(node);
}
else if (isDeclarationName(node)) {
@ -114,7 +114,7 @@ namespace ts {
return SemanticMeaning.Namespace;
}
function isInRightSideOfImport(node: Node) {
export function isInRightSideOfInternalImportEqualsDeclaration(node: Node) {
while (node.parent.kind === SyntaxKind.QualifiedName) {
node = node.parent;
}

View File

@ -346,7 +346,7 @@ verify.quickInfos({
});
goTo.marker('16');
verify.completionListContains("i1", "interface i1", "i1 is interface with properties");
verify.not.completionListContains("i1", "interface i1", "i1 is interface with properties");
verify.completionListContains("i1_i", "var i1_i: i1", "");
verify.completionListContains("c1", "class c1", "");
verify.completionListContains("c1_i", "var c1_i: c1", "");
@ -603,9 +603,9 @@ verify.quickInfos({
});
goTo.marker('51');
verify.completionListContains("i2", "interface i2", "");
verify.not.completionListContains("i2", "interface i2", "");
verify.completionListContains("i2_i", "var i2_i: i2", "");
verify.completionListContains("i3", "interface i3", "");
verify.not.completionListContains("i3", "interface i3", "");
verify.completionListContains("i3_i", "var i3_i: i3", "");
goTo.marker('51i');

View File

@ -163,11 +163,11 @@ verify.currentParameterHelpArgumentDocCommentIs("");
verify.quickInfoAt("33q", "(method) i2.nc_fnfoo(b: number): string");
goTo.marker('34');
verify.completionListContains("i1", "interface i1", "this is interface 1");
verify.not.completionListContains("i1", "interface i1", "this is interface 1");
verify.completionListContains("i1_i", "var i1_i: i1", "");
verify.completionListContains("nc_i1", "interface nc_i1", "");
verify.not.completionListContains("nc_i1", "interface nc_i1", "");
verify.completionListContains("nc_i1_i", "var nc_i1_i: nc_i1", "");
verify.completionListContains("i2", "interface i2", "this is interface 2 with memebers");
verify.not.completionListContains("i2", "interface i2", "this is interface 2 with memebers");
verify.completionListContains("i2_i", "var i2_i: i2", "");
verify.completionListContains("i2_i_x", "var i2_i_x: number", "");
verify.completionListContains("i2_i_foo", "var i2_i_foo: (b: number) => string", "");
@ -194,7 +194,7 @@ verify.completionListContains("a", "(parameter) a: number", "i3_i a");
verify.quickInfoAt("40q", "var i3_i: i3");
goTo.marker('40');
verify.completionListContains("i3", "interface i3", "");
verify.not.completionListContains("i3", "interface i3", "");
verify.completionListContains("i3_i", "var i3_i: i3", "");
goTo.marker('41');

View File

@ -295,13 +295,13 @@ verify.completionListContains('f3', 'function f3(a: number): number (+1 overload
verify.completionListContains('f4', 'function f4(a: number): number (+1 overload)', 'this is signature 4 - with number parameter');
goTo.marker('18');
verify.completionListContains('i1', 'interface i1', '');
verify.not.completionListContains('i1', 'interface i1', '');
verify.completionListContains('i1_i', 'var i1_i: new i1(b: number) => any (+1 overload)', '');
verify.completionListContains('i2', 'interface i2', '');
verify.not.completionListContains('i2', 'interface i2', '');
verify.completionListContains('i2_i', 'var i2_i: new i2(a: string) => any (+1 overload)', '');
verify.completionListContains('i3', 'interface i3', '');
verify.not.completionListContains('i3', 'interface i3', '');
verify.completionListContains('i3_i', 'var i3_i: new i3(a: string) => any (+1 overload)', 'new 1');
verify.completionListContains('i4', 'interface i4', '');
verify.not.completionListContains('i4', 'interface i4', '');
verify.completionListContains('i4_i', 'var i4_i: new i4(a: string) => any (+1 overload)', '');
goTo.marker('19');

View File

@ -9,5 +9,6 @@ goTo.marker("1");
verify.not.completionListContains("a");
goTo.marker("2");
verify.not.completionListContains("b");
edit.insert("typeof ");
verify.completionListContains("b");

View File

@ -8,7 +8,7 @@
//// export var x: number;
////}
////Foo/*c1*/; // should get "x", "prototype"
////var s: Foo/*c2*/; // should get "x" and "prototype"
////var s: Foo/*c2*/; // no types, in Foo, so shouldnt have anything
////var f = new Foo();
////f/*c3*/;
@ -20,9 +20,7 @@ verify.completionListContains("staticMethod");
goTo.marker("c2");
edit.insert(".");
verify.completionListContains("x");
verify.completionListContains("staticMethod");
verify.completionListContains("prototype");
verify.completionListIsEmpty();
goTo.marker("c3");
edit.insert(".");

View File

@ -1,13 +1,16 @@
///<reference path="fourslash.ts" />
///<reference path="fourslash.ts" />
//// var x = class myClass <TypeParam> {
//// getClassName (){
//// /*0*/
//// var tmp: /*0Type*/;
//// }
//// prop: Ty/*1*/
//// }
goTo.marker("0");
verify.not.completionListContains("TypeParam", "(type parameter) TypeParam in myClass<TypeParam>", /*documentation*/ undefined, "type parameter");
goTo.marker("0Type");
verify.completionListContains("TypeParam", "(type parameter) TypeParam in myClass<TypeParam>", /*documentation*/ undefined, "type parameter");
goTo.marker("1");

View File

@ -14,5 +14,5 @@ verify.completionListContains("TString");
verify.completionListContains("TNumber");
// Ideally the following shouldn't show up since they're not types.
verify.completionListContains("foo");
verify.completionListContains("obj");
verify.not.completionListContains("foo");
verify.not.completionListContains("obj");

View File

@ -14,5 +14,5 @@ verify.completionListContains("TString");
verify.completionListContains("TNumber"); // REVIEW: Is this intended behavior?
// Ideally the following shouldn't show up since they're not types.
verify.completionListContains("foo");
verify.completionListContains("obj");
verify.not.completionListContains("foo");
verify.not.completionListContains("obj");

View File

@ -14,5 +14,5 @@ verify.completionListContains("TString");
verify.completionListContains("TNumber"); // REVIEW: Is this intended behavior?
// Ideally the following shouldn't show up since they're not types.
verify.completionListContains("foo");
verify.completionListContains("obj");
verify.not.completionListContains("foo");
verify.not.completionListContains("obj");

View File

@ -27,4 +27,4 @@ goTo.marker("3");
verify.completionListIsEmpty();
goTo.marker("4");
verify.not.completionListIsEmpty();
verify.completionListIsEmpty();

View File

@ -85,11 +85,11 @@ verify.completionListContains("exportedInterface");
verify.completionListContains("localClass");
verify.completionListContains("exportedClass");
verify.completionListContains("localModule");
verify.completionListContains("exportedModule");
verify.not.completionListContains("localModule");
verify.not.completionListContains("exportedModule");
verify.completionListContains("exportedClass2");
verify.completionListContains("exportedModule2");
verify.not.completionListContains("exportedModule2");
goTo.marker("insideMethod");
verify.not.completionListContains("property");

View File

@ -1,4 +1,4 @@
/// <reference path='fourslash.ts'/>
/// <reference path='fourslash.ts'/>
////type List1</*0*/
////type List2</*1*/T> = T[];
@ -8,7 +8,7 @@
goTo.marker("0");
verify.completionListIsEmpty();
goTo.marker("1");
verify.not.completionListIsEmpty();
verify.completionListIsEmpty();
goTo.marker("2");
verify.completionListContains("T");
goTo.marker("3");

View File

@ -1,4 +1,4 @@
/// <reference path='fourslash.ts'/>
/// <reference path='fourslash.ts'/>
////type Map1<K, /*0*/
////type Map1<K, /*1*/V> = [];
@ -8,12 +8,12 @@
goTo.marker("0");
verify.completionListIsEmpty();
goTo.marker("1");
verify.completionListContains("V");
verify.completionListIsEmpty();
goTo.marker("2");
verify.completionListContains("K");
verify.completionListContains("V");
goTo.marker("3");
verify.not.completionListContains("K");
verify.not.completionListContains("V");
verify.completionListContains("K1");
verify.completionListContains("V1");
verify.not.completionListContains("K1");
verify.not.completionListContains("V1");

View File

@ -1,13 +1,13 @@
/// <reference path='fourslash.ts'/>
/// <reference path='fourslash.ts'/>
//// type constructorType<T1, T2> = new <T/*1*/, /*2*/
goTo.marker("1");
verify.completionListContains("T");
verify.completionListContains("T1");
verify.completionListContains("T2");
verify.not.completionListContains("T");
verify.not.completionListContains("T1");
verify.not.completionListContains("T2");
goTo.marker("2");
verify.completionListContains("T");
verify.completionListContains("T1");
verify.completionListContains("T2");
verify.not.completionListContains("T");
verify.not.completionListContains("T1");
verify.not.completionListContains("T2");

View File

@ -7,7 +7,7 @@
goTo.marker("1");
verify.completionListContains("C");
verify.completionListContains("foo"); // ideally this shouldn't show up for a type
verify.not.completionListContains("foo"); // ideally this shouldn't show up for a type
edit.insert("typeof ");
verify.completionListContains("C");
verify.completionListContains("foo");

View File

@ -14,5 +14,5 @@ verify.completionListContains("TString");
verify.completionListContains("TNumber");
// Ideally the following shouldn't show up since they're not types.
verify.completionListContains("foo");
verify.completionListContains("obj");
verify.not.completionListContains("foo");
verify.not.completionListContains("obj");

View File

@ -14,5 +14,5 @@ verify.completionListContains("TString");
verify.completionListContains("TNumber"); // REVIEW: Is this intended behavior?
// Ideally the following shouldn't show up since they're not types.
verify.completionListContains("foo");
verify.completionListContains("obj");
verify.not.completionListContains("foo");
verify.not.completionListContains("obj");

View File

@ -14,5 +14,5 @@ verify.completionListContains("TString");
verify.completionListContains("TNumber"); // REVIEW: Is this intended behavior?
// Ideally the following shouldn't show up since they're not types.
verify.completionListContains("foo");
verify.completionListContains("obj");
verify.not.completionListContains("foo");
verify.not.completionListContains("obj");

View File

@ -21,36 +21,40 @@
////
////interface TestInterface implements Module./*TypeReferenceInImplementsList*/ { }
goTo.marker("ValueReference");
verify.completionListContains("exportedVariable");
verify.completionListContains("exportedFunction");
verify.completionListContains("exportedClass");
verify.completionListContains("exportedModule");
// No inner declarations
verify.not.completionListContains("innerVariable");
verify.not.completionListContains("innerClass");
// Include type declarations
verify.completionListContains("exportedInterface");
function getVerify(isTypeLocation: boolean) {
return {
verifyValue: isTypeLocation ? verify.not : verify,
verifyType: isTypeLocation ? verify : verify.not,
verifyValueOrType: verify,
verifyNotValueOrType: verify.not,
};
}
goTo.marker("TypeReference");
verify.completionListContains("exportedClass");
verify.completionListContains("exportedModule");
verify.completionListContains("exportedInterface");
// Include value completions
verify.completionListContains("exportedVariable");
function verifyModuleMembers(marker: string, isTypeLocation: boolean) {
goTo.marker(marker);
goTo.marker("TypeReferenceInExtendsList");
verify.completionListContains("exportedClass");
verify.completionListContains("exportedModule");
verify.completionListContains("exportedInterface");
// Include value completions
verify.completionListContains("exportedVariable");
const { verifyValue, verifyType, verifyValueOrType, verifyNotValueOrType } = getVerify(isTypeLocation);
verifyValue.completionListContains("exportedVariable");
verifyValue.completionListContains("exportedFunction");
verifyValue.completionListContains("exportedModule");
goTo.marker("TypeReferenceInImplementsList");
verify.completionListContains("exportedClass");
verify.completionListContains("exportedModule");
verify.completionListContains("exportedInterface");
// Include value completions
verify.completionListContains("exportedVariable");
verifyValueOrType.completionListContains("exportedClass");
// Include type declarations
verifyType.completionListContains("exportedInterface");
// No inner declarations
verifyNotValueOrType.completionListContains("innerVariable");
verifyNotValueOrType.completionListContains("innerFunction");
verifyNotValueOrType.completionListContains("innerClass");
verifyNotValueOrType.completionListContains("innerModule");
verifyNotValueOrType.completionListContains("innerInterface");
verifyNotValueOrType.completionListContains("exportedInnerModuleVariable");
}
verifyModuleMembers("ValueReference", /*isTypeLocation*/ false);
verifyModuleMembers("TypeReference", /*isTypeLocation*/ true);
verifyModuleMembers("TypeReferenceInExtendsList", /*isTypeLocation*/ false);
verifyModuleMembers("TypeReferenceInImplementsList", /*isTypeLocation*/ true);

View File

@ -1,10 +1,13 @@
/// <reference path='fourslash.ts' />
/// <reference path='fourslash.ts' />
////var x : (s/*1*/
////var y : (s:string, list/*2*/
goTo.eachMarker(() => {
verify.not.completionListIsEmpty();
verify.completionListAllowsNewIdentifier();
});
goTo.marker("1");
verify.not.completionListIsEmpty();// As this can either be type or become arrow function parameter
verify.completionListAllowsNewIdentifier();
goTo.marker("2");
verify.completionListIsEmpty(); // Parameter name
verify.completionListAllowsNewIdentifier();

View File

@ -25,23 +25,47 @@
////import a = M.A;
////
////m./*1*/;
////var tmp: m./*1Type*/;
////c./*2*/;
////e./*3*/;
////n./*4*/;
////v./*5*/;
////f./*6*/;
////a./*7*/;
////var tmp2: a./*7Type*/;
function getVerify(isTypeLocation?: boolean) {
return {
verifyValue: isTypeLocation ? verify.not : verify,
verifyType: isTypeLocation ? verify : verify.not,
verifyValueOrType: verify
};
}
function typeLocationVerify(valueMarker: string, verify: (typeMarker: string) => void) {
verify(valueMarker + "Type");
return valueMarker;
}
function verifyModuleM(marker: string) {
const isTypeLocation = marker.indexOf("Type") !== -1;
const { verifyValue, verifyType, verifyValueOrType } = getVerify(isTypeLocation);
if (!isTypeLocation) {
marker = typeLocationVerify(marker, verifyModuleM);
}
goTo.marker(marker);
verifyType.completionListContains("I");
verifyValueOrType.completionListContains("C");
verifyValueOrType.completionListContains("E");
verifyValue.completionListContains("N");
verifyValue.completionListContains("V");
verifyValue.completionListContains("F");
verifyValueOrType.completionListContains("A");
}
// Module m
goTo.marker("1");
verify.completionListContains("I");
verify.completionListContains("C");
verify.completionListContains("E");
verify.completionListContains("N");
verify.completionListContains("V");
verify.completionListContains("F");
verify.completionListContains("A");
verifyModuleM("1");
// Class C
goTo.marker("2");
@ -64,11 +88,4 @@ goTo.marker("6");
verify.completionListContains("call");
// alias a
goTo.marker("7");
verify.completionListContains("I");
verify.completionListContains("C");
verify.completionListContains("E");
verify.completionListContains("N");
verify.completionListContains("V");
verify.completionListContains("F");
verify.completionListContains("A");
verifyModuleM("7");

View File

@ -5,5 +5,5 @@
////}
goTo.marker();
verify.completionListContains('parseInt');
verify.not.completionListContains('parseInt');
verify.completionListContains('encoder');

View File

@ -0,0 +1,68 @@
/// <reference path="fourslash.ts" />
////namespace m { export interface point2 { } }
////namespace m2 { export var zz = 10; }
////namespace m3 { export var zz2 = 10; export interface point3 { } }
////interface point {
//// x: number;
//// y: number;
////}
////var xx = 10;
////var tt = /*valueExpr*/xx;
////var yy: /*typeExpr*/point = { x: 4, y: 3 + /*valueExprInObjectLiteral*/tt };
////var kk: m3.point3/*membertypeExpr*/ = m3.zz2/*membervalueExpr*/;
const markers = test.markerNames();
function getVerifyBasedOnMarker(marker: string, meaning: string) {
return marker.indexOf(meaning) === 0 ? verify : verify.not;
}
function verifyCompletions(verify: FourSlashInterface.verifyNegatable, completions: CompletionInfo[]) {
for (const info of completions) {
verify.completionListContains(info[0], info[1]);
}
}
type CompletionInfo = [string, string];
function verifyCompletionsExistForMeaning(marker: string, meaning: string, completions: CompletionInfo[]) {
verifyCompletions(getVerifyBasedOnMarker(marker, meaning), completions);
}
function verifyCompletionsDoNotExistForMeaning(marker: string, meaning: string, completions: CompletionInfo[]) {
verifyCompletions(getVerifyBasedOnMarker(marker, meaning) === verify.not ? verify : verify.not, completions);
}
const values: CompletionInfo[] = [
["xx", "var xx: number"],
["tt", "var tt: number"],
["yy", "var yy: point"],
["m2", "namespace m2"], // With no type side, allowed only in value
];
const types: CompletionInfo[] = [
["point", "interface point"],
["m", "namespace m"], // Uninstantiated namespace only allowed at type locations
];
const namespaces: CompletionInfo[] = [
["m3", "namespace m3"], // Has both type and values, allowed in all locations
];
const membervalues: CompletionInfo[] = [
["zz2", "var m3.zz2: number"],
];
const membertypes: CompletionInfo[] = [
["point3", "interface m3.point3"],
];
for (const marker of markers) {
goTo.marker(marker);
verifyCompletionsExistForMeaning(marker, "value", values);
verifyCompletionsExistForMeaning(marker, "type", types);
verifyCompletionsExistForMeaning(marker, "membervalue", membervalues);
verifyCompletionsExistForMeaning(marker, "membertype", membertypes);
verifyCompletionsDoNotExistForMeaning(marker, "member", namespaces);
}

View File

@ -191,6 +191,7 @@
//// sifn(shadow: any): any;
//// }
//// /*shadowNamespaceWithNoExport*/
//// var tmp: /*shadowNamespaceWithNoExportType*/
////}
////
////namespace mod4 {
@ -214,12 +215,14 @@
//// sifn(shadow: any): any;
//// }
//// /*shadowNamespaceWithExport*/
//// var tmp: /*shadowNamespaceWithExportType*/
////}
////
////namespace mod5 {
//// import Mod1 = mod1;
//// import iMod1 = mod1.mod1emod;
//// /*namespaceWithImport*/
//// var tmp: /*namespaceWithImportType*/
////}
////
////function shwfn() {
@ -276,51 +279,87 @@ function goToMarkAndVerifyShadow()
verify.not.completionListContains('mod2emod');
}
function getVerify(isTypeLocation?: boolean) {
return {
verifyValue: isTypeLocation ? verify.not : verify,
verifyType: isTypeLocation ? verify : verify.not,
verifyValueOrType: verify
};
}
function typeLocationVerify(valueMarker: string, verify: (typeMarker: string) => void) {
verify(valueMarker + "Type");
return valueMarker;
}
// from a shadow namespace with no export
goTo.marker('shadowNamespaceWithNoExport');
verify.completionListContains('shwvar', 'var shwvar: string');
verify.completionListContains('shwfn', 'function shwfn(shadow: any): void');
verify.completionListContains('shwcls', 'class shwcls');
verify.completionListContains('shwint', 'interface shwint');
goToMarkAndVerifyShadow();
verifyShadowNamespaceWithNoExport();
function verifyShadowNamespaceWithNoExport(marker?: string) {
const { verifyValue, verifyType, verifyValueOrType } = getVerify(!!marker);
if (!marker) {
marker = typeLocationVerify('shadowNamespaceWithNoExport', verifyShadowNamespaceWithNoExport);
}
goTo.marker(marker);
verifyValue.completionListContains('shwvar', 'var shwvar: string');
verifyValue.completionListContains('shwfn', 'function shwfn(shadow: any): void');
verifyValueOrType.completionListContains('shwcls', 'class shwcls');
verifyType.completionListContains('shwint', 'interface shwint');
goToMarkAndVerifyShadow();
}
// from a shadow namespace with export
goTo.marker('shadowNamespaceWithExport');
verify.completionListContains('shwvar', 'var mod4.shwvar: string');
verify.completionListContains('shwfn', 'function mod4.shwfn(shadow: any): void');
verify.completionListContains('shwcls', 'class mod4.shwcls');
verify.completionListContains('shwint', 'interface mod4.shwint');
goToMarkAndVerifyShadow();
verifyShadowNamespaceWithNoExport();
function verifyShadowNamespaceWithExport(marker?: string) {
const { verifyValue, verifyType, verifyValueOrType } = getVerify(!!marker);
if (!marker) {
marker = typeLocationVerify('shadowNamespaceWithExport', verifyShadowNamespaceWithExport);
}
goTo.marker(marker);
verifyValue.completionListContains('shwvar', 'var mod4.shwvar: string');
verifyValue.completionListContains('shwfn', 'function mod4.shwfn(shadow: any): void');
verifyValueOrType.completionListContains('shwcls', 'class mod4.shwcls');
verifyType.completionListContains('shwint', 'interface mod4.shwint');
goToMarkAndVerifyShadow();
}
// from a namespace with import
goTo.marker('namespaceWithImport');
verify.completionListContains('mod1', 'namespace mod1');
verify.completionListContains('mod2', 'namespace mod2');
verify.completionListContains('mod3', 'namespace mod3');
verify.completionListContains('shwvar', 'var shwvar: number');
verify.completionListContains('shwfn', 'function shwfn(): void');
verify.completionListContains('shwcls', 'class shwcls');
verify.completionListContains('shwint', 'interface shwint');
verifyShadowNamespaceWithNoExport();
function verifyNamespaceWithImport(marker?: string) {
const { verifyValue, verifyType, verifyValueOrType } = getVerify(!!marker);
if (!marker) {
marker = typeLocationVerify('namespaceWithImport', verifyNamespaceWithImport);
}
goTo.marker(marker);
sharedNegativeVerify();
verifyValue.completionListContains('mod1', 'namespace mod1');
verifyValue.completionListContains('mod2', 'namespace mod2');
verifyValue.completionListContains('mod3', 'namespace mod3');
verifyValue.completionListContains('shwvar', 'var shwvar: number');
verifyValue.completionListContains('shwfn', 'function shwfn(): void');
verifyValueOrType.completionListContains('shwcls', 'class shwcls');
verifyType.completionListContains('shwint', 'interface shwint');
verify.not.completionListContains('mod1var');
verify.not.completionListContains('mod1fn');
verify.not.completionListContains('mod1cls');
verify.not.completionListContains('mod1int');
verify.not.completionListContains('mod1mod');
verify.not.completionListContains('mod1evar');
verify.not.completionListContains('mod1efn');
verify.not.completionListContains('mod1ecls');
verify.not.completionListContains('mod1eint');
verify.not.completionListContains('mod1emod');
verify.not.completionListContains('mX');
verify.not.completionListContains('mFunc');
verify.not.completionListContains('mClass');
verify.not.completionListContains('mInt');
verify.not.completionListContains('mMod');
verify.not.completionListContains('meX');
verify.not.completionListContains('meFunc');
verify.not.completionListContains('meClass');
verify.not.completionListContains('meInt');
verify.not.completionListContains('meMod');
sharedNegativeVerify();
verify.not.completionListContains('mod1var');
verify.not.completionListContains('mod1fn');
verify.not.completionListContains('mod1cls');
verify.not.completionListContains('mod1int');
verify.not.completionListContains('mod1mod');
verify.not.completionListContains('mod1evar');
verify.not.completionListContains('mod1efn');
verify.not.completionListContains('mod1ecls');
verify.not.completionListContains('mod1eint');
verify.not.completionListContains('mod1emod');
verify.not.completionListContains('mX');
verify.not.completionListContains('mFunc');
verify.not.completionListContains('mClass');
verify.not.completionListContains('mInt');
verify.not.completionListContains('mMod');
verify.not.completionListContains('meX');
verify.not.completionListContains('meFunc');
verify.not.completionListContains('meClass');
verify.not.completionListContains('meInt');
verify.not.completionListContains('meMod');
}

View File

@ -62,6 +62,7 @@
//// namespace m1Mod { }
//// export namespace m1eMod { }
//// /*namespace*/
//// var tmp: /*namespaceType*/
//// }
//// export var mod1evar = 1;
//// export function mod1efn() {
@ -124,8 +125,10 @@
//// namespace mMod { }
//// export namespace meMod { }
//// /*exportedNamespace*/
//// var tmp: /*exportedNamespaceType*/
//// }
//// /*mod1*/
//// var tmp: /*mod1Type*/;
////}
////
////// EXTENDING NAMESPACE 1
@ -133,6 +136,7 @@
//// export var mod1eexvar = 1;
//// var mod1exvar = 2;
//// /*extendedNamespace*/
//// var tmp: /*extendedNamespaceType*/;
////}
////
////namespace mod2 {
@ -225,28 +229,46 @@
////
////var shwvar = 1;
function goToMarkAndGeneralVerify(marker: string, isClassScope?: boolean)
interface GotoMarkVerifyOptions {
isClassScope?: boolean;
isTypeLocation?: boolean;
}
function getVerify(isTypeLocation: boolean) {
return {
verifyValue: isTypeLocation ? verify.not : verify,
verifyType: isTypeLocation ? verify : verify.not,
verifyValueOrType: verify,
verifyNotValueOrType: verify.not,
};
}
function goToMarkAndGeneralVerify(marker: string, { isClassScope, isTypeLocation }: GotoMarkVerifyOptions = {})
{
goTo.marker(marker);
const verifyModule = isClassScope ? verify.not : verify;
verifyModule.completionListContains('mod1var', 'var mod1var: number');
verifyModule.completionListContains('mod1fn', 'function mod1fn(): void');
verifyModule.completionListContains('mod1cls', 'class mod1cls');
verifyModule.completionListContains('mod1int', 'interface mod1int');
verifyModule.completionListContains('mod1mod', 'namespace mod1mod');
verifyModule.completionListContains('mod1evar', 'var mod1.mod1evar: number');
verifyModule.completionListContains('mod1efn', 'function mod1.mod1efn(): void');
verifyModule.completionListContains('mod1ecls', 'class mod1.mod1ecls');
verifyModule.completionListContains('mod1eint', 'interface mod1.mod1eint');
verifyModule.completionListContains('mod1emod', 'namespace mod1.mod1emod');
verifyModule.completionListContains('mod1eexvar', 'var mod1.mod1eexvar: number');
verifyModule.completionListContains('mod2', 'namespace mod2');
verifyModule.completionListContains('mod3', 'namespace mod3');
verifyModule.completionListContains('shwvar', 'var shwvar: number');
verifyModule.completionListContains('shwfn', 'function shwfn(): void');
verifyModule.completionListContains('shwcls', 'class shwcls');
verifyModule.completionListContains('shwint', 'interface shwint');
const verifyValueInModule = isClassScope || isTypeLocation ? verify.not : verify;
const verifyValueOrTypeInModule = isClassScope ? verify.not : verify;
const verifyTypeInModule = isTypeLocation ? verify : verify.not;
verifyValueInModule.completionListContains('mod1var', 'var mod1var: number');
verifyValueInModule.completionListContains('mod1fn', 'function mod1fn(): void');
verifyValueInModule.completionListContains('mod1evar', 'var mod1.mod1evar: number');
verifyValueInModule.completionListContains('mod1efn', 'function mod1.mod1efn(): void');
verifyValueInModule.completionListContains('mod1eexvar', 'var mod1.mod1eexvar: number');
verifyValueInModule.completionListContains('mod3', 'namespace mod3');
verifyValueInModule.completionListContains('shwvar', 'var shwvar: number');
verifyValueInModule.completionListContains('shwfn', 'function shwfn(): void');
verifyTypeInModule.completionListContains('mod1int', 'interface mod1int');
verifyTypeInModule.completionListContains('mod1eint', 'interface mod1.mod1eint');
verifyTypeInModule.completionListContains('shwint', 'interface shwint');
verifyValueOrTypeInModule.completionListContains('mod1cls', 'class mod1cls');
verifyValueOrTypeInModule.completionListContains('mod1mod', 'namespace mod1mod');
verifyValueOrTypeInModule.completionListContains('mod1ecls', 'class mod1.mod1ecls');
verifyValueOrTypeInModule.completionListContains('mod1emod', 'namespace mod1.mod1emod');
verifyValueOrTypeInModule.completionListContains('mod2', 'namespace mod2');
verifyValueOrTypeInModule.completionListContains('shwcls', 'class shwcls');
verify.not.completionListContains('mod2var');
verify.not.completionListContains('mod2fn');
@ -274,6 +296,8 @@ function goToMarkAndGeneralVerify(marker: string, isClassScope?: boolean)
// from mod1
goToMarkAndGeneralVerify('mod1');
// from mod1 in type position
goToMarkAndGeneralVerify('mod1Type', { isTypeLocation: true });
// from function in mod1
goToMarkAndGeneralVerify('function');
@ -281,7 +305,7 @@ verify.completionListContains('bar', '(local var) bar: number');
verify.completionListContains('foob', '(local function) foob(): void');
// from class in mod1
goToMarkAndGeneralVerify('class', /*isClassScope*/ true);
goToMarkAndGeneralVerify('class', { isClassScope: true });
//verify.not.completionListContains('ceFunc');
//verify.not.completionListContains('ceVar');
@ -289,17 +313,28 @@ goToMarkAndGeneralVerify('class', /*isClassScope*/ true);
goToMarkAndGeneralVerify('interface');
// from namespace in mod1
goToMarkAndGeneralVerify('namespace');
verify.completionListContains('m1X', 'var m1X: number');
verify.completionListContains('m1Func', 'function m1Func(): void');
verify.completionListContains('m1Class', 'class m1Class');
verify.completionListContains('m1Int', 'interface m1Int');
verify.completionListContains('m1Mod', 'namespace m1Mod');
verify.completionListContains('m1eX', 'var mod1mod.m1eX: number');
verify.completionListContains('m1eFunc', 'function mod1mod.m1eFunc(): void');
verify.completionListContains('m1eClass', 'class mod1mod.m1eClass');
verify.completionListContains('m1eInt', 'interface mod1mod.m1eInt');
verify.completionListContains('m1eMod', 'namespace mod1mod.m1eMod');
verifyNamespaceInMod1('namespace');
verifyNamespaceInMod1('namespaceType', /*isTypeLocation*/ true);
function verifyNamespaceInMod1(marker: string, isTypeLocation?: boolean) {
goToMarkAndGeneralVerify(marker, { isTypeLocation });
const { verifyValue, verifyType, verifyValueOrType, verifyNotValueOrType } = getVerify(isTypeLocation);
verifyValue.completionListContains('m1X', 'var m1X: number');
verifyValue.completionListContains('m1Func', 'function m1Func(): void');
verifyValue.completionListContains('m1eX', 'var mod1mod.m1eX: number');
verifyValue.completionListContains('m1eFunc', 'function mod1mod.m1eFunc(): void');
verifyType.completionListContains('m1Int', 'interface m1Int');
verifyType.completionListContains('m1eInt', 'interface mod1mod.m1eInt');
verifyValueOrType.completionListContains('m1Class', 'class m1Class');
verifyValueOrType.completionListContains('m1eClass', 'class mod1mod.m1eClass');
verifyNotValueOrType.completionListContains('m1Mod', 'namespace m1Mod');
verifyNotValueOrType.completionListContains('m1eMod', 'namespace mod1mod.m1eMod');
}
// from exported function in mod1
goToMarkAndGeneralVerify('exportedFunction');
@ -307,59 +342,77 @@ verify.completionListContains('bar', '(local var) bar: number');
verify.completionListContains('foob', '(local function) foob(): void');
// from exported class in mod1
goToMarkAndGeneralVerify('exportedClass', /*isClassScope*/ true);
//verify.not.completionListContains('ceFunc');
//verify.not.completionListContains('ceVar');
goToMarkAndGeneralVerify('exportedClass', { isClassScope: true });
verify.not.completionListContains('ceFunc');
verify.not.completionListContains('ceVar');
// from exported interface in mod1
goToMarkAndGeneralVerify('exportedInterface');
// from exported namespace in mod1
goToMarkAndGeneralVerify('exportedNamespace');
verify.completionListContains('mX', 'var mX: number');
verify.completionListContains('mFunc', 'function mFunc(): void');
verify.completionListContains('mClass', 'class mClass');
verify.completionListContains('mInt', 'interface mInt');
verify.completionListContains('mMod', 'namespace mMod');
verify.completionListContains('meX', 'var mod1.mod1emod.meX: number');
verify.completionListContains('meFunc', 'function mod1.mod1emod.meFunc(): void');
verify.completionListContains('meClass', 'class mod1.mod1emod.meClass');
verify.completionListContains('meInt', 'interface mod1.mod1emod.meInt');
verify.completionListContains('meMod', 'namespace mod1.mod1emod.meMod');
verifyExportedNamespace('exportedNamespace');
verifyExportedNamespace('exportedNamespaceType', /*isTypeLocation*/ true);
function verifyExportedNamespace(marker: string, isTypeLocation?: boolean) {
goToMarkAndGeneralVerify(marker, { isTypeLocation });
const { verifyValue, verifyType, verifyValueOrType, verifyNotValueOrType } = getVerify(isTypeLocation);
verifyValue.completionListContains('mX', 'var mX: number');
verifyValue.completionListContains('mFunc', 'function mFunc(): void');
verifyValue.completionListContains('meX', 'var mod1.mod1emod.meX: number');
verifyValue.completionListContains('meFunc', 'function mod1.mod1emod.meFunc(): void');
verifyType.completionListContains('mInt', 'interface mInt');
verifyType.completionListContains('meInt', 'interface mod1.mod1emod.meInt');
verifyValueOrType.completionListContains('mClass', 'class mClass');
verifyValueOrType.completionListContains('meClass', 'class mod1.mod1emod.meClass');
verifyNotValueOrType.completionListContains('mMod', 'namespace mMod');
verifyNotValueOrType.completionListContains('meMod', 'namespace mod1.mod1emod.meMod');
}
// from extended namespace
goTo.marker('extendedNamespace');
verify.completionListContains('mod1evar', 'var mod1.mod1evar: number');
verify.completionListContains('mod1efn', 'function mod1.mod1efn(): void');
verify.completionListContains('mod1ecls', 'class mod1.mod1ecls');
verify.completionListContains('mod1eint', 'interface mod1.mod1eint');
verify.completionListContains('mod1emod', 'namespace mod1.mod1emod');
verify.completionListContains('mod1eexvar', 'var mod1.mod1eexvar: number');
verify.completionListContains('mod2', 'namespace mod2');
verify.completionListContains('mod3', 'namespace mod3');
verify.completionListContains('shwvar', 'var shwvar: number');
verify.completionListContains('shwfn', 'function shwfn(): void');
verify.completionListContains('shwcls', 'class shwcls');
verify.completionListContains('shwint', 'interface shwint');
verifyExtendedNamespace('extendedNamespace');
verifyExtendedNamespace('extendedNamespaceType', /*isTypeLocation*/ true);
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.not.completionListContains('scpfn');
verify.not.completionListContains('scpvar');
verify.not.completionListContains('scsvar');
verify.not.completionListContains('scsfn');
verify.not.completionListContains('sivar');
verify.not.completionListContains('sifn');
verify.not.completionListContains('mod2eexvar');
function verifyExtendedNamespace(marker: string, isTypeLocation?: boolean) {
goTo.marker(marker);
const { verifyValue, verifyType, verifyValueOrType, verifyNotValueOrType } = getVerify(isTypeLocation);
verifyValue.completionListContains('mod1evar', 'var mod1.mod1evar: number');
verifyValue.completionListContains('mod1efn', 'function mod1.mod1efn(): void');
verifyValue.completionListContains('mod1eexvar', 'var mod1.mod1eexvar: number');
verifyValue.completionListContains('mod3', 'namespace mod3');
verifyValue.completionListContains('shwvar', 'var shwvar: number');
verifyValue.completionListContains('shwfn', 'function shwfn(): void');
verifyType.completionListContains('mod1eint', 'interface mod1.mod1eint');
verifyType.completionListContains('shwint', 'interface shwint');
verifyValueOrType.completionListContains('mod1ecls', 'class mod1.mod1ecls');
verifyValueOrType.completionListContains('mod1emod', 'namespace mod1.mod1emod');
verifyValueOrType.completionListContains('mod2', 'namespace mod2');
verifyValueOrType.completionListContains('shwcls', 'class shwcls');
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.not.completionListContains('scpfn');
verify.not.completionListContains('scpvar');
verify.not.completionListContains('scsvar');
verify.not.completionListContains('scsfn');
verify.not.completionListContains('sivar');
verify.not.completionListContains('sifn');
verify.not.completionListContains('mod2eexvar');
}

View File

@ -266,7 +266,7 @@ verify.completionListContains('mod3', 'namespace mod3');
verify.completionListContains('shwvar', 'var shwvar: number');
verify.completionListContains('shwfn', 'function shwfn(): void');
verify.completionListContains('shwcls', 'class shwcls');
verify.completionListContains('shwint', 'interface shwint');
verify.not.completionListContains('shwint', 'interface shwint');
verifyNotContainFunctionMembers();
verifyNotContainClassMembers();

View File

@ -274,7 +274,7 @@ function goToMarkerAndVerify(marker: string)
verify.completionListContains('shwvar', 'var shwvar: number');
verify.completionListContains('shwfn', 'function shwfn(): void');
verify.completionListContains('shwcls', 'class shwcls');
verify.completionListContains('shwint', 'interface shwint');
verify.not.completionListContains('shwint', 'interface shwint');
verify.not.completionListContains('mod2var');
verify.not.completionListContains('mod2fn');

View File

@ -10,15 +10,37 @@
//// /*2*/
////}
/////*3*/
////function f2() {
//// namespace n2 {
//// class I2 {
//// x: number
//// }
//// /*11*/
//// }
//// /*22*/
////}
/////*33*/
goTo.marker('1');
verify.completionListContains("f", "function f(): void");
verify.completionListContains("n", "namespace n");
verify.completionListContains("I", "interface I");
verify.not.completionListContains("n", "namespace n");
verify.not.completionListContains("I", "interface I");
goTo.marker('2');
verify.completionListContains("f", "function f(): void");
verify.completionListContains("n", "namespace n");
verify.not.completionListContains("n", "namespace n");
goTo.marker('3');
verify.completionListContains("f", "function f(): void");
verify.completionListContains("f", "function f(): void");
goTo.marker('11');
verify.completionListContains("f2", "function f2(): void");
verify.completionListContains("n2", "namespace n2");
verify.completionListContains("I2", "class I2");
goTo.marker('22');
verify.completionListContains("f2", "function f2(): void");
verify.completionListContains("n2", "namespace n2");
goTo.marker('33');
verify.completionListContains("f2", "function f2(): void");

View File

@ -56,8 +56,8 @@ goTo.marker('9');
verify.quickInfoIs("(property) test1: a1.connectModule(res: any, req: any, next: any) => void", undefined);
verify.completionListContains("test1", "(property) test1: a1.connectModule(res: any, req: any, next: any) => void", undefined);
verify.completionListContains("test2", "(method) test2(): a1.connectModule", undefined);
verify.completionListContains("connectModule");
verify.completionListContains("connectExport");
verify.not.completionListContains("connectModule");
verify.not.completionListContains("connectExport");
goTo.marker('10');
verify.currentSignatureHelpIs("test1(res: any, req: any, next: any): void");

View File

@ -14,6 +14,6 @@
////var x: Foo./**/
goTo.marker();
verify.completionListCount(2);
verify.completionListCount(1);
verify.completionListContains('Bar');
verify.completionListContains('Blah');
verify.not.completionListContains('Blah');