Merge pull request #676 from Microsoft/completionFixes

Completion fixes
This commit is contained in:
Mohamed Hegazy 2014-09-17 17:31:30 -07:00
commit beb2725f11
97 changed files with 506 additions and 322 deletions

View file

@ -2432,7 +2432,7 @@ module ts {
case SyntaxKind.Identifier:
case SyntaxKind.QualifiedName:
var symbol = getSymbolInfo(node);
return getDeclaredTypeOfSymbol(symbol);
return symbol && getDeclaredTypeOfSymbol(symbol);
default:
return unknownType;
}
@ -3472,41 +3472,6 @@ module ts {
return getAncestor(node, kind) !== undefined;
}
function getAncestor(node: Node, kind: SyntaxKind): Node {
switch (kind) {
// special-cases that can be come first
case SyntaxKind.ClassDeclaration:
while (node) {
switch (node.kind) {
case SyntaxKind.ClassDeclaration:
return <ClassDeclaration>node;
case SyntaxKind.EnumDeclaration:
case SyntaxKind.InterfaceDeclaration:
case SyntaxKind.ModuleDeclaration:
case SyntaxKind.ImportDeclaration:
// early exit cases - declarations cannot be nested in classes
return undefined;
default:
node = node.parent;
continue;
}
}
break;
default:
while (node) {
if (node.kind === kind) {
return node;
}
else {
node = node.parent;
}
}
break;
}
return undefined;
}
// EXPRESSION TYPE CHECKING
function checkIdentifier(node: Identifier): Type {
@ -3853,6 +3818,11 @@ module ts {
// Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily
// be "pushed" onto a node using the contextualType property.
function getContextualType(node: Expression): Type {
if (isInsideWithStatementBody(node)) {
// We cannot answer semantic questions within a with block, do not proceed any further
return undefined;
}
if (node.contextualType) {
return node.contextualType;
}
@ -6718,7 +6688,20 @@ module ts {
return findChildAtPosition(sourceFile);
}
function getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[] {
function isInsideWithStatementBody(node: Node): boolean {
if (node) {
while (node.parent) {
if (node.parent.kind === SyntaxKind.WithStatement && (<WithStatement>node.parent).statement === node) {
return true;
}
node = node.parent;
}
}
return false;
}
function getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[]{
var symbols: SymbolTable = {};
var memberFlags: NodeFlags = 0;
function copySymbol(symbol: Symbol, meaning: SymbolFlags) {
@ -6738,6 +6721,12 @@ module ts {
}
}
}
if (isInsideWithStatementBody(location)) {
// We cannot answer semantic questions within a with block, do not proceed any further
return [];
}
while (location) {
if (location.locals && !isGlobalSourceFile(location)) {
copySymbols(location.locals, meaning);
@ -7010,6 +6999,11 @@ module ts {
}
function getSymbolInfo(node: Node) {
if (isInsideWithStatementBody(node)) {
// We cannot answer semantic questions within a with block, do not proceed any further
return undefined;
}
if (isDeclarationOrFunctionExpressionOrCatchVariableName(node)) {
// This is a declaration, call getSymbolOfNode
return getSymbolOfNode(node.parent);
@ -7064,9 +7058,15 @@ module ts {
}
function getTypeOfNode(node: Node): Type {
if (isInsideWithStatementBody(node)) {
// We cannot answer semantic questions within a with block, do not proceed any further
return unknownType;
}
if (isExpression(node)) {
return getTypeOfExpression(<Expression>node);
}
if (isTypeNode(node)) {
return getTypeFromTypeNode(<TypeNode>node);
}
@ -7079,7 +7079,7 @@ module ts {
if (isTypeDeclarationName(node)) {
var symbol = getSymbolInfo(node);
return getDeclaredTypeOfSymbol(symbol);
return symbol && getDeclaredTypeOfSymbol(symbol);
}
if (isDeclaration(node)) {
@ -7090,12 +7090,12 @@ module ts {
if (isDeclarationOrFunctionExpressionOrCatchVariableName(node)) {
var symbol = getSymbolInfo(node);
return getTypeOfSymbol(symbol);
return symbol && getTypeOfSymbol(symbol);
}
if (isInRightSideOfImportOrExportAssignment(node)) {
var symbol = getSymbolInfo(node);
var declaredType = getDeclaredTypeOfSymbol(symbol);
var declaredType = symbol && getDeclaredTypeOfSymbol(symbol);
return declaredType !== unknownType ? declaredType : getTypeOfSymbol(symbol);
}
@ -7147,7 +7147,7 @@ module ts {
}
function getRootSymbol(symbol: Symbol) {
return (symbol.flags & SymbolFlags.Transient) ? getSymbolLinks(symbol).target : symbol;
return ((symbol.flags & SymbolFlags.Transient) && getSymbolLinks(symbol).target) || symbol;
}
// Emitter support

View file

@ -531,6 +531,39 @@ module ts {
return false;
}
export function getAncestor(node: Node, kind: SyntaxKind): Node {
switch (kind) {
// special-cases that can be come first
case SyntaxKind.ClassDeclaration:
while (node) {
switch (node.kind) {
case SyntaxKind.ClassDeclaration:
return <ClassDeclaration>node;
case SyntaxKind.EnumDeclaration:
case SyntaxKind.InterfaceDeclaration:
case SyntaxKind.ModuleDeclaration:
case SyntaxKind.ImportDeclaration:
// early exit cases - declarations cannot be nested in classes
return undefined;
default:
node = node.parent;
continue;
}
}
break;
default:
while (node) {
if (node.kind === kind) {
return node;
}
node = node.parent;
}
break;
}
return undefined;
}
enum ParsingContext {
SourceElements, // Elements in source file
ModuleElements, // Elements in module declaration
@ -2200,10 +2233,38 @@ module ts {
function parseCallAndAccess(expr: Expression, inNewExpression: boolean): Expression {
while (true) {
var dotStart = scanner.getTokenPos();
if (parseOptional(SyntaxKind.DotToken)) {
var propertyAccess = <PropertyAccess>createNode(SyntaxKind.PropertyAccess, expr.pos);
// Technically a keyword is valid here as all keywords are identifier names.
// However, often we'll encounter this in error situations when the keyword
// is actually starting another valid construct.
//
// So, we check for the following specific case:
//
// name.
// keyword identifierNameOrKeyword
//
// Note: the newlines are important here. For example, if that above code
// were rewritten into:
//
// name.keyword
// identifierNameOrKeyword
//
// Then we would consider it valid. That's because ASI would take effect and
// the code would be implicitly: "name.keyword; identifierNameOrKeyword".
// In the first case though, ASI will not take effect because there is not a
// line terminator after the keyword.
if (scanner.hasPrecedingLineBreak() && scanner.isReservedWord() && lookAhead(() => scanner.isReservedWord())) {
grammarErrorAtPos(dotStart, scanner.getStartPos() - dotStart, Diagnostics.Identifier_expected);
var id = <Identifier>createMissingNode();
}
else {
var id = parseIdentifierName();
}
propertyAccess.left = expr;
propertyAccess.right = parseIdentifierName();
propertyAccess.right = id;
expr = finishNode(propertyAccess);
continue;
}

View file

@ -770,7 +770,6 @@ module ts {
InMultiLineCommentTrivia,
InSingleQuoteStringLiteral,
InDoubleQuoteStringLiteral,
EndingWithDotToken,
}
export enum TokenClass {
@ -1667,14 +1666,20 @@ module ts {
/// Completion
function getValidCompletionEntryDisplayName(displayName: string, target: ScriptTarget): string {
if (displayName && displayName.length > 0) {
var firstChar = displayName.charCodeAt(0);
if (firstChar === TypeScript.CharacterCodes.singleQuote || firstChar === TypeScript.CharacterCodes.doubleQuote) {
var firstCharCode = displayName.charCodeAt(0);
if (displayName && displayName.length >= 2 && firstCharCode === displayName.charCodeAt(displayName.length - 1) &&
(firstCharCode === CharacterCodes.singleQuote || firstCharCode === CharacterCodes.doubleQuote)) {
// If the user entered name for the symbol was quoted, removing the quotes is not enough, as the name could be an
// invalid identifier name. We need to check if whatever was inside the quotes is actually a valid identifier name.
displayName = TypeScript.stripStartAndEndQuotes(displayName);
// invalid identifer name. We need to check if whatever was inside the quotes is actually a valid identifier name.
displayName = displayName.substring(1, displayName.length - 1);
}
var isValid = isIdentifierStart(displayName.charCodeAt(0), target);
for (var i = 1, n = displayName.length; isValid && i < n; i++) {
isValid = isIdentifierPart(displayName.charCodeAt(i), target);
}
if (TypeScript.Scanner.isValidIdentifier(TypeScript.SimpleText.fromString(displayName), target)) {
if (isValid) {
return displayName;
}
}
@ -1692,7 +1697,6 @@ module ts {
}
var declarations = symbol.getDeclarations();
var firstDeclaration = [0];
return {
name: displayName,
kind: getSymbolKind(symbol),
@ -1704,7 +1708,7 @@ module ts {
function getCompletionEntriesFromSymbols(symbols: Symbol[], session: CompletionSession): void {
forEach(symbols, (symbol) => {
var entry = createCompletionEntry(symbol);
if (entry) {
if (entry && !lookUp(session.symbols, entry.name)) {
session.entries.push(entry);
session.symbols[entry.name] = symbol;
}
@ -1834,6 +1838,49 @@ module ts {
return false;
}
function isPunctuation(kind: SyntaxKind) {
return (SyntaxKind.FirstPunctuation <= kind && kind <= SyntaxKind.LastPunctuation);
}
function isVisibleWithinClassDeclaration(symbol: Symbol, containingClass: Declaration): boolean {
var declaration = symbol.declarations && symbol.declarations[0];
if (declaration && (declaration.flags & NodeFlags.Private)) {
var declarationClass = getAncestor(declaration, SyntaxKind.ClassDeclaration);
return containingClass === declarationClass;
}
return true;
}
function filterContextualMembersList(contextualMemberSymbols: Symbol[], existingMembers: Declaration[]): Symbol[] {
if (!existingMembers || existingMembers.length === 0) {
return contextualMemberSymbols;
}
var existingMemberNames: Map<boolean> = {};
forEach(existingMembers, m => {
if (m.kind !== SyntaxKind.PropertyAssignment) {
// Ignore omitted expressions for missing members in the object literal
return;
}
if (m.getStart() <= position && position <= m.getEnd()) {
// If this is the current item we are editing right now, do not filter it out
return;
}
existingMemberNames[m.name.text] = true;
});
var filteredMembers: Symbol[] = [];
forEach(contextualMemberSymbols, s => {
if (!existingMemberNames[s.name]) {
filteredMembers.push(s);
}
});
return filteredMembers;
}
synchronizeHostData();
filename = TypeScript.switchToForwardSlashes(filename);
@ -1888,6 +1935,9 @@ module ts {
// TODO: this is a hack for now, we need a proper walking mechanism to verify that we have the correct node
var mappedNode = getNodeAtPosition(sourceFile, TypeScript.end(node) - 1);
if (isPunctuation(mappedNode.kind)) {
mappedNode = mappedNode.parent;
}
Debug.assert(mappedNode, "Could not map a Fidelity node to an AST node");
@ -1903,13 +1953,33 @@ module ts {
// Right of dot member completion list
if (isRightOfDot) {
var type: ApparentType = typeInfoResolver.getApparentType(typeInfoResolver.getTypeOfNode(mappedNode));
if (!type) {
return undefined;
var symbols: Symbol[] = [];
var containingClass = getAncestor(mappedNode, SyntaxKind.ClassDeclaration);
isMemberCompletion = true;
if (mappedNode.kind === SyntaxKind.Identifier || mappedNode.kind === SyntaxKind.QualifiedName || mappedNode.kind === SyntaxKind.PropertyAccess) {
var symbol = typeInfoResolver.getSymbolInfo(mappedNode);
if (symbol && symbol.flags & SymbolFlags.HasExports) {
// Extract module or enum members
forEachValue(symbol.exports, symbol => {
if (isVisibleWithinClassDeclaration(symbol, containingClass)) {
symbols.push(symbol);
}
});
}
}
var type = typeInfoResolver.getTypeOfNode(mappedNode);
var apparentType = type && typeInfoResolver.getApparentType(type);
if (apparentType) {
// Filter private properties
forEach(apparentType.getApparentProperties(), symbol => {
if (isVisibleWithinClassDeclaration(symbol, containingClass)) {
symbols.push(symbol);
}
});
}
var symbols = type.getApparentProperties();
isMemberCompletion = true;
getCompletionEntriesFromSymbols(symbols, activeCompletionSession);
}
else {
@ -1917,34 +1987,23 @@ module ts {
// Object literal expression, look up possible property names from contextual type
if (containingObjectLiteral) {
var searchPosition = Math.min(position, TypeScript.end(containingObjectLiteral));
var path = TypeScript.ASTHelpers.getAstAtPosition(sourceUnit, searchPosition);
// Get the object literal node
var objectLiteral = <ObjectLiteral>(mappedNode.kind === SyntaxKind.ObjectLiteral ? mappedNode : getAncestor(mappedNode, SyntaxKind.ObjectLiteral));
while (node && node.kind() !== TypeScript.SyntaxKind.ObjectLiteralExpression) {
node = node.parent;
}
if (!node || node.kind() !== TypeScript.SyntaxKind.ObjectLiteralExpression) {
// AST Path look up did not result in the same node as Fidelity Syntax Tree look up.
// Once we remove AST this will no longer be a problem.
return null;
}
Debug.assert(objectLiteral);
isMemberCompletion = true;
//// Try to get the object members form contextual typing
//var contextualMembers = compiler.getContextualMembersFromAST(node, document);
//if (contextualMembers && contextualMembers.symbols && contextualMembers.symbols.length > 0) {
// // get existing members
// var existingMembers = compiler.getVisibleMemberSymbolsFromAST(node, document);
var contextualType = typeInfoResolver.getContextualType(objectLiteral);
if (!contextualType) {
return undefined;
}
// // Add filtered items to the completion list
// getCompletionEntriesFromSymbols({
// symbols: filterContextualMembersList(contextualMembers.symbols, existingMembers, filename, position),
// enclosingScopeSymbol: contextualMembers.enclosingScopeSymbol
// }, entries);
//}
var contextualTypeMembers = typeInfoResolver.getPropertiesOfType(contextualType);
if (contextualTypeMembers && contextualTypeMembers.length > 0) {
// Add filtered items to the completion list
var filteredMembers = filterContextualMembersList(contextualTypeMembers, objectLiteral.properties);
getCompletionEntriesFromSymbols(filteredMembers, activeCompletionSession);
}
}
// Get scope members
else {
@ -2048,7 +2107,7 @@ module ts {
}
function getSymbolKind(symbol: Symbol): string {
var flags = symbol.getFlags();
var flags = typeInfoResolver.getRootSymbol(symbol).getFlags();
if (flags & SymbolFlags.Module) return ScriptElementKind.moduleElement;
if (flags & SymbolFlags.Class) return ScriptElementKind.classElement;
@ -4004,9 +4063,6 @@ module ts {
text = "/*\n" + text;
offset = 3;
break;
case EndOfLineState.EndingWithDotToken:
lastToken = SyntaxKind.DotToken;
break;
}
var result: ClassificationResult = {
@ -4074,9 +4130,6 @@ module ts {
: EndOfLineState.InSingleQuoteStringLiteral;
}
}
else if (token === SyntaxKind.DotToken) {
result.finalLexState = EndOfLineState.EndingWithDotToken;
}
}
}

View file

@ -1,4 +1,4 @@
tests/cases/compiler/enumConflictsWithGlobalIdentifier.ts(5,5): error TS1005: ',' expected.
tests/cases/compiler/enumConflictsWithGlobalIdentifier.ts(4,28): error TS1003: Identifier expected.
tests/cases/compiler/enumConflictsWithGlobalIdentifier.ts(4,9): error TS2304: Cannot find name 'IgnoreRulesSpecific'.
@ -7,9 +7,9 @@ tests/cases/compiler/enumConflictsWithGlobalIdentifier.ts(4,9): error TS2304: Ca
IgnoreRulesSpecific = 0,
}
var x = IgnoreRulesSpecific.
~
!!! error TS1003: Identifier expected.
~~~~~~~~~~~~~~~~~~~
!!! error TS2304: Cannot find name 'IgnoreRulesSpecific'.
var y = Position.IgnoreRulesSpecific;
~
!!! error TS1005: ',' expected.

View file

@ -1,4 +1,4 @@
tests/cases/compiler/enumMemberResolution.ts(5,5): error TS1005: ',' expected.
tests/cases/compiler/enumMemberResolution.ts(4,28): error TS1003: Identifier expected.
tests/cases/compiler/enumMemberResolution.ts(4,9): error TS2304: Cannot find name 'IgnoreRulesSpecific'.
@ -7,10 +7,10 @@ tests/cases/compiler/enumMemberResolution.ts(4,9): error TS2304: Cannot find nam
IgnoreRulesSpecific = 0
}
var x = IgnoreRulesSpecific. // error
~
!!! error TS1003: Identifier expected.
~~~~~~~~~~~~~~~~~~~
!!! error TS2304: Cannot find name 'IgnoreRulesSpecific'.
var y = 1;
~
!!! error TS1005: ',' expected.
var z = Position2.IgnoreRulesSpecific; // no error

View file

@ -1,30 +1,30 @@
EmitOutputStatus : Succeeded
Filename : tests/cases/fourslash/inputFile1.js
var x = 5;
var Bar = (function () {
function Bar() {
}
return Bar;
})();
var x = 5;
var Bar = (function () {
function Bar() {
}
return Bar;
})();
Filename : tests/cases/fourslash/inputFile1.d.ts
declare var x: number;
declare class Bar {
x: string;
y: number;
}
declare var x: number;
declare class Bar {
x: string;
y: number;
}
EmitOutputStatus : Succeeded
Filename : tests/cases/fourslash/inputFile2.js
var x1 = "hello world";
var Foo = (function () {
function Foo() {
}
return Foo;
})();
var x1 = "hello world";
var Foo = (function () {
function Foo() {
}
return Foo;
})();
Filename : tests/cases/fourslash/inputFile2.d.ts
declare var x1: string;
declare class Foo {
x: string;
y: number;
}
declare var x1: string;
declare class Foo {
x: string;
y: number;
}

View file

@ -1,26 +1,26 @@
EmitOutputStatus : Succeeded
Filename : declSingleFile.js
var x = 5;
var Bar = (function () {
function Bar() {
}
return Bar;
})();
var x1 = "hello world";
var Foo = (function () {
function Foo() {
}
return Foo;
})();
var x = 5;
var Bar = (function () {
function Bar() {
}
return Bar;
})();
var x1 = "hello world";
var Foo = (function () {
function Foo() {
}
return Foo;
})();
Filename : declSingleFile.d.ts
declare var x: number;
declare class Bar {
x: string;
y: number;
}
declare var x1: string;
declare class Foo {
x: string;
y: number;
}
declare var x: number;
declare class Bar {
x: string;
y: number;
}
declare var x1: string;
declare class Foo {
x: string;
y: number;
}

View file

@ -1,11 +1,11 @@
EmitOutputStatus : Succeeded
Filename : declSingleFile.js.map
{"version":3,"file":"declSingleFile.js","sourceRoot":"","sources":["../tests/cases/fourslash/inputFile.ts"],"names":["M","M.constructor"],"mappings":"AAAA,IAAI,CAAC,GAAG,GAAG,CAAC;AACZ,IAAI,GAAG,GAAG,aAAa,CAAC;AACxB,IAAM,CAAC;IAAPA,SAAMA,CAACA;IAGPC,CAACA;IAADD,QAACA;AAADA,CAACA,AAHD,IAGC"}Filename : declSingleFile.js
var x = 109;
var foo = "hello world";
var M = (function () {
function M() {
}
return M;
})();
var x = 109;
var foo = "hello world";
var M = (function () {
function M() {
}
return M;
})();
//# sourceMappingURL=mapRootDir/declSingleFile.js.map

View file

@ -1,9 +1,9 @@
EmitOutputStatus : Succeeded
Filename : tests/cases/fourslash/inputFile.js
var x;
var M = (function () {
function M() {
}
return M;
})();
var x;
var M = (function () {
function M() {
}
return M;
})();

View file

@ -1,9 +1,9 @@
EmitOutputStatus : Succeeded
Filename : tests/cases/fourslash/inputFile2.js
var x;
var Foo = (function () {
function Foo() {
}
return Foo;
})();
var x;
var Foo = (function () {
function Foo() {
}
return Foo;
})();

View file

@ -1,15 +1,15 @@
EmitOutputStatus : Succeeded
Filename : outputDir/singleFile.js
var x;
var Bar = (function () {
function Bar() {
}
return Bar;
})();
var x;
var Foo = (function () {
function Foo() {
}
return Foo;
})();
var x;
var Bar = (function () {
function Bar() {
}
return Bar;
})();
var x;
var Foo = (function () {
function Foo() {
}
return Foo;
})();

View file

@ -1,32 +1,32 @@
EmitOutputStatus : Succeeded
Filename : tests/cases/fourslash/inputFile3.js
exports.foo = 10;
exports.bar = "hello world";
exports.foo = 10;
exports.bar = "hello world";
Filename : tests/cases/fourslash/inputFile3.d.ts
export declare var foo: number;
export declare var bar: string;
export declare var foo: number;
export declare var bar: string;
Filename : declSingleFile.js
var x = 5;
var Bar = (function () {
function Bar() {
}
return Bar;
})();
var x1 = "hello world";
var Foo = (function () {
function Foo() {
}
return Foo;
})();
var x = 5;
var Bar = (function () {
function Bar() {
}
return Bar;
})();
var x1 = "hello world";
var Foo = (function () {
function Foo() {
}
return Foo;
})();
Filename : declSingleFile.d.ts
declare var x: number;
declare class Bar {
x: string;
y: number;
}
declare var x1: string;
declare class Foo {
x: string;
y: number;
}
declare var x: number;
declare class Bar {
x: string;
y: number;
}
declare var x1: string;
declare class Foo {
x: string;
y: number;
}

View file

@ -1,11 +1,11 @@
EmitOutputStatus : Succeeded
Filename : tests/cases/fourslash/inputFile.js.map
{"version":3,"file":"inputFile.js","sourceRoot":"","sources":["inputFile.ts"],"names":["M","M.constructor"],"mappings":"AAAA,IAAI,CAAC,GAAG,GAAG,CAAC;AACZ,IAAI,GAAG,GAAG,aAAa,CAAC;AACxB,IAAM,CAAC;IAAPA,SAAMA,CAACA;IAGPC,CAACA;IAADD,QAACA;AAADA,CAACA,AAHD,IAGC"}Filename : tests/cases/fourslash/inputFile.js
var x = 109;
var foo = "hello world";
var M = (function () {
function M() {
}
return M;
})();
var x = 109;
var foo = "hello world";
var M = (function () {
function M() {
}
return M;
})();
//# sourceMappingURL=inputFile.js.map

View file

@ -1,19 +1,19 @@
EmitOutputStatus : Succeeded
Filename : sample/outDir/inputFile1.js.map
{"version":3,"file":"inputFile1.js","sourceRoot":"","sources":["../../tests/cases/fourslash/inputFile1.ts"],"names":["M","M.constructor"],"mappings":"AAAA,IAAI,CAAC,GAAG,GAAG,CAAC;AACZ,IAAI,GAAG,GAAG,aAAa,CAAC;AACxB,IAAM,CAAC;IAAPA,SAAMA,CAACA;IAGPC,CAACA;IAADD,QAACA;AAADA,CAACA,AAHD,IAGC"}Filename : sample/outDir/inputFile1.js
var x = 109;
var foo = "hello world";
var M = (function () {
function M() {
}
return M;
})();
var x = 109;
var foo = "hello world";
var M = (function () {
function M() {
}
return M;
})();
//# sourceMappingURL=inputFile1.js.map
EmitOutputStatus : Succeeded
Filename : sample/outDir/inputFile2.js.map
{"version":3,"file":"inputFile2.js","sourceRoot":"","sources":["../../tests/cases/fourslash/inputFile2.ts"],"names":[],"mappings":"AAAA,IAAI,KAAK,GAAG,aAAa,CAAC;AAC1B,EAAE,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC;IACvB,IAAI,CAAC,GAAG,EAAE,CAAC;AACd,CAAC"}Filename : sample/outDir/inputFile2.js
var intro = "hello world";
if (intro !== undefined) {
var k = 10;
}
var intro = "hello world";
if (intro !== undefined) {
var k = 10;
}
//# sourceMappingURL=inputFile2.js.map

View file

@ -1,11 +1,11 @@
EmitOutputStatus : Succeeded
Filename : tests/cases/fourslash/inputFile.js.map
{"version":3,"file":"inputFile.js","sourceRoot":"sourceRootDir/","sources":["inputFile.ts"],"names":["M","M.constructor"],"mappings":"AAAA,IAAI,CAAC,GAAG,GAAG,CAAC;AACZ,IAAI,GAAG,GAAG,aAAa,CAAC;AACxB,IAAM,CAAC;IAAPA,SAAMA,CAACA;IAGPC,CAACA;IAADD,QAACA;AAADA,CAACA,AAHD,IAGC"}Filename : tests/cases/fourslash/inputFile.js
var x = 109;
var foo = "hello world";
var M = (function () {
function M() {
}
return M;
})();
var x = 109;
var foo = "hello world";
var M = (function () {
function M() {
}
return M;
})();
//# sourceMappingURL=inputFile.js.map

View file

@ -1,21 +1,21 @@
EmitOutputStatus : Succeeded
Filename : tests/cases/fourslash/inputFile1.js.map
{"version":3,"file":"inputFile1.js","sourceRoot":"sourceRootDir/","sources":["inputFile1.ts"],"names":["M","M.constructor"],"mappings":"AAAA,IAAI,CAAC,GAAG,GAAG,CAAC;AACZ,IAAI,GAAG,GAAG,aAAa,CAAC;AACxB,IAAM,CAAC;IAAPA,SAAMA,CAACA;IAGPC,CAACA;IAADD,QAACA;AAADA,CAACA,AAHD,IAGC"}Filename : tests/cases/fourslash/inputFile1.js
var x = 109;
var foo = "hello world";
var M = (function () {
function M() {
}
return M;
})();
var x = 109;
var foo = "hello world";
var M = (function () {
function M() {
}
return M;
})();
//# sourceMappingURL=inputFile1.js.map
EmitOutputStatus : Succeeded
Filename : tests/cases/fourslash/inputFile2.js.map
{"version":3,"file":"inputFile2.js","sourceRoot":"sourceRootDir/","sources":["inputFile2.ts"],"names":["C","C.constructor"],"mappings":"AAAA,IAAI,GAAG,GAAG,wBAAwB,CAAC;AACnC,IAAM,CAAC;IAAPA,SAAMA,CAACA;IAGPC,CAACA;IAADD,QAACA;AAADA,CAACA,AAHD,IAGC"}Filename : tests/cases/fourslash/inputFile2.js
var bar = "hello world Typescript";
var C = (function () {
function C() {
}
return C;
})();
var bar = "hello world Typescript";
var C = (function () {
function C() {
}
return C;
})();
//# sourceMappingURL=inputFile2.js.map

View file

@ -1,12 +1,12 @@
EmitOutputStatus : EmitErrorsEncountered
Filename : tests/cases/fourslash/inputFile.js
var M;
(function (M) {
var C = (function () {
function C() {
}
return C;
})();
M.foo = new C();
})(M || (M = {}));
var M;
(function (M) {
var C = (function () {
function C() {
}
return C;
})();
M.foo = new C();
})(M || (M = {}));

View file

@ -1,14 +1,14 @@
EmitOutputStatus : EmitErrorsEncountered
Filename : tests/cases/fourslash/inputFile.js
define(["require", "exports"], function (require, exports) {
var C = (function () {
function C() {
}
return C;
})();
var M;
(function (M) {
M.foo = new C();
})(M = exports.M || (exports.M = {}));
});
define(["require", "exports"], function (require, exports) {
var C = (function () {
function C() {
}
return C;
})();
var M;
(function (M) {
M.foo = new C();
})(M = exports.M || (exports.M = {}));
});

View file

@ -1,4 +1,4 @@
EmitOutputStatus : JSGeneratedWithSemanticErrors
Filename : tests/cases/fourslash/inputFile.js
var x = "hello world";
var x = "hello world";

View file

@ -1,4 +1,4 @@
EmitOutputStatus : DeclarationGenerationSkipped
Filename : tests/cases/fourslash/inputFile.js
var x = "hello world";
var x = "hello world";

View file

@ -6,4 +6,4 @@ diagnostics.setEditValidation(IncrementalEditValidation.None);
goTo.marker();
verify.not.completionListIsEmpty();
edit.insert("nu");
verify.completionListContains("number", undefined, undefined, undefined, "primitive type");
verify.completionListContains("number", undefined, undefined, undefined, "keyword");

View file

@ -12,10 +12,10 @@
////f2./*2*/ // here bar has return type any, but bar2 is Foo2
goTo.marker('1');
verify.completionListContains('bar', '(): IFoo');
verify.completionListContains('bar', '() => IFoo');
verify.not.completionListContains('bar2');
edit.insert('bar();'); // just to make the file valid before checking next completion location
goTo.marker('2');
verify.completionListContains('bar', '(): IFoo');
verify.completionListContains('bar2', '(): IFoo2');
verify.completionListContains('bar', '() => IFoo');
verify.completionListContains('bar2', '() => IFoo2');

View file

@ -18,8 +18,15 @@
////interface test4 implements Foo./*4*/ {}
test.markers().forEach((marker) => {
goTo.position(marker.position, marker.fileName);
goTo.marker("1");
verify.completionListIsEmpty();
verify.completionListIsEmpty();
});
goTo.marker("2");
verify.completionListIsEmpty();
goTo.marker("3");
verify.completionListIsEmpty();
// This needs comletion list filtering based on location to work
goTo.marker("4");
verify.not.completionListIsEmpty();

View file

@ -24,9 +24,9 @@ goTo.marker("insideFunctionExpression");
verify.memberListContains("foo");
goTo.marker("referenceInsideFunctionExpression");
verify.quickInfoIs("(): number");
verify.quickInfoIs("() => number");
goTo.marker("referenceInGlobalScope");
verify.quickInfoIs("(a: number): string");
verify.quickInfoIs("(a: number) => string");

View file

@ -19,7 +19,7 @@ verify.completionListContains("bar");
verify.completionListContains("break");
verify.completionListContains("any");
verify.completionListContains("$");
verify.completionListContains("\\u0062");
verify.completionListContains("b");
// Nothing else should show up
verify.memberListCount(5);

View file

@ -11,4 +11,4 @@
goTo.marker();
verify.memberListContains("bar", 'any');
verify.memberListContains("foo", '(bar: any): any');
verify.memberListContains("foo", '(bar: any) => any');

View file

@ -0,0 +1,11 @@
/// <reference path="fourslash.ts" />
// Ensure kind is set correctelly on completions of a generic symbol
////var a = [1,2,3];
////a./**/
goTo.marker();
verify.memberListContains('length', "number", /*docComments*/ undefined, /*fullSymbolName*/ undefined,/*kind*/ "property");
verify.memberListContains('toString', "() => string", /*docComments*/ undefined, /*fullSymbolName*/ undefined,/*kind*/ "method");

View file

@ -0,0 +1,17 @@
/// <reference path="fourslash.ts"/>
////class Foo {
//// private y;
//// constructor(private x) {}
//// method() { this./*1*/; }
////}
////var f:Foo;
////f./*2*/
goTo.marker("1");
verify.memberListContains("y");
verify.memberListContains("x");
goTo.marker("2");
verify.not.memberListContains("x");
verify.not.memberListContains("y");

View file

@ -0,0 +1,16 @@
/// <reference path='fourslash.ts'/>
////var x = 0;
////
////with ({}) {
//// var y = x; // Reference of x here should not be picked
//// /*2*/y++; // also reference for y should be ignored
////}
////
////x = /*1*/x + 1;
goTo.marker('1');
verify.referencesCountIs(3);
goTo.marker('2');
verify.referencesCountIs(1);

View file

@ -1,11 +1,11 @@
/// <reference path='fourslash.ts'/>
////interface IFoo {
//// x: number;
//// y: string;
////}
////
////function foo<S, T extends IFoo, U extends T, V extends U>() {
/// <reference path='fourslash.ts'/>
////interface IFoo {
//// x: number;
//// y: string;
////}
////
////function foo<S, T extends IFoo, U extends Object, V extends IFoo>() {
//// var s:S, t: T, u: U, v: V;
//// s./*S*/; // no constraint, no completion
//// t./*T*/; // IFoo
@ -22,9 +22,8 @@ verify.memberListContains("y", "string");
verify.memberListCount(2);
goTo.marker("U");
verify.memberListContains("x", "number");
verify.memberListContains("y", "string");
verify.memberListCount(2);
verify.memberListContains("toString", "() => string");
verify.memberListCount(7); // constructor, toString, toLocaleString, valueOf, hasOwnProperty, isPrototypeOf, propertyIsEnumerable
goTo.marker("V");
verify.memberListContains("x", "number");

View file

@ -1,5 +1,5 @@
/// <reference path='fourslash.ts'/>
/// <reference path='fourslash.ts'/>
////class A {
//// foo(): string { return ''; }
////}
@ -10,7 +10,7 @@
//// }
////}
////
////class C<U extends T, T extends A> {
////class C<U extends A, T extends A> {
//// x: U;
//// y = this.x./**/ // completion list here
////}

View file

@ -0,0 +1,18 @@
/// <reference path='fourslash.ts'/>
////module M {
//// enum E {
//// A, B
//// }
//// enum E {
//// C = 0, D
//// }
//// var x = E./*1*/
////}
goTo.marker('1');
verify.memberListContains('A', 'E', undefined, "E.A");
verify.memberListContains('B', 'E', undefined, "E.B");
verify.memberListContains('C', 'E', undefined, "E.C");
verify.memberListContains('D', 'E', undefined, "E.D");

View file

@ -15,8 +15,10 @@ goTo.marker('1');
verify.memberListIsEmpty();
goTo.marker('2');
// Only keywords should show in completion, no members or types
verify.not.completionListContains("foo");
verify.not.completionListContains("f");
verify.not.completionListContains("c");
verify.not.completionListContains("d");
verify.not.completionListContains("x");
verify.not.completionListContains("Object");

View file

@ -0,0 +1,12 @@
/// <reference path='fourslash.ts'/>
////interface IFoo {
//// a: number;
////}
////
////with (x) {
//// var y: IFoo = { /*1*/ };
////}
goTo.marker('1');
verify.memberListIsEmpty();

View file

@ -0,0 +1,7 @@
/// <reference path='fourslash.ts'/>
////var x = { a: 0 };
////with(x./*1*/
goTo.marker('1');
verify.memberListContains("a");

View file

@ -11,5 +11,5 @@
goTo.marker();
verify.memberListCount(2);
verify.memberListContains('pubMeth', '(): void');
verify.memberListContains('pubMeth', '() => void');
verify.memberListContains('pubProp', 'number');

View file

@ -16,9 +16,9 @@
// Verify the memberlist of module when the following line has a keyword
goTo.marker('namedType');
verify.completionListContains('C1', 'TypeModule1.C1');
verify.completionListContains('C2', 'TypeModule1.C2');
verify.completionListContains('C1');
verify.completionListContains('C2');
goTo.marker('dotedExpression');
verify.completionListContains('C1', 'TypeModule1.C1');
verify.completionListContains('C2', 'TypeModule1.C2');
verify.completionListContains('C1');
verify.completionListContains('C2');

View file

@ -8,6 +8,6 @@
////}
goTo.marker();
verify.memberListContains('privMeth', '(): void');
verify.memberListContains('pubMeth', '(): void');
verify.memberListContains('privMeth', '() => void');
verify.memberListContains('pubMeth', '() => void');
verify.memberListContains('pubProp', 'number');

View file

@ -1,3 +1,3 @@
//// // [|TODO|]
debugger;
verify.todoCommentsInCurrentFile(["TODO"]);

View file

@ -2,5 +2,5 @@
//// [|todo 1|]
//// [|hack 2|]
//// */
debugger;
verify.todoCommentsInCurrentFile(["TODO", "HACK"]);

View file

@ -2,5 +2,5 @@
//// [|TODO(jason) 1|]
//// [|HACK 2|]
//// */
debugger;
verify.todoCommentsInCurrentFile(["TODO(jason)", "HACK"]);

View file

@ -2,5 +2,5 @@
//// [|TODO(jason) 1|]
//// [|HACK 2|]
//// */
debugger;
verify.todoCommentsInCurrentFile(["HACK", "TODO(jason)"]);

View file

@ -1,4 +1,3 @@
//// TODO
debugger;
verify.todoCommentsInCurrentFile(["TODO"]);

View file

@ -1,3 +1,3 @@
//// BAR // [|TODO|]
debugger;
verify.todoCommentsInCurrentFile(["TODO"]);

View file

@ -1,3 +1,3 @@
//// "// HACK 1";
debugger;
verify.todoCommentsInCurrentFile(["TODO(jason)", "HACK"]);

View file

@ -1,3 +1,3 @@
//// //// [|HACK 1|]
debugger;
verify.todoCommentsInCurrentFile(["TODO(jason)", "HACK"]);

View file

@ -1,3 +1,3 @@
//// /**** [|HACK 1 |]*/ a
debugger;
verify.todoCommentsInCurrentFile(["TODO(jason)", "HACK"]);

View file

@ -1,3 +1,3 @@
//// // not TODO
debugger;
verify.todoCommentsInCurrentFile(["TODO"]);

View file

@ -1,3 +1,3 @@
//// // [|TODO with stuff|]
debugger;
verify.todoCommentsInCurrentFile(["TODO"]);

View file

@ -1,3 +1,3 @@
//// // TODOnomatch
debugger;
verify.todoCommentsInCurrentFile(["TODO"]);

View file

@ -2,5 +2,5 @@
//// [|TODO 1|]
//// [|TODO 2|]
//// */
debugger;
verify.todoCommentsInCurrentFile(["TODO"]);

View file

@ -2,5 +2,5 @@
//// * [|TODO 1|]
//// * [|TODO 2|]
//// */
debugger;
verify.todoCommentsInCurrentFile(["TODO"]);

View file

@ -2,5 +2,5 @@
//// [|TODO 1|]
//// [|HACK 2|]
//// */
debugger;
verify.todoCommentsInCurrentFile(["TODO", "HACK"]);

View file

@ -2,5 +2,5 @@
//// [|HACK 1|]
//// [|TODO 2|]
//// */
debugger;
verify.todoCommentsInCurrentFile(["TODO", "HACK"]);

View file

@ -2,5 +2,5 @@
//// [|TODO HACK|]
//// [|HACK TODO|]
//// */
debugger;
verify.todoCommentsInCurrentFile(["TODO", "HACK"]);

View file

@ -1,18 +0,0 @@
/// <reference path='fourslash.ts'/>
////module M {
//// enum E {
//// A, B
//// }
//// enum E {
//// C = 0, D
//// }
//// var x = E./*1*/
////}
goTo.marker('1');
verify.memberListContains('A', 'E', undefined, "M.E.A");
verify.memberListContains('B', 'E', undefined, "M.E.B");
verify.memberListContains('C', 'E', undefined, "M.E.C");
verify.memberListContains('D', 'E', undefined, "M.E.D");

View file

@ -170,8 +170,8 @@ describe('Colorization', function () {
it("classifies keyword after a dot on previous line", function () {
test("var",
ts.EndOfLineState.EndingWithDotToken,
identifier("var"),
ts.EndOfLineState.Start,
keyword("var"),
finalEndOfLineState(ts.EndOfLineState.Start));
});
});