diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 18fd8c711b8..3622f4cda2f 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -380,6 +380,7 @@ module ts { break; case SyntaxKind.Property: case SyntaxKind.PropertyAssignment: + case SyntaxKind.ShorthandPropertyAssignment: bindDeclaration(node, SymbolFlags.Property, SymbolFlags.PropertyExcludes, /*isBlockScopeContainer*/ false); break; case SyntaxKind.EnumMember: diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0e42f2eb4ee..e642fcce944 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -93,6 +93,7 @@ module ts { getReturnTypeOfSignature: getReturnTypeOfSignature, getSymbolsInScope: getSymbolsInScope, getSymbolInfo: getSymbolInfo, + getShorthandAssignmentValueSymbol: getShorthandAssignmentValueSymbol, getTypeOfNode: getTypeOfNode, typeToString: typeToString, getSymbolDisplayBuilder: getSymbolDisplayBuilder, @@ -109,6 +110,7 @@ module ts { getAliasedSymbol: resolveImport, isUndefinedSymbol: symbol => symbol === undefinedSymbol, isArgumentsSymbol: symbol => symbol === argumentsSymbol, + hasEarlyErrors: hasEarlyErrors, isEmitBlocked: isEmitBlocked }; @@ -1665,6 +1667,13 @@ module ts { } return type; } + + // If it is a short-hand property assignment; Use the type of the identifier + if (declaration.kind === SyntaxKind.ShorthandPropertyAssignment) { + var type = checkIdentifier(declaration.name); + return type + } + // Rest parameters default to type any[], other parameters default to type any var type = declaration.flags & NodeFlags.Rest ? createArrayType(anyType) : anyType; checkImplicitAny(type); @@ -2399,7 +2408,7 @@ module ts { } // Return the symbol for the property with the given name in the given type. Creates synthetic union properties when - // necessary, maps primtive types and type parameters are to their apparent types, and augments with properties from + // necessary, maps primitive types and type parameters are to their apparent types, and augments with properties from // Object and Function as appropriate. function getPropertyOfType(type: Type, name: string): Symbol { if (type.flags & TypeFlags.Union) { @@ -2434,7 +2443,7 @@ module ts { } // Return the signatures of the given kind in the given type. Creates synthetic union signatures when necessary and - // maps primtive types and type parameters are to their apparent types. + // maps primitive types and type parameters are to their apparent types. function getSignaturesOfType(type: Type, kind: SignatureKind): Signature[] { return getSignaturesOfObjectOrUnionType(getApparentType(type), kind); } @@ -2447,7 +2456,7 @@ module ts { } // Return the index type of the given kind in the given type. Creates synthetic union index types when necessary and - // maps primtive types and type parameters are to their apparent types. + // maps primitive types and type parameters are to their apparent types. function getIndexTypeOfType(type: Type, kind: IndexKind): Type { return getIndexTypeOfObjectOrUnionType(getApparentType(type), kind); } @@ -3225,9 +3234,9 @@ module ts { // TYPE CHECKING - var subtypeRelation: Map = {}; - var assignableRelation: Map = {}; - var identityRelation: Map = {}; + var subtypeRelation: Map = {}; + var assignableRelation: Map = {}; + var identityRelation: Map = {}; function isTypeIdenticalTo(source: Type, target: Type): boolean { return checkTypeRelatedTo(source, target, identityRelation, /*errorNode*/ undefined); @@ -3262,7 +3271,7 @@ module ts { function checkTypeRelatedTo( source: Type, target: Type, - relation: Map, + relation: Map, errorNode: Node, headMessage?: DiagnosticMessage, containingMessageChain?: DiagnosticMessageChain): boolean { @@ -3270,6 +3279,7 @@ module ts { var errorInfo: DiagnosticMessageChain; var sourceStack: ObjectType[]; var targetStack: ObjectType[]; + var maybeStack: Map[]; var expandingFlags: number; var depth = 0; var overflow = false; @@ -3428,12 +3438,12 @@ module ts { var id = source.id + "," + target.id; var related = relation[id]; if (related !== undefined) { - return related; + return related ? Ternary.True : Ternary.False; } if (depth > 0) { for (var i = 0; i < depth; i++) { // If source and target are already being compared, consider them related with assumptions - if (source === sourceStack[i] && target === targetStack[i]) { + if (maybeStack[i][id]) { return Ternary.Maybe; } } @@ -3445,16 +3455,19 @@ module ts { else { sourceStack = []; targetStack = []; + maybeStack = []; expandingFlags = 0; } sourceStack[depth] = source; targetStack[depth] = target; + maybeStack[depth] = {}; + maybeStack[depth][id] = true; depth++; var saveExpandingFlags = expandingFlags; if (!(expandingFlags & 1) && isDeeplyNestedGeneric(source, sourceStack)) expandingFlags |= 1; if (!(expandingFlags & 2) && isDeeplyNestedGeneric(target, targetStack)) expandingFlags |= 2; if (expandingFlags === 3) { - var result = Ternary.True; + var result = Ternary.Maybe; } else { var result = propertiesRelatedTo(source, target, reportErrors); @@ -3473,9 +3486,18 @@ module ts { } expandingFlags = saveExpandingFlags; depth--; - // Only cache results that are free of assumptions - if (result !== Ternary.Maybe) { - relation[id] = result; + if (result) { + var maybeCache = maybeStack[depth]; + // If result is definitely true, copy assumptions to global cache, else copy to next level up + var destinationCache = result === Ternary.True || depth === 0 ? relation : maybeStack[depth - 1]; + for (var p in maybeCache) { + destinationCache[p] = maybeCache[p]; + } + } + else { + // A false result goes straight into global cache (when something is false under assumptions it + // will also be false without assumptions) + relation[id] = false; } return result; } @@ -5000,7 +5022,15 @@ module ts { if (hasProperty(members, id)) { var member = members[id]; if (member.flags & SymbolFlags.Property) { - var type = checkExpression((member.declarations[0]).initializer, contextualMapper); + var memberDecl = member.declarations[0]; + var type: Type; + if (memberDecl.kind === SyntaxKind.PropertyAssignment) { + type = checkExpression(memberDecl.initializer, contextualMapper); + } + else { + Debug.assert(memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment); + type = checkExpression(memberDecl.name, contextualMapper); + } var prop = createSymbol(SymbolFlags.Property | SymbolFlags.Transient | member.flags, member.name); prop.declarations = member.declarations; prop.parent = member.parent; @@ -5403,7 +5433,7 @@ module ts { return typeArgumentsAreAssignable; } - function checkApplicableSignature(node: CallLikeExpression, args: Node[], signature: Signature, relation: Map, excludeArgument: boolean[], reportErrors: boolean) { + function checkApplicableSignature(node: CallLikeExpression, args: Node[], signature: Signature, relation: Map, excludeArgument: boolean[], reportErrors: boolean) { for (var i = 0; i < args.length; i++) { var arg = args[i]; var argType: Type; @@ -5597,7 +5627,7 @@ module ts { return resolveErrorCall(node); - function chooseOverload(candidates: Signature[], relation: Map) { + function chooseOverload(candidates: Signature[], relation: Map) { for (var i = 0; i < candidates.length; i++) { if (!hasCorrectArity(node, args, candidates[i])) { continue; @@ -8816,6 +8846,16 @@ module ts { return undefined; } + function getShorthandAssignmentValueSymbol(location: Node): Symbol { + // The function returns a value symbol of an identifier in the short-hand property assignment. + // This is necessary as an identifier in short-hand property assignment can contains two meaning: + // property name and property value. + if (location && location.kind === SyntaxKind.ShorthandPropertyAssignment) { + return resolveEntityName(location, (location).name, SymbolFlags.Value); + } + return undefined; + } + function getTypeOfNode(node: Node): Type { if (isInsideWithStatementBody(node)) { // We cannot answer semantic questions within a with block, do not proceed any further diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index bae908b2774..acb7aaaed26 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -122,6 +122,7 @@ module ts { let_declarations_can_only_be_declared_inside_a_block: { code: 1157, category: DiagnosticCategory.Error, key: "'let' declarations can only be declared inside a block." }, Invalid_template_literal_expected: { code: 1158, category: DiagnosticCategory.Error, key: "Invalid template literal; expected '}'" }, Tagged_templates_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1159, category: DiagnosticCategory.Error, key: "Tagged templates are only available when targeting ECMAScript 6 and higher." }, + A_object_member_cannot_be_declared_optional: { code: 1160, category: DiagnosticCategory.Error, key: "A object member cannot be declared optional." }, Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." }, Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." }, Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 93638b6dade..9145b345b2d 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -480,6 +480,11 @@ "code": 1159 }, + "A object member cannot be declared optional.": { + "category": "Error", + "code": 1160 + }, + "Duplicate identifier '{0}'.": { "category": "Error", "code": 2300 diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 00d958604c7..fe80e48dc64 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -927,13 +927,14 @@ module ts { } } - function isNonExpressionIdentifier(node: Identifier) { + function isNotExpressionIdentifier(node: Identifier) { var parent = node.parent; switch (parent.kind) { case SyntaxKind.Parameter: case SyntaxKind.VariableDeclaration: case SyntaxKind.Property: case SyntaxKind.PropertyAssignment: + case SyntaxKind.ShorthandPropertyAssignment: case SyntaxKind.EnumMember: case SyntaxKind.Method: case SyntaxKind.FunctionDeclaration: @@ -957,17 +958,24 @@ module ts { } } - function emitIdentifier(node: Identifier) { - if (!isNonExpressionIdentifier(node)) { - var prefix = resolver.getExpressionNamePrefix(node); - if (prefix) { - write(prefix); - write("."); - } + function emitExpressionIdentifier(node: Identifier) { + var prefix = resolver.getExpressionNamePrefix(node); + if (prefix) { + write(prefix); + write("."); } write(getSourceTextOfLocalNode(node)); } + function emitIdentifier(node: Identifier) { + if (!isNotExpressionIdentifier(node)) { + emitExpressionIdentifier(node); + } + else { + write(getSourceTextOfLocalNode(node)); + } + } + function emitThis(node: Node) { if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.LexicalThis) { write("_this"); @@ -1033,6 +1041,36 @@ module ts { emitTrailingComments(node); } + function emitShortHandPropertyAssignment(node: ShortHandPropertyDeclaration) { + function emitAsNormalPropertyAssignment() { + emitLeadingComments(node); + // Emit identifier as an identifier + emit(node.name); + write(": "); + // Even though this is stored as identified because it is in short-hand property assignment, + // treated it as expression + emitExpressionIdentifier(node.name); + emitTrailingComments(node); + } + + if (compilerOptions.target < ScriptTarget.ES6) { + emitAsNormalPropertyAssignment(); + } + else if (compilerOptions.target >= ScriptTarget.ES6) { + // If short-hand property has a prefix, then regardless of the target version, we will emit it as normal property assignment + var prefix = resolver.getExpressionNamePrefix(node.name); + if (prefix) { + emitAsNormalPropertyAssignment(); + } + // If short-hand property has no prefix, emit it as short-hand. + else { + emitLeadingComments(node); + emit(node.name); + emitTrailingComments(node); + } + } + } + function tryEmitConstantValue(node: PropertyAccess | IndexedAccess): boolean { var constantValue = resolver.getConstantValue(node); if (constantValue !== undefined) { @@ -2250,6 +2288,8 @@ module ts { return emitObjectLiteral(node); case SyntaxKind.PropertyAssignment: return emitPropertyAssignment(node); + case SyntaxKind.ShorthandPropertyAssignment: + return emitShortHandPropertyAssignment(node); case SyntaxKind.PropertyAccess: return emitPropertyAccess(node); case SyntaxKind.IndexedAccess: diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 7db9b9101da..c4b19fcb7af 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -202,6 +202,7 @@ module ts { child((node).initializer); case SyntaxKind.Property: case SyntaxKind.PropertyAssignment: + case SyntaxKind.ShorthandPropertyAssignment: return child((node).name) || child((node).type) || child((node).initializer); @@ -589,6 +590,7 @@ module ts { case SyntaxKind.VariableDeclaration: case SyntaxKind.Property: case SyntaxKind.PropertyAssignment: + case SyntaxKind.ShorthandPropertyAssignment: case SyntaxKind.EnumMember: case SyntaxKind.Method: case SyntaxKind.FunctionDeclaration: @@ -2743,10 +2745,14 @@ module ts { return finishNode(node); } - function parsePropertyAssignment(): PropertyDeclaration { - var node = createNode(SyntaxKind.PropertyAssignment); - node.name = parsePropertyName(); + function parsePropertyAssignment(): Declaration { + var nodePos = scanner.getStartPos(); + var nameToken = token; + var propertyName = parsePropertyName(); + var node: Declaration; if (token === SyntaxKind.OpenParenToken || token === SyntaxKind.LessThanToken) { + node = createNode(SyntaxKind.PropertyAssignment, nodePos); + node.name = propertyName; var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false); var body = parseBody(/* ignoreMissingOpenBrace */ false); // do not propagate property name as name for function expression @@ -2754,11 +2760,26 @@ module ts { // var x = 1; // var y = { x() { } } // otherwise this will bring y.x into the scope of x which is incorrect - node.initializer = makeFunctionExpression(SyntaxKind.FunctionExpression, node.pos, undefined, sig, body); + (node).initializer = makeFunctionExpression(SyntaxKind.FunctionExpression, node.pos, undefined, sig, body); + return finishNode(node); + } + // Disallow optional property assignment + if (token === SyntaxKind.QuestionToken) { + var questionStart = scanner.getTokenPos(); + grammarErrorAtPos(questionStart, scanner.getStartPos() - questionStart, Diagnostics.A_object_member_cannot_be_declared_optional); + nextToken(); + } + + // Parse to check if it is short-hand property assignment or normal property assignment + if (token !== SyntaxKind.ColonToken && nameToken === SyntaxKind.Identifier) { + node = createNode(SyntaxKind.ShorthandPropertyAssignment, nodePos); + node.name = propertyName; } else { + node = createNode(SyntaxKind.PropertyAssignment, nodePos); + node.name = propertyName; parseExpected(SyntaxKind.ColonToken); - node.initializer = parseAssignmentExpression(false); + (node).initializer = parseAssignmentExpression(false); } return finishNode(node); } @@ -2808,6 +2829,9 @@ module ts { if (p.kind === SyntaxKind.PropertyAssignment) { currentKind = Property; } + else if (p.kind === SyntaxKind.ShorthandPropertyAssignment) { + currentKind = Property; + } else if (p.kind === SyntaxKind.GetAccessor) { currentKind = GetAccessor; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index c890d7a2aaf..4caa5a47633 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -167,6 +167,7 @@ module ts { ArrayLiteral, ObjectLiteral, PropertyAssignment, + ShorthandPropertyAssignment, PropertyAccess, IndexedAccess, CallExpression, @@ -335,6 +336,10 @@ module ts { initializer?: Expression; } + export interface ShortHandPropertyDeclaration extends Declaration { + name: Identifier; + } + export interface ParameterDeclaration extends VariableDeclaration { } /** @@ -719,6 +724,7 @@ module ts { getReturnTypeOfSignature(signature: Signature): Type; getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[]; getSymbolInfo(node: Node): Symbol; + getShorthandAssignmentValueSymbol(location: Node): Symbol; getTypeOfNode(node: Node): Type; typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string; symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): string; diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index ffb0ed16cb8..144cc9745d9 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -215,7 +215,7 @@ module FourSlash { } public setCancelled(numberOfCalls: number = 0): void { - TypeScript.Debug.assert(numberOfCalls >= 0); + ts.Debug.assert(numberOfCalls >= 0); this.numberOfCallsBeforeCancellation = numberOfCalls; } @@ -239,7 +239,7 @@ module FourSlash { // This function creates IScriptSnapshot object for testing getPreProcessedFileInfo // Return object may lack some functionalities for other purposes. - function createScriptSnapShot(sourceText: string): TypeScript.IScriptSnapshot { + function createScriptSnapShot(sourceText: string): ts.IScriptSnapshot { return { getText: (start: number, end: number) => { return sourceText.substr(start, end - start); @@ -250,8 +250,8 @@ module FourSlash { getLineStartPositions: () => { return []; }, - getChangeRange: (oldSnapshot: TypeScript.IScriptSnapshot) => { - return undefined; + getChangeRange: (oldSnapshot: ts.IScriptSnapshot) => { + return undefined; } }; } @@ -262,7 +262,7 @@ module FourSlash { private languageService: ts.LanguageService; // A reference to the language service's compiler state's compiler instance - private compiler: () => { getSyntaxTree(fileName: string): TypeScript.SyntaxTree; getSourceUnit(fileName: string): TypeScript.SourceUnitSyntax; }; + private compiler: () => { getSyntaxTree(fileName: string): ts.SourceFile }; // The current caret position in the active file public currentCaretPosition = 0; @@ -403,8 +403,9 @@ module FourSlash { public goToPosition(pos: number) { this.currentCaretPosition = pos; - var lineCharPos = TypeScript.LineMap1.fromString(this.getCurrentFileContent()).getLineAndCharacterFromPosition(pos); - this.scenarioActions.push(''); + var lineStarts = ts.computeLineStarts(this.getCurrentFileContent()); + var lineCharPos = ts.getLineAndCharacterOfPosition(lineStarts, pos); + this.scenarioActions.push(''); } public moveCaretRight(count = 1) { @@ -1017,7 +1018,7 @@ module FourSlash { private alignmentForExtraInfo = 50; - private spanInfoToString(pos: number, spanInfo: TypeScript.TextSpan, prefixString: string) { + private spanInfoToString(pos: number, spanInfo: ts.TextSpan, prefixString: string) { var resultString = "SpanInfo: " + JSON.stringify(spanInfo); if (spanInfo) { var spanString = this.activeFile.content.substr(spanInfo.start(), spanInfo.length()); @@ -1034,7 +1035,7 @@ module FourSlash { return resultString; } - private baselineCurrentFileLocations(getSpanAtPos: (pos: number) => TypeScript.TextSpan): string { + private baselineCurrentFileLocations(getSpanAtPos: (pos: number) => ts.TextSpan): string { var fileLineMap = ts.computeLineStarts(this.activeFile.content); var nextLine = 0; var resultString = ""; @@ -1748,14 +1749,14 @@ module FourSlash { public verifySemanticClassifications(expected: { classificationType: string; text: string }[]) { var actual = this.languageService.getSemanticClassifications(this.activeFile.fileName, - new TypeScript.TextSpan(0, this.activeFile.content.length)); + new ts.TextSpan(0, this.activeFile.content.length)); this.verifyClassifications(expected, actual); } public verifySyntacticClassifications(expected: { classificationType: string; text: string }[]) { var actual = this.languageService.getSyntacticClassifications(this.activeFile.fileName, - new TypeScript.TextSpan(0, this.activeFile.content.length)); + new ts.TextSpan(0, this.activeFile.content.length)); this.verifyClassifications(expected, actual); } @@ -1789,7 +1790,7 @@ module FourSlash { for (var i = 0; i < spans.length; i++) { var expectedSpan = spans[i]; var actualComment = actual[i]; - var actualCommentSpan = new TypeScript.TextSpan(actualComment.position, actualComment.message.length); + var actualCommentSpan = new ts.TextSpan(actualComment.position, actualComment.message.length); if (expectedSpan.start !== actualCommentSpan.start() || expectedSpan.end !== actualCommentSpan.end()) { this.raiseError('verifyOutliningSpans failed - span ' + (i + 1) + ' expected: (' + expectedSpan.start + ',' + expectedSpan.end + '), actual: (' + actualCommentSpan.start() + ',' + actualCommentSpan.end() + ')'); @@ -2240,11 +2241,12 @@ module FourSlash { (fn, contents) => result = contents, ts.ScriptTarget.Latest, sys.useCaseSensitiveFileNames); - var program = ts.createProgram([Harness.Compiler.fourslashFilename, fileName], { out: "fourslashTestOutput.js" }, host); + // TODO (drosen): We need to enforce checking on these tests. + var program = ts.createProgram([Harness.Compiler.fourslashFilename, fileName], { out: "fourslashTestOutput.js", noResolve: true }, host); var checker = ts.createTypeChecker(program, /*fullTypeCheckMode*/ true); checker.checkProgram(); - var errs = checker.getDiagnostics(program.getSourceFile(fileName)); + var errs = program.getDiagnostics().concat(checker.getDiagnostics()); if (errs.length > 0) { throw new Error('Error compiling ' + fileName + ': ' + errs.map(e => e.messageText).join('\r\n')); } diff --git a/src/harness/harness.ts b/src/harness/harness.ts index d5eaa3828a1..aee0ef3c534 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -585,7 +585,7 @@ module Harness { return defaultLibSourceFile; } // Don't throw here -- the compiler might be looking for a test that actually doesn't exist as part of the TC - return null; + return undefined; } }, getDefaultLibFilename: () => defaultLibFileName, diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 6163dfd0e79..d3082a17ba2 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -4,8 +4,8 @@ module Harness.LanguageService { export class ScriptInfo { public version: number = 1; - public editRanges: { length: number; textChangeRange: TypeScript.TextChangeRange; }[] = []; - public lineMap: TypeScript.LineMap = null; + public editRanges: { length: number; textChangeRange: ts.TextChangeRange; }[] = []; + public lineMap: number[] = null; constructor(public fileName: string, public content: string, public isOpen = true) { this.setContent(content); @@ -13,7 +13,7 @@ module Harness.LanguageService { private setContent(content: string): void { this.content = content; - this.lineMap = TypeScript.LineMap1.fromString(content); + this.lineMap = ts.computeLineStarts(content); } public updateContent(content: string): void { @@ -32,30 +32,30 @@ module Harness.LanguageService { // Store edit range + new length of script this.editRanges.push({ length: this.content.length, - textChangeRange: new TypeScript.TextChangeRange( - TypeScript.TextSpan.fromBounds(minChar, limChar), newText.length) + textChangeRange: new ts.TextChangeRange( + ts.TextSpan.fromBounds(minChar, limChar), newText.length) }); // Update version # this.version++; } - public getTextChangeRangeBetweenVersions(startVersion: number, endVersion: number): TypeScript.TextChangeRange { + public getTextChangeRangeBetweenVersions(startVersion: number, endVersion: number): ts.TextChangeRange { if (startVersion === endVersion) { // No edits! - return TypeScript.TextChangeRange.unchanged; + return ts.TextChangeRange.unchanged; } var initialEditRangeIndex = this.editRanges.length - (this.version - startVersion); var lastEditRangeIndex = this.editRanges.length - (this.version - endVersion); var entries = this.editRanges.slice(initialEditRangeIndex, lastEditRangeIndex); - return TypeScript.TextChangeRange.collapseChangesAcrossMultipleVersions(entries.map(e => e.textChangeRange)); + return ts.TextChangeRange.collapseChangesAcrossMultipleVersions(entries.map(e => e.textChangeRange)); } } class ScriptSnapshotShim implements ts.ScriptSnapshotShim { - private lineMap: TypeScript.LineMap = null; + private lineMap: number[] = null; private textSnapshot: string; private version: number; @@ -74,10 +74,10 @@ module Harness.LanguageService { public getLineStartPositions(): string { if (this.lineMap === null) { - this.lineMap = TypeScript.LineMap1.fromString(this.textSnapshot); + this.lineMap = ts.computeLineStarts(this.textSnapshot); } - return JSON.stringify(this.lineMap.lineStarts()); + return JSON.stringify(this.lineMap); } public getChangeRange(oldScript: ts.ScriptSnapshotShim): string { @@ -108,7 +108,7 @@ module Harness.LanguageService { public acquireDocument( fileName: string, compilationSettings: ts.CompilerOptions, - scriptSnapshot: TypeScript.IScriptSnapshot, + scriptSnapshot: ts.IScriptSnapshot, version: string, isOpen: boolean): ts.SourceFile { return ts.createSourceFile(fileName, scriptSnapshot.getText(0, scriptSnapshot.getLength()), compilationSettings.target, version, isOpen); @@ -118,10 +118,10 @@ module Harness.LanguageService { document: ts.SourceFile, fileName: string, compilationSettings: ts.CompilerOptions, - scriptSnapshot: TypeScript.IScriptSnapshot, + scriptSnapshot: ts.IScriptSnapshot, version: string, isOpen: boolean, - textChangeRange: TypeScript.TextChangeRange + textChangeRange: ts.TextChangeRange ): ts.SourceFile { return document.update(scriptSnapshot, version, isOpen, textChangeRange); } @@ -263,13 +263,13 @@ module Harness.LanguageService { } /** Parse file given its source text */ - public parseSourceText(fileName: string, sourceText: TypeScript.IScriptSnapshot): TypeScript.SourceUnitSyntax { - return TypeScript.Parser.parse(fileName, TypeScript.SimpleText.fromScriptSnapshot(sourceText), ts.ScriptTarget.Latest, TypeScript.isDTSFile(fileName)).sourceUnit(); + public parseSourceText(fileName: string, sourceText: ts.IScriptSnapshot): ts.SourceFile { + return ts.createSourceFile(fileName, sourceText.getText(0, sourceText.getLength()), ts.ScriptTarget.Latest, "1", true); } /** Parse a file on disk given its fileName */ public parseFile(fileName: string) { - var sourceText = TypeScript.ScriptSnapshot.fromString(Harness.IO.readFile(fileName)); + var sourceText = ts.ScriptSnapshot.fromString(Harness.IO.readFile(fileName)); return this.parseSourceText(fileName, sourceText); } @@ -283,22 +283,22 @@ module Harness.LanguageService { assert.isTrue(line >= 1); assert.isTrue(col >= 1); - return script.lineMap.getPosition(line - 1, col - 1); + return ts.getPositionFromLineAndCharacter(script.lineMap, line, col); } /** * @param line 0 based index * @param col 0 based index */ - public positionToZeroBasedLineCol(fileName: string, position: number): TypeScript.ILineAndCharacter { + public positionToZeroBasedLineCol(fileName: string, position: number): ts.LineAndCharacter { var script: ScriptInfo = this.fileNameToScript[fileName]; assert.isNotNull(script); - var result = script.lineMap.getLineAndCharacterFromPosition(position); + var result = ts.getLineAndCharacterOfPosition(script.lineMap, position); - assert.isTrue(result.line() >= 0); - assert.isTrue(result.character() >= 0); - return { line: result.line(), character: result.character() }; + assert.isTrue(result.line >= 1); + assert.isTrue(result.character >= 1); + return { line: result.line - 1, character: result.character - 1 }; } /** Verify that applying edits to sourceFileName result in the content of the file baselineFileName */ diff --git a/src/services/breakpoints.ts b/src/services/breakpoints.ts index f8688b3c479..7867751a96f 100644 --- a/src/services/breakpoints.ts +++ b/src/services/breakpoints.ts @@ -38,25 +38,25 @@ module ts.BreakpointResolver { return spanInNode(tokenAtLocation); function textSpan(startNode: Node, endNode?: Node) { - return TypeScript.TextSpan.fromBounds(startNode.getStart(), (endNode || startNode).getEnd()); + return TextSpan.fromBounds(startNode.getStart(), (endNode || startNode).getEnd()); } - function spanInNodeIfStartsOnSameLine(node: Node, otherwiseOnNode?: Node): TypeScript.TextSpan { + function spanInNodeIfStartsOnSameLine(node: Node, otherwiseOnNode?: Node): TextSpan { if (node && lineOfPosition === sourceFile.getLineAndCharacterFromPosition(node.getStart()).line) { return spanInNode(node); } return spanInNode(otherwiseOnNode); } - function spanInPreviousNode(node: Node): TypeScript.TextSpan { + function spanInPreviousNode(node: Node): TextSpan { return spanInNode(findPrecedingToken(node.pos, sourceFile)); } - function spanInNextNode(node: Node): TypeScript.TextSpan { + function spanInNextNode(node: Node): TextSpan { return spanInNode(findNextToken(node, node.parent)); } - function spanInNode(node: Node): TypeScript.TextSpan { + function spanInNode(node: Node): TextSpan { if (node) { if (isExpression(node)) { if (node.parent.kind === SyntaxKind.DoStatement) { @@ -256,7 +256,7 @@ module ts.BreakpointResolver { } } - function spanInVariableDeclaration(variableDeclaration: VariableDeclaration): TypeScript.TextSpan { + function spanInVariableDeclaration(variableDeclaration: VariableDeclaration): TextSpan { // If declaration of for in statement, just set the span in parent if (variableDeclaration.parent.kind === SyntaxKind.ForInStatement) { return spanInNode(variableDeclaration.parent); @@ -301,7 +301,7 @@ module ts.BreakpointResolver { !!(parameter.flags & NodeFlags.Public) || !!(parameter.flags & NodeFlags.Private); } - function spanInParameterDeclaration(parameter: ParameterDeclaration): TypeScript.TextSpan { + function spanInParameterDeclaration(parameter: ParameterDeclaration): TextSpan { if (canHaveSpanInParameterDeclaration(parameter)) { return textSpan(parameter); } @@ -324,7 +324,7 @@ module ts.BreakpointResolver { (functionDeclaration.parent.kind === SyntaxKind.ClassDeclaration && functionDeclaration.kind !== SyntaxKind.Constructor); } - function spanInFunctionDeclaration(functionDeclaration: FunctionLikeDeclaration): TypeScript.TextSpan { + function spanInFunctionDeclaration(functionDeclaration: FunctionLikeDeclaration): TextSpan { // No breakpoints in the function signature if (!functionDeclaration.body) { return undefined; @@ -339,7 +339,7 @@ module ts.BreakpointResolver { return spanInNode(functionDeclaration.body); } - function spanInFunctionBlock(block: Block): TypeScript.TextSpan { + function spanInFunctionBlock(block: Block): TextSpan { var nodeForSpanInBlock = block.statements.length ? block.statements[0] : block.getLastToken(); if (canFunctionHaveSpanInWholeDeclaration(block.parent)) { return spanInNodeIfStartsOnSameLine(block.parent, nodeForSpanInBlock); @@ -348,7 +348,7 @@ module ts.BreakpointResolver { return spanInNode(nodeForSpanInBlock); } - function spanInBlock(block: Block): TypeScript.TextSpan { + function spanInBlock(block: Block): TextSpan { switch (block.parent.kind) { case SyntaxKind.ModuleDeclaration: if (getModuleInstanceState(block.parent) !== ModuleInstanceState.Instantiated) { @@ -370,7 +370,7 @@ module ts.BreakpointResolver { return spanInNode(block.statements[0]); } - function spanInForStatement(forStatement: ForStatement): TypeScript.TextSpan { + function spanInForStatement(forStatement: ForStatement): TextSpan { if (forStatement.declarations) { return spanInNode(forStatement.declarations[0]); } @@ -386,7 +386,7 @@ module ts.BreakpointResolver { } // Tokens: - function spanInOpenBraceToken(node: Node): TypeScript.TextSpan { + function spanInOpenBraceToken(node: Node): TextSpan { switch (node.parent.kind) { case SyntaxKind.EnumDeclaration: var enumDeclaration = node.parent; @@ -404,7 +404,7 @@ module ts.BreakpointResolver { return spanInNode(node.parent); } - function spanInCloseBraceToken(node: Node): TypeScript.TextSpan { + function spanInCloseBraceToken(node: Node): TextSpan { switch (node.parent.kind) { case SyntaxKind.ModuleBlock: // If this is not instantiated module block no bp span @@ -439,7 +439,7 @@ module ts.BreakpointResolver { } } - function spanInOpenParenToken(node: Node): TypeScript.TextSpan { + function spanInOpenParenToken(node: Node): TextSpan { if (node.parent.kind === SyntaxKind.DoStatement) { // Go to while keyword and do action instead return spanInPreviousNode(node); @@ -449,7 +449,7 @@ module ts.BreakpointResolver { return spanInNode(node.parent); } - function spanInCloseParenToken(node: Node): TypeScript.TextSpan { + function spanInCloseParenToken(node: Node): TextSpan { // Is this close paren token of parameter list, set span in previous token switch (node.parent.kind) { case SyntaxKind.FunctionExpression: @@ -473,7 +473,7 @@ module ts.BreakpointResolver { return spanInNode(node.parent); } - function spanInColonToken(node: Node): TypeScript.TextSpan { + function spanInColonToken(node: Node): TextSpan { // Is this : specifying return annotation of the function declaration if (isAnyFunction(node.parent) || node.parent.kind === SyntaxKind.PropertyAssignment) { return spanInPreviousNode(node); @@ -482,7 +482,7 @@ module ts.BreakpointResolver { return spanInNode(node.parent); } - function spanInGreaterThanOrLessThanToken(node: Node): TypeScript.TextSpan { + function spanInGreaterThanOrLessThanToken(node: Node): TextSpan { if (node.parent.kind === SyntaxKind.TypeAssertion) { return spanInNode((node.parent).operand); } @@ -490,7 +490,7 @@ module ts.BreakpointResolver { return spanInNode(node.parent); } - function spanInWhileKeyword(node: Node): TypeScript.TextSpan { + function spanInWhileKeyword(node: Node): TextSpan { if (node.parent.kind === SyntaxKind.DoStatement) { // Set span on while expression return textSpan(node, findNextToken((node.parent).expression, node.parent)); diff --git a/src/services/formatting.ts b/src/services/formatting.ts index dbe85fc4c64..91a3a362fda 100644 --- a/src/services/formatting.ts +++ b/src/services/formatting.ts @@ -834,7 +834,7 @@ module ts.formatting { } function newTextChange(start: number, len: number, newText: string): TextChange { - return { span: new TypeScript.TextSpan(start, len), newText: newText } + return { span: new TextSpan(start, len), newText: newText } } function recordDelete(start: number, len: number) { diff --git a/src/services/formatting/references.ts b/src/services/formatting/references.ts index 3d19b33d821..9f4b7e37436 100644 --- a/src/services/formatting/references.ts +++ b/src/services/formatting/references.ts @@ -13,6 +13,7 @@ // limitations under the License. // +/// /// /// /// diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts index 4b42591936e..2485945df0b 100644 --- a/src/services/formatting/rules.ts +++ b/src/services/formatting/rules.ts @@ -24,7 +24,7 @@ module ts.formatting { return name; } } - throw new Error(TypeScript.getDiagnosticMessage(TypeScript.DiagnosticCode.Unknown_rule, null)); + throw new Error("Unknown rule"); } [name: string]: any; diff --git a/src/services/formatting/rulesProvider.ts b/src/services/formatting/rulesProvider.ts index 1469e86971b..7ad1b65400c 100644 --- a/src/services/formatting/rulesProvider.ts +++ b/src/services/formatting/rulesProvider.ts @@ -22,7 +22,7 @@ module ts.formatting { private activeRules: Rule[]; private rulesMap: RulesMap; - constructor(private logger: TypeScript.Logger) { + constructor(private logger: Logger) { this.globalRules = new Rules(); } diff --git a/src/services/formatting/tokenSpan.ts b/src/services/formatting/tokenSpan.ts index 95f9bab3eee..1d8173a8227 100644 --- a/src/services/formatting/tokenSpan.ts +++ b/src/services/formatting/tokenSpan.ts @@ -16,7 +16,7 @@ /// module ts.formatting { - export class TokenSpan extends TypeScript.TextSpan { + export class TokenSpan extends TextSpan { constructor(public kind: SyntaxKind, start: number, length: number) { super(start, length); } diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index ca06d40fa88..c0ec80c98ea 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -1,5 +1,4 @@ /// -/// module ts.NavigationBar { export function getNavigationBarItems(sourceFile: SourceFile): ts.NavigationBarItem[] { @@ -257,7 +256,7 @@ module ts.NavigationBar { return !text || text.trim() === ""; } - function getNavigationBarItem(text: string, kind: string, kindModifiers: string, spans: TypeScript.TextSpan[], childItems: ts.NavigationBarItem[] = [], indent: number = 0): ts.NavigationBarItem { + function getNavigationBarItem(text: string, kind: string, kindModifiers: string, spans: TextSpan[], childItems: NavigationBarItem[] = [], indent: number = 0): NavigationBarItem { if (isEmpty(text)) { return undefined; } @@ -424,8 +423,8 @@ module ts.NavigationBar { function getNodeSpan(node: Node) { return node.kind === SyntaxKind.SourceFile - ? TypeScript.TextSpan.fromBounds(node.getFullStart(), node.getEnd()) - : TypeScript.TextSpan.fromBounds(node.getStart(), node.getEnd()); + ? TextSpan.fromBounds(node.getFullStart(), node.getEnd()) + : TextSpan.fromBounds(node.getStart(), node.getEnd()); } function getTextOfNode(node: Node): string { diff --git a/src/services/outliningElementsCollector.ts b/src/services/outliningElementsCollector.ts index aaaedb735ea..27f75b8d20e 100644 --- a/src/services/outliningElementsCollector.ts +++ b/src/services/outliningElementsCollector.ts @@ -24,8 +24,8 @@ module ts { * @param autoCollapse Whether or not this region should be automatically collapsed when * the 'Collapse to Definitions' command is invoked. */ - textSpan: TypeScript.TextSpan; - hintSpan: TypeScript.TextSpan; + textSpan: TextSpan; + hintSpan: TextSpan; bannerText: string; autoCollapse: boolean; } @@ -38,8 +38,8 @@ module ts { function addOutliningSpan(hintSpanNode: Node, startElement: Node, endElement: Node, autoCollapse: boolean) { if (hintSpanNode && startElement && endElement) { var span: OutliningSpan = { - textSpan: TypeScript.TextSpan.fromBounds(startElement.pos, endElement.end), - hintSpan: TypeScript.TextSpan.fromBounds(hintSpanNode.getStart(), hintSpanNode.end), + textSpan: TextSpan.fromBounds(startElement.pos, endElement.end), + hintSpan: TextSpan.fromBounds(hintSpanNode.getStart(), hintSpanNode.end), bannerText: collapseText, autoCollapse: autoCollapse }; @@ -86,7 +86,7 @@ module ts { else { // Block was a standalone block. In this case we want to only collapse // the span of the block, independent of any parent span. - var span = TypeScript.TextSpan.fromBounds(n.getStart(), n.end); + var span = TextSpan.fromBounds(n.getStart(), n.end); elements.push({ textSpan: span, hintSpan: span, diff --git a/src/services/services.ts b/src/services/services.ts index 1eed221d403..540a4b0b6c3 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -4,7 +4,7 @@ /// /// -/// +/// /// /// /// @@ -13,17 +13,6 @@ /// /// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// - module ts { export interface Node { getSourceFile(): SourceFile; @@ -70,11 +59,72 @@ module ts { } export interface SourceFile { - getScriptSnapshot(): TypeScript.IScriptSnapshot; + getScriptSnapshot(): IScriptSnapshot; getNamedDeclarations(): Declaration[]; - update(scriptSnapshot: TypeScript.IScriptSnapshot, version: string, isOpen: boolean, textChangeRange: TypeScript.TextChangeRange): SourceFile; + update(scriptSnapshot: IScriptSnapshot, version: string, isOpen: boolean, textChangeRange: TextChangeRange): SourceFile; } + /** + * Represents an immutable snapshot of a script at a specified time.Once acquired, the + * snapshot is observably immutable. i.e. the same calls with the same parameters will return + * the same values. + */ + export interface IScriptSnapshot { + /** Gets a portion of the script snapshot specified by [start, end). */ + getText(start: number, end: number): string; + + /** Gets the length of this script snapshot. */ + getLength(): number; + + /** + * This call returns the array containing the start position of every line. + * i.e."[0, 10, 55]". TODO: consider making this optional. The language service could + * always determine this (albeit in a more expensive manner). + */ + getLineStartPositions(): number[]; + + /** + * Gets the TextChangeRange that describe how the text changed between this text and + * an older version. This information is used by the incremental parser to determine + * what sections of the script need to be re-parsed. 'undefined' can be returned if the + * change range cannot be determined. However, in that case, incremental parsing will + * not happen and the entire document will be re - parsed. + */ + getChangeRange(oldSnapshot: IScriptSnapshot): TextChangeRange; + } + + export module ScriptSnapshot { + class StringScriptSnapshot implements IScriptSnapshot { + private _lineStartPositions: number[] = undefined; + + constructor(private text: string) { + } + + public getText(start: number, end: number): string { + return this.text.substring(start, end); + } + + public getLength(): number { + return this.text.length; + } + + public getLineStartPositions(): number[] { + if (!this._lineStartPositions) { + this._lineStartPositions = computeLineStarts(this.text); + } + + return this._lineStartPositions; + } + + public getChangeRange(oldSnapshot: IScriptSnapshot): TextChangeRange { + throw new Error("not yet implemented"); + } + } + + export function fromString(text: string): IScriptSnapshot { + return new StringScriptSnapshot(text); + } + } export interface PreProcessedFileInfo { referencedFiles: FileReference[]; importedFiles: FileReference[]; @@ -682,10 +732,10 @@ module ts { public languageVersion: ScriptTarget; public identifiers: Map; - private scriptSnapshot: TypeScript.IScriptSnapshot; + private scriptSnapshot: IScriptSnapshot; private namedDeclarations: Declaration[]; - public getScriptSnapshot(): TypeScript.IScriptSnapshot { + public getScriptSnapshot(): IScriptSnapshot { return this.scriptSnapshot; } @@ -761,28 +811,28 @@ module ts { return this.namedDeclarations; } - public update(scriptSnapshot: TypeScript.IScriptSnapshot, version: string, isOpen: boolean, textChangeRange: TypeScript.TextChangeRange): SourceFile { + public update(scriptSnapshot: IScriptSnapshot, version: string, isOpen: boolean, textChangeRange: TextChangeRange): SourceFile { if (textChangeRange && Debug.shouldAssert(AssertionLevel.Normal)) { var oldText = this.scriptSnapshot; var newText = scriptSnapshot; - TypeScript.Debug.assert((oldText.getLength() - textChangeRange.span().length() + textChangeRange.newLength()) === newText.getLength()); + Debug.assert((oldText.getLength() - textChangeRange.span().length() + textChangeRange.newLength()) === newText.getLength()); if (Debug.shouldAssert(AssertionLevel.VeryAggressive)) { var oldTextPrefix = oldText.getText(0, textChangeRange.span().start()); var newTextPrefix = newText.getText(0, textChangeRange.span().start()); - TypeScript.Debug.assert(oldTextPrefix === newTextPrefix); + Debug.assert(oldTextPrefix === newTextPrefix); var oldTextSuffix = oldText.getText(textChangeRange.span().end(), oldText.getLength()); var newTextSuffix = newText.getText(textChangeRange.newSpan().end(), newText.getLength()); - TypeScript.Debug.assert(oldTextSuffix === newTextSuffix); + Debug.assert(oldTextSuffix === newTextSuffix); } } return SourceFileObject.createSourceFileObject(this.filename, scriptSnapshot, this.languageVersion, version, isOpen); } - public static createSourceFileObject(filename: string, scriptSnapshot: TypeScript.IScriptSnapshot, languageVersion: ScriptTarget, version: string, isOpen: boolean) { + public static createSourceFileObject(filename: string, scriptSnapshot: IScriptSnapshot, languageVersion: ScriptTarget, version: string, isOpen: boolean) { var newSourceFile = createSourceFile(filename, scriptSnapshot.getText(0, scriptSnapshot.getLength()), languageVersion, version, isOpen); newSourceFile.scriptSnapshot = scriptSnapshot; return newSourceFile; @@ -801,7 +851,7 @@ module ts { getScriptFileNames(): string[]; getScriptVersion(fileName: string): string; getScriptIsOpen(fileName: string): boolean; - getScriptSnapshot(fileName: string): TypeScript.IScriptSnapshot; + getScriptSnapshot(fileName: string): IScriptSnapshot; getLocalizedDiagnosticMessages(): any; getCancellationToken(): CancellationToken; getCurrentDirectory(): string; @@ -819,17 +869,17 @@ module ts { getSemanticDiagnostics(fileName: string): Diagnostic[]; getCompilerOptionsDiagnostics(): Diagnostic[]; - getSyntacticClassifications(fileName: string, span: TypeScript.TextSpan): ClassifiedSpan[]; - getSemanticClassifications(fileName: string, span: TypeScript.TextSpan): ClassifiedSpan[]; + getSyntacticClassifications(fileName: string, span: TextSpan): ClassifiedSpan[]; + getSemanticClassifications(fileName: string, span: TextSpan): ClassifiedSpan[]; getCompletionsAtPosition(fileName: string, position: number, isMemberCompletion: boolean): CompletionInfo; getCompletionEntryDetails(fileName: string, position: number, entryName: string): CompletionEntryDetails; getQuickInfoAtPosition(fileName: string, position: number): QuickInfo; - getNameOrDottedNameSpan(fileName: string, startPos: number, endPos: number): TypeScript.TextSpan; + getNameOrDottedNameSpan(fileName: string, startPos: number, endPos: number): TextSpan; - getBreakpointStatementAtPosition(fileName: string, position: number): TypeScript.TextSpan; + getBreakpointStatementAtPosition(fileName: string, position: number): TextSpan; getSignatureHelpItems(fileName: string, position: number): SignatureHelpItems; @@ -849,7 +899,7 @@ module ts { getOutliningSpans(fileName: string): OutliningSpan[]; getTodoComments(fileName: string, descriptors: TodoCommentDescriptor[]): TodoComment[]; - getBraceMatchingAtPosition(fileName: string, position: number): TypeScript.TextSpan[]; + getBraceMatchingAtPosition(fileName: string, position: number): TextSpan[]; getIndentationAtPosition(fileName: string, position: number, options: EditorOptions): number; getFormattingEditsForRange(fileName: string, start: number, end: number, options: FormatCodeOptions): TextChange[]; @@ -858,8 +908,6 @@ module ts { getEmitOutput(fileName: string): EmitOutput; - //getSyntaxTree(fileName: string): TypeScript.SyntaxTree; - dispose(): void; } @@ -899,7 +947,7 @@ module ts { } export interface ClassifiedSpan { - textSpan: TypeScript.TextSpan; + textSpan: TextSpan; classificationType: string; // ClassificationTypeNames } @@ -907,7 +955,7 @@ module ts { text: string; kind: string; kindModifiers: string; - spans: TypeScript.TextSpan[]; + spans: TextSpan[]; childItems: NavigationBarItem[]; indent: number; bolded: boolean; @@ -926,17 +974,17 @@ module ts { } export class TextChange { - span: TypeScript.TextSpan; + span: TextSpan; newText: string; } export interface RenameLocation { - textSpan: TypeScript.TextSpan; + textSpan: TextSpan; fileName: string; } export interface ReferenceEntry { - textSpan: TypeScript.TextSpan; + textSpan: TextSpan; fileName: string; isWriteAccess: boolean; } @@ -947,7 +995,7 @@ module ts { kindModifiers: string; matchKind: string; fileName: string; - textSpan: TypeScript.TextSpan; + textSpan: TextSpan; containerName: string; containerKind: string; } @@ -972,7 +1020,7 @@ module ts { export interface DefinitionInfo { fileName: string; - textSpan: TypeScript.TextSpan; + textSpan: TextSpan; kind: string; name: string; containerKind: string; @@ -1012,7 +1060,7 @@ module ts { export interface QuickInfo { kind: string; kindModifiers: string; - textSpan: TypeScript.TextSpan; + textSpan: TextSpan; displayParts: SymbolDisplayPart[]; documentation: SymbolDisplayPart[]; } @@ -1024,7 +1072,7 @@ module ts { fullDisplayName: string; kind: string; kindModifiers: string; - triggerSpan: TypeScript.TextSpan; + triggerSpan: TextSpan; } export interface SignatureHelpParameter { @@ -1055,7 +1103,7 @@ module ts { */ export interface SignatureHelpItems { items: SignatureHelpItem[]; - applicableSpan: TypeScript.TextSpan; + applicableSpan: TextSpan; selectedItemIndex: number; argumentIndex: number; argumentCount: number; @@ -1134,7 +1182,7 @@ module ts { acquireDocument( filename: string, compilationSettings: CompilerOptions, - scriptSnapshot: TypeScript.IScriptSnapshot, + scriptSnapshot: IScriptSnapshot, version: string, isOpen: boolean): SourceFile; @@ -1142,10 +1190,10 @@ module ts { sourceFile: SourceFile, filename: string, compilationSettings: CompilerOptions, - scriptSnapshot: TypeScript.IScriptSnapshot, + scriptSnapshot: IScriptSnapshot, version: string, isOpen: boolean, - textChangeRange: TypeScript.TextChangeRange + textChangeRange: TextChangeRange ): SourceFile; releaseDocument(filename: string, compilationSettings: CompilerOptions): void @@ -1263,10 +1311,6 @@ module ts { prefix = 3 } - interface IncrementalParse { - (oldSyntaxTree: TypeScript.SyntaxTree, textChangeRange: TypeScript.TextChangeRange, newText: TypeScript.ISimpleText): TypeScript.SyntaxTree - } - /// Language Service interface CompletionSession { @@ -1289,7 +1333,7 @@ module ts { filename: string; version: string; isOpen: boolean; - sourceText?: TypeScript.IScriptSnapshot; + sourceText?: IScriptSnapshot; } interface DocumentRegistryEntry { @@ -1579,7 +1623,7 @@ module ts { return this.getEntry(filename).isOpen; } - public getScriptSnapshot(filename: string): TypeScript.IScriptSnapshot { + public getScriptSnapshot(filename: string): IScriptSnapshot { var file = this.getEntry(filename); if (!file.sourceText) { file.sourceText = this.host.getScriptSnapshot(file.filename); @@ -1587,10 +1631,10 @@ module ts { return file.sourceText; } - public getChangeRange(filename: string, lastKnownVersion: string, oldScriptSnapshot: TypeScript.IScriptSnapshot): TypeScript.TextChangeRange { + public getChangeRange(filename: string, lastKnownVersion: string, oldScriptSnapshot: IScriptSnapshot): TextChangeRange { var currentVersion = this.getVersion(filename); if (lastKnownVersion === currentVersion) { - return TypeScript.TextChangeRange.unchanged; // "No changes" + return TextChangeRange.unchanged; // "No changes" } var scriptSnapshot = this.getScriptSnapshot(filename); @@ -1606,7 +1650,6 @@ module ts { private currentFilename: string = ""; private currentFileVersion: string = null; private currentSourceFile: SourceFile = null; - private currentFileSyntaxTree: TypeScript.SyntaxTree = null; constructor(private host: LanguageServiceHost) { this.hostCache = new HostCache(host); @@ -1614,20 +1657,15 @@ module ts { private initialize(filename: string) { // ensure that both source file and syntax tree are either initialized or not initialized - Debug.assert(!!this.currentFileSyntaxTree === !!this.currentSourceFile); var start = new Date().getTime(); this.hostCache = new HostCache(this.host); this.host.log("SyntaxTreeCache.Initialize: new HostCache: " + (new Date().getTime() - start)); var version = this.hostCache.getVersion(filename); - var syntaxTree: TypeScript.SyntaxTree = null; var sourceFile: SourceFile; - if (this.currentFileSyntaxTree === null || this.currentFilename !== filename) { + if (this.currentFilename !== filename) { var scriptSnapshot = this.hostCache.getScriptSnapshot(filename); - var start = new Date().getTime(); - syntaxTree = this.createSyntaxTree(filename, scriptSnapshot); - this.host.log("SyntaxTreeCache.Initialize: createSyntaxTree: " + (new Date().getTime() - start)); var start = new Date().getTime(); sourceFile = createSourceFileFromScriptSnapshot(filename, scriptSnapshot, getDefaultCompilerOptions(), version, /*isOpen*/ true); @@ -1640,11 +1678,6 @@ module ts { else if (this.currentFileVersion !== version) { var scriptSnapshot = this.hostCache.getScriptSnapshot(filename); - var start = new Date().getTime(); - syntaxTree = this.updateSyntaxTree(filename, scriptSnapshot, - this.currentSourceFile.getScriptSnapshot(), this.currentFileSyntaxTree, this.currentFileVersion); - this.host.log("SyntaxTreeCache.Initialize: updateSyntaxTree: " + (new Date().getTime() - start)); - var editRange = this.hostCache.getChangeRange(filename, this.currentFileVersion, this.currentSourceFile.getScriptSnapshot()); var start = new Date().getTime(); @@ -1658,12 +1691,10 @@ module ts { this.host.log("SyntaxTreeCache.Initialize: fixupParentRefs : " + (new Date().getTime() - start)); } - if (syntaxTree !== null) { - Debug.assert(sourceFile !== undefined); + if (sourceFile) { // All done, ensure state is up to date this.currentFileVersion = version; this.currentFilename = filename; - this.currentFileSyntaxTree = syntaxTree; this.currentSourceFile = sourceFile; } @@ -1684,115 +1715,17 @@ module ts { } } - public getCurrentFileSyntaxTree(filename: string): TypeScript.SyntaxTree { - this.initialize(filename); - return this.currentFileSyntaxTree; - } - public getCurrentSourceFile(filename: string): SourceFile { this.initialize(filename); return this.currentSourceFile; } - public getCurrentScriptSnapshot(filename: string): TypeScript.IScriptSnapshot { - // update currentFileScriptSnapshot as a part of 'getCurrentFileSyntaxTree' call - this.getCurrentFileSyntaxTree(filename); + public getCurrentScriptSnapshot(filename: string): IScriptSnapshot { return this.getCurrentSourceFile(filename).getScriptSnapshot(); } - - private createSyntaxTree(filename: string, scriptSnapshot: TypeScript.IScriptSnapshot): TypeScript.SyntaxTree { - var text = TypeScript.SimpleText.fromScriptSnapshot(scriptSnapshot); - - // For the purposes of features that use this syntax tree, we can just use the default - // compilation settings. The features only use the syntax (and not the diagnostics), - // and the syntax isn't affected by the compilation settings. - var syntaxTree = TypeScript.Parser.parse(filename, text, getDefaultCompilerOptions().target, TypeScript.isDTSFile(filename)); - - return syntaxTree; - } - - private updateSyntaxTree(filename: string, scriptSnapshot: TypeScript.IScriptSnapshot, previousScriptSnapshot: TypeScript.IScriptSnapshot, previousSyntaxTree: TypeScript.SyntaxTree, previousFileVersion: string): TypeScript.SyntaxTree { - var editRange = this.hostCache.getChangeRange(filename, previousFileVersion, previousScriptSnapshot); - - // Debug.assert(newLength >= 0); - - // The host considers the entire buffer changed. So parse a completely new tree. - if (editRange === null) { - return this.createSyntaxTree(filename, scriptSnapshot); - } - - var nextSyntaxTree = TypeScript.IncrementalParser.parse( - previousSyntaxTree, editRange, TypeScript.SimpleText.fromScriptSnapshot(scriptSnapshot)); - - this.ensureInvariants(filename, editRange, nextSyntaxTree, previousScriptSnapshot, scriptSnapshot); - - return nextSyntaxTree; - } - - private ensureInvariants(filename: string, editRange: TypeScript.TextChangeRange, incrementalTree: TypeScript.SyntaxTree, oldScriptSnapshot: TypeScript.IScriptSnapshot, newScriptSnapshot: TypeScript.IScriptSnapshot) { - // First, verify that the edit range and the script snapshots make sense. - - // If this fires, then the edit range is completely bogus. Somehow the lengths of the - // old snapshot, the change range and the new snapshot aren't in sync. This is very - // bad. - var expectedNewLength = oldScriptSnapshot.getLength() - editRange.span().length() + editRange.newLength(); - var actualNewLength = newScriptSnapshot.getLength(); - - function provideMoreDebugInfo() { - - var debugInformation = ["expected length:", expectedNewLength, "and actual length:", actualNewLength, "are not equal\r\n"]; - - var oldSpan = editRange.span(); - - function prettyPrintString(s: string): string { - return '"' + s.replace(/\r/g, '\\r').replace(/\n/g, '\\n') + '"'; - } - - debugInformation.push('Edit range (old text) (start: ' + oldSpan.start() + ', end: ' + oldSpan.end() + ') \r\n'); - debugInformation.push('Old text edit range contents: ' + prettyPrintString(oldScriptSnapshot.getText(oldSpan.start(), oldSpan.end()))); - - var newSpan = editRange.newSpan(); - - debugInformation.push('Edit range (new text) (start: ' + newSpan.start() + ', end: ' + newSpan.end() + ') \r\n'); - debugInformation.push('New text edit range contents: ' + prettyPrintString(newScriptSnapshot.getText(newSpan.start(), newSpan.end()))); - - return debugInformation.join(' '); - } - - Debug.assert( - expectedNewLength === actualNewLength, - "Expected length is different from actual!", - provideMoreDebugInfo); - - if (Debug.shouldAssert(AssertionLevel.VeryAggressive)) { - // If this fires, the text change range is bogus. It says the change starts at point - // 'X', but we can see a text difference *before* that point. - var oldPrefixText = oldScriptSnapshot.getText(0, editRange.span().start()); - var newPrefixText = newScriptSnapshot.getText(0, editRange.span().start()); - Debug.assert(oldPrefixText === newPrefixText, 'Expected equal prefix texts!'); - - // If this fires, the text change range is bogus. It says the change goes only up to - // point 'X', but we can see a text difference *after* that point. - var oldSuffixText = oldScriptSnapshot.getText(editRange.span().end(), oldScriptSnapshot.getLength()); - var newSuffixText = newScriptSnapshot.getText(editRange.newSpan().end(), newScriptSnapshot.getLength()); - Debug.assert(oldSuffixText === newSuffixText, 'Expected equal suffix texts!'); - - // Ok, text change range and script snapshots look ok. Let's verify that our - // incremental parsing worked properly. - //var normalTree = this.createSyntaxTree(filename, newScriptSnapshot); - //Debug.assert(normalTree.structuralEquals(incrementalTree), 'Expected equal incremental and normal trees'); - - // Ok, the trees looked good. So at least our incremental parser agrees with the - // normal parser. Now, verify that the incremental tree matches the contents of the - // script snapshot. - var incrementalTreeText = TypeScript.fullText(incrementalTree.sourceUnit()); - var actualSnapshotText = newScriptSnapshot.getText(0, newScriptSnapshot.getLength()); - Debug.assert(incrementalTreeText === actualSnapshotText, 'Expected full texts to be equal'); - } - } } - function createSourceFileFromScriptSnapshot(filename: string, scriptSnapshot: TypeScript.IScriptSnapshot, settings: CompilerOptions, version: string, isOpen: boolean) { + function createSourceFileFromScriptSnapshot(filename: string, scriptSnapshot: IScriptSnapshot, settings: CompilerOptions, version: string, isOpen: boolean) { return SourceFileObject.createSourceFileObject(filename, scriptSnapshot, settings.target, version, isOpen); } @@ -1836,7 +1769,7 @@ module ts { function acquireDocument( filename: string, compilationSettings: CompilerOptions, - scriptSnapshot: TypeScript.IScriptSnapshot, + scriptSnapshot: IScriptSnapshot, version: string, isOpen: boolean): SourceFile { @@ -1860,10 +1793,10 @@ module ts { sourceFile: SourceFile, filename: string, compilationSettings: CompilerOptions, - scriptSnapshot: TypeScript.IScriptSnapshot, + scriptSnapshot: IScriptSnapshot, version: string, isOpen: boolean, - textChangeRange: TypeScript.TextChangeRange + textChangeRange: TextChangeRange ): SourceFile { var bucket = getBucketForCompilationSettings(compilationSettings, /*createIfMissing*/ false); @@ -2051,7 +1984,7 @@ module ts { /** Returns true if node is a name of an object literal property, e.g. "a" in x = { "a": 1 } */ function isNameOfPropertyAssignment(node: Node): boolean { return (node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.StringLiteral || node.kind === SyntaxKind.NumericLiteral) && - node.parent.kind === SyntaxKind.PropertyAssignment && (node.parent).name === node; + (node.parent.kind === SyntaxKind.PropertyAssignment || node.parent.kind === SyntaxKind.ShorthandPropertyAssignment) && (node.parent).name === node; } function isLiteralNameOfPropertyDeclarationOrIndexAccess(node: Node): boolean { @@ -2137,7 +2070,7 @@ module ts { export function createLanguageService(host: LanguageServiceHost, documentRegistry: DocumentRegistry): LanguageService { var syntaxTreeCache: SyntaxTreeCache = new SyntaxTreeCache(host); - var ruleProvider: ts.formatting.RulesProvider; + var ruleProvider: formatting.RulesProvider; var hostCache: HostCache; // A cache of all the information about the files on the host side. var program: Program; @@ -2171,7 +2104,7 @@ module ts { function getRuleProvider(options: FormatCodeOptions) { // Ensure rules are initialized and up to date wrt to formatting options if (!ruleProvider) { - ruleProvider = new ts.formatting.RulesProvider(host); + ruleProvider = new formatting.RulesProvider(host); } ruleProvider.ensureUpToDate(options); @@ -2288,7 +2221,7 @@ module ts { // file was closed, then we always want to re-parse. This is so our tree doesn't keep // the old buffer alive that represented the file on disk (as the host has moved to a // new text buffer). - var textChangeRange: TypeScript.TextChangeRange = null; + var textChangeRange: TextChangeRange = null; if (sourceFile.isOpen && isOpen) { textChangeRange = hostCache.getChangeRange(filename, sourceFile.version, sourceFile.getScriptSnapshot()); } @@ -2745,7 +2678,7 @@ module ts { var existingMemberNames: Map = {}; forEach(existingMembers, m => { - if (m.kind !== SyntaxKind.PropertyAssignment) { + if (m.kind !== SyntaxKind.PropertyAssignment && m.kind !== SyntaxKind.ShorthandPropertyAssignment) { // Ignore omitted expressions for missing members in the object literal return; } @@ -3295,7 +3228,7 @@ module ts { return { kind: ScriptElementKind.unknown, kindModifiers: ScriptElementKindModifier.none, - textSpan: new TypeScript.TextSpan(node.getStart(), node.getWidth()), + textSpan: new TextSpan(node.getStart(), node.getWidth()), displayParts: typeToDisplayParts(typeInfoResolver, type, getContainerNode(node)), documentation: type.symbol ? type.symbol.getDocumentationComment() : undefined }; @@ -3309,7 +3242,7 @@ module ts { return { kind: displayPartsDocumentationsAndKind.symbolKind, kindModifiers: getSymbolModifiers(symbol), - textSpan: new TypeScript.TextSpan(node.getStart(), node.getWidth()), + textSpan: new TextSpan(node.getStart(), node.getWidth()), displayParts: displayPartsDocumentationsAndKind.displayParts, documentation: displayPartsDocumentationsAndKind.documentation }; @@ -3320,7 +3253,7 @@ module ts { function getDefinitionInfo(node: Node, symbolKind: string, symbolName: string, containerName: string): DefinitionInfo { return { fileName: node.getSourceFile().filename, - textSpan: TypeScript.TextSpan.fromBounds(node.getStart(), node.getEnd()), + textSpan: TextSpan.fromBounds(node.getStart(), node.getEnd()), kind: symbolKind, name: symbolName, containerKind: undefined, @@ -3398,7 +3331,7 @@ module ts { if (program.getSourceFile(targetFilename)) { return [{ fileName: targetFilename, - textSpan: TypeScript.TextSpan.fromBounds(0, 0), + textSpan: TextSpan.fromBounds(0, 0), kind: ScriptElementKind.scriptElement, name: comment.filename, containerName: undefined, @@ -3567,7 +3500,7 @@ module ts { if (shouldHighlightNextKeyword) { result.push({ fileName: filename, - textSpan: TypeScript.TextSpan.fromBounds(elseKeyword.getStart(), ifKeyword.end), + textSpan: TextSpan.fromBounds(elseKeyword.getStart(), ifKeyword.end), isWriteAccess: false }); i++; // skip the next keyword @@ -4153,7 +4086,7 @@ module ts { (findInComments && isInComment(position))) { result.push({ fileName: sourceFile.filename, - textSpan: new TypeScript.TextSpan(position, searchText.length), + textSpan: new TextSpan(position, searchText.length), isWriteAccess: false }); } @@ -4165,8 +4098,21 @@ module ts { } var referenceSymbol = typeInfoResolver.getSymbolInfo(referenceLocation); - if (referenceSymbol && isRelatableToSearchSet(searchSymbols, referenceSymbol, referenceLocation)) { - result.push(getReferenceEntryFromNode(referenceLocation)); + if (referenceSymbol) { + var referenceSymbolDeclaration = referenceSymbol.valueDeclaration; + var shorthandValueSymbol = typeInfoResolver.getShorthandAssignmentValueSymbol(referenceSymbolDeclaration); + if (isRelatableToSearchSet(searchSymbols, referenceSymbol, referenceLocation)) { + result.push(getReferenceEntryFromNode(referenceLocation)); + } + /* Because in short-hand property assignment, an identifier which stored as name of the short-hand property assignment + * has two meaning : property name and property value. Therefore when we do findAllReference at the position where + * an identifier is declared, the language service should return the position of the variable declaration as well as + * the position in short-hand property assignment excluding property accessing. However, if we do findAllReference at the + * position of property accessing, the referenceEntry of such position will be handled in the first case. + */ + else if (!(referenceSymbol.flags & SymbolFlags.Transient) && searchSymbols.indexOf(shorthandValueSymbol) >= 0) { + result.push(getReferenceEntryFromNode(referenceSymbolDeclaration.name)); + } } }); } @@ -4334,6 +4280,22 @@ module ts { forEach(getPropertySymbolsFromContextualType(location), contextualSymbol => { result.push.apply(result, typeInfoResolver.getRootSymbols(contextualSymbol)); }); + + /* Because in short-hand property assignment, location has two meaning : property name and as value of the property + * When we do findAllReference at the position of the short-hand property assignment, we would want to have references to position of + * property name and variable declaration of the identifier. + * Like in below example, when querying for all references for an identifier 'name', of the property assignment, the language service + * should show both 'name' in 'obj' and 'name' in variable declaration + * var name = "Foo"; + * var obj = { name }; + * In order to do that, we will populate the search set with the value symbol of the identifier as a value of the property assignment + * so that when matching with potential reference symbol, both symbols from property declaration and variable declaration + * will be included correctly. + */ + var shorthandValueSymbol = typeInfoResolver.getShorthandAssignmentValueSymbol(location.parent); + if (shorthandValueSymbol) { + result.push(shorthandValueSymbol); + } } // If this is a union property, add all the symbols from all its source symbols in all unioned types. @@ -4493,7 +4455,7 @@ module ts { return { fileName: node.getSourceFile().filename, - textSpan: TypeScript.TextSpan.fromBounds(start, end), + textSpan: TextSpan.fromBounds(start, end), isWriteAccess: isWriteAccess(node) }; } @@ -4549,7 +4511,7 @@ module ts { kindModifiers: getNodeModifiers(declaration), matchKind: MatchKind[matchKind], fileName: filename, - textSpan: TypeScript.TextSpan.fromBounds(declaration.getStart(), declaration.getEnd()), + textSpan: TextSpan.fromBounds(declaration.getStart(), declaration.getEnd()), // TODO(jfreeman): What should be the containerName when the container has a computed name? containerName: container.name ? (container.name).text : "", containerKind: container.name ? getNodeKind(container) : "" @@ -4674,6 +4636,7 @@ module ts { case SyntaxKind.VariableDeclaration: case SyntaxKind.Property: case SyntaxKind.PropertyAssignment: + case SyntaxKind.ShorthandPropertyAssignment: case SyntaxKind.EnumMember: case SyntaxKind.Method: case SyntaxKind.Constructor: @@ -4853,18 +4816,13 @@ module ts { } /// Syntactic features - function getSyntaxTree(filename: string): TypeScript.SyntaxTree { - filename = normalizeSlashes(filename); - return syntaxTreeCache.getCurrentFileSyntaxTree(filename); - } - function getCurrentSourceFile(filename: string): SourceFile { filename = normalizeSlashes(filename); var currentSourceFile = syntaxTreeCache.getCurrentSourceFile(filename); return currentSourceFile; } - function getNameOrDottedNameSpan(filename: string, startPos: number, endPos: number): TypeScript.TextSpan { + function getNameOrDottedNameSpan(filename: string, startPos: number, endPos: number): TextSpan { filename = ts.normalizeSlashes(filename); // Get node at the location var node = getTouchingPropertyName(getCurrentSourceFile(filename), startPos); @@ -4916,7 +4874,7 @@ module ts { } } - return TypeScript.TextSpan.fromBounds(nodeForStartPos.getStart(), node.getEnd()); + return TextSpan.fromBounds(nodeForStartPos.getStart(), node.getEnd()); } function getBreakpointStatementAtPosition(filename: string, position: number) { @@ -4931,7 +4889,7 @@ module ts { return NavigationBar.getNavigationBarItems(getCurrentSourceFile(filename)); } - function getSemanticClassifications(fileName: string, span: TypeScript.TextSpan): ClassifiedSpan[] { + function getSemanticClassifications(fileName: string, span: TextSpan): ClassifiedSpan[] { synchronizeHostData(); fileName = normalizeSlashes(fileName); @@ -4990,7 +4948,7 @@ module ts { var type = classifySymbol(symbol, getMeaningFromLocation(node)); if (type) { result.push({ - textSpan: new TypeScript.TextSpan(node.getStart(), node.getWidth()), + textSpan: new TextSpan(node.getStart(), node.getWidth()), classificationType: type }); } @@ -5002,7 +4960,7 @@ module ts { } } - function getSyntacticClassifications(fileName: string, span: TypeScript.TextSpan): ClassifiedSpan[] { + function getSyntacticClassifications(fileName: string, span: TextSpan): ClassifiedSpan[] { // doesn't use compiler - no need to synchronize with host fileName = normalizeSlashes(fileName); var sourceFile = getCurrentSourceFile(fileName); @@ -5016,7 +4974,7 @@ module ts { var width = comment.end - comment.pos; if (span.intersectsWith(comment.pos, width)) { result.push({ - textSpan: new TypeScript.TextSpan(comment.pos, width), + textSpan: new TextSpan(comment.pos, width), classificationType: ClassificationTypeNames.comment }); } @@ -5029,7 +4987,7 @@ module ts { var type = classifyTokenType(token); if (type) { result.push({ - textSpan: new TypeScript.TextSpan(token.getStart(), token.getWidth()), + textSpan: new TextSpan(token.getStart(), token.getWidth()), classificationType: type }); } @@ -5141,7 +5099,7 @@ module ts { function getBraceMatchingAtPosition(filename: string, position: number) { var sourceFile = getCurrentSourceFile(filename); - var result: TypeScript.TextSpan[] = []; + var result: TextSpan[] = []; var token = getTouchingToken(sourceFile, position); @@ -5153,12 +5111,12 @@ module ts { var parentElement = token.parent; var childNodes = parentElement.getChildren(sourceFile); - for (var i = 0, n = childNodes.length; i < n; i++) { + for (var i = 0, n = childNodes.length; i < n; i++) {33 var current = childNodes[i]; if (current.kind === matchKind) { - var range1 = new TypeScript.TextSpan(token.getStart(sourceFile), token.getWidth(sourceFile)); - var range2 = new TypeScript.TextSpan(current.getStart(sourceFile), current.getWidth(sourceFile)); + var range1 = new TextSpan(token.getStart(sourceFile), token.getWidth(sourceFile)); + var range2 = new TextSpan(current.getStart(sourceFile), current.getWidth(sourceFile)); // We want to order the braces when we return the result. if (range1.start() < range2.start()) { @@ -5397,9 +5355,9 @@ module ts { } function isLetterOrDigit(char: number): boolean { - return (char >= TypeScript.CharacterCodes.a && char <= TypeScript.CharacterCodes.z) || - (char >= TypeScript.CharacterCodes.A && char <= TypeScript.CharacterCodes.Z) || - (char >= TypeScript.CharacterCodes._0 && char <= TypeScript.CharacterCodes._9); + return (char >= CharacterCodes.a && char <= CharacterCodes.z) || + (char >= CharacterCodes.A && char <= CharacterCodes.Z) || + (char >= CharacterCodes._0 && char <= CharacterCodes._9); } } @@ -5422,7 +5380,7 @@ module ts { if (kind) { return getRenameInfo(symbol.name, typeInfoResolver.getFullyQualifiedName(symbol), kind, getSymbolModifiers(symbol), - new TypeScript.TextSpan(node.getStart(), node.getWidth())); + new TextSpan(node.getStart(), node.getWidth())); } } } @@ -5441,7 +5399,7 @@ module ts { }; } - function getRenameInfo(displayName: string, fullDisplayName: string, kind: string, kindModifiers: string, triggerSpan: TypeScript.TextSpan): RenameInfo { + function getRenameInfo(displayName: string, fullDisplayName: string, kind: string, kindModifiers: string, triggerSpan: TextSpan): RenameInfo { return { canRename: true, localizedErrorMessage: undefined, diff --git a/src/services/shims.ts b/src/services/shims.ts index 00acff3798a..38c68c067f8 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -15,8 +15,6 @@ /// -/// - var debugObjectHost = (this); module ts { @@ -176,7 +174,7 @@ module ts { } export interface CoreServicesShim extends Shim { - getPreProcessedFileInfo(fileName: string, sourceText: TypeScript.IScriptSnapshot): string; + getPreProcessedFileInfo(fileName: string, sourceText: IScriptSnapshot): string; getDefaultCompilationSettings(): string; } @@ -309,7 +307,7 @@ module ts { logger.log("*INTERNAL ERROR* - Exception in typescript services: " + err.message); } - class ScriptSnapshotShimAdapter implements TypeScript.IScriptSnapshot { + class ScriptSnapshotShimAdapter implements IScriptSnapshot { private lineStartPositions: number[] = null; constructor(private scriptSnapshotShim: ScriptSnapshotShim) { @@ -331,7 +329,7 @@ module ts { return this.lineStartPositions; } - public getChangeRange(oldSnapshot: TypeScript.IScriptSnapshot): TypeScript.TextChangeRange { + public getChangeRange(oldSnapshot: IScriptSnapshot): TextChangeRange { var oldSnapshotShim = oldSnapshot; var encoded = this.scriptSnapshotShim.getChangeRange(oldSnapshotShim.scriptSnapshotShim); if (encoded == null) { @@ -339,8 +337,8 @@ module ts { } var decoded: { span: { start: number; length: number; }; newLength: number; } = JSON.parse(encoded); - return new TypeScript.TextChangeRange( - new TypeScript.TextSpan(decoded.span.start, decoded.span.length), decoded.newLength); + return new TextChangeRange( + new TextSpan(decoded.span.start, decoded.span.length), decoded.newLength); } } @@ -368,7 +366,7 @@ module ts { return JSON.parse(encoded); } - public getScriptSnapshot(fileName: string): TypeScript.IScriptSnapshot { + public getScriptSnapshot(fileName: string): IScriptSnapshot { return new ScriptSnapshotShimAdapter(this.shimHost.getScriptSnapshot(fileName)); } @@ -521,7 +519,7 @@ module ts { return this.forwardJSONCall( "getSyntacticClassifications('" + fileName + "', " + start + ", " + length + ")", () => { - var classifications = this.languageService.getSyntacticClassifications(fileName, new TypeScript.TextSpan(start, length)); + var classifications = this.languageService.getSyntacticClassifications(fileName, new TextSpan(start, length)); return classifications; }); } @@ -530,7 +528,7 @@ module ts { return this.forwardJSONCall( "getSemanticClassifications('" + fileName + "', " + start + ", " + length + ")", () => { - var classifications = this.languageService.getSemanticClassifications(fileName, new TypeScript.TextSpan(start, length)); + var classifications = this.languageService.getSemanticClassifications(fileName, new TextSpan(start, length)); return classifications; }); } @@ -845,7 +843,7 @@ module ts { return forwardJSONCall(this.logger, actionDescription, action); } - public getPreProcessedFileInfo(fileName: string, sourceTextSnapshot: TypeScript.IScriptSnapshot): string { + public getPreProcessedFileInfo(fileName: string, sourceTextSnapshot: IScriptSnapshot): string { return this.forwardJSONCall( "getPreProcessedFileInfo('" + fileName + "')", () => { @@ -938,7 +936,7 @@ module ts { } } - throw TypeScript.Errors.invalidOperation(); + throw new Error("Invalid operation"); } } } diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index bba70da4627..223b523c42f 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -173,7 +173,7 @@ module ts.SignatureHelp { export interface ArgumentListInfo { kind: ArgumentListKind; invocation: CallLikeExpression; - argumentsSpan: TypeScript.TextSpan; + argumentsSpan: TextSpan; argumentIndex?: number; argumentCount: number; } @@ -361,7 +361,7 @@ module ts.SignatureHelp { }; } - function getApplicableSpanForArguments(argumentsList: Node): TypeScript.TextSpan { + function getApplicableSpanForArguments(argumentsList: Node): TextSpan { // We use full start and skip trivia on the end because we want to include trivia on // both sides. For example, // @@ -370,12 +370,12 @@ module ts.SignatureHelp { // // The applicable span is from the first bar to the second bar (inclusive, // but not including parentheses) - var applicableSpanStart = argumentsList.pos; - var applicableSpanEnd = skipTrivia(sourceFile.text, argumentsList.end, /*stopAfterLineBreak*/ false); - return new TypeScript.TextSpan(applicableSpanStart, applicableSpanEnd - applicableSpanStart); + var applicableSpanStart = argumentsList.getFullStart(); + var applicableSpanEnd = skipTrivia(sourceFile.text, argumentsList.getEnd(), /*stopAfterLineBreak*/ false); + return new TextSpan(applicableSpanStart, applicableSpanEnd - applicableSpanStart); } - function getApplicableSpanForTaggedTemplate(template: TemplateExpression | LiteralExpression): TypeScript.TextSpan { + function getApplicableSpanForTaggedTemplate(template: TemplateExpression | LiteralExpression): TextSpan { var applicableSpanStart = template.getStart(); var applicableSpanEnd = template.getEnd(); @@ -387,7 +387,7 @@ module ts.SignatureHelp { } } - return new TypeScript.TextSpan(applicableSpanStart, applicableSpanEnd - applicableSpanStart); + return new TextSpan(applicableSpanStart, applicableSpanEnd - applicableSpanStart); } function getContainingArgumentInfo(node: Node, position: number): ArgumentListInfo { diff --git a/src/services/text.ts b/src/services/text.ts new file mode 100644 index 00000000000..fd768785dea --- /dev/null +++ b/src/services/text.ts @@ -0,0 +1,296 @@ +module ts { + export class TextSpan { + private _start: number; + private _length: number; + + /** + * Creates a TextSpan instance beginning with the position Start and having the Length + * specified with length. + */ + constructor(start: number, length: number) { + Debug.assert(start >= 0, "start"); + Debug.assert(length >= 0, "length"); + + this._start = start; + this._length = length; + } + + public toJSON(key: any): any { + return { start: this._start, length: this._length }; + } + + public start(): number { + return this._start; + } + + public length(): number { + return this._length; + } + + public end(): number { + return this._start + this._length; + } + + public isEmpty(): boolean { + return this._length === 0; + } + + /** + * Determines whether the position lies within the span. Returns true if the position is greater than or equal to Start and strictly less + * than End, otherwise false. + * @param position The position to check. + */ + public containsPosition(position: number): boolean { + return position >= this._start && position < this.end(); + } + + /** + * Determines whether span falls completely within this span. Returns true if the specified span falls completely within this span, otherwise false. + * @param span The span to check. + */ + public containsTextSpan(span: TextSpan): boolean { + return span._start >= this._start && span.end() <= this.end(); + } + + /** + * Determines whether the given span overlaps this span. Two spans are considered to overlap + * if they have positions in common and neither is empty. Empty spans do not overlap with any + * other span. Returns true if the spans overlap, false otherwise. + * @param span The span to check. + */ + public overlapsWith(span: TextSpan): boolean { + var overlapStart = Math.max(this._start, span._start); + var overlapEnd = Math.min(this.end(), span.end()); + + return overlapStart < overlapEnd; + } + + /** + * Returns the overlap with the given span, or undefined if there is no overlap. + * @param span The span to check. + */ + public overlap(span: TextSpan): TextSpan { + var overlapStart = Math.max(this._start, span._start); + var overlapEnd = Math.min(this.end(), span.end()); + + if (overlapStart < overlapEnd) { + return TextSpan.fromBounds(overlapStart, overlapEnd); + } + + return undefined; + } + + /** + * Determines whether span intersects this span. Two spans are considered to + * intersect if they have positions in common or the end of one span + * coincides with the start of the other span. Returns true if the spans intersect, false otherwise. + * @param The span to check. + */ + public intersectsWithTextSpan(span: TextSpan): boolean { + return span._start <= this.end() && span.end() >= this._start; + } + + public intersectsWith(start: number, length: number): boolean { + var end = start + length; + return start <= this.end() && end >= this._start; + } + + /** + * Determines whether the given position intersects this span. + * A position is considered to intersect if it is between the start and + * end positions (inclusive) of this span. Returns true if the position intersects, false otherwise. + * @param position The position to check. + */ + public intersectsWithPosition(position: number): boolean { + return position <= this.end() && position >= this._start; + } + + /** + * Returns the intersection with the given span, or undefined if there is no intersection. + * @param span The span to check. + */ + public intersection(span: TextSpan): TextSpan { + var intersectStart = Math.max(this._start, span._start); + var intersectEnd = Math.min(this.end(), span.end()); + + if (intersectStart <= intersectEnd) { + return TextSpan.fromBounds(intersectStart, intersectEnd); + } + + return undefined; + } + + /** + * Creates a new TextSpan from the given start and end positions + * as opposed to a position and length. + */ + public static fromBounds(start: number, end: number): TextSpan { + Debug.assert(start >= 0); + Debug.assert(end - start >= 0); + return new TextSpan(start, end - start); + } + } + + export class TextChangeRange { + public static unchanged = new TextChangeRange(new TextSpan(0, 0), 0); + + private _span: TextSpan; + private _newLength: number; + + /** + * Initializes a new instance of TextChangeRange. + */ + constructor(span: TextSpan, newLength: number) { + Debug.assert(newLength >= 0, "newLength"); + + this._span = span; + this._newLength = newLength; + } + + /** + * The span of text before the edit which is being changed + */ + public span(): TextSpan { + return this._span; + } + + /** + * Width of the span after the edit. A 0 here would represent a delete + */ + public newLength(): number { + return this._newLength; + } + + public newSpan(): TextSpan { + return new TextSpan(this.span().start(), this.newLength()); + } + + public isUnchanged(): boolean { + return this.span().isEmpty() && this.newLength() === 0; + } + + /** + * Called to merge all the changes that occurred across several versions of a script snapshot + * into a single change. i.e. if a user keeps making successive edits to a script we will + * have a text change from V1 to V2, V2 to V3, ..., Vn. + * + * This function will then merge those changes into a single change range valid between V1 and + * Vn. + */ + public static collapseChangesAcrossMultipleVersions(changes: TextChangeRange[]): TextChangeRange { + if (changes.length === 0) { + return TextChangeRange.unchanged; + } + + if (changes.length === 1) { + return changes[0]; + } + + // We change from talking about { { oldStart, oldLength }, newLength } to { oldStart, oldEnd, newEnd } + // as it makes things much easier to reason about. + var change0 = changes[0]; + + var oldStartN = change0.span().start(); + var oldEndN = change0.span().end(); + var newEndN = oldStartN + change0.newLength(); + + for (var i = 1; i < changes.length; i++) { + var nextChange = changes[i]; + + // Consider the following case: + // i.e. two edits. The first represents the text change range { { 10, 50 }, 30 }. i.e. The span starting + // at 10, with length 50 is reduced to length 30. The second represents the text change range { { 30, 30 }, 40 }. + // i.e. the span starting at 30 with length 30 is increased to length 40. + // + // 0 10 20 30 40 50 60 70 80 90 100 + // ------------------------------------------------------------------------------------------------------- + // | / + // | /---- + // T1 | /---- + // | /---- + // | /---- + // ------------------------------------------------------------------------------------------------------- + // | \ + // | \ + // T2 | \ + // | \ + // | \ + // ------------------------------------------------------------------------------------------------------- + // + // Merging these turns out to not be too difficult. First, determining the new start of the change is trivial + // it's just the min of the old and new starts. i.e.: + // + // 0 10 20 30 40 50 60 70 80 90 100 + // ------------------------------------------------------------*------------------------------------------ + // | / + // | /---- + // T1 | /---- + // | /---- + // | /---- + // ----------------------------------------$-------------------$------------------------------------------ + // . | \ + // . | \ + // T2 . | \ + // . | \ + // . | \ + // ----------------------------------------------------------------------*-------------------------------- + // + // (Note the dots represent the newly inferrred start. + // Determining the new and old end is also pretty simple. Basically it boils down to paying attention to the + // absolute positions at the asterixes, and the relative change between the dollar signs. Basically, we see + // which if the two $'s precedes the other, and we move that one forward until they line up. in this case that + // means: + // + // 0 10 20 30 40 50 60 70 80 90 100 + // --------------------------------------------------------------------------------*---------------------- + // | / + // | /---- + // T1 | /---- + // | /---- + // | /---- + // ------------------------------------------------------------$------------------------------------------ + // . | \ + // . | \ + // T2 . | \ + // . | \ + // . | \ + // ----------------------------------------------------------------------*-------------------------------- + // + // In other words (in this case), we're recognizing that the second edit happened after where the first edit + // ended with a delta of 20 characters (60 - 40). Thus, if we go back in time to where the first edit started + // that's the same as if we started at char 80 instead of 60. + // + // As it so happens, the same logic applies if the second edit precedes the first edit. In that case rahter + // than pusing the first edit forward to match the second, we'll push the second edit forward to match the + // first. + // + // In this case that means we have { oldStart: 10, oldEnd: 80, newEnd: 70 } or, in TextChangeRange + // semantics: { { start: 10, length: 70 }, newLength: 60 } + // + // The math then works out as follows. + // If we have { oldStart1, oldEnd1, newEnd1 } and { oldStart2, oldEnd2, newEnd2 } then we can compute the + // final result like so: + // + // { + // oldStart3: Min(oldStart1, oldStart2), + // oldEnd3 : Max(oldEnd1, oldEnd1 + (oldEnd2 - newEnd1)), + // newEnd3 : Max(newEnd2, newEnd2 + (newEnd1 - oldEnd2)) + // } + + var oldStart1 = oldStartN; + var oldEnd1 = oldEndN; + var newEnd1 = newEndN; + + var oldStart2 = nextChange.span().start(); + var oldEnd2 = nextChange.span().end(); + var newEnd2 = oldStart2 + nextChange.newLength(); + + oldStartN = Math.min(oldStart1, oldStart2); + oldEndN = Math.max(oldEnd1, oldEnd1 + (oldEnd2 - newEnd1)); + newEndN = Math.max(newEnd2, newEnd2 + (newEnd1 - oldEnd2)); + } + + return new TextChangeRange(TextSpan.fromBounds(oldStartN, oldEndN), /*newLength: */newEndN - oldStartN); + } + } +} \ No newline at end of file diff --git a/tests/baselines/reference/incompleteObjectLiteral1.errors.txt b/tests/baselines/reference/incompleteObjectLiteral1.errors.txt index 2e363de591e..c37f308960a 100644 --- a/tests/baselines/reference/incompleteObjectLiteral1.errors.txt +++ b/tests/baselines/reference/incompleteObjectLiteral1.errors.txt @@ -1,11 +1,14 @@ -tests/cases/compiler/incompleteObjectLiteral1.ts(1,14): error TS1005: ':' expected. +tests/cases/compiler/incompleteObjectLiteral1.ts(1,14): error TS1005: ',' expected. tests/cases/compiler/incompleteObjectLiteral1.ts(1,16): error TS1128: Declaration or statement expected. +tests/cases/compiler/incompleteObjectLiteral1.ts(1,12): error TS2304: Cannot find name 'aa'. -==== tests/cases/compiler/incompleteObjectLiteral1.ts (2 errors) ==== +==== tests/cases/compiler/incompleteObjectLiteral1.ts (3 errors) ==== var tt = { aa; } ~ -!!! error TS1005: ':' expected. +!!! error TS1005: ',' expected. ~ !!! error TS1128: Declaration or statement expected. + ~~ +!!! error TS2304: Cannot find name 'aa'. var x = tt; \ No newline at end of file diff --git a/tests/baselines/reference/objectLiteralShorthandProperties.js b/tests/baselines/reference/objectLiteralShorthandProperties.js new file mode 100644 index 00000000000..776b2bbe454 --- /dev/null +++ b/tests/baselines/reference/objectLiteralShorthandProperties.js @@ -0,0 +1,39 @@ +//// [objectLiteralShorthandProperties.ts] +var a, b, c; + +var x1 = { + a +}; + +var x2 = { + a, +} + +var x3 = { + a: 0, + b, + c, + d() { }, + x3, + parent: x3 +}; + + + +//// [objectLiteralShorthandProperties.js] +var a, b, c; +var x1 = { + a: a +}; +var x2 = { + a: a, +}; +var x3 = { + a: 0, + b: b, + c: c, + d: function () { + }, + x3: x3, + parent: x3 +}; diff --git a/tests/baselines/reference/objectLiteralShorthandProperties.types b/tests/baselines/reference/objectLiteralShorthandProperties.types new file mode 100644 index 00000000000..f28f25e815c --- /dev/null +++ b/tests/baselines/reference/objectLiteralShorthandProperties.types @@ -0,0 +1,50 @@ +=== tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandProperties.ts === +var a, b, c; +>a : any +>b : any +>c : any + +var x1 = { +>x1 : { a: any; } +>{ a} : { a: any; } + + a +>a : any + +}; + +var x2 = { +>x2 : { a: any; } +>{ a,} : { a: any; } + + a, +>a : any +} + +var x3 = { +>x3 : any +>{ a: 0, b, c, d() { }, x3, parent: x3} : { a: number; b: any; c: any; d: () => void; x3: any; parent: any; } + + a: 0, +>a : number + + b, +>b : any + + c, +>c : any + + d() { }, +>d : () => void +>d() { } : () => void + + x3, +>x3 : any + + parent: x3 +>parent : any +>x3 : any + +}; + + diff --git a/tests/baselines/reference/objectLiteralShorthandPropertiesAssignment.js b/tests/baselines/reference/objectLiteralShorthandPropertiesAssignment.js new file mode 100644 index 00000000000..2ef29a37084 --- /dev/null +++ b/tests/baselines/reference/objectLiteralShorthandPropertiesAssignment.js @@ -0,0 +1,36 @@ +//// [objectLiteralShorthandPropertiesAssignment.ts] +var id: number = 10000; +var name: string = "my name"; + +var person: { name: string; id: number } = { name, id }; +function foo( obj:{ name: string }): void { }; +function bar(name: string, id: number) { return { name, id }; } +function bar1(name: string, id: number) { return { name }; } +function baz(name: string, id: number): { name: string; id: number } { return { name, id }; } + +foo(person); +var person1 = bar("Hello", 5); +var person2: { name: string } = bar("Hello", 5); +var person3: { name: string; id:number } = bar("Hello", 5); + + +//// [objectLiteralShorthandPropertiesAssignment.js] +var id = 10000; +var name = "my name"; +var person = { name: name, id: id }; +function foo(obj) { +} +; +function bar(name, id) { + return { name: name, id: id }; +} +function bar1(name, id) { + return { name: name }; +} +function baz(name, id) { + return { name: name, id: id }; +} +foo(person); +var person1 = bar("Hello", 5); +var person2 = bar("Hello", 5); +var person3 = bar("Hello", 5); diff --git a/tests/baselines/reference/objectLiteralShorthandPropertiesAssignment.types b/tests/baselines/reference/objectLiteralShorthandPropertiesAssignment.types new file mode 100644 index 00000000000..91d9e528d63 --- /dev/null +++ b/tests/baselines/reference/objectLiteralShorthandPropertiesAssignment.types @@ -0,0 +1,68 @@ +=== tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignment.ts === +var id: number = 10000; +>id : number + +var name: string = "my name"; +>name : string + +var person: { name: string; id: number } = { name, id }; +>person : { name: string; id: number; } +>name : string +>id : number +>{ name, id } : { name: string; id: number; } +>name : string +>id : number + +function foo( obj:{ name: string }): void { }; +>foo : (obj: { name: string; }) => void +>obj : { name: string; } +>name : string + +function bar(name: string, id: number) { return { name, id }; } +>bar : (name: string, id: number) => { name: string; id: number; } +>name : string +>id : number +>{ name, id } : { name: string; id: number; } +>name : string +>id : number + +function bar1(name: string, id: number) { return { name }; } +>bar1 : (name: string, id: number) => { name: string; } +>name : string +>id : number +>{ name } : { name: string; } +>name : string + +function baz(name: string, id: number): { name: string; id: number } { return { name, id }; } +>baz : (name: string, id: number) => { name: string; id: number; } +>name : string +>id : number +>name : string +>id : number +>{ name, id } : { name: string; id: number; } +>name : string +>id : number + +foo(person); +>foo(person) : void +>foo : (obj: { name: string; }) => void +>person : { name: string; id: number; } + +var person1 = bar("Hello", 5); +>person1 : { name: string; id: number; } +>bar("Hello", 5) : { name: string; id: number; } +>bar : (name: string, id: number) => { name: string; id: number; } + +var person2: { name: string } = bar("Hello", 5); +>person2 : { name: string; } +>name : string +>bar("Hello", 5) : { name: string; id: number; } +>bar : (name: string, id: number) => { name: string; id: number; } + +var person3: { name: string; id:number } = bar("Hello", 5); +>person3 : { name: string; id: number; } +>name : string +>id : number +>bar("Hello", 5) : { name: string; id: number; } +>bar : (name: string, id: number) => { name: string; id: number; } + diff --git a/tests/baselines/reference/objectLiteralShorthandPropertiesAssignmentES6.js b/tests/baselines/reference/objectLiteralShorthandPropertiesAssignmentES6.js new file mode 100644 index 00000000000..b2f9004b076 --- /dev/null +++ b/tests/baselines/reference/objectLiteralShorthandPropertiesAssignmentES6.js @@ -0,0 +1,36 @@ +//// [objectLiteralShorthandPropertiesAssignmentES6.ts] +var id: number = 10000; +var name: string = "my name"; + +var person: { name: string; id: number } = { name, id }; +function foo(obj: { name: string }): void { }; +function bar(name: string, id: number) { return { name, id }; } +function bar1(name: string, id: number) { return { name }; } +function baz(name: string, id: number): { name: string; id: number } { return { name, id }; } + +foo(person); +var person1 = bar("Hello", 5); +var person2: { name: string } = bar("Hello", 5); +var person3: { name: string; id: number } = bar("Hello", 5); + + +//// [objectLiteralShorthandPropertiesAssignmentES6.js] +var id = 10000; +var name = "my name"; +var person = { name, id }; +function foo(obj) { +} +; +function bar(name, id) { + return { name, id }; +} +function bar1(name, id) { + return { name }; +} +function baz(name, id) { + return { name, id }; +} +foo(person); +var person1 = bar("Hello", 5); +var person2 = bar("Hello", 5); +var person3 = bar("Hello", 5); diff --git a/tests/baselines/reference/objectLiteralShorthandPropertiesAssignmentES6.types b/tests/baselines/reference/objectLiteralShorthandPropertiesAssignmentES6.types new file mode 100644 index 00000000000..38791fc1beb --- /dev/null +++ b/tests/baselines/reference/objectLiteralShorthandPropertiesAssignmentES6.types @@ -0,0 +1,68 @@ +=== tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentES6.ts === +var id: number = 10000; +>id : number + +var name: string = "my name"; +>name : string + +var person: { name: string; id: number } = { name, id }; +>person : { name: string; id: number; } +>name : string +>id : number +>{ name, id } : { name: string; id: number; } +>name : string +>id : number + +function foo(obj: { name: string }): void { }; +>foo : (obj: { name: string; }) => void +>obj : { name: string; } +>name : string + +function bar(name: string, id: number) { return { name, id }; } +>bar : (name: string, id: number) => { name: string; id: number; } +>name : string +>id : number +>{ name, id } : { name: string; id: number; } +>name : string +>id : number + +function bar1(name: string, id: number) { return { name }; } +>bar1 : (name: string, id: number) => { name: string; } +>name : string +>id : number +>{ name } : { name: string; } +>name : string + +function baz(name: string, id: number): { name: string; id: number } { return { name, id }; } +>baz : (name: string, id: number) => { name: string; id: number; } +>name : string +>id : number +>name : string +>id : number +>{ name, id } : { name: string; id: number; } +>name : string +>id : number + +foo(person); +>foo(person) : void +>foo : (obj: { name: string; }) => void +>person : { name: string; id: number; } + +var person1 = bar("Hello", 5); +>person1 : { name: string; id: number; } +>bar("Hello", 5) : { name: string; id: number; } +>bar : (name: string, id: number) => { name: string; id: number; } + +var person2: { name: string } = bar("Hello", 5); +>person2 : { name: string; } +>name : string +>bar("Hello", 5) : { name: string; id: number; } +>bar : (name: string, id: number) => { name: string; id: number; } + +var person3: { name: string; id: number } = bar("Hello", 5); +>person3 : { name: string; id: number; } +>name : string +>id : number +>bar("Hello", 5) : { name: string; id: number; } +>bar : (name: string, id: number) => { name: string; id: number; } + diff --git a/tests/baselines/reference/objectLiteralShorthandPropertiesAssignmentError.errors.txt b/tests/baselines/reference/objectLiteralShorthandPropertiesAssignmentError.errors.txt new file mode 100644 index 00000000000..2db47d0f7ae --- /dev/null +++ b/tests/baselines/reference/objectLiteralShorthandPropertiesAssignmentError.errors.txt @@ -0,0 +1,44 @@ +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentError.ts(5,16): error TS1131: Property or signature expected. +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentError.ts(5,25): error TS1128: Declaration or statement expected. +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentError.ts(6,53): error TS1005: ';' expected. +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentError.ts(4,5): error TS2322: Type '{ name: string; id: number; }' is not assignable to type '{ b: string; id: number; }'. + Property 'b' is missing in type '{ name: string; id: number; }'. +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentError.ts(5,22): error TS2403: Subsequent variable declarations must have the same type. Variable 'id' must be of type 'number', but here has type 'any'. +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentError.ts(6,79): error TS2322: Type '{ name: string; id: number; }' is not assignable to type '{ id: string; name: number; }'. + Types of property 'id' are incompatible. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentError.ts(8,5): error TS2345: Argument of type '{ name: string; id: number; }' is not assignable to parameter of type '{ name: string; id: boolean; }'. + Types of property 'id' are incompatible. + Type 'number' is not assignable to type 'boolean'. + + +==== tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentError.ts (7 errors) ==== + var id: number = 10000; + var name: string = "my name"; + + var person: { b: string; id: number } = { name, id }; // error + ~~~~~~ +!!! error TS2322: Type '{ name: string; id: number; }' is not assignable to type '{ b: string; id: number; }'. +!!! error TS2322: Property 'b' is missing in type '{ name: string; id: number; }'. + var person1: { name, id }; // error: can't use short-hand property assignment in type position + ~~~~ +!!! error TS1131: Property or signature expected. + ~ +!!! error TS1128: Declaration or statement expected. + ~~ +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'id' must be of type 'number', but here has type 'any'. + function foo(name: string, id: number): { id: string, name: number } { return { name, id }; } // error + ~ +!!! error TS1005: ';' expected. + ~~~~~~~~~~~~ +!!! error TS2322: Type '{ name: string; id: number; }' is not assignable to type '{ id: string; name: number; }'. +!!! error TS2322: Types of property 'id' are incompatible. +!!! error TS2322: Type 'number' is not assignable to type 'string'. + function bar(obj: { name: string; id: boolean }) { } + bar({ name, id }); // error + ~~~~~~~~~~~~ +!!! error TS2345: Argument of type '{ name: string; id: number; }' is not assignable to parameter of type '{ name: string; id: boolean; }'. +!!! error TS2345: Types of property 'id' are incompatible. +!!! error TS2345: Type 'number' is not assignable to type 'boolean'. + + \ No newline at end of file diff --git a/tests/baselines/reference/objectLiteralShorthandPropertiesAssignmentErrorFromMissingIdentifier.errors.txt b/tests/baselines/reference/objectLiteralShorthandPropertiesAssignmentErrorFromMissingIdentifier.errors.txt new file mode 100644 index 00000000000..708bbb0935f --- /dev/null +++ b/tests/baselines/reference/objectLiteralShorthandPropertiesAssignmentErrorFromMissingIdentifier.errors.txt @@ -0,0 +1,48 @@ +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentErrorFromMissingIdentifier.ts(5,55): error TS1005: ';' expected. +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentErrorFromMissingIdentifier.ts(6,55): error TS1005: ';' expected. +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentErrorFromMissingIdentifier.ts(7,16): error TS1131: Property or signature expected. +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentErrorFromMissingIdentifier.ts(7,25): error TS1128: Declaration or statement expected. +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentErrorFromMissingIdentifier.ts(8,28): error TS1005: ';' expected. +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentErrorFromMissingIdentifier.ts(4,5): error TS2322: Type '{ name: string; id: number; }' is not assignable to type '{ b: string; id: number; }'. + Property 'b' is missing in type '{ name: string; id: number; }'. +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentErrorFromMissingIdentifier.ts(5,79): error TS2322: Type '{ name: string; id: number; }' is not assignable to type '{ name: number; id: string; }'. + Types of property 'name' are incompatible. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentErrorFromMissingIdentifier.ts(7,22): error TS2403: Subsequent variable declarations must have the same type. Variable 'id' must be of type 'number', but here has type 'any'. +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentErrorFromMissingIdentifier.ts(8,5): error TS2322: Type '{ name: number; id: string; }' is not assignable to type '{ name: string; id: number; }'. + Types of property 'name' are incompatible. + Type 'number' is not assignable to type 'string'. + + +==== tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentErrorFromMissingIdentifier.ts (9 errors) ==== + var id: number = 10000; + var name: string = "my name"; + + var person: { b: string; id: number } = { name, id }; // error + ~~~~~~ +!!! error TS2322: Type '{ name: string; id: number; }' is not assignable to type '{ b: string; id: number; }'. +!!! error TS2322: Property 'b' is missing in type '{ name: string; id: number; }'. + function bar(name: string, id: number): { name: number, id: string } { return { name, id }; } // error + ~ +!!! error TS1005: ';' expected. + ~~~~~~~~~~~~ +!!! error TS2322: Type '{ name: string; id: number; }' is not assignable to type '{ name: number; id: string; }'. +!!! error TS2322: Types of property 'name' are incompatible. +!!! error TS2322: Type 'string' is not assignable to type 'number'. + function foo(name: string, id: number): { name: string, id: number } { return { name, id }; } // error + ~ +!!! error TS1005: ';' expected. + var person1: { name, id }; // error : Can't use shorthand in the type position + ~~~~ +!!! error TS1131: Property or signature expected. + ~ +!!! error TS1128: Declaration or statement expected. + ~~ +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'id' must be of type 'number', but here has type 'any'. + var person2: { name: string, id: number } = bar("hello", 5); + ~ +!!! error TS1005: ';' expected. + ~~~~~~~ +!!! error TS2322: Type '{ name: number; id: string; }' is not assignable to type '{ name: string; id: number; }'. +!!! error TS2322: Types of property 'name' are incompatible. +!!! error TS2322: Type 'number' is not assignable to type 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/objectLiteralShorthandPropertiesES6.js b/tests/baselines/reference/objectLiteralShorthandPropertiesES6.js new file mode 100644 index 00000000000..b398a231351 --- /dev/null +++ b/tests/baselines/reference/objectLiteralShorthandPropertiesES6.js @@ -0,0 +1,39 @@ +//// [objectLiteralShorthandPropertiesES6.ts] +var a, b, c; + +var x1 = { + a +}; + +var x2 = { + a, +} + +var x3 = { + a: 0, + b, + c, + d() { }, + x3, + parent: x3 +}; + + + +//// [objectLiteralShorthandPropertiesES6.js] +var a, b, c; +var x1 = { + a +}; +var x2 = { + a, +}; +var x3 = { + a: 0, + b, + c, + d: function () { + }, + x3, + parent: x3 +}; diff --git a/tests/baselines/reference/objectLiteralShorthandPropertiesES6.types b/tests/baselines/reference/objectLiteralShorthandPropertiesES6.types new file mode 100644 index 00000000000..0383a3f5d2e --- /dev/null +++ b/tests/baselines/reference/objectLiteralShorthandPropertiesES6.types @@ -0,0 +1,50 @@ +=== tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesES6.ts === +var a, b, c; +>a : any +>b : any +>c : any + +var x1 = { +>x1 : { a: any; } +>{ a} : { a: any; } + + a +>a : any + +}; + +var x2 = { +>x2 : { a: any; } +>{ a,} : { a: any; } + + a, +>a : any +} + +var x3 = { +>x3 : any +>{ a: 0, b, c, d() { }, x3, parent: x3} : { a: number; b: any; c: any; d: () => void; x3: any; parent: any; } + + a: 0, +>a : number + + b, +>b : any + + c, +>c : any + + d() { }, +>d : () => void +>d() { } : () => void + + x3, +>x3 : any + + parent: x3 +>parent : any +>x3 : any + +}; + + diff --git a/tests/baselines/reference/objectLiteralShorthandPropertiesErrorFromNoneExistingIdentifier.errors.txt b/tests/baselines/reference/objectLiteralShorthandPropertiesErrorFromNoneExistingIdentifier.errors.txt new file mode 100644 index 00000000000..fcd04b27754 --- /dev/null +++ b/tests/baselines/reference/objectLiteralShorthandPropertiesErrorFromNoneExistingIdentifier.errors.txt @@ -0,0 +1,11 @@ +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNoneExistingIdentifier.ts(3,5): error TS2304: Cannot find name 'undefinedVariable'. + + +==== tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNoneExistingIdentifier.ts (1 errors) ==== + var x = { + x, // OK + undefinedVariable // Error + ~~~~~~~~~~~~~~~~~ +!!! error TS2304: Cannot find name 'undefinedVariable'. + } + \ No newline at end of file diff --git a/tests/baselines/reference/objectLiteralShorthandPropertiesErrorFromNoneExistingIdentifier.js b/tests/baselines/reference/objectLiteralShorthandPropertiesErrorFromNoneExistingIdentifier.js new file mode 100644 index 00000000000..6050e5b756f --- /dev/null +++ b/tests/baselines/reference/objectLiteralShorthandPropertiesErrorFromNoneExistingIdentifier.js @@ -0,0 +1,12 @@ +//// [objectLiteralShorthandPropertiesErrorFromNoneExistingIdentifier.ts] +var x = { + x, // OK + undefinedVariable // Error +} + + +//// [objectLiteralShorthandPropertiesErrorFromNoneExistingIdentifier.js] +var x = { + x: x, + undefinedVariable: undefinedVariable // Error +}; diff --git a/tests/baselines/reference/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.errors.txt b/tests/baselines/reference/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.errors.txt new file mode 100644 index 00000000000..3c5f4e97d80 --- /dev/null +++ b/tests/baselines/reference/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.errors.txt @@ -0,0 +1,77 @@ +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.ts(3,20): error TS1005: ':' expected. +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.ts(4,7): error TS1005: ':' expected. +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.ts(5,10): error TS1005: '(' expected. +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.ts(6,10): error TS1005: '(' expected. +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.ts(7,9): error TS1005: ':' expected. +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.ts(8,10): error TS1005: ':' expected. +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.ts(9,8): error TS1005: ':' expected. +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.ts(10,10): error TS1005: ':' expected. +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.ts(12,1): error TS1005: ':' expected. +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.ts(15,6): error TS1005: ',' expected. +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.ts(16,6): error TS1005: ',' expected. +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.ts(17,6): error TS1005: '=' expected. +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.ts(18,1): error TS1128: Declaration or statement expected. +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.ts(20,17): error TS1005: ':' expected. +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.ts(5,9): error TS2378: A 'get' accessor must return a value or consist of a single 'throw' statement. +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.ts(15,5): error TS2300: Duplicate identifier 'a'. +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.ts(15,7): error TS2304: Cannot find name 'b'. +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.ts(16,5): error TS2300: Duplicate identifier 'a'. + + +==== tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.ts (18 errors) ==== + // errors + var y = { + "stringLiteral", + ~ +!!! error TS1005: ':' expected. + 42, + ~ +!!! error TS1005: ':' expected. + get e, + ~ +!!! error TS1005: '(' expected. + ~ +!!! error TS2378: A 'get' accessor must return a value or consist of a single 'throw' statement. + set f, + ~ +!!! error TS1005: '(' expected. + this, + ~ +!!! error TS1005: ':' expected. + super, + ~ +!!! error TS1005: ':' expected. + var, + ~ +!!! error TS1005: ':' expected. + class, + ~ +!!! error TS1005: ':' expected. + typeof + }; + ~ +!!! error TS1005: ':' expected. + + var x = { + a.b, + ~ +!!! error TS1005: ',' expected. + ~ +!!! error TS2300: Duplicate identifier 'a'. + ~ +!!! error TS2304: Cannot find name 'b'. + a["ss"], + ~ +!!! error TS1005: ',' expected. + ~ +!!! error TS2300: Duplicate identifier 'a'. + a[1], + ~ +!!! error TS1005: '=' expected. + }; + ~ +!!! error TS1128: Declaration or statement expected. + + var v = { class }; // error + ~ +!!! error TS1005: ':' expected. \ No newline at end of file diff --git a/tests/baselines/reference/objectLiteralShorthandPropertiesErrorWithModule.errors.txt b/tests/baselines/reference/objectLiteralShorthandPropertiesErrorWithModule.errors.txt new file mode 100644 index 00000000000..f5fd8ed53f2 --- /dev/null +++ b/tests/baselines/reference/objectLiteralShorthandPropertiesErrorWithModule.errors.txt @@ -0,0 +1,24 @@ +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorWithModule.ts(10,10): error TS1005: ',' expected. +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorWithModule.ts(14,3): error TS2339: Property 'y' does not exist on type 'typeof m'. + + +==== tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorWithModule.ts (2 errors) ==== + // module export + var x = "Foo"; + module m { + export var x; + } + + module n { + var z = 10000; + export var y = { + m.x // error + ~ +!!! error TS1005: ',' expected. + }; + } + + m.y.x; + ~ +!!! error TS2339: Property 'y' does not exist on type 'typeof m'. + \ No newline at end of file diff --git a/tests/baselines/reference/objectLiteralShorthandPropertiesFunctionArgument.js b/tests/baselines/reference/objectLiteralShorthandPropertiesFunctionArgument.js new file mode 100644 index 00000000000..f6e20b605b6 --- /dev/null +++ b/tests/baselines/reference/objectLiteralShorthandPropertiesFunctionArgument.js @@ -0,0 +1,20 @@ +//// [objectLiteralShorthandPropertiesFunctionArgument.ts] +var id: number = 10000; +var name: string = "my name"; + +var person = { name, id }; + +function foo(p: { name: string; id: number }) { } +foo(person); + + +var obj = { name: name, id: id }; + +//// [objectLiteralShorthandPropertiesFunctionArgument.js] +var id = 10000; +var name = "my name"; +var person = { name: name, id: id }; +function foo(p) { +} +foo(person); +var obj = { name: name, id: id }; diff --git a/tests/baselines/reference/objectLiteralShorthandPropertiesFunctionArgument.types b/tests/baselines/reference/objectLiteralShorthandPropertiesFunctionArgument.types new file mode 100644 index 00000000000..9b4261a74be --- /dev/null +++ b/tests/baselines/reference/objectLiteralShorthandPropertiesFunctionArgument.types @@ -0,0 +1,33 @@ +=== tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesFunctionArgument.ts === +var id: number = 10000; +>id : number + +var name: string = "my name"; +>name : string + +var person = { name, id }; +>person : { name: string; id: number; } +>{ name, id } : { name: string; id: number; } +>name : string +>id : number + +function foo(p: { name: string; id: number }) { } +>foo : (p: { name: string; id: number; }) => void +>p : { name: string; id: number; } +>name : string +>id : number + +foo(person); +>foo(person) : void +>foo : (p: { name: string; id: number; }) => void +>person : { name: string; id: number; } + + +var obj = { name: name, id: id }; +>obj : { name: string; id: number; } +>{ name: name, id: id } : { name: string; id: number; } +>name : string +>name : string +>id : number +>id : number + diff --git a/tests/baselines/reference/objectLiteralShorthandPropertiesFunctionArgument2.errors.txt b/tests/baselines/reference/objectLiteralShorthandPropertiesFunctionArgument2.errors.txt new file mode 100644 index 00000000000..44426a8afb0 --- /dev/null +++ b/tests/baselines/reference/objectLiteralShorthandPropertiesFunctionArgument2.errors.txt @@ -0,0 +1,14 @@ +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesFunctionArgument2.ts(7,5): error TS2345: Argument of type '{ name: string; id: number; }' is not assignable to parameter of type '{ a: string; id: number; }'. + + +==== tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesFunctionArgument2.ts (1 errors) ==== + var id: number = 10000; + var name: string = "my name"; + + var person = { name, id }; + + function foo(p: { a: string; id: number }) { } + foo(person); // error + ~~~~~~ +!!! error TS2345: Argument of type '{ name: string; id: number; }' is not assignable to parameter of type '{ a: string; id: number; }'. + \ No newline at end of file diff --git a/tests/baselines/reference/objectLiteralShorthandPropertiesFunctionArgument2.js b/tests/baselines/reference/objectLiteralShorthandPropertiesFunctionArgument2.js new file mode 100644 index 00000000000..2f3535ef78a --- /dev/null +++ b/tests/baselines/reference/objectLiteralShorthandPropertiesFunctionArgument2.js @@ -0,0 +1,17 @@ +//// [objectLiteralShorthandPropertiesFunctionArgument2.ts] +var id: number = 10000; +var name: string = "my name"; + +var person = { name, id }; + +function foo(p: { a: string; id: number }) { } +foo(person); // error + + +//// [objectLiteralShorthandPropertiesFunctionArgument2.js] +var id = 10000; +var name = "my name"; +var person = { name: name, id: id }; +function foo(p) { +} +foo(person); // error diff --git a/tests/baselines/reference/objectLiteralShorthandPropertiesWithModule.js b/tests/baselines/reference/objectLiteralShorthandPropertiesWithModule.js new file mode 100644 index 00000000000..e2eb1fc128c --- /dev/null +++ b/tests/baselines/reference/objectLiteralShorthandPropertiesWithModule.js @@ -0,0 +1,30 @@ +//// [objectLiteralShorthandPropertiesWithModule.ts] +// module export + +module m { + export var x; +} + +module m { + var z = x; + var y = { + a: x, + x + }; +} + + +//// [objectLiteralShorthandPropertiesWithModule.js] +// module export +var m; +(function (m) { + m.x; +})(m || (m = {})); +var m; +(function (m) { + var z = m.x; + var y = { + a: m.x, + x: m.x + }; +})(m || (m = {})); diff --git a/tests/baselines/reference/objectLiteralShorthandPropertiesWithModule.types b/tests/baselines/reference/objectLiteralShorthandPropertiesWithModule.types new file mode 100644 index 00000000000..77e139a3426 --- /dev/null +++ b/tests/baselines/reference/objectLiteralShorthandPropertiesWithModule.types @@ -0,0 +1,31 @@ +=== tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesWithModule.ts === +// module export + +module m { +>m : typeof m + + export var x; +>x : any +} + +module m { +>m : typeof m + + var z = x; +>z : any +>x : any + + var y = { +>y : { a: any; x: any; } +>{ a: x, x } : { a: any; x: any; } + + a: x, +>a : any +>x : any + + x +>x : any + + }; +} + diff --git a/tests/baselines/reference/objectLiteralShorthandPropertiesWithModuleES6.js b/tests/baselines/reference/objectLiteralShorthandPropertiesWithModuleES6.js new file mode 100644 index 00000000000..edb4e6c2953 --- /dev/null +++ b/tests/baselines/reference/objectLiteralShorthandPropertiesWithModuleES6.js @@ -0,0 +1,28 @@ +//// [objectLiteralShorthandPropertiesWithModuleES6.ts] + +module m { + export var x; +} + +module m { + var z = x; + var y = { + a: x, + x + }; +} + + +//// [objectLiteralShorthandPropertiesWithModuleES6.js] +var m; +(function (m) { + m.x; +})(m || (m = {})); +var m; +(function (m) { + var z = m.x; + var y = { + a: m.x, + x: m.x + }; +})(m || (m = {})); diff --git a/tests/baselines/reference/objectLiteralShorthandPropertiesWithModuleES6.types b/tests/baselines/reference/objectLiteralShorthandPropertiesWithModuleES6.types new file mode 100644 index 00000000000..1030010d6c6 --- /dev/null +++ b/tests/baselines/reference/objectLiteralShorthandPropertiesWithModuleES6.types @@ -0,0 +1,30 @@ +=== tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesWithModuleES6.ts === + +module m { +>m : typeof m + + export var x; +>x : any +} + +module m { +>m : typeof m + + var z = x; +>z : any +>x : any + + var y = { +>y : { a: any; x: any; } +>{ a: x, x } : { a: any; x: any; } + + a: x, +>a : any +>x : any + + x +>x : any + + }; +} + diff --git a/tests/baselines/reference/objectTypesWithOptionalProperties.errors.txt b/tests/baselines/reference/objectTypesWithOptionalProperties.errors.txt index 0622b7badb0..e73e8adc930 100644 --- a/tests/baselines/reference/objectTypesWithOptionalProperties.errors.txt +++ b/tests/baselines/reference/objectTypesWithOptionalProperties.errors.txt @@ -1,10 +1,9 @@ tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWithOptionalProperties.ts(12,6): error TS1112: A class member cannot be declared optional. tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWithOptionalProperties.ts(20,6): error TS1112: A class member cannot be declared optional. -tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWithOptionalProperties.ts(24,6): error TS1005: ':' expected. -tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWithOptionalProperties.ts(24,7): error TS1109: Expression expected. +tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWithOptionalProperties.ts(24,6): error TS1160: A object member cannot be declared optional. -==== tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWithOptionalProperties.ts (4 errors) ==== +==== tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWithOptionalProperties.ts (3 errors) ==== // Basic uses of optional properties var a: { @@ -33,8 +32,6 @@ tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWith var b = { x?: 1 // error - ~ -!!! error TS1005: ':' expected. - ~ -!!! error TS1109: Expression expected. + +!!! error TS1160: A object member cannot be declared optional. } \ No newline at end of file diff --git a/tests/baselines/reference/parser512097.errors.txt b/tests/baselines/reference/parser512097.errors.txt index 3963d969c34..181060db95d 100644 --- a/tests/baselines/reference/parser512097.errors.txt +++ b/tests/baselines/reference/parser512097.errors.txt @@ -1,13 +1,16 @@ -tests/cases/conformance/parser/ecmascript5/RegressionTests/parser512097.ts(1,14): error TS1005: ':' expected. +tests/cases/conformance/parser/ecmascript5/RegressionTests/parser512097.ts(1,14): error TS1005: ',' expected. tests/cases/conformance/parser/ecmascript5/RegressionTests/parser512097.ts(1,16): error TS1128: Declaration or statement expected. +tests/cases/conformance/parser/ecmascript5/RegressionTests/parser512097.ts(1,12): error TS2304: Cannot find name 'aa'. -==== tests/cases/conformance/parser/ecmascript5/RegressionTests/parser512097.ts (2 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/RegressionTests/parser512097.ts (3 errors) ==== var tt = { aa; } // After this point, no useful parsing occurs in the entire file ~ -!!! error TS1005: ':' expected. +!!! error TS1005: ',' expected. ~ !!! error TS1128: Declaration or statement expected. + ~~ +!!! error TS2304: Cannot find name 'aa'. if (true) { } \ No newline at end of file diff --git a/tests/baselines/reference/parserErrorRecovery_ObjectLiteral2.errors.txt b/tests/baselines/reference/parserErrorRecovery_ObjectLiteral2.errors.txt index 55667d42de5..1c526f0c9ec 100644 --- a/tests/baselines/reference/parserErrorRecovery_ObjectLiteral2.errors.txt +++ b/tests/baselines/reference/parserErrorRecovery_ObjectLiteral2.errors.txt @@ -1,11 +1,14 @@ -tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ObjectLiterals/parserErrorRecovery_ObjectLiteral2.ts(2,1): error TS1005: ':' expected. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ObjectLiterals/parserErrorRecovery_ObjectLiteral2.ts(2,1): error TS1005: ',' expected. tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ObjectLiterals/parserErrorRecovery_ObjectLiteral2.ts(2,7): error TS1005: ':' expected. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ObjectLiterals/parserErrorRecovery_ObjectLiteral2.ts(1,11): error TS2304: Cannot find name 'a'. -==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ObjectLiterals/parserErrorRecovery_ObjectLiteral2.ts (2 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ObjectLiterals/parserErrorRecovery_ObjectLiteral2.ts (3 errors) ==== var v = { a + ~ +!!! error TS2304: Cannot find name 'a'. return; ~~~~~~ -!!! error TS1005: ':' expected. +!!! error TS1005: ',' expected. ~ !!! error TS1005: ':' expected. \ No newline at end of file diff --git a/tests/baselines/reference/recursiveTypeComparison.js b/tests/baselines/reference/recursiveTypeComparison.js new file mode 100644 index 00000000000..8195360de17 --- /dev/null +++ b/tests/baselines/reference/recursiveTypeComparison.js @@ -0,0 +1,21 @@ +//// [recursiveTypeComparison.ts] +// Before fix this would take an exceeding long time to complete (#1170) + +interface Observable { + // This member can't be of type T, Property, or Observable + needThisOne: Observable; + // Add more to make it slower + expo1: Property; // 0.31 seconds in check + expo2: Property; // 3.11 seconds + expo3: Property; // 82.28 seconds +} +interface Property extends Observable { } + +var p: Observable<{}>; +var stuck: Property = p; + + +//// [recursiveTypeComparison.js] +// Before fix this would take an exceeding long time to complete (#1170) +var p; +var stuck = p; diff --git a/tests/baselines/reference/recursiveTypeComparison.types b/tests/baselines/reference/recursiveTypeComparison.types new file mode 100644 index 00000000000..5504de74d85 --- /dev/null +++ b/tests/baselines/reference/recursiveTypeComparison.types @@ -0,0 +1,44 @@ +=== tests/cases/compiler/recursiveTypeComparison.ts === +// Before fix this would take an exceeding long time to complete (#1170) + +interface Observable { +>Observable : Observable +>T : T + + // This member can't be of type T, Property, or Observable + needThisOne: Observable; +>needThisOne : Observable +>Observable : Observable +>T : T + + // Add more to make it slower + expo1: Property; // 0.31 seconds in check +>expo1 : Property +>Property : Property +>T : T + + expo2: Property; // 3.11 seconds +>expo2 : Property +>Property : Property +>T : T + + expo3: Property; // 82.28 seconds +>expo3 : Property +>Property : Property +>T : T +} +interface Property extends Observable { } +>Property : Property +>T : T +>Observable : Observable +>T : T + +var p: Observable<{}>; +>p : Observable<{}> +>Observable : Observable + +var stuck: Property = p; +>stuck : Property +>Property : Property +>p : Observable<{}> + diff --git a/tests/baselines/reference/recursiveTypeComparison2.errors.txt b/tests/baselines/reference/recursiveTypeComparison2.errors.txt new file mode 100644 index 00000000000..ce6311c0089 --- /dev/null +++ b/tests/baselines/reference/recursiveTypeComparison2.errors.txt @@ -0,0 +1,36 @@ +tests/cases/compiler/recursiveTypeComparison2.ts(13,80): error TS2304: Cannot find name 'StateValue'. + + +==== tests/cases/compiler/recursiveTypeComparison2.ts (1 errors) ==== + // Before fix this would cause compiler to hang (#1170) + + declare module Bacon { + interface Event { + } + interface Error extends Event { + } + interface Observable { + zip(other: EventStream, f: (a: T, b: U) => V): EventStream; + slidingWindow(max: number, min?: number): Property; + log(): Observable; + combine(other: Observable, f: (a: T, b: U) => V): Property; + withStateMachine(initState: U, f: (state: U, event: Event) => StateValue): EventStream; + ~~~~~~~~~~~~~~~~ +!!! error TS2304: Cannot find name 'StateValue'. + decode(mapping: Object): Property; + awaiting(other: Observable): Property; + endOnError(f?: (value: T) => boolean): Observable; + withHandler(f: (event: Event) => any): Observable; + name(name: string): Observable; + withDescription(...args: any[]): Observable; + } + interface Property extends Observable { + } + interface EventStream extends Observable { + } + interface Bus extends EventStream { + } + var Bus: new () => Bus; + } + + var stuck: Bacon.Bus = new Bacon.Bus(); \ No newline at end of file diff --git a/tests/baselines/reference/recursiveTypeComparison2.js b/tests/baselines/reference/recursiveTypeComparison2.js new file mode 100644 index 00000000000..5844ff3be44 --- /dev/null +++ b/tests/baselines/reference/recursiveTypeComparison2.js @@ -0,0 +1,35 @@ +//// [recursiveTypeComparison2.ts] +// Before fix this would cause compiler to hang (#1170) + +declare module Bacon { + interface Event { + } + interface Error extends Event { + } + interface Observable { + zip(other: EventStream, f: (a: T, b: U) => V): EventStream; + slidingWindow(max: number, min?: number): Property; + log(): Observable; + combine(other: Observable, f: (a: T, b: U) => V): Property; + withStateMachine(initState: U, f: (state: U, event: Event) => StateValue): EventStream; + decode(mapping: Object): Property; + awaiting(other: Observable): Property; + endOnError(f?: (value: T) => boolean): Observable; + withHandler(f: (event: Event) => any): Observable; + name(name: string): Observable; + withDescription(...args: any[]): Observable; + } + interface Property extends Observable { + } + interface EventStream extends Observable { + } + interface Bus extends EventStream { + } + var Bus: new () => Bus; +} + +var stuck: Bacon.Bus = new Bacon.Bus(); + +//// [recursiveTypeComparison2.js] +// Before fix this would cause compiler to hang (#1170) +var stuck = new Bacon.Bus(); diff --git a/tests/cases/compiler/recursiveTypeComparison.ts b/tests/cases/compiler/recursiveTypeComparison.ts new file mode 100644 index 00000000000..6ba96cb3aad --- /dev/null +++ b/tests/cases/compiler/recursiveTypeComparison.ts @@ -0,0 +1,14 @@ +// Before fix this would take an exceeding long time to complete (#1170) + +interface Observable { + // This member can't be of type T, Property, or Observable + needThisOne: Observable; + // Add more to make it slower + expo1: Property; // 0.31 seconds in check + expo2: Property; // 3.11 seconds + expo3: Property; // 82.28 seconds +} +interface Property extends Observable { } + +var p: Observable<{}>; +var stuck: Property = p; diff --git a/tests/cases/compiler/recursiveTypeComparison2.ts b/tests/cases/compiler/recursiveTypeComparison2.ts new file mode 100644 index 00000000000..6a781437abe --- /dev/null +++ b/tests/cases/compiler/recursiveTypeComparison2.ts @@ -0,0 +1,30 @@ +// Before fix this would cause compiler to hang (#1170) + +declare module Bacon { + interface Event { + } + interface Error extends Event { + } + interface Observable { + zip(other: EventStream, f: (a: T, b: U) => V): EventStream; + slidingWindow(max: number, min?: number): Property; + log(): Observable; + combine(other: Observable, f: (a: T, b: U) => V): Property; + withStateMachine(initState: U, f: (state: U, event: Event) => StateValue): EventStream; + decode(mapping: Object): Property; + awaiting(other: Observable): Property; + endOnError(f?: (value: T) => boolean): Observable; + withHandler(f: (event: Event) => any): Observable; + name(name: string): Observable; + withDescription(...args: any[]): Observable; + } + interface Property extends Observable { + } + interface EventStream extends Observable { + } + interface Bus extends EventStream { + } + var Bus: new () => Bus; +} + +var stuck: Bacon.Bus = new Bacon.Bus(); \ No newline at end of file diff --git a/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandProperties.ts b/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandProperties.ts new file mode 100644 index 00000000000..ffeab289584 --- /dev/null +++ b/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandProperties.ts @@ -0,0 +1,20 @@ +// @target: es5 +var a, b, c; + +var x1 = { + a +}; + +var x2 = { + a, +} + +var x3 = { + a: 0, + b, + c, + d() { }, + x3, + parent: x3 +}; + diff --git a/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignment.ts b/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignment.ts new file mode 100644 index 00000000000..38782100166 --- /dev/null +++ b/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignment.ts @@ -0,0 +1,13 @@ +var id: number = 10000; +var name: string = "my name"; + +var person: { name: string; id: number } = { name, id }; +function foo( obj:{ name: string }): void { }; +function bar(name: string, id: number) { return { name, id }; } +function bar1(name: string, id: number) { return { name }; } +function baz(name: string, id: number): { name: string; id: number } { return { name, id }; } + +foo(person); +var person1 = bar("Hello", 5); +var person2: { name: string } = bar("Hello", 5); +var person3: { name: string; id:number } = bar("Hello", 5); diff --git a/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentES6.ts b/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentES6.ts new file mode 100644 index 00000000000..19fd21b47b5 --- /dev/null +++ b/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentES6.ts @@ -0,0 +1,14 @@ +// @target: es6 +var id: number = 10000; +var name: string = "my name"; + +var person: { name: string; id: number } = { name, id }; +function foo(obj: { name: string }): void { }; +function bar(name: string, id: number) { return { name, id }; } +function bar1(name: string, id: number) { return { name }; } +function baz(name: string, id: number): { name: string; id: number } { return { name, id }; } + +foo(person); +var person1 = bar("Hello", 5); +var person2: { name: string } = bar("Hello", 5); +var person3: { name: string; id: number } = bar("Hello", 5); diff --git a/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentError.ts b/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentError.ts new file mode 100644 index 00000000000..b745b93b3ca --- /dev/null +++ b/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentError.ts @@ -0,0 +1,9 @@ +var id: number = 10000; +var name: string = "my name"; + +var person: { b: string; id: number } = { name, id }; // error +var person1: { name, id }; // error: can't use short-hand property assignment in type position +function foo(name: string, id: number): { id: string, name: number } { return { name, id }; } // error +function bar(obj: { name: string; id: boolean }) { } +bar({ name, id }); // error + diff --git a/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentErrorFromMissingIdentifier.ts b/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentErrorFromMissingIdentifier.ts new file mode 100644 index 00000000000..6b0943a8d77 --- /dev/null +++ b/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentErrorFromMissingIdentifier.ts @@ -0,0 +1,8 @@ +var id: number = 10000; +var name: string = "my name"; + +var person: { b: string; id: number } = { name, id }; // error +function bar(name: string, id: number): { name: number, id: string } { return { name, id }; } // error +function foo(name: string, id: number): { name: string, id: number } { return { name, id }; } // error +var person1: { name, id }; // error : Can't use shorthand in the type position +var person2: { name: string, id: number } = bar("hello", 5); \ No newline at end of file diff --git a/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesES6.ts b/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesES6.ts new file mode 100644 index 00000000000..bf4c2583c07 --- /dev/null +++ b/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesES6.ts @@ -0,0 +1,20 @@ +// @target: es6 +var a, b, c; + +var x1 = { + a +}; + +var x2 = { + a, +} + +var x3 = { + a: 0, + b, + c, + d() { }, + x3, + parent: x3 +}; + diff --git a/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNoneExistingIdentifier.ts b/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNoneExistingIdentifier.ts new file mode 100644 index 00000000000..1f44dc18ae8 --- /dev/null +++ b/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNoneExistingIdentifier.ts @@ -0,0 +1,4 @@ +var x = { + x, // OK + undefinedVariable // Error +} diff --git a/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.ts b/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.ts new file mode 100644 index 00000000000..527154c66bd --- /dev/null +++ b/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.ts @@ -0,0 +1,20 @@ +// errors +var y = { + "stringLiteral", + 42, + get e, + set f, + this, + super, + var, + class, + typeof +}; + +var x = { + a.b, + a["ss"], + a[1], +}; + +var v = { class }; // error \ No newline at end of file diff --git a/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorWithModule.ts b/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorWithModule.ts new file mode 100644 index 00000000000..7da6e7b0c70 --- /dev/null +++ b/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorWithModule.ts @@ -0,0 +1,14 @@ +// module export +var x = "Foo"; +module m { + export var x; +} + +module n { + var z = 10000; + export var y = { + m.x // error + }; +} + +m.y.x; diff --git a/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesFunctionArgument.ts b/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesFunctionArgument.ts new file mode 100644 index 00000000000..c50c4e3fbdf --- /dev/null +++ b/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesFunctionArgument.ts @@ -0,0 +1,10 @@ +var id: number = 10000; +var name: string = "my name"; + +var person = { name, id }; + +function foo(p: { name: string; id: number }) { } +foo(person); + + +var obj = { name: name, id: id }; \ No newline at end of file diff --git a/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesFunctionArgument2.ts b/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesFunctionArgument2.ts new file mode 100644 index 00000000000..45c248a5911 --- /dev/null +++ b/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesFunctionArgument2.ts @@ -0,0 +1,7 @@ +var id: number = 10000; +var name: string = "my name"; + +var person = { name, id }; + +function foo(p: { a: string; id: number }) { } +foo(person); // error diff --git a/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesWithModule.ts b/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesWithModule.ts new file mode 100644 index 00000000000..005885bb901 --- /dev/null +++ b/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesWithModule.ts @@ -0,0 +1,13 @@ +// module export + +module m { + export var x; +} + +module m { + var z = x; + var y = { + a: x, + x + }; +} diff --git a/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesWithModuleES6.ts b/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesWithModuleES6.ts new file mode 100644 index 00000000000..f8937625afe --- /dev/null +++ b/tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesWithModuleES6.ts @@ -0,0 +1,13 @@ +// @target: es6 + +module m { + export var x; +} + +module m { + var z = x; + var y = { + a: x, + x + }; +} diff --git a/tests/cases/fourslash/completionEntryForShorthandPropertyAssignment.ts b/tests/cases/fourslash/completionEntryForShorthandPropertyAssignment.ts new file mode 100644 index 00000000000..dae5762d92c --- /dev/null +++ b/tests/cases/fourslash/completionEntryForShorthandPropertyAssignment.ts @@ -0,0 +1,6 @@ +/// + +//// var person: {name:string; id:number} = {n/**/ + +goTo.marker(); +verify.completionListContains("name", /*text*/ undefined, /*documentation*/ undefined, "property"); \ No newline at end of file diff --git a/tests/cases/fourslash/completionListForShorthandPropertyAssignment.ts b/tests/cases/fourslash/completionListForShorthandPropertyAssignment.ts new file mode 100644 index 00000000000..d8262d71047 --- /dev/null +++ b/tests/cases/fourslash/completionListForShorthandPropertyAssignment.ts @@ -0,0 +1,7 @@ +/// + +//// var person: {name:string; id: number} = { n/**/ + +goTo.marker(); +verify.memberListContains('name'); +verify.memberListContains('id'); \ No newline at end of file diff --git a/tests/cases/fourslash/completionListForShorthandPropertyAssignment2.ts b/tests/cases/fourslash/completionListForShorthandPropertyAssignment2.ts new file mode 100644 index 00000000000..d8262d71047 --- /dev/null +++ b/tests/cases/fourslash/completionListForShorthandPropertyAssignment2.ts @@ -0,0 +1,7 @@ +/// + +//// var person: {name:string; id: number} = { n/**/ + +goTo.marker(); +verify.memberListContains('name'); +verify.memberListContains('id'); \ No newline at end of file diff --git a/tests/cases/fourslash/completionListInTemplateLiteralParts1.ts b/tests/cases/fourslash/completionListInTemplateLiteralParts1.ts index a71584bdbdd..0166546f63e 100644 --- a/tests/cases/fourslash/completionListInTemplateLiteralParts1.ts +++ b/tests/cases/fourslash/completionListInTemplateLiteralParts1.ts @@ -8,4 +8,4 @@ test.markers().forEach(marker => { goTo.position(marker.position); verify.completionListItemsCountIsGreaterThan(0) -}} \ No newline at end of file +}); \ No newline at end of file diff --git a/tests/cases/fourslash/completionListInTemplateLiteralPartsNegatives1.ts b/tests/cases/fourslash/completionListInTemplateLiteralPartsNegatives1.ts index 1624192057b..ac64a41fb56 100644 --- a/tests/cases/fourslash/completionListInTemplateLiteralPartsNegatives1.ts +++ b/tests/cases/fourslash/completionListInTemplateLiteralPartsNegatives1.ts @@ -8,4 +8,4 @@ test.markers().forEach(marker => { goTo.position(marker.position); verify.completionListIsEmpty() -} \ No newline at end of file +}); \ No newline at end of file diff --git a/tests/cases/fourslash/findAllRefsInsideTemplates1.ts b/tests/cases/fourslash/findAllRefsInsideTemplates1.ts index e4501219265..dd4461751de 100644 --- a/tests/cases/fourslash/findAllRefsInsideTemplates1.ts +++ b/tests/cases/fourslash/findAllRefsInsideTemplates1.ts @@ -8,5 +8,5 @@ test.ranges().forEach(targetRange => { test.ranges().forEach(range => { verify.referencesAtPositionContains(range); - } -} \ No newline at end of file + }); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/findAllRefsInsideTemplates2.ts b/tests/cases/fourslash/findAllRefsInsideTemplates2.ts index cafddd4f45b..7f585234082 100644 --- a/tests/cases/fourslash/findAllRefsInsideTemplates2.ts +++ b/tests/cases/fourslash/findAllRefsInsideTemplates2.ts @@ -8,5 +8,5 @@ test.ranges().forEach(targetRange => { test.ranges().forEach(range => { verify.referencesAtPositionContains(range); - } -} \ No newline at end of file + }); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/findAllRefsWithShorthandPropertyAssignment.ts b/tests/cases/fourslash/findAllRefsWithShorthandPropertyAssignment.ts new file mode 100644 index 00000000000..7a1f7a0225f --- /dev/null +++ b/tests/cases/fourslash/findAllRefsWithShorthandPropertyAssignment.ts @@ -0,0 +1,19 @@ +/// + +//// var /*1*/name = "Foo"; +//// +//// var obj = { /*2*/name }; +//// var obj1 = { /*3*/name:name }; +//// obj./*4*/name; + +goTo.marker('1'); +verify.referencesCountIs(3); + +goTo.marker('2'); +verify.referencesCountIs(4); + +goTo.marker('3'); +verify.referencesCountIs(1); + +goTo.marker('4'); +verify.referencesCountIs(2); diff --git a/tests/cases/fourslash/findAllRefsWithShorthandPropertyAssignment2.ts b/tests/cases/fourslash/findAllRefsWithShorthandPropertyAssignment2.ts new file mode 100644 index 00000000000..e9bb7bf02a8 --- /dev/null +++ b/tests/cases/fourslash/findAllRefsWithShorthandPropertyAssignment2.ts @@ -0,0 +1,23 @@ +/// + +//// var /*1*/dx = "Foo"; +//// +//// module M { export var /*2*/dx; } +//// module M { +//// var z = 100; +//// export var y = { /*3*/dx, z }; +//// } +//// M.y./*4*/dx; + +goTo.marker('1'); +debugger; +verify.referencesCountIs(1); + +goTo.marker('2'); +verify.referencesCountIs(2); + +goTo.marker('3'); +verify.referencesCountIs(3); + +goTo.marker('4'); +verify.referencesCountIs(2); diff --git a/tests/cases/fourslash/formattingInMultilineComments.ts b/tests/cases/fourslash/formattingInMultilineComments.ts new file mode 100644 index 00000000000..7c58aa957ac --- /dev/null +++ b/tests/cases/fourslash/formattingInMultilineComments.ts @@ -0,0 +1,14 @@ +/// + +////var x = function() { +//// if (true) { +//// /*1*/} else {/*2*/ +////} +//// +////// newline at the end of the file + +goTo.marker("2"); +edit.insertLine(""); +goTo.marker("1"); +// else formating should not be affected +verify.currentLineContentIs(' } else {'); diff --git a/tests/cases/fourslash/getOccurrencesReturnBroken.ts b/tests/cases/fourslash/getOccurrencesReturnBroken.ts index e740e7f2bb3..08ec794f7e8 100644 --- a/tests/cases/fourslash/getOccurrencesReturnBroken.ts +++ b/tests/cases/fourslash/getOccurrencesReturnBroken.ts @@ -51,4 +51,4 @@ for (var i = 1; i <= test.markers().length; i++) { verify.occurrencesAtPositionCount(1); // 'return' is an instance member break; } -}); \ No newline at end of file +} \ No newline at end of file diff --git a/tests/cases/fourslash/quickInfoForShorthandProperty.ts b/tests/cases/fourslash/quickInfoForShorthandProperty.ts new file mode 100644 index 00000000000..21ba9db683d --- /dev/null +++ b/tests/cases/fourslash/quickInfoForShorthandProperty.ts @@ -0,0 +1,21 @@ +/// + +//// var name1 = undefined, id1 = undefined; +//// var /*obj1*/obj1 = {/*name1*/name1, /*id1*/id1}; +//// var name2 = "Hello"; +//// var id2 = 10000; +//// var /*obj2*/obj2 = {/*name2*/name2, /*id2*/id2}; + +goTo.marker("obj1"); +verify.quickInfoIs("(var) obj1: {\n name1: any;\n id1: any;\n}"); +goTo.marker("name1"); +verify.quickInfoIs("(property) name1: any"); +goTo.marker("id1"); +verify.quickInfoIs("(property) id1: any"); + +goTo.marker("obj2"); +verify.quickInfoIs("(var) obj2: {\n name2: string;\n id2: number;\n}"); +goTo.marker("name2"); +verify.quickInfoIs("(property) name2: string"); +goTo.marker("id2"); +verify.quickInfoIs("(property) id2: number"); diff --git a/tests/cases/unittests/services/documentRegistry.ts b/tests/cases/unittests/services/documentRegistry.ts index 88503149715..044aea0095d 100644 --- a/tests/cases/unittests/services/documentRegistry.ts +++ b/tests/cases/unittests/services/documentRegistry.ts @@ -5,8 +5,8 @@ describe("DocumentRegistry", () => { var documentRegistry = ts.createDocumentRegistry(); var defaultCompilerOptions = ts.getDefaultCompilerOptions(); - var f1 = documentRegistry.acquireDocument("file1.ts", defaultCompilerOptions, TypeScript.ScriptSnapshot.fromString("var x = 1;"), "1", false); - var f2 = documentRegistry.acquireDocument("file1.ts", defaultCompilerOptions, TypeScript.ScriptSnapshot.fromString("var x = 1;"), "1", false); + var f1 = documentRegistry.acquireDocument("file1.ts", defaultCompilerOptions, ts.ScriptSnapshot.fromString("var x = 1;"), "1", false); + var f2 = documentRegistry.acquireDocument("file1.ts", defaultCompilerOptions, ts.ScriptSnapshot.fromString("var x = 1;"), "1", false); assert(f1 === f2, "DocumentRegistry should return the same document for the same name"); }); @@ -17,21 +17,21 @@ describe("DocumentRegistry", () => { // change compilation setting that doesn't affect parsing - should have the same document compilerOptions.declaration = true; - var f1 = documentRegistry.acquireDocument("file1.ts", compilerOptions, TypeScript.ScriptSnapshot.fromString("var x = 1;"), "1", false); + var f1 = documentRegistry.acquireDocument("file1.ts", compilerOptions, ts.ScriptSnapshot.fromString("var x = 1;"), "1", false); compilerOptions.declaration = false; - var f2 = documentRegistry.acquireDocument("file1.ts", compilerOptions, TypeScript.ScriptSnapshot.fromString("var x = 1;"), "1", false); + var f2 = documentRegistry.acquireDocument("file1.ts", compilerOptions, ts.ScriptSnapshot.fromString("var x = 1;"), "1", false); assert(f1 === f2, "Expected to have the same document instance"); // change value of compilation setting that is used during production of AST - new document is required compilerOptions.target = ts.ScriptTarget.ES3; - var f3 = documentRegistry.acquireDocument("file1.ts", compilerOptions, TypeScript.ScriptSnapshot.fromString("var x = 1;"), "1", false); + var f3 = documentRegistry.acquireDocument("file1.ts", compilerOptions, ts.ScriptSnapshot.fromString("var x = 1;"), "1", false); assert(f1 !== f3, "Changed target: Expected to have different instances of document"); compilerOptions.module = ts.ModuleKind.CommonJS; - var f4 = documentRegistry.acquireDocument("file1.ts", compilerOptions, TypeScript.ScriptSnapshot.fromString("var x = 1;"), "1", false); + var f4 = documentRegistry.acquireDocument("file1.ts", compilerOptions, ts.ScriptSnapshot.fromString("var x = 1;"), "1", false); assert(f1 !== f4, "Changed module: Expected to have different instances of document"); });