From df7066f2e738a06f06c62e1291c7e60feb06236d Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 10 Sep 2014 12:30:33 -0700 Subject: [PATCH 01/31] Enable completion fourslash tests --- ...eforeSemanticDiagnosticsInArrowFunction1.ts | 0 .../completionEntryForPrimitive.ts | 0 .../completionInTypeOf1.ts | 0 .../completionListAfterNumericLiteral.ts | 0 .../completionListAfterObjectLiteral1.ts | 0 .../completionListAtEOF2.ts | 0 .../completionListAtNodeBoundry.ts | 0 .../completionListBeforeKeyword.ts | 0 .../completionListCladule.ts | 0 .../completionListClassMembers.ts | 0 .../completionListEnumMembers.ts | 0 .../completionListEnumValues.ts | 0 .../completionListForDerivedType1.ts | 6 +++--- ...mberInAmbientModuleWithExportAssignment1.ts | 0 .../completionListFunctionExpression.ts | 0 .../completionListGenericConstraints.ts | 0 .../completionListGenericConstraintsNames.ts | 0 ...ompletionListInContextuallyTypedArgument.ts | 0 .../completionListInExtendsClause.ts | 0 .../completionListInExtendsClauseAtEOF.ts | 0 .../completionListInNamedFunctionExpression.ts | 4 ++-- .../completionListInObjectLiteral3.ts | 0 .../completionListInTypedObjectLiterals.ts | 0 .../completionListInTypedObjectLiterals2.ts | 0 .../completionListInTypedObjectLiterals3.ts | 0 .../completionListInTypedObjectLiterals4.ts | 0 ...edObjectLiteralsWithPartialPropertyNames.ts | 0 ...dObjectLiteralsWithPartialPropertyNames2.ts | 0 .../completionListInsideTargetTypedFunction.ts | 0 .../completionListInvalidMemberNames.ts | 0 .../completionListInvalidMemberNames2.ts | 0 .../completionListModuleMembers.ts | 0 .../completionListObjectMembers.ts | 2 +- ...onListOnFunctionCallWithOptionalArgument.ts | 0 .../completionListOnParam.ts | 0 .../completionListOnVarBetweenModules.ts | 0 .../completionListPrimitives.ts | 0 .../completionListPrivateMembers.ts | 0 .../completionListSuperMembers.ts | 0 .../completionListWithUnresolvedModule.ts | 0 .../memberCompletionFromFunctionCall.ts | 0 .../memberCompletionInForEach1.ts | 0 .../memberCompletionOnTypeParameters.ts | 0 .../memberCompletionOnTypeParameters2.ts | 0 .../fourslash/memberListInReopenedEnum.ts | 18 ++++++++++++++++++ .../memberListInWithBlock.ts | 0 .../memberListInsideObjectLiterals.ts | 0 .../memberListOfClass.ts | 1 + .../memberListOfEnumFromExternalModule.ts | 0 .../memberListOfExportedClass.ts | 1 + .../memberListOfModule.ts | 0 .../memberListOfModuleBeforeKeyword.ts | 0 .../memberListOnFunctionParameter.ts | 0 .../memberListOnThisInClassWithPrivates.ts | 4 ++-- .../fourslash_old/memberListInReopenedEnum.ts | 18 ------------------ 55 files changed, 28 insertions(+), 26 deletions(-) rename tests/cases/{fourslash_old => fourslash}/completionBeforeSemanticDiagnosticsInArrowFunction1.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionEntryForPrimitive.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionInTypeOf1.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionListAfterNumericLiteral.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionListAfterObjectLiteral1.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionListAtEOF2.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionListAtNodeBoundry.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionListBeforeKeyword.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionListCladule.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionListClassMembers.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionListEnumMembers.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionListEnumValues.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionListForDerivedType1.ts (73%) rename tests/cases/{fourslash_old => fourslash}/completionListForNonExportedMemberInAmbientModuleWithExportAssignment1.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionListFunctionExpression.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionListGenericConstraints.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionListGenericConstraintsNames.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionListInContextuallyTypedArgument.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionListInExtendsClause.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionListInExtendsClauseAtEOF.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionListInNamedFunctionExpression.ts (85%) rename tests/cases/{fourslash_old => fourslash}/completionListInObjectLiteral3.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionListInTypedObjectLiterals.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionListInTypedObjectLiterals2.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionListInTypedObjectLiterals3.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionListInTypedObjectLiterals4.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionListInTypedObjectLiteralsWithPartialPropertyNames.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionListInTypedObjectLiteralsWithPartialPropertyNames2.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionListInsideTargetTypedFunction.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionListInvalidMemberNames.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionListInvalidMemberNames2.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionListModuleMembers.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionListObjectMembers.ts (80%) rename tests/cases/{fourslash_old => fourslash}/completionListOnFunctionCallWithOptionalArgument.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionListOnParam.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionListOnVarBetweenModules.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionListPrimitives.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionListPrivateMembers.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionListSuperMembers.ts (100%) rename tests/cases/{fourslash_old => fourslash}/completionListWithUnresolvedModule.ts (100%) rename tests/cases/{fourslash_old => fourslash}/memberCompletionFromFunctionCall.ts (100%) rename tests/cases/{fourslash_old => fourslash}/memberCompletionInForEach1.ts (100%) rename tests/cases/{fourslash_old => fourslash}/memberCompletionOnTypeParameters.ts (100%) rename tests/cases/{fourslash_old => fourslash}/memberCompletionOnTypeParameters2.ts (100%) create mode 100644 tests/cases/fourslash/memberListInReopenedEnum.ts rename tests/cases/{fourslash_old => fourslash}/memberListInWithBlock.ts (100%) rename tests/cases/{fourslash_old => fourslash}/memberListInsideObjectLiterals.ts (100%) rename tests/cases/{fourslash_old => fourslash}/memberListOfClass.ts (90%) rename tests/cases/{fourslash_old => fourslash}/memberListOfEnumFromExternalModule.ts (100%) rename tests/cases/{fourslash_old => fourslash}/memberListOfExportedClass.ts (89%) rename tests/cases/{fourslash_old => fourslash}/memberListOfModule.ts (100%) rename tests/cases/{fourslash_old => fourslash}/memberListOfModuleBeforeKeyword.ts (100%) rename tests/cases/{fourslash_old => fourslash}/memberListOnFunctionParameter.ts (100%) rename tests/cases/{fourslash_old => fourslash}/memberListOnThisInClassWithPrivates.ts (71%) delete mode 100644 tests/cases/fourslash_old/memberListInReopenedEnum.ts diff --git a/tests/cases/fourslash_old/completionBeforeSemanticDiagnosticsInArrowFunction1.ts b/tests/cases/fourslash/completionBeforeSemanticDiagnosticsInArrowFunction1.ts similarity index 100% rename from tests/cases/fourslash_old/completionBeforeSemanticDiagnosticsInArrowFunction1.ts rename to tests/cases/fourslash/completionBeforeSemanticDiagnosticsInArrowFunction1.ts diff --git a/tests/cases/fourslash_old/completionEntryForPrimitive.ts b/tests/cases/fourslash/completionEntryForPrimitive.ts similarity index 100% rename from tests/cases/fourslash_old/completionEntryForPrimitive.ts rename to tests/cases/fourslash/completionEntryForPrimitive.ts diff --git a/tests/cases/fourslash_old/completionInTypeOf1.ts b/tests/cases/fourslash/completionInTypeOf1.ts similarity index 100% rename from tests/cases/fourslash_old/completionInTypeOf1.ts rename to tests/cases/fourslash/completionInTypeOf1.ts diff --git a/tests/cases/fourslash_old/completionListAfterNumericLiteral.ts b/tests/cases/fourslash/completionListAfterNumericLiteral.ts similarity index 100% rename from tests/cases/fourslash_old/completionListAfterNumericLiteral.ts rename to tests/cases/fourslash/completionListAfterNumericLiteral.ts diff --git a/tests/cases/fourslash_old/completionListAfterObjectLiteral1.ts b/tests/cases/fourslash/completionListAfterObjectLiteral1.ts similarity index 100% rename from tests/cases/fourslash_old/completionListAfterObjectLiteral1.ts rename to tests/cases/fourslash/completionListAfterObjectLiteral1.ts diff --git a/tests/cases/fourslash_old/completionListAtEOF2.ts b/tests/cases/fourslash/completionListAtEOF2.ts similarity index 100% rename from tests/cases/fourslash_old/completionListAtEOF2.ts rename to tests/cases/fourslash/completionListAtEOF2.ts diff --git a/tests/cases/fourslash_old/completionListAtNodeBoundry.ts b/tests/cases/fourslash/completionListAtNodeBoundry.ts similarity index 100% rename from tests/cases/fourslash_old/completionListAtNodeBoundry.ts rename to tests/cases/fourslash/completionListAtNodeBoundry.ts diff --git a/tests/cases/fourslash_old/completionListBeforeKeyword.ts b/tests/cases/fourslash/completionListBeforeKeyword.ts similarity index 100% rename from tests/cases/fourslash_old/completionListBeforeKeyword.ts rename to tests/cases/fourslash/completionListBeforeKeyword.ts diff --git a/tests/cases/fourslash_old/completionListCladule.ts b/tests/cases/fourslash/completionListCladule.ts similarity index 100% rename from tests/cases/fourslash_old/completionListCladule.ts rename to tests/cases/fourslash/completionListCladule.ts diff --git a/tests/cases/fourslash_old/completionListClassMembers.ts b/tests/cases/fourslash/completionListClassMembers.ts similarity index 100% rename from tests/cases/fourslash_old/completionListClassMembers.ts rename to tests/cases/fourslash/completionListClassMembers.ts diff --git a/tests/cases/fourslash_old/completionListEnumMembers.ts b/tests/cases/fourslash/completionListEnumMembers.ts similarity index 100% rename from tests/cases/fourslash_old/completionListEnumMembers.ts rename to tests/cases/fourslash/completionListEnumMembers.ts diff --git a/tests/cases/fourslash_old/completionListEnumValues.ts b/tests/cases/fourslash/completionListEnumValues.ts similarity index 100% rename from tests/cases/fourslash_old/completionListEnumValues.ts rename to tests/cases/fourslash/completionListEnumValues.ts diff --git a/tests/cases/fourslash_old/completionListForDerivedType1.ts b/tests/cases/fourslash/completionListForDerivedType1.ts similarity index 73% rename from tests/cases/fourslash_old/completionListForDerivedType1.ts rename to tests/cases/fourslash/completionListForDerivedType1.ts index a3dd192a75..0c514713c2 100644 --- a/tests/cases/fourslash_old/completionListForDerivedType1.ts +++ b/tests/cases/fourslash/completionListForDerivedType1.ts @@ -12,10 +12,10 @@ ////f2./*2*/ // here bar has return type any, but bar2 is Foo2 goTo.marker('1'); -verify.completionListContains('bar', '(): IFoo'); +verify.completionListContains('bar', '() => IFoo'); verify.not.completionListContains('bar2'); edit.insert('bar();'); // just to make the file valid before checking next completion location goTo.marker('2'); -verify.completionListContains('bar', '(): IFoo'); -verify.completionListContains('bar2', '(): IFoo2'); \ No newline at end of file +verify.completionListContains('bar', '() => IFoo'); +verify.completionListContains('bar2', '() => IFoo2'); \ No newline at end of file diff --git a/tests/cases/fourslash_old/completionListForNonExportedMemberInAmbientModuleWithExportAssignment1.ts b/tests/cases/fourslash/completionListForNonExportedMemberInAmbientModuleWithExportAssignment1.ts similarity index 100% rename from tests/cases/fourslash_old/completionListForNonExportedMemberInAmbientModuleWithExportAssignment1.ts rename to tests/cases/fourslash/completionListForNonExportedMemberInAmbientModuleWithExportAssignment1.ts diff --git a/tests/cases/fourslash_old/completionListFunctionExpression.ts b/tests/cases/fourslash/completionListFunctionExpression.ts similarity index 100% rename from tests/cases/fourslash_old/completionListFunctionExpression.ts rename to tests/cases/fourslash/completionListFunctionExpression.ts diff --git a/tests/cases/fourslash_old/completionListGenericConstraints.ts b/tests/cases/fourslash/completionListGenericConstraints.ts similarity index 100% rename from tests/cases/fourslash_old/completionListGenericConstraints.ts rename to tests/cases/fourslash/completionListGenericConstraints.ts diff --git a/tests/cases/fourslash_old/completionListGenericConstraintsNames.ts b/tests/cases/fourslash/completionListGenericConstraintsNames.ts similarity index 100% rename from tests/cases/fourslash_old/completionListGenericConstraintsNames.ts rename to tests/cases/fourslash/completionListGenericConstraintsNames.ts diff --git a/tests/cases/fourslash_old/completionListInContextuallyTypedArgument.ts b/tests/cases/fourslash/completionListInContextuallyTypedArgument.ts similarity index 100% rename from tests/cases/fourslash_old/completionListInContextuallyTypedArgument.ts rename to tests/cases/fourslash/completionListInContextuallyTypedArgument.ts diff --git a/tests/cases/fourslash_old/completionListInExtendsClause.ts b/tests/cases/fourslash/completionListInExtendsClause.ts similarity index 100% rename from tests/cases/fourslash_old/completionListInExtendsClause.ts rename to tests/cases/fourslash/completionListInExtendsClause.ts diff --git a/tests/cases/fourslash_old/completionListInExtendsClauseAtEOF.ts b/tests/cases/fourslash/completionListInExtendsClauseAtEOF.ts similarity index 100% rename from tests/cases/fourslash_old/completionListInExtendsClauseAtEOF.ts rename to tests/cases/fourslash/completionListInExtendsClauseAtEOF.ts diff --git a/tests/cases/fourslash_old/completionListInNamedFunctionExpression.ts b/tests/cases/fourslash/completionListInNamedFunctionExpression.ts similarity index 85% rename from tests/cases/fourslash_old/completionListInNamedFunctionExpression.ts rename to tests/cases/fourslash/completionListInNamedFunctionExpression.ts index 6023cfee44..a4dd328e1e 100644 --- a/tests/cases/fourslash_old/completionListInNamedFunctionExpression.ts +++ b/tests/cases/fourslash/completionListInNamedFunctionExpression.ts @@ -24,9 +24,9 @@ goTo.marker("insideFunctionExpression"); verify.memberListContains("foo"); goTo.marker("referenceInsideFunctionExpression"); -verify.quickInfoIs("(): number"); +verify.quickInfoIs("() => number"); goTo.marker("referenceInGlobalScope"); -verify.quickInfoIs("(a: number): string"); +verify.quickInfoIs("(a: number) => string"); diff --git a/tests/cases/fourslash_old/completionListInObjectLiteral3.ts b/tests/cases/fourslash/completionListInObjectLiteral3.ts similarity index 100% rename from tests/cases/fourslash_old/completionListInObjectLiteral3.ts rename to tests/cases/fourslash/completionListInObjectLiteral3.ts diff --git a/tests/cases/fourslash_old/completionListInTypedObjectLiterals.ts b/tests/cases/fourslash/completionListInTypedObjectLiterals.ts similarity index 100% rename from tests/cases/fourslash_old/completionListInTypedObjectLiterals.ts rename to tests/cases/fourslash/completionListInTypedObjectLiterals.ts diff --git a/tests/cases/fourslash_old/completionListInTypedObjectLiterals2.ts b/tests/cases/fourslash/completionListInTypedObjectLiterals2.ts similarity index 100% rename from tests/cases/fourslash_old/completionListInTypedObjectLiterals2.ts rename to tests/cases/fourslash/completionListInTypedObjectLiterals2.ts diff --git a/tests/cases/fourslash_old/completionListInTypedObjectLiterals3.ts b/tests/cases/fourslash/completionListInTypedObjectLiterals3.ts similarity index 100% rename from tests/cases/fourslash_old/completionListInTypedObjectLiterals3.ts rename to tests/cases/fourslash/completionListInTypedObjectLiterals3.ts diff --git a/tests/cases/fourslash_old/completionListInTypedObjectLiterals4.ts b/tests/cases/fourslash/completionListInTypedObjectLiterals4.ts similarity index 100% rename from tests/cases/fourslash_old/completionListInTypedObjectLiterals4.ts rename to tests/cases/fourslash/completionListInTypedObjectLiterals4.ts diff --git a/tests/cases/fourslash_old/completionListInTypedObjectLiteralsWithPartialPropertyNames.ts b/tests/cases/fourslash/completionListInTypedObjectLiteralsWithPartialPropertyNames.ts similarity index 100% rename from tests/cases/fourslash_old/completionListInTypedObjectLiteralsWithPartialPropertyNames.ts rename to tests/cases/fourslash/completionListInTypedObjectLiteralsWithPartialPropertyNames.ts diff --git a/tests/cases/fourslash_old/completionListInTypedObjectLiteralsWithPartialPropertyNames2.ts b/tests/cases/fourslash/completionListInTypedObjectLiteralsWithPartialPropertyNames2.ts similarity index 100% rename from tests/cases/fourslash_old/completionListInTypedObjectLiteralsWithPartialPropertyNames2.ts rename to tests/cases/fourslash/completionListInTypedObjectLiteralsWithPartialPropertyNames2.ts diff --git a/tests/cases/fourslash_old/completionListInsideTargetTypedFunction.ts b/tests/cases/fourslash/completionListInsideTargetTypedFunction.ts similarity index 100% rename from tests/cases/fourslash_old/completionListInsideTargetTypedFunction.ts rename to tests/cases/fourslash/completionListInsideTargetTypedFunction.ts diff --git a/tests/cases/fourslash_old/completionListInvalidMemberNames.ts b/tests/cases/fourslash/completionListInvalidMemberNames.ts similarity index 100% rename from tests/cases/fourslash_old/completionListInvalidMemberNames.ts rename to tests/cases/fourslash/completionListInvalidMemberNames.ts diff --git a/tests/cases/fourslash_old/completionListInvalidMemberNames2.ts b/tests/cases/fourslash/completionListInvalidMemberNames2.ts similarity index 100% rename from tests/cases/fourslash_old/completionListInvalidMemberNames2.ts rename to tests/cases/fourslash/completionListInvalidMemberNames2.ts diff --git a/tests/cases/fourslash_old/completionListModuleMembers.ts b/tests/cases/fourslash/completionListModuleMembers.ts similarity index 100% rename from tests/cases/fourslash_old/completionListModuleMembers.ts rename to tests/cases/fourslash/completionListModuleMembers.ts diff --git a/tests/cases/fourslash_old/completionListObjectMembers.ts b/tests/cases/fourslash/completionListObjectMembers.ts similarity index 80% rename from tests/cases/fourslash_old/completionListObjectMembers.ts rename to tests/cases/fourslash/completionListObjectMembers.ts index 63c0e96bc0..c23eff12db 100644 --- a/tests/cases/fourslash_old/completionListObjectMembers.ts +++ b/tests/cases/fourslash/completionListObjectMembers.ts @@ -11,4 +11,4 @@ goTo.marker(); verify.memberListContains("bar", 'any'); -verify.memberListContains("foo", '(bar: any): any'); +verify.memberListContains("foo", '(bar: any) => any'); diff --git a/tests/cases/fourslash_old/completionListOnFunctionCallWithOptionalArgument.ts b/tests/cases/fourslash/completionListOnFunctionCallWithOptionalArgument.ts similarity index 100% rename from tests/cases/fourslash_old/completionListOnFunctionCallWithOptionalArgument.ts rename to tests/cases/fourslash/completionListOnFunctionCallWithOptionalArgument.ts diff --git a/tests/cases/fourslash_old/completionListOnParam.ts b/tests/cases/fourslash/completionListOnParam.ts similarity index 100% rename from tests/cases/fourslash_old/completionListOnParam.ts rename to tests/cases/fourslash/completionListOnParam.ts diff --git a/tests/cases/fourslash_old/completionListOnVarBetweenModules.ts b/tests/cases/fourslash/completionListOnVarBetweenModules.ts similarity index 100% rename from tests/cases/fourslash_old/completionListOnVarBetweenModules.ts rename to tests/cases/fourslash/completionListOnVarBetweenModules.ts diff --git a/tests/cases/fourslash_old/completionListPrimitives.ts b/tests/cases/fourslash/completionListPrimitives.ts similarity index 100% rename from tests/cases/fourslash_old/completionListPrimitives.ts rename to tests/cases/fourslash/completionListPrimitives.ts diff --git a/tests/cases/fourslash_old/completionListPrivateMembers.ts b/tests/cases/fourslash/completionListPrivateMembers.ts similarity index 100% rename from tests/cases/fourslash_old/completionListPrivateMembers.ts rename to tests/cases/fourslash/completionListPrivateMembers.ts diff --git a/tests/cases/fourslash_old/completionListSuperMembers.ts b/tests/cases/fourslash/completionListSuperMembers.ts similarity index 100% rename from tests/cases/fourslash_old/completionListSuperMembers.ts rename to tests/cases/fourslash/completionListSuperMembers.ts diff --git a/tests/cases/fourslash_old/completionListWithUnresolvedModule.ts b/tests/cases/fourslash/completionListWithUnresolvedModule.ts similarity index 100% rename from tests/cases/fourslash_old/completionListWithUnresolvedModule.ts rename to tests/cases/fourslash/completionListWithUnresolvedModule.ts diff --git a/tests/cases/fourslash_old/memberCompletionFromFunctionCall.ts b/tests/cases/fourslash/memberCompletionFromFunctionCall.ts similarity index 100% rename from tests/cases/fourslash_old/memberCompletionFromFunctionCall.ts rename to tests/cases/fourslash/memberCompletionFromFunctionCall.ts diff --git a/tests/cases/fourslash_old/memberCompletionInForEach1.ts b/tests/cases/fourslash/memberCompletionInForEach1.ts similarity index 100% rename from tests/cases/fourslash_old/memberCompletionInForEach1.ts rename to tests/cases/fourslash/memberCompletionInForEach1.ts diff --git a/tests/cases/fourslash_old/memberCompletionOnTypeParameters.ts b/tests/cases/fourslash/memberCompletionOnTypeParameters.ts similarity index 100% rename from tests/cases/fourslash_old/memberCompletionOnTypeParameters.ts rename to tests/cases/fourslash/memberCompletionOnTypeParameters.ts diff --git a/tests/cases/fourslash_old/memberCompletionOnTypeParameters2.ts b/tests/cases/fourslash/memberCompletionOnTypeParameters2.ts similarity index 100% rename from tests/cases/fourslash_old/memberCompletionOnTypeParameters2.ts rename to tests/cases/fourslash/memberCompletionOnTypeParameters2.ts diff --git a/tests/cases/fourslash/memberListInReopenedEnum.ts b/tests/cases/fourslash/memberListInReopenedEnum.ts new file mode 100644 index 0000000000..ede924b678 --- /dev/null +++ b/tests/cases/fourslash/memberListInReopenedEnum.ts @@ -0,0 +1,18 @@ +/// + +////module M { +//// enum E { +//// A, B +//// } +//// enum E { +//// C = 0, D +//// } +//// var x = E./*1*/ +////} + + +goTo.marker('1'); +verify.memberListContains('A', 'E', undefined, "E.A"); +verify.memberListContains('B', 'E', undefined, "E.B"); +verify.memberListContains('C', 'E', undefined, "E.C"); +verify.memberListContains('D', 'E', undefined, "E.D"); \ No newline at end of file diff --git a/tests/cases/fourslash_old/memberListInWithBlock.ts b/tests/cases/fourslash/memberListInWithBlock.ts similarity index 100% rename from tests/cases/fourslash_old/memberListInWithBlock.ts rename to tests/cases/fourslash/memberListInWithBlock.ts diff --git a/tests/cases/fourslash_old/memberListInsideObjectLiterals.ts b/tests/cases/fourslash/memberListInsideObjectLiterals.ts similarity index 100% rename from tests/cases/fourslash_old/memberListInsideObjectLiterals.ts rename to tests/cases/fourslash/memberListInsideObjectLiterals.ts diff --git a/tests/cases/fourslash_old/memberListOfClass.ts b/tests/cases/fourslash/memberListOfClass.ts similarity index 90% rename from tests/cases/fourslash_old/memberListOfClass.ts rename to tests/cases/fourslash/memberListOfClass.ts index c6ac4973fb..a28f568b75 100644 --- a/tests/cases/fourslash_old/memberListOfClass.ts +++ b/tests/cases/fourslash/memberListOfClass.ts @@ -10,6 +10,7 @@ ////f./**/ goTo.marker(); +debug.printCompletionListMembers(); verify.memberListCount(2); verify.memberListContains('pubMeth', '(): void'); verify.memberListContains('pubProp', 'number'); \ No newline at end of file diff --git a/tests/cases/fourslash_old/memberListOfEnumFromExternalModule.ts b/tests/cases/fourslash/memberListOfEnumFromExternalModule.ts similarity index 100% rename from tests/cases/fourslash_old/memberListOfEnumFromExternalModule.ts rename to tests/cases/fourslash/memberListOfEnumFromExternalModule.ts diff --git a/tests/cases/fourslash_old/memberListOfExportedClass.ts b/tests/cases/fourslash/memberListOfExportedClass.ts similarity index 89% rename from tests/cases/fourslash_old/memberListOfExportedClass.ts rename to tests/cases/fourslash/memberListOfExportedClass.ts index a564504e7e..853856747d 100644 --- a/tests/cases/fourslash_old/memberListOfExportedClass.ts +++ b/tests/cases/fourslash/memberListOfExportedClass.ts @@ -11,5 +11,6 @@ ////c./**/ // test on c. goTo.marker(); +debug.printCompletionListMembers(); verify.memberListCount(1); verify.memberListContains('pub', 'number'); \ No newline at end of file diff --git a/tests/cases/fourslash_old/memberListOfModule.ts b/tests/cases/fourslash/memberListOfModule.ts similarity index 100% rename from tests/cases/fourslash_old/memberListOfModule.ts rename to tests/cases/fourslash/memberListOfModule.ts diff --git a/tests/cases/fourslash_old/memberListOfModuleBeforeKeyword.ts b/tests/cases/fourslash/memberListOfModuleBeforeKeyword.ts similarity index 100% rename from tests/cases/fourslash_old/memberListOfModuleBeforeKeyword.ts rename to tests/cases/fourslash/memberListOfModuleBeforeKeyword.ts diff --git a/tests/cases/fourslash_old/memberListOnFunctionParameter.ts b/tests/cases/fourslash/memberListOnFunctionParameter.ts similarity index 100% rename from tests/cases/fourslash_old/memberListOnFunctionParameter.ts rename to tests/cases/fourslash/memberListOnFunctionParameter.ts diff --git a/tests/cases/fourslash_old/memberListOnThisInClassWithPrivates.ts b/tests/cases/fourslash/memberListOnThisInClassWithPrivates.ts similarity index 71% rename from tests/cases/fourslash_old/memberListOnThisInClassWithPrivates.ts rename to tests/cases/fourslash/memberListOnThisInClassWithPrivates.ts index 1b77948f17..6df5b55577 100644 --- a/tests/cases/fourslash_old/memberListOnThisInClassWithPrivates.ts +++ b/tests/cases/fourslash/memberListOnThisInClassWithPrivates.ts @@ -8,6 +8,6 @@ ////} goTo.marker(); -verify.memberListContains('privMeth', '(): void'); -verify.memberListContains('pubMeth', '(): void'); +verify.memberListContains('privMeth', '() => void'); +verify.memberListContains('pubMeth', '() => void'); verify.memberListContains('pubProp', 'number'); \ No newline at end of file diff --git a/tests/cases/fourslash_old/memberListInReopenedEnum.ts b/tests/cases/fourslash_old/memberListInReopenedEnum.ts deleted file mode 100644 index b1168f54b1..0000000000 --- a/tests/cases/fourslash_old/memberListInReopenedEnum.ts +++ /dev/null @@ -1,18 +0,0 @@ -/// - -////module M { -//// enum E { -//// A, B -//// } -//// enum E { -//// C = 0, D -//// } -//// var x = E./*1*/ -////} - - -goTo.marker('1'); -verify.memberListContains('A', 'E', undefined, "M.E.A"); -verify.memberListContains('B', 'E', undefined, "M.E.B"); -verify.memberListContains('C', 'E', undefined, "M.E.C"); -verify.memberListContains('D', 'E', undefined, "M.E.D"); \ No newline at end of file From 8e0227eba26c46695b7e56325c19b64e013b8b7f Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 10 Sep 2014 12:56:37 -0700 Subject: [PATCH 02/31] Enable completion on expressions --- src/services/services.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/services/services.ts b/src/services/services.ts index d51eeee97c..7f4a3ff87c 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1734,6 +1734,11 @@ module ts { return false; } + function isToken(kind: SyntaxKind) { + return (SyntaxKind.FirstPunctuation <= kind && kind <= SyntaxKind.LastPunctuation) || + (SyntaxKind.FirstKeyword <= kind && kind <= SyntaxKind.LastKeyword); + } + synchronizeHostData(); filename = TypeScript.switchToForwardSlashes(filename); @@ -1788,6 +1793,9 @@ module ts { // TODO: this is a hack for now, we need a proper walking mechanism to verify that we have the correct node var mappedNode = getNodeAtPosition(sourceFile, TypeScript.end(node) - 1); + if (isToken(mappedNode.kind)) { + mappedNode = mappedNode.parent; + } Debug.assert(mappedNode, "Could not map a Fidelity node to an AST node"); From 885569d4e7e18260b0347f5892c0034248fae4da Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 10 Sep 2014 13:16:44 -0700 Subject: [PATCH 03/31] Get correct kind for generic symbol completion entries --- src/compiler/checker.ts | 2 +- src/services/services.ts | 3 +-- tests/cases/fourslash/completionListOfGnericSymbol.ts | 11 +++++++++++ 3 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 tests/cases/fourslash/completionListOfGnericSymbol.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b99d6d27d2..7376f291bc 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7145,7 +7145,7 @@ module ts { } function getRootSymbol(symbol: Symbol) { - return (symbol.flags & SymbolFlags.Transient) ? getSymbolLinks(symbol).target : symbol; + return (symbol.flags & SymbolFlags.Transient) && getSymbolLinks(symbol).target || symbol; } // Emitter support diff --git a/src/services/services.ts b/src/services/services.ts index 7f4a3ff87c..a34c670987 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1592,7 +1592,6 @@ module ts { } var declarations = symbol.getDeclarations(); - var firstDeclaration = [0]; return { name: displayName, kind: getSymbolKind(symbol), @@ -1956,7 +1955,7 @@ module ts { } function getSymbolKind(symbol: Symbol): string { - var flags = symbol.getFlags(); + var flags = typeInfoResolver.getRootSymbol(symbol).getFlags(); if (flags & SymbolFlags.Module) return ScriptElementKind.moduleElement; if (flags & SymbolFlags.Class) return ScriptElementKind.classElement; diff --git a/tests/cases/fourslash/completionListOfGnericSymbol.ts b/tests/cases/fourslash/completionListOfGnericSymbol.ts new file mode 100644 index 0000000000..fd223b68ca --- /dev/null +++ b/tests/cases/fourslash/completionListOfGnericSymbol.ts @@ -0,0 +1,11 @@ +/// + +// Ensure kind is set correctelly on completions of a generic symbol + +////var a = [1,2,3]; +////a./**/ + +goTo.marker(); +verify.memberListContains('length', "number", /*docComments*/ undefined, /*fullSymbolName*/ undefined,/*kind*/ "property"); +verify.memberListContains('toString', "() => string", /*docComments*/ undefined, /*fullSymbolName*/ undefined,/*kind*/ "method"); + From 5149c8f0379217144f701326ef08507b5a5b7218 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 10 Sep 2014 15:54:55 -0700 Subject: [PATCH 04/31] handel completion on missing symbols correctelly --- src/compiler/checker.ts | 8 ++++---- src/services/services.ts | 7 ++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7376f291bc..b45c588875 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2431,7 +2431,7 @@ module ts { case SyntaxKind.Identifier: case SyntaxKind.QualifiedName: var symbol = getSymbolInfo(node); - return getDeclaredTypeOfSymbol(symbol); + return symbol && getDeclaredTypeOfSymbol(symbol); default: return unknownType; } @@ -7077,7 +7077,7 @@ module ts { if (isTypeDeclarationName(node)) { var symbol = getSymbolInfo(node); - return getDeclaredTypeOfSymbol(symbol); + return symbol && getDeclaredTypeOfSymbol(symbol); } if (isDeclaration(node)) { @@ -7088,12 +7088,12 @@ module ts { if (isDeclarationOrFunctionExpressionOrCatchVariableName(node)) { var symbol = getSymbolInfo(node); - return getTypeOfSymbol(symbol); + return symbol && getTypeOfSymbol(symbol); } if (isInRightSideOfImportOrExportAssignment(node)) { var symbol = getSymbolInfo(node); - var declaredType = getDeclaredTypeOfSymbol(symbol); + var declaredType = symbol && getDeclaredTypeOfSymbol(symbol); return declaredType !== unknownType ? declaredType : getTypeOfSymbol(symbol); } diff --git a/src/services/services.ts b/src/services/services.ts index a34c670987..3e1595c314 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1810,12 +1810,13 @@ module ts { // Right of dot member completion list if (isRightOfDot) { - var type: ApparentType = typeInfoResolver.getApparentType(typeInfoResolver.getTypeOfNode(mappedNode)); - if (!type) { + var type = typeInfoResolver.getTypeOfNode(mappedNode); + var apparentType: ApparentType = type && typeInfoResolver.getApparentType(type); + if (!apparentType) { return undefined; } - var symbols = type.getApparentProperties(); + var symbols = apparentType.getApparentProperties(); isMemberCompletion = true; getCompletionEntriesFromSymbols(symbols, activeCompletionSession); } From 1a58afbd9f3a54ec534f7364c44a892a579f3d4c Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 10 Sep 2014 16:09:17 -0700 Subject: [PATCH 05/31] do not consider keywords tokens for compleation reasons, to allow completion on this and super --- src/services/services.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index 3e1595c314..3ca0757328 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1734,8 +1734,7 @@ module ts { } function isToken(kind: SyntaxKind) { - return (SyntaxKind.FirstPunctuation <= kind && kind <= SyntaxKind.LastPunctuation) || - (SyntaxKind.FirstKeyword <= kind && kind <= SyntaxKind.LastKeyword); + return (SyntaxKind.FirstPunctuation <= kind && kind <= SyntaxKind.LastPunctuation); } synchronizeHostData(); From 44adc06496141f5722a3928267d4ac0b61fa1275 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 10 Sep 2014 16:49:42 -0700 Subject: [PATCH 06/31] expose getAncestor method --- src/compiler/checker.ts | 35 ----------------------------------- src/compiler/parser.ts | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b45c588875..809857db2c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3469,41 +3469,6 @@ module ts { return getAncestor(node, kind) !== undefined; } - function getAncestor(node: Node, kind: SyntaxKind): Node { - switch (kind) { - // special-cases that can be come first - case SyntaxKind.ClassDeclaration: - while (node) { - switch (node.kind) { - case SyntaxKind.ClassDeclaration: - return node; - case SyntaxKind.EnumDeclaration: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.ModuleDeclaration: - case SyntaxKind.ImportDeclaration: - // early exit cases - declarations cannot be nested in classes - return undefined; - default: - node = node.parent; - continue; - } - } - break; - default: - while (node) { - if (node.kind === kind) { - return node; - } - else { - node = node.parent; - } - } - break; - } - - return undefined; - } - // EXPRESSION TYPE CHECKING function checkIdentifier(node: Identifier): Type { diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 25ca24ae61..70cdffc75c 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -505,6 +505,41 @@ module ts { return false; } + export function getAncestor(node: Node, kind: SyntaxKind): Node { + switch (kind) { + // special-cases that can be come first + case SyntaxKind.ClassDeclaration: + while (node) { + switch (node.kind) { + case SyntaxKind.ClassDeclaration: + return node; + case SyntaxKind.EnumDeclaration: + case SyntaxKind.InterfaceDeclaration: + case SyntaxKind.ModuleDeclaration: + case SyntaxKind.ImportDeclaration: + // early exit cases - declarations cannot be nested in classes + return undefined; + default: + node = node.parent; + continue; + } + } + break; + default: + while (node) { + if (node.kind === kind) { + return node; + } + else { + node = node.parent; + } + } + break; + } + + return undefined; + } + enum ParsingContext { SourceElements, // Elements in source file ModuleElements, // Elements in module declaration From 5db12f357f208536cb6ebe2f62bf74e677a88f70 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 10 Sep 2014 16:50:04 -0700 Subject: [PATCH 07/31] Filter private mebemers in class completions --- src/services/services.ts | 12 +++++++++++- tests/cases/fourslash/memberListOfClass.ts | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index 3ca0757328..9cc6acfd5f 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1815,7 +1815,17 @@ module ts { return undefined; } - var symbols = apparentType.getApparentProperties(); + var containingClass = getAncestor(mappedNode, SyntaxKind.ClassDeclaration); + + var symbols: Symbol[] = []; + // Filter private properties + forEach(apparentType.getApparentProperties(), symbol => { + var declaration = symbol.declarations && symbol.declarations[0]; + if (declaration && declaration.flags & NodeFlags.Private && containingClass !== declaration.parent) + return; + + symbols.push(symbol); + }); isMemberCompletion = true; getCompletionEntriesFromSymbols(symbols, activeCompletionSession); } diff --git a/tests/cases/fourslash/memberListOfClass.ts b/tests/cases/fourslash/memberListOfClass.ts index a28f568b75..137903e5aa 100644 --- a/tests/cases/fourslash/memberListOfClass.ts +++ b/tests/cases/fourslash/memberListOfClass.ts @@ -12,5 +12,5 @@ goTo.marker(); debug.printCompletionListMembers(); verify.memberListCount(2); -verify.memberListContains('pubMeth', '(): void'); +verify.memberListContains('pubMeth', '() => void'); verify.memberListContains('pubProp', 'number'); \ No newline at end of file From 91b52b271f8c839f65b71d10574890d81a05eaa8 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Thu, 11 Sep 2014 13:44:14 -0700 Subject: [PATCH 08/31] Support enum and module completions --- src/services/services.ts | 47 ++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index 9cc6acfd5f..f2000cfb18 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1603,7 +1603,7 @@ module ts { function getCompletionEntriesFromSymbols(symbols: Symbol[], session: CompletionSession): void { forEach(symbols, (symbol) => { var entry = createCompletionEntry(symbol); - if (entry) { + if (entry && !lookUp(session.symbols, entry.name)) { session.entries.push(entry); session.symbols[entry.name] = symbol; } @@ -1737,6 +1737,11 @@ module ts { return (SyntaxKind.FirstPunctuation <= kind && kind <= SyntaxKind.LastPunctuation); } + function isVisibleWithenDeclaration(symbol: Symbol, containingClass: Declaration): boolean { + var declaration = symbol.declarations && symbol.declarations[0]; + return !(declaration && declaration.flags & NodeFlags.Private && containingClass !== declaration.parent); + } + synchronizeHostData(); filename = TypeScript.switchToForwardSlashes(filename); @@ -1809,24 +1814,34 @@ module ts { // Right of dot member completion list if (isRightOfDot) { - var type = typeInfoResolver.getTypeOfNode(mappedNode); - var apparentType: ApparentType = type && typeInfoResolver.getApparentType(type); - if (!apparentType) { - return undefined; + var symbols: Symbol[] = []; + var containingClass = getAncestor(mappedNode, SyntaxKind.ClassDeclaration); + isMemberCompletion = true; + + + if (mappedNode.kind === SyntaxKind.Identifier || mappedNode.kind === SyntaxKind.QualifiedName || mappedNode.kind === SyntaxKind.PropertyAccess) { + var symbol = typeInfoResolver.getSymbolInfo(mappedNode); + if (symbol && symbol.flags & SymbolFlags.HasExports) { + // Extract module or enum members + forEachValue(symbol.exports, symbol => { + if (isVisibleWithenDeclaration(symbol, containingClass)) { + symbols.push(symbol); + } + }); + } } - var containingClass = getAncestor(mappedNode, SyntaxKind.ClassDeclaration); + var type = typeInfoResolver.getTypeOfNode(mappedNode); + var apparentType: ApparentType = type && typeInfoResolver.getApparentType(type); + if (apparentType) { + // Filter private properties + forEach(apparentType.getApparentProperties(), symbol => { + if (isVisibleWithenDeclaration(symbol, containingClass)) { + symbols.push(symbol); + } + }); + } - var symbols: Symbol[] = []; - // Filter private properties - forEach(apparentType.getApparentProperties(), symbol => { - var declaration = symbol.declarations && symbol.declarations[0]; - if (declaration && declaration.flags & NodeFlags.Private && containingClass !== declaration.parent) - return; - - symbols.push(symbol); - }); - isMemberCompletion = true; getCompletionEntriesFromSymbols(symbols, activeCompletionSession); } else { From 57fa018a1915976e4ab4506decc6c0c81096988d Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Thu, 11 Sep 2014 14:38:48 -0700 Subject: [PATCH 09/31] Use scanner APIs to identify if a display name is valid completion entry --- src/services/services.ts | 14 ++++++++++---- .../fourslash/completionListInvalidMemberNames.ts | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index f2000cfb18..851901ea13 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1567,14 +1567,20 @@ module ts { /// Completion function getValidCompletionEntryDisplayName(displayName: string, target: ScriptTarget): string { if (displayName && displayName.length > 0) { - var firstChar = displayName.charCodeAt(0); - if (firstChar === TypeScript.CharacterCodes.singleQuote || firstChar === TypeScript.CharacterCodes.doubleQuote) { + var firstCharCode = displayName.charCodeAt(0); + if (displayName && displayName.length >= 2 && firstCharCode === displayName.charCodeAt(displayName.length - 1) && + (firstCharCode === CharacterCodes.singleQuote || firstCharCode === CharacterCodes.doubleQuote)) { // If the user entered name for the symbol was quoted, removing the quotes is not enough, as the name could be an // invalid identifer name. We need to check if whatever was inside the quotes is actually a valid identifier name. - displayName = TypeScript.stripStartAndEndQuotes(displayName); + displayName = displayName.substring(1, displayName.length - 1); } - if (TypeScript.Scanner.isValidIdentifier(TypeScript.SimpleText.fromString(displayName), target)) { + var isValid = isIdentifierStart(displayName.charCodeAt(0), target); + for (var i = 1, n = displayName.length; isValid && i < n; i++) { + isValid = isValid && isIdentifierPart(displayName.charCodeAt(i), target); + } + + if (isValid) { return displayName; } } diff --git a/tests/cases/fourslash/completionListInvalidMemberNames.ts b/tests/cases/fourslash/completionListInvalidMemberNames.ts index 7091850bb3..7fff46e2a8 100644 --- a/tests/cases/fourslash/completionListInvalidMemberNames.ts +++ b/tests/cases/fourslash/completionListInvalidMemberNames.ts @@ -19,7 +19,7 @@ verify.completionListContains("bar"); verify.completionListContains("break"); verify.completionListContains("any"); verify.completionListContains("$"); -verify.completionListContains("\\u0062"); +verify.completionListContains("b"); // Nothing else should show up verify.memberListCount(5); From 85c6d34047f29f553da832288c59cbe05f9d6c93 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Fri, 12 Sep 2014 12:43:34 -0700 Subject: [PATCH 10/31] add basic support for contextual object literal completions --- src/services/services.ts | 67 ++++++++++++------- .../memberCompletionOnTypeParameters.ts | 14 ++-- 2 files changed, 50 insertions(+), 31 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index 851901ea13..42913ac64d 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1574,7 +1574,7 @@ module ts { // invalid identifer name. We need to check if whatever was inside the quotes is actually a valid identifier name. displayName = displayName.substring(1, displayName.length - 1); } - + var isValid = isIdentifierStart(displayName.charCodeAt(0), target); for (var i = 1, n = displayName.length; isValid && i < n; i++) { isValid = isValid && isIdentifierPart(displayName.charCodeAt(i), target); @@ -1748,6 +1748,36 @@ module ts { return !(declaration && declaration.flags & NodeFlags.Private && containingClass !== declaration.parent); } + function filterContextualMembersList(contextualMemberSymbols: Symbol[], existingMembers: Declaration[]): Symbol[] { + if (!existingMembers || existingMembers.length === 0) { + return contextualMemberSymbols; + } + + var existingMemberNames: Map = {}; + forEach(existingMembers, m => { + if (m.kind !== SyntaxKind.PropertyAssignment) { + // Ignore ommited expressions for missing members in the object literal + return; + } + + if (position <= m.getEnd() && position >= m.getStart()) { + // If this is the current item we are editing right now, do not filter it out + return; + } + + existingMemberNames[m.name.text] = true; + }); + + var filteredMembers: Symbol[] = []; + forEach(contextualMemberSymbols, s=> { + if (!existingMemberNames[s.name]) { + filteredMembers.push(s); + } + }); + + return filteredMembers; + } + synchronizeHostData(); filename = TypeScript.switchToForwardSlashes(filename); @@ -1855,34 +1885,23 @@ module ts { // Object literal expression, look up possible property names from contextual type if (containingObjectLiteral) { - var searchPosition = Math.min(position, TypeScript.end(containingObjectLiteral)); - var path = TypeScript.ASTHelpers.getAstAtPosition(sourceUnit, searchPosition); - // Get the object literal node + var objectLiteral = mappedNode.kind === SyntaxKind.ObjectLiteral ? mappedNode : getAncestor(mappedNode, SyntaxKind.ObjectLiteral); - while (node && node.kind() !== TypeScript.SyntaxKind.ObjectLiteralExpression) { - node = node.parent; - } - - if (!node || node.kind() !== TypeScript.SyntaxKind.ObjectLiteralExpression) { - // AST Path look up did not result in the same node as Fidelity Syntax Tree look up. - // Once we remove AST this will no longer be a problem. - return null; - } + Debug.assert(objectLiteral); isMemberCompletion = true; - //// Try to get the object members form contextual typing - //var contextualMembers = compiler.getContextualMembersFromAST(node, document); - //if (contextualMembers && contextualMembers.symbols && contextualMembers.symbols.length > 0) { - // // get existing members - // var existingMembers = compiler.getVisibleMemberSymbolsFromAST(node, document); + var contextualType = typeInfoResolver.getContextualType(objectLiteral); + if (!contextualType) { + return undefined; + } - // // Add filtterd items to the completion list - // getCompletionEntriesFromSymbols({ - // symbols: filterContextualMembersList(contextualMembers.symbols, existingMembers, filename, position), - // enclosingScopeSymbol: contextualMembers.enclosingScopeSymbol - // }, entries); - //} + var contextualTypeMembers = typeInfoResolver.getPropertiesOfType(contextualType); + if (contextualTypeMembers && contextualTypeMembers.length > 0) { + // Add filtterd items to the completion list + var filteredMembers = filterContextualMembersList(contextualTypeMembers, objectLiteral.properties); + getCompletionEntriesFromSymbols(filteredMembers, activeCompletionSession); + } } // Get scope memebers else { diff --git a/tests/cases/fourslash/memberCompletionOnTypeParameters.ts b/tests/cases/fourslash/memberCompletionOnTypeParameters.ts index 117b6e48c4..5fc8a55327 100644 --- a/tests/cases/fourslash/memberCompletionOnTypeParameters.ts +++ b/tests/cases/fourslash/memberCompletionOnTypeParameters.ts @@ -1,10 +1,10 @@ -/// - -////interface IFoo { -//// x: number; -//// y: string; -////} -//// +/// + +////interface IFoo { +//// x: number; +//// y: string; +////} +//// ////function foo() { //// var s:S, t: T, u: U, v: V; //// s./*S*/; // no constraint, no completion From aa571ff0886fa4908d7452a0a7e09c6208a67eaa Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Fri, 12 Sep 2014 15:31:47 -0700 Subject: [PATCH 11/31] Short-circuit semantic operations within with blocks --- src/compiler/checker.ts | 37 ++++++++++++++++++- .../fourslash/findAllRefsInsideWithBlock.ts | 16 ++++++++ .../cases/fourslash/memberListInWithBlock.ts | 2 + .../cases/fourslash/memberListInWithBlock2.ts | 12 ++++++ .../cases/fourslash/memberListInWithBlock3.ts | 7 ++++ .../quickInfoInWithBlock.ts | 0 6 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/findAllRefsInsideWithBlock.ts create mode 100644 tests/cases/fourslash/memberListInWithBlock2.ts create mode 100644 tests/cases/fourslash/memberListInWithBlock3.ts rename tests/cases/{fourslash_old => fourslash}/quickInfoInWithBlock.ts (100%) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 809857db2c..f83c1c9a01 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3815,6 +3815,11 @@ module ts { // Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily // be "pushed" onto a node using the contextualType property. function getContextualType(node: Expression): Type { + if (isInsideWithStatementBody(node)) { + // We cannot answer semantic questions within a with block, do not proceed any further + return undefined; + } + if (node.contextualType) { return node.contextualType; } @@ -6681,7 +6686,20 @@ module ts { return findChildAtPosition(sourceFile); } - function getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[] { + function isInsideWithStatementBody(node: Node): boolean { + if (node) { + while (node.parent) { + if (node.parent.kind === SyntaxKind.WithStatement && (node.parent).statement === node) { + return true; + } + node = node.parent; + } + } + + return false; + } + + function getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[]{ var symbols: SymbolTable = {}; var memberFlags: NodeFlags = 0; function copySymbol(symbol: Symbol, meaning: SymbolFlags) { @@ -6701,6 +6719,12 @@ module ts { } } } + + if (isInsideWithStatementBody(location)) { + // We cannot answer semantic questions within a with block, do not proceed any further + return []; + } + while (location) { if (location.locals && !isGlobalSourceFile(location)) { copySymbols(location.locals, meaning); @@ -6973,6 +6997,11 @@ module ts { } function getSymbolInfo(node: Node) { + if (isInsideWithStatementBody(node)) { + // We cannot answer semantic questions within a with block, do not proceed any further + return undefined; + } + if (isDeclarationOrFunctionExpressionOrCatchVariableName(node)) { // This is a declaration, call getSymbolOfNode return getSymbolOfNode(node.parent); @@ -7027,9 +7056,15 @@ module ts { } function getTypeOfNode(node: Node): Type { + if (isInsideWithStatementBody(node)) { + // We cannot answer semantic questions within a with block, do not proceed any further + return unknownType; + } + if (isExpression(node)) { return getTypeOfExpression(node); } + if (isTypeNode(node)) { return getTypeFromTypeNode(node); } diff --git a/tests/cases/fourslash/findAllRefsInsideWithBlock.ts b/tests/cases/fourslash/findAllRefsInsideWithBlock.ts new file mode 100644 index 0000000000..394d30d89d --- /dev/null +++ b/tests/cases/fourslash/findAllRefsInsideWithBlock.ts @@ -0,0 +1,16 @@ +/// + +////var x = 0; +//// +////with ({}) { +//// var y = x; // Reference of x here should not be picked +//// /*2*/y++; // also reference for y should be ignored +////} +//// +////x = /*1*/x + 1; + +goTo.marker('1'); +verify.referencesCountIs(3); + +goTo.marker('2'); +verify.referencesCountIs(1); \ No newline at end of file diff --git a/tests/cases/fourslash/memberListInWithBlock.ts b/tests/cases/fourslash/memberListInWithBlock.ts index 973f4612cd..a37c20dadf 100644 --- a/tests/cases/fourslash/memberListInWithBlock.ts +++ b/tests/cases/fourslash/memberListInWithBlock.ts @@ -15,8 +15,10 @@ goTo.marker('1'); verify.memberListIsEmpty(); goTo.marker('2'); +// Only keywords should show in completion, no members or types verify.not.completionListContains("foo"); verify.not.completionListContains("f"); verify.not.completionListContains("c"); verify.not.completionListContains("d"); verify.not.completionListContains("x"); +verify.not.completionListContains("Object"); diff --git a/tests/cases/fourslash/memberListInWithBlock2.ts b/tests/cases/fourslash/memberListInWithBlock2.ts new file mode 100644 index 0000000000..72bccb6926 --- /dev/null +++ b/tests/cases/fourslash/memberListInWithBlock2.ts @@ -0,0 +1,12 @@ +/// + +////interface IFoo { +//// a: number; +////} +//// +////with (x) { +//// var y: IFoo = { /*1*/ }; +////} + +goTo.marker('1'); +verify.memberListIsEmpty(); \ No newline at end of file diff --git a/tests/cases/fourslash/memberListInWithBlock3.ts b/tests/cases/fourslash/memberListInWithBlock3.ts new file mode 100644 index 0000000000..a007b08cd0 --- /dev/null +++ b/tests/cases/fourslash/memberListInWithBlock3.ts @@ -0,0 +1,7 @@ +/// + +////var x = { a: 0 }; +////with(x./*1*/ + +goTo.marker('1'); +verify.memberListContains("a"); diff --git a/tests/cases/fourslash_old/quickInfoInWithBlock.ts b/tests/cases/fourslash/quickInfoInWithBlock.ts similarity index 100% rename from tests/cases/fourslash_old/quickInfoInWithBlock.ts rename to tests/cases/fourslash/quickInfoInWithBlock.ts From 085cabf8e01f485aac6ce87b0427e0de92022483 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Fri, 12 Sep 2014 16:41:24 -0700 Subject: [PATCH 12/31] Change test untill we have filtering on location --- .../fourslash/completionListInExtendsClause.ts | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/tests/cases/fourslash/completionListInExtendsClause.ts b/tests/cases/fourslash/completionListInExtendsClause.ts index 0ffb083606..97ebc51701 100644 --- a/tests/cases/fourslash/completionListInExtendsClause.ts +++ b/tests/cases/fourslash/completionListInExtendsClause.ts @@ -18,8 +18,15 @@ ////interface test4 implements Foo./*4*/ {} -test.markers().forEach((marker) => { - goTo.position(marker.position, marker.fileName); +goTo.marker("1"); +verify.completionListIsEmpty(); - verify.completionListIsEmpty(); -}); +goTo.marker("2"); +verify.completionListIsEmpty(); + +goTo.marker("3"); +verify.completionListIsEmpty(); + +// This needs comletion list filtering based on location to work +goTo.marker("4"); +verify.not.completionListIsEmpty(); \ No newline at end of file From 5d577df69e50a03f1edfcbf66b232925d7d1e13c Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Fri, 12 Sep 2014 16:48:52 -0700 Subject: [PATCH 13/31] Add better error recovery logic for cases with line ending with "id." followed by a declaration e.g. "class id" --- src/compiler/parser.ts | 30 ++++++++++++++++++- ...umConflictsWithGlobalIdentifier.errors.txt | 4 +-- .../reference/enumMemberResolution.errors.txt | 4 +-- .../memberListOfModuleBeforeKeyword.ts | 8 ++--- 4 files changed, 37 insertions(+), 9 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 70cdffc75c..c380c1e0df 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2198,10 +2198,38 @@ module ts { function parseCallAndAccess(expr: Expression, inNewExpression: boolean): Expression { while (true) { + var dotStart = scanner.getTokenPos(); if (parseOptional(SyntaxKind.DotToken)) { var propertyAccess = createNode(SyntaxKind.PropertyAccess, expr.pos); + // Technically a keyword is valid here as all keywords are identifier names. + // However, often we'll encounter this in error situations when the keyword + // is actually starting another valid construct. + // + // So, we check for the following specific case: + // + // name. + // keyword identifierNameOrKeyword + // + // Note: the newlines are important here. For example, if that above code + // were rewritten into: + // + // name.keyword + // identifierNameOrKeyword + // + // Then we would consider it valid. That's because ASI would take effect and + // the code would be implicitly: "name.keyword; identifierNameOrKeyword". + // In the first case though, ASI will not take effect because there is not a + // line terminator after the keyword. + if (scanner.hasPrecedingLineBreak() && scanner.isReservedWord() && lookAhead(() => scanner.isReservedWord())) { + grammarErrorAtPos(dotStart, scanner.getStartPos() - dotStart, Diagnostics.Identifier_expected); + var id = createMissingNode(); + } + else { + var id = parseIdentifierName(); + } + propertyAccess.left = expr; - propertyAccess.right = parseIdentifierName(); + propertyAccess.right = id; expr = finishNode(propertyAccess); continue; } diff --git a/tests/baselines/reference/enumConflictsWithGlobalIdentifier.errors.txt b/tests/baselines/reference/enumConflictsWithGlobalIdentifier.errors.txt index 7fb893354a..41e01d6fa4 100644 --- a/tests/baselines/reference/enumConflictsWithGlobalIdentifier.errors.txt +++ b/tests/baselines/reference/enumConflictsWithGlobalIdentifier.errors.txt @@ -3,9 +3,9 @@ IgnoreRulesSpecific = 0, } var x = IgnoreRulesSpecific. + ~ +!!! Identifier expected. ~~~~~~~~~~~~~~~~~~~ !!! Cannot find name 'IgnoreRulesSpecific'. var y = Position.IgnoreRulesSpecific; - ~ -!!! ',' expected. \ No newline at end of file diff --git a/tests/baselines/reference/enumMemberResolution.errors.txt b/tests/baselines/reference/enumMemberResolution.errors.txt index 71f6f8e45b..9fa148d849 100644 --- a/tests/baselines/reference/enumMemberResolution.errors.txt +++ b/tests/baselines/reference/enumMemberResolution.errors.txt @@ -3,10 +3,10 @@ IgnoreRulesSpecific = 0 } var x = IgnoreRulesSpecific. // error + ~ +!!! Identifier expected. ~~~~~~~~~~~~~~~~~~~ !!! Cannot find name 'IgnoreRulesSpecific'. var y = 1; - ~ -!!! ',' expected. var z = Position2.IgnoreRulesSpecific; // no error \ No newline at end of file diff --git a/tests/cases/fourslash/memberListOfModuleBeforeKeyword.ts b/tests/cases/fourslash/memberListOfModuleBeforeKeyword.ts index 2356a35d94..33f085cde0 100644 --- a/tests/cases/fourslash/memberListOfModuleBeforeKeyword.ts +++ b/tests/cases/fourslash/memberListOfModuleBeforeKeyword.ts @@ -16,9 +16,9 @@ // Verify the memberlist of module when the following line has a keyword goTo.marker('namedType'); -verify.completionListContains('C1', 'TypeModule1.C1'); -verify.completionListContains('C2', 'TypeModule1.C2'); +verify.completionListContains('C1'); +verify.completionListContains('C2'); goTo.marker('dotedExpression'); -verify.completionListContains('C1', 'TypeModule1.C1'); -verify.completionListContains('C2', 'TypeModule1.C2'); \ No newline at end of file +verify.completionListContains('C1'); +verify.completionListContains('C2'); \ No newline at end of file From 4e17787cb5f8e69b97540a5e1d70c3f9b4fa7704 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Fri, 12 Sep 2014 16:49:45 -0700 Subject: [PATCH 14/31] Do not colorize a keyword following an identifier. as it is likely an error scenario as the user is typing --- src/services/services.ts | 7 ------- tests/cases/unittests/services/colorization.ts | 4 ++-- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index 42913ac64d..26469a1fd1 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -692,7 +692,6 @@ module ts { InMultiLineCommentTrivia, InSingleQuoteStringLiteral, InDoubleQuoteStringLiteral, - EndingWithDotToken, } export enum TokenClass { @@ -3502,9 +3501,6 @@ module ts { text = "/*\n" + text; offset = 3; break; - case EndOfLineState.EndingWithDotToken: - lastToken = SyntaxKind.DotToken; - break; } var result: ClassificationResult = { @@ -3572,9 +3568,6 @@ module ts { : EndOfLineState.InSingleQuoteStringLiteral; } } - else if (token === SyntaxKind.DotToken) { - result.finalLexState = EndOfLineState.EndingWithDotToken; - } } } diff --git a/tests/cases/unittests/services/colorization.ts b/tests/cases/unittests/services/colorization.ts index 414942bbde..7b8ee37606 100644 --- a/tests/cases/unittests/services/colorization.ts +++ b/tests/cases/unittests/services/colorization.ts @@ -170,8 +170,8 @@ describe('Colorization', function () { it("classifies keyword after a dot on previous line", function () { test("var", - ts.EndOfLineState.EndingWithDotToken, - identifier("var"), + ts.EndOfLineState.Start, + keyword("var"), finalEndOfLineState(ts.EndOfLineState.Start)); }); }); From 3667c6a43e1745c7a82e71cb3d6ffa027439f7ed Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Fri, 12 Sep 2014 17:25:00 -0700 Subject: [PATCH 15/31] remove debug statements from tests --- tests/cases/fourslash/memberListOfClass.ts | 1 - tests/cases/fourslash/memberListOfExportedClass.ts | 1 - tests/cases/fourslash/todoComments1.ts | 2 +- tests/cases/fourslash/todoComments10.ts | 2 +- tests/cases/fourslash/todoComments11.ts | 2 +- tests/cases/fourslash/todoComments12.ts | 2 +- tests/cases/fourslash/todoComments13.ts | 1 - tests/cases/fourslash/todoComments14.ts | 2 +- tests/cases/fourslash/todoComments15.ts | 2 +- tests/cases/fourslash/todoComments16.ts | 2 +- tests/cases/fourslash/todoComments17.ts | 2 +- tests/cases/fourslash/todoComments2.ts | 2 +- tests/cases/fourslash/todoComments3.ts | 2 +- tests/cases/fourslash/todoComments4.ts | 2 +- tests/cases/fourslash/todoComments5.ts | 2 +- tests/cases/fourslash/todoComments6.ts | 2 +- tests/cases/fourslash/todoComments7.ts | 2 +- tests/cases/fourslash/todoComments8.ts | 2 +- tests/cases/fourslash/todoComments9.ts | 2 +- 19 files changed, 16 insertions(+), 19 deletions(-) diff --git a/tests/cases/fourslash/memberListOfClass.ts b/tests/cases/fourslash/memberListOfClass.ts index 137903e5aa..567dfc0ddc 100644 --- a/tests/cases/fourslash/memberListOfClass.ts +++ b/tests/cases/fourslash/memberListOfClass.ts @@ -10,7 +10,6 @@ ////f./**/ goTo.marker(); -debug.printCompletionListMembers(); verify.memberListCount(2); verify.memberListContains('pubMeth', '() => void'); verify.memberListContains('pubProp', 'number'); \ No newline at end of file diff --git a/tests/cases/fourslash/memberListOfExportedClass.ts b/tests/cases/fourslash/memberListOfExportedClass.ts index 853856747d..a564504e7e 100644 --- a/tests/cases/fourslash/memberListOfExportedClass.ts +++ b/tests/cases/fourslash/memberListOfExportedClass.ts @@ -11,6 +11,5 @@ ////c./**/ // test on c. goTo.marker(); -debug.printCompletionListMembers(); verify.memberListCount(1); verify.memberListContains('pub', 'number'); \ No newline at end of file diff --git a/tests/cases/fourslash/todoComments1.ts b/tests/cases/fourslash/todoComments1.ts index 900b4694c6..b1e0086b93 100644 --- a/tests/cases/fourslash/todoComments1.ts +++ b/tests/cases/fourslash/todoComments1.ts @@ -1,3 +1,3 @@ //// // [|TODO|] -debugger; + verify.todoCommentsInCurrentFile(["TODO"]); \ No newline at end of file diff --git a/tests/cases/fourslash/todoComments10.ts b/tests/cases/fourslash/todoComments10.ts index 26ee7a4014..cde41dd6fb 100644 --- a/tests/cases/fourslash/todoComments10.ts +++ b/tests/cases/fourslash/todoComments10.ts @@ -2,5 +2,5 @@ //// [|todo 1|] //// [|hack 2|] //// */ -debugger; + verify.todoCommentsInCurrentFile(["TODO", "HACK"]); \ No newline at end of file diff --git a/tests/cases/fourslash/todoComments11.ts b/tests/cases/fourslash/todoComments11.ts index 976368315d..dd69091130 100644 --- a/tests/cases/fourslash/todoComments11.ts +++ b/tests/cases/fourslash/todoComments11.ts @@ -2,5 +2,5 @@ //// [|TODO(jason) 1|] //// [|HACK 2|] //// */ -debugger; + verify.todoCommentsInCurrentFile(["TODO(jason)", "HACK"]); \ No newline at end of file diff --git a/tests/cases/fourslash/todoComments12.ts b/tests/cases/fourslash/todoComments12.ts index d9cd3dea4d..7f9a0a0cd7 100644 --- a/tests/cases/fourslash/todoComments12.ts +++ b/tests/cases/fourslash/todoComments12.ts @@ -2,5 +2,5 @@ //// [|TODO(jason) 1|] //// [|HACK 2|] //// */ -debugger; + verify.todoCommentsInCurrentFile(["HACK", "TODO(jason)"]); \ No newline at end of file diff --git a/tests/cases/fourslash/todoComments13.ts b/tests/cases/fourslash/todoComments13.ts index 93147b30e4..82304e2ab8 100644 --- a/tests/cases/fourslash/todoComments13.ts +++ b/tests/cases/fourslash/todoComments13.ts @@ -1,4 +1,3 @@ //// TODO -debugger; verify.todoCommentsInCurrentFile(["TODO"]); \ No newline at end of file diff --git a/tests/cases/fourslash/todoComments14.ts b/tests/cases/fourslash/todoComments14.ts index 46f8f48fe3..3a3294f4bb 100644 --- a/tests/cases/fourslash/todoComments14.ts +++ b/tests/cases/fourslash/todoComments14.ts @@ -1,3 +1,3 @@ //// BAR // [|TODO|] -debugger; + verify.todoCommentsInCurrentFile(["TODO"]); \ No newline at end of file diff --git a/tests/cases/fourslash/todoComments15.ts b/tests/cases/fourslash/todoComments15.ts index 22cee54d0f..6bb327ecdf 100644 --- a/tests/cases/fourslash/todoComments15.ts +++ b/tests/cases/fourslash/todoComments15.ts @@ -1,3 +1,3 @@ //// "// HACK 1"; -debugger; + verify.todoCommentsInCurrentFile(["TODO(jason)", "HACK"]); \ No newline at end of file diff --git a/tests/cases/fourslash/todoComments16.ts b/tests/cases/fourslash/todoComments16.ts index bbdeac0c5e..d980034090 100644 --- a/tests/cases/fourslash/todoComments16.ts +++ b/tests/cases/fourslash/todoComments16.ts @@ -1,3 +1,3 @@ //// //// [|HACK 1|] -debugger; + verify.todoCommentsInCurrentFile(["TODO(jason)", "HACK"]); \ No newline at end of file diff --git a/tests/cases/fourslash/todoComments17.ts b/tests/cases/fourslash/todoComments17.ts index 5231694160..a751bb10dd 100644 --- a/tests/cases/fourslash/todoComments17.ts +++ b/tests/cases/fourslash/todoComments17.ts @@ -1,3 +1,3 @@ //// /**** [|HACK 1 |]*/ a -debugger; + verify.todoCommentsInCurrentFile(["TODO(jason)", "HACK"]); \ No newline at end of file diff --git a/tests/cases/fourslash/todoComments2.ts b/tests/cases/fourslash/todoComments2.ts index b58b0fda7a..ddf8520c48 100644 --- a/tests/cases/fourslash/todoComments2.ts +++ b/tests/cases/fourslash/todoComments2.ts @@ -1,3 +1,3 @@ //// // not TODO -debugger; + verify.todoCommentsInCurrentFile(["TODO"]); \ No newline at end of file diff --git a/tests/cases/fourslash/todoComments3.ts b/tests/cases/fourslash/todoComments3.ts index 62eb02642e..f38b80ae8f 100644 --- a/tests/cases/fourslash/todoComments3.ts +++ b/tests/cases/fourslash/todoComments3.ts @@ -1,3 +1,3 @@ //// // [|TODO with stuff|] -debugger; + verify.todoCommentsInCurrentFile(["TODO"]); \ No newline at end of file diff --git a/tests/cases/fourslash/todoComments4.ts b/tests/cases/fourslash/todoComments4.ts index c9ec94785f..86d6ce2407 100644 --- a/tests/cases/fourslash/todoComments4.ts +++ b/tests/cases/fourslash/todoComments4.ts @@ -1,3 +1,3 @@ //// // TODOnomatch -debugger; + verify.todoCommentsInCurrentFile(["TODO"]); \ No newline at end of file diff --git a/tests/cases/fourslash/todoComments5.ts b/tests/cases/fourslash/todoComments5.ts index 157ac162a8..05db2aca16 100644 --- a/tests/cases/fourslash/todoComments5.ts +++ b/tests/cases/fourslash/todoComments5.ts @@ -2,5 +2,5 @@ //// [|TODO 1|] //// [|TODO 2|] //// */ -debugger; + verify.todoCommentsInCurrentFile(["TODO"]); \ No newline at end of file diff --git a/tests/cases/fourslash/todoComments6.ts b/tests/cases/fourslash/todoComments6.ts index 0d2692511c..84e0542811 100644 --- a/tests/cases/fourslash/todoComments6.ts +++ b/tests/cases/fourslash/todoComments6.ts @@ -2,5 +2,5 @@ //// * [|TODO 1|] //// * [|TODO 2|] //// */ -debugger; + verify.todoCommentsInCurrentFile(["TODO"]); \ No newline at end of file diff --git a/tests/cases/fourslash/todoComments7.ts b/tests/cases/fourslash/todoComments7.ts index ffb5bcf660..10b18a53bc 100644 --- a/tests/cases/fourslash/todoComments7.ts +++ b/tests/cases/fourslash/todoComments7.ts @@ -2,5 +2,5 @@ //// [|TODO 1|] //// [|HACK 2|] //// */ -debugger; + verify.todoCommentsInCurrentFile(["TODO", "HACK"]); \ No newline at end of file diff --git a/tests/cases/fourslash/todoComments8.ts b/tests/cases/fourslash/todoComments8.ts index 5d53b7b57c..e63c07d631 100644 --- a/tests/cases/fourslash/todoComments8.ts +++ b/tests/cases/fourslash/todoComments8.ts @@ -2,5 +2,5 @@ //// [|HACK 1|] //// [|TODO 2|] //// */ -debugger; + verify.todoCommentsInCurrentFile(["TODO", "HACK"]); \ No newline at end of file diff --git a/tests/cases/fourslash/todoComments9.ts b/tests/cases/fourslash/todoComments9.ts index 36cba71cec..107f6c279a 100644 --- a/tests/cases/fourslash/todoComments9.ts +++ b/tests/cases/fourslash/todoComments9.ts @@ -2,5 +2,5 @@ //// [|TODO HACK|] //// [|HACK TODO|] //// */ -debugger; + verify.todoCommentsInCurrentFile(["TODO", "HACK"]); \ No newline at end of file From cb30eaf8b1653b12333fb2e1c29d6ef901eefcc2 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 15 Sep 2014 12:53:16 -0700 Subject: [PATCH 16/31] Allow built in types to show up in the completion list as keywords instead of types --- tests/cases/fourslash/completionEntryForPrimitive.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cases/fourslash/completionEntryForPrimitive.ts b/tests/cases/fourslash/completionEntryForPrimitive.ts index d5beda9327..9b800c7b7e 100644 --- a/tests/cases/fourslash/completionEntryForPrimitive.ts +++ b/tests/cases/fourslash/completionEntryForPrimitive.ts @@ -6,4 +6,4 @@ diagnostics.setEditValidation(IncrementalEditValidation.None); goTo.marker(); verify.not.completionListIsEmpty(); edit.insert("nu"); -verify.completionListContains("number", undefined, undefined, undefined, "primitive type"); \ No newline at end of file +verify.completionListContains("number", undefined, undefined, undefined, "keyword"); \ No newline at end of file From 4c3589fd6e84d82c288cdcbb9f57b06ec5be60df Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 15 Sep 2014 13:00:50 -0700 Subject: [PATCH 17/31] Update tests to remove other type paramters from constraints --- tests/cases/fourslash/memberCompletionOnTypeParameters.ts | 7 +++---- tests/cases/fourslash/memberCompletionOnTypeParameters2.ts | 6 +++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/tests/cases/fourslash/memberCompletionOnTypeParameters.ts b/tests/cases/fourslash/memberCompletionOnTypeParameters.ts index 5fc8a55327..7b415c4b3e 100644 --- a/tests/cases/fourslash/memberCompletionOnTypeParameters.ts +++ b/tests/cases/fourslash/memberCompletionOnTypeParameters.ts @@ -5,7 +5,7 @@ //// y: string; ////} //// -////function foo() { +////function foo() { //// var s:S, t: T, u: U, v: V; //// s./*S*/; // no constraint, no completion //// t./*T*/; // IFoo @@ -22,9 +22,8 @@ verify.memberListContains("y", "string"); verify.memberListCount(2); goTo.marker("U"); -verify.memberListContains("x", "number"); -verify.memberListContains("y", "string"); -verify.memberListCount(2); +verify.memberListContains("toString", "() => string"); +verify.memberListCount(7); // constructor, toString, toLocaleString, valueOf, hasOwnProperty, isPrototypeOf, propertyIsEnumerable goTo.marker("V"); verify.memberListContains("x", "number"); diff --git a/tests/cases/fourslash/memberCompletionOnTypeParameters2.ts b/tests/cases/fourslash/memberCompletionOnTypeParameters2.ts index 8d97b7089c..e7f6c5c651 100644 --- a/tests/cases/fourslash/memberCompletionOnTypeParameters2.ts +++ b/tests/cases/fourslash/memberCompletionOnTypeParameters2.ts @@ -1,5 +1,5 @@ -/// - +/// + ////class A { //// foo(): string { return ''; } ////} @@ -10,7 +10,7 @@ //// } ////} //// -////class C { +////class C { //// x: U; //// y = this.x./**/ // completion list here ////} From 71eab5fc2691b3972409dc16132f4527dc7cddd4 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 15 Sep 2014 13:51:27 -0700 Subject: [PATCH 18/31] disable tests that are dependent on QuickInfo and Signature help work --- .../completionBeforeSemanticDiagnosticsInArrowFunction1.ts | 0 .../completionListGenericConstraintsNames.ts | 0 .../completionListInObjectLiteralThatIsParameterOfFunctionCall.ts | 0 .../completionListInTypedObjectLiterals.ts | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename tests/cases/{fourslash => fourslash_old}/completionBeforeSemanticDiagnosticsInArrowFunction1.ts (100%) rename tests/cases/{fourslash => fourslash_old}/completionListGenericConstraintsNames.ts (100%) rename tests/cases/{fourslash => fourslash_old}/completionListInObjectLiteralThatIsParameterOfFunctionCall.ts (100%) rename tests/cases/{fourslash => fourslash_old}/completionListInTypedObjectLiterals.ts (100%) diff --git a/tests/cases/fourslash/completionBeforeSemanticDiagnosticsInArrowFunction1.ts b/tests/cases/fourslash_old/completionBeforeSemanticDiagnosticsInArrowFunction1.ts similarity index 100% rename from tests/cases/fourslash/completionBeforeSemanticDiagnosticsInArrowFunction1.ts rename to tests/cases/fourslash_old/completionBeforeSemanticDiagnosticsInArrowFunction1.ts diff --git a/tests/cases/fourslash/completionListGenericConstraintsNames.ts b/tests/cases/fourslash_old/completionListGenericConstraintsNames.ts similarity index 100% rename from tests/cases/fourslash/completionListGenericConstraintsNames.ts rename to tests/cases/fourslash_old/completionListGenericConstraintsNames.ts diff --git a/tests/cases/fourslash/completionListInObjectLiteralThatIsParameterOfFunctionCall.ts b/tests/cases/fourslash_old/completionListInObjectLiteralThatIsParameterOfFunctionCall.ts similarity index 100% rename from tests/cases/fourslash/completionListInObjectLiteralThatIsParameterOfFunctionCall.ts rename to tests/cases/fourslash_old/completionListInObjectLiteralThatIsParameterOfFunctionCall.ts diff --git a/tests/cases/fourslash/completionListInTypedObjectLiterals.ts b/tests/cases/fourslash_old/completionListInTypedObjectLiterals.ts similarity index 100% rename from tests/cases/fourslash/completionListInTypedObjectLiterals.ts rename to tests/cases/fourslash_old/completionListInTypedObjectLiterals.ts From 511c0769ff2ac177b8fb6b00b93a5a66ad700c88 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 15 Sep 2014 13:52:17 -0700 Subject: [PATCH 19/31] fix typo --- src/services/services.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index 26469a1fd1..a792346a85 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1742,7 +1742,7 @@ module ts { return (SyntaxKind.FirstPunctuation <= kind && kind <= SyntaxKind.LastPunctuation); } - function isVisibleWithenDeclaration(symbol: Symbol, containingClass: Declaration): boolean { + function isVisibleWithinDeclaration(symbol: Symbol, containingClass: Declaration): boolean { var declaration = symbol.declarations && symbol.declarations[0]; return !(declaration && declaration.flags & NodeFlags.Private && containingClass !== declaration.parent); } @@ -1859,7 +1859,7 @@ module ts { if (symbol && symbol.flags & SymbolFlags.HasExports) { // Extract module or enum members forEachValue(symbol.exports, symbol => { - if (isVisibleWithenDeclaration(symbol, containingClass)) { + if (isVisibleWithinDeclaration(symbol, containingClass)) { symbols.push(symbol); } }); @@ -1871,7 +1871,7 @@ module ts { if (apparentType) { // Filter private properties forEach(apparentType.getApparentProperties(), symbol => { - if (isVisibleWithenDeclaration(symbol, containingClass)) { + if (isVisibleWithinDeclaration(symbol, containingClass)) { symbols.push(symbol); } }); From a164e6a5b7c3990de117c8832a0e965166c2cab2 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 16 Sep 2014 14:10:21 -0700 Subject: [PATCH 20/31] respond to code review comments --- src/compiler/checker.ts | 2 +- src/services/services.ts | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f83c1c9a01..d5ef4f41a7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7145,7 +7145,7 @@ module ts { } function getRootSymbol(symbol: Symbol) { - return (symbol.flags & SymbolFlags.Transient) && getSymbolLinks(symbol).target || symbol; + return ((symbol.flags & SymbolFlags.Transient) && getSymbolLinks(symbol).target) || symbol; } // Emitter support diff --git a/src/services/services.ts b/src/services/services.ts index a792346a85..40d64d9370 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1576,7 +1576,7 @@ module ts { var isValid = isIdentifierStart(displayName.charCodeAt(0), target); for (var i = 1, n = displayName.length; isValid && i < n; i++) { - isValid = isValid && isIdentifierPart(displayName.charCodeAt(i), target); + isValid = isIdentifierPart(displayName.charCodeAt(i), target); } if (isValid) { @@ -1742,9 +1742,9 @@ module ts { return (SyntaxKind.FirstPunctuation <= kind && kind <= SyntaxKind.LastPunctuation); } - function isVisibleWithinDeclaration(symbol: Symbol, containingClass: Declaration): boolean { + function isVisibleWithinClassDeclaration(symbol: Symbol, containingClass: Declaration): boolean { var declaration = symbol.declarations && symbol.declarations[0]; - return !(declaration && declaration.flags & NodeFlags.Private && containingClass !== declaration.parent); + return !(declaration && (declaration.flags & NodeFlags.Private) && containingClass !== declaration.parent); } function filterContextualMembersList(contextualMemberSymbols: Symbol[], existingMembers: Declaration[]): Symbol[] { @@ -1755,11 +1755,11 @@ module ts { var existingMemberNames: Map = {}; forEach(existingMembers, m => { if (m.kind !== SyntaxKind.PropertyAssignment) { - // Ignore ommited expressions for missing members in the object literal + // Ignore omitted expressions for missing members in the object literal return; } - if (position <= m.getEnd() && position >= m.getStart()) { + if (m.getStart() <= position && position <= m.getEnd()) { // If this is the current item we are editing right now, do not filter it out return; } @@ -1768,7 +1768,7 @@ module ts { }); var filteredMembers: Symbol[] = []; - forEach(contextualMemberSymbols, s=> { + forEach(contextualMemberSymbols, s => { if (!existingMemberNames[s.name]) { filteredMembers.push(s); } @@ -1859,7 +1859,7 @@ module ts { if (symbol && symbol.flags & SymbolFlags.HasExports) { // Extract module or enum members forEachValue(symbol.exports, symbol => { - if (isVisibleWithinDeclaration(symbol, containingClass)) { + if (isVisibleWithinClassDeclaration(symbol, containingClass)) { symbols.push(symbol); } }); @@ -1871,7 +1871,7 @@ module ts { if (apparentType) { // Filter private properties forEach(apparentType.getApparentProperties(), symbol => { - if (isVisibleWithinDeclaration(symbol, containingClass)) { + if (isVisibleWithinClassDeclaration(symbol, containingClass)) { symbols.push(symbol); } }); @@ -1884,7 +1884,7 @@ module ts { // Object literal expression, look up possible property names from contextual type if (containingObjectLiteral) { - var objectLiteral = mappedNode.kind === SyntaxKind.ObjectLiteral ? mappedNode : getAncestor(mappedNode, SyntaxKind.ObjectLiteral); + var objectLiteral = (mappedNode.kind === SyntaxKind.ObjectLiteral ? mappedNode : getAncestor(mappedNode, SyntaxKind.ObjectLiteral)); Debug.assert(objectLiteral); @@ -1897,7 +1897,7 @@ module ts { var contextualTypeMembers = typeInfoResolver.getPropertiesOfType(contextualType); if (contextualTypeMembers && contextualTypeMembers.length > 0) { - // Add filtterd items to the completion list + // Add filtered items to the completion list var filteredMembers = filterContextualMembersList(contextualTypeMembers, objectLiteral.properties); getCompletionEntriesFromSymbols(filteredMembers, activeCompletionSession); } From 27805d6585dfb12298d78f62ca064839e30308aa Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 16 Sep 2014 14:51:47 -0700 Subject: [PATCH 21/31] Implement the getRenameInfo language service entrypoint. Tests pending. --- src/compiler/checker.ts | 3 +- src/compiler/types.ts | 1 + src/services/services.ts | 89 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 91 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index da03c9fb61..be53e7c4da 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -65,7 +65,8 @@ module ts { symbolToString: symbolToString, getAugmentedPropertiesOfApparentType: getAugmentedPropertiesOfApparentType, getRootSymbol: getRootSymbol, - getContextualType: getContextualType + getContextualType: getContextualType, + getFullyQualifiedName: getFullyQualifiedName }; var undefinedSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, "undefined"); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 6955689797..b652418ffc 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -623,6 +623,7 @@ module ts { getApparentType(type: Type): ApparentType; typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string; symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): string; + getFullyQualifiedName(symbol: Symbol): string; getAugmentedPropertiesOfApparentType(type: Type): Symbol[]; getRootSymbol(symbol: Symbol): Symbol; getContextualType(node: Node): Type; diff --git a/src/services/services.ts b/src/services/services.ts index 7447e56df8..7572423047 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -3673,6 +3673,93 @@ module ts { return null; } + function getRenameInfo(fileName: string, position: number): RenameInfo { + synchronizeHostData(); + + fileName = TypeScript.switchToForwardSlashes(fileName); + var sourceFile = getSourceFile(fileName); + + var node = getNodeAtPosition(sourceFile, position); + + // Can only rename an identifier. + if (node && node.kind === SyntaxKind.Identifier) { + var symbol = typeInfoResolver.getSymbolInfo(node); + + // Only allow a symbol to be renamed if it actually has at least one declaration. + if (symbol && symbol.getDeclarations() && symbol.getDeclarations().length > 0) { + var kind = getKind(symbol); + if (kind) { + return RenameInfo.Create(symbol.name, typeInfoResolver.getFullyQualifiedName(symbol), kind, getKindModifiers(symbol), + new TypeScript.TextSpan(node.getStart(), node.getWidth())); + } + } + } + + function getKindModifiers(symbol: Symbol): string { + var modifiers: string[] = []; + var decl = symbol.getDeclarations()[0]; + + if (decl.flags & NodeFlags.Ambient) { + modifiers.push(ScriptElementKindModifier.ambientModifier); + } + if (decl.flags & NodeFlags.Export) { + modifiers.push(ScriptElementKindModifier.exportedModifier); + } + if (decl.flags & NodeFlags.Private) { + modifiers.push(ScriptElementKindModifier.privateMemberModifier); + } + if (decl.flags & NodeFlags.Public) { + modifiers.push(ScriptElementKindModifier.publicMemberModifier); + } + if (decl.flags & NodeFlags.Static) { + modifiers.push(ScriptElementKindModifier.staticModifier); + } + + return modifiers.length == 0 ? ScriptElementKindModifier.none : modifiers.join(','); + } + + function getKind(symbol: Symbol): string { + if (symbol.flags & SymbolFlags.Module) { + return ScriptElementKind.moduleElement; + } + else if (symbol.flags & SymbolFlags.Class) { + return ScriptElementKind.classElement; + } + else if (symbol.flags & SymbolFlags.Interface) { + return ScriptElementKind.interfaceElement; + } + else if (symbol.flags & SymbolFlags.Enum) { + return ScriptElementKind.enumElement; + } + else if (symbol.flags & SymbolFlags.Variable) { + return ScriptElementKind.variableElement; + } + else if (symbol.flags & SymbolFlags.Function) { + return ScriptElementKind.functionElement; + } + else if (symbol.flags & SymbolFlags.Method) { + return ScriptElementKind.memberFunctionElement; + } + else if (symbol.flags & SymbolFlags.GetAccessor) { + return ScriptElementKind.memberGetAccessorElement; + } + else if (symbol.flags & SymbolFlags.SetAccessor) { + return ScriptElementKind.memberSetAccessorElement; + } + else if (symbol.flags & SymbolFlags.Property) { + return ScriptElementKind.memberVariableElement; + } + else if (symbol.flags & SymbolFlags.TypeParameter) { + return ScriptElementKind.typeParameterElement; + } + else if (symbol.flags & SymbolFlags.EnumMember) { + return ScriptElementKind.memberVariableElement; + } + } + + return RenameInfo.CreateError(getLocaleSpecificMessage(Diagnostics.You_cannot_rename_this_element.key)); + } + return { dispose: dispose, cleanupSemanticCache: cleanupSemanticCache, @@ -3693,7 +3780,7 @@ module ts { getNameOrDottedNameSpan: getNameOrDottedNameSpan, getBreakpointStatementAtPosition: getBreakpointStatementAtPosition, getNavigateToItems: (searchValue) => [], - getRenameInfo: (fileName, position): RenameInfo => RenameInfo.CreateError(getLocaleSpecificMessage(Diagnostics.You_cannot_rename_this_element.key)), + getRenameInfo: getRenameInfo, getNavigationBarItems: getNavigationBarItems, getOutliningSpans: getOutliningSpans, getTodoComments: getTodoComments, From 85ddc352689fce82482c99a41e8c07a54bf13c54 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 16 Sep 2014 17:05:05 -0700 Subject: [PATCH 22/31] respond to code review comments --- src/compiler/parser.ts | 4 +--- src/services/services.ts | 5 ++--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 09668541b9..3eb1756992 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -556,9 +556,7 @@ module ts { if (node.kind === kind) { return node; } - else { - node = node.parent; - } + node = node.parent; } break; } diff --git a/src/services/services.ts b/src/services/services.ts index b33d673357..f93631fc4b 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1790,7 +1790,7 @@ module ts { return false; } - function isToken(kind: SyntaxKind) { + function isPunctuation(kind: SyntaxKind) { return (SyntaxKind.FirstPunctuation <= kind && kind <= SyntaxKind.LastPunctuation); } @@ -1883,7 +1883,7 @@ module ts { // TODO: this is a hack for now, we need a proper walking mechanism to verify that we have the correct node var mappedNode = getNodeAtPosition(sourceFile, TypeScript.end(node) - 1); - if (isToken(mappedNode.kind)) { + if (isPunctuation(mappedNode.kind)) { mappedNode = mappedNode.parent; } @@ -1905,7 +1905,6 @@ module ts { var containingClass = getAncestor(mappedNode, SyntaxKind.ClassDeclaration); isMemberCompletion = true; - if (mappedNode.kind === SyntaxKind.Identifier || mappedNode.kind === SyntaxKind.QualifiedName || mappedNode.kind === SyntaxKind.PropertyAccess) { var symbol = typeInfoResolver.getSymbolInfo(mappedNode); if (symbol && symbol.flags & SymbolFlags.HasExports) { From d58272dd849a4d35218379f8cece184db4c07c37 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 17 Sep 2014 11:55:19 -0700 Subject: [PATCH 23/31] move getTodoComments to the new tree --- src/services/services.ts | 80 ++++++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 31 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index 7447e56df8..6d66a98235 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1977,6 +1977,24 @@ module ts { } } + function getTokenAtPosition(sourceFile: SourceFile, position: number) { + var current: Node = sourceFile; + outer: while (true) { + // find the child that has this + for (var i = 0, n = current.getChildCount(); i < n; i++) { + var child = current.getChildAt(i); + if (child.getFullStart() <= position && position < child.getEnd()) { + current = child; + continue outer; + } + if (child.end > position) { + break; + } + } + return current; + } + } + function getContainerNode(node: Node): Node { while (true) { node = node.parent; @@ -3569,19 +3587,19 @@ module ts { // // 'i' is for case insensitivity (We do this to match C# TODO comment code). // - // 'm' is so we can find matches in a multiline input. + // 'm' is so we can find matches in a multi-line input. return new RegExp(regExpString, "gim"); } - function getTodoComments(fileName: string, descriptors: TodoCommentDescriptor[]): TodoComment[] { - fileName = TypeScript.switchToForwardSlashes(fileName); + function getTodoComments(filename: string, descriptors: TodoCommentDescriptor[]): TodoComment[] { + filename = TypeScript.switchToForwardSlashes(filename); + + var sourceFile = getCurrentSourceFile(filename); - var sourceFile = getCurrentSourceFile(fileName); - var syntaxTree = sourceFile.getSyntaxTree(); cancellationToken.throwIfCancellationRequested(); - var text = syntaxTree.text; - var fileContents = text.substr(0, text.length()); + var fileContents = sourceFile.text; + cancellationToken.throwIfCancellationRequested(); var result: TodoComment[] = []; @@ -3602,7 +3620,7 @@ module ts { // ["// hack 1", "// ", "hack 1", undefined, "hack"] // // Here are the relevant capture groups: - // 0) The full match for the entire regex. + // 0) The full match for the entire regexp. // 1) The preamble to the message portion. // 2) The message portion. // 3...N) The descriptor that was matched - by index. 'undefined' for each @@ -3616,20 +3634,18 @@ module ts { var preamble = matchArray[1]; var matchPosition = matchArray.index + preamble.length; - // Ok, we have found a match in the file. This is only an acceptable match if + // OK, we have found a match in the file. This is only an acceptable match if // it is contained within a comment. - var token = TypeScript.findToken(syntaxTree.sourceUnit(), matchPosition); + var token = getTokenAtPosition(sourceFile, matchPosition); - if (matchPosition >= TypeScript.start(token) && matchPosition < TypeScript.end(token)) { - // match was within the token itself. Not in the comment. Keep searching - // descriptor. + if (token.getStart() <= matchPosition && matchPosition < token.getEnd()) { + // match was within the token itself. Not in the comment. Keep searching // descriptor. continue; } - // Looks to be within the trivia. See if we can find the comment containing it. - var triviaList = matchPosition < TypeScript.start(token) ? token.leadingTrivia(syntaxTree.text) : token.trailingTrivia(syntaxTree.text); - var trivia = findContainingComment(triviaList, matchPosition); - if (trivia === null) { + // Looks to be within the trivia. See if we can find the comment containing it. + if (!getContainingComment(getTrailingComments(fileContents, token.getFullStart()), matchPosition) && + !getContainingComment(getLeadingComments(fileContents, token.getFullStart()), matchPosition)) { continue; } @@ -3653,25 +3669,27 @@ module ts { } return result; - } - 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); - } - - function findContainingComment(triviaList: TypeScript.ISyntaxTriviaList, position: number): TypeScript.ISyntaxTrivia { - for (var i = 0, n = triviaList.count(); i < n; i++) { - var trivia = triviaList.syntaxTriviaAt(i); - var fullEnd = trivia.fullStart() + trivia.fullWidth(); - if (trivia.isComment() && trivia.fullStart() <= position && position < fullEnd) { - return trivia; + function getContainingComment(comments: Comment[], position: number): Comment { + if (comments) { + for (var i = 0, n = comments.length; i < n; i++) { + var comment = comments[i]; + if (comment.pos <= position && position < comment.end) { + return comment; + } + } } + + return undefined; } - return null; + 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 { dispose: dispose, From eeefae0bfb517c2ce81f10ce9727465de3249b9e Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 17 Sep 2014 11:58:08 -0700 Subject: [PATCH 24/31] move helper functions inside the scope of the main function --- src/services/services.ts | 126 +++++++++++++++++++-------------------- 1 file changed, 63 insertions(+), 63 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index 6d66a98235..042b3ac748 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -3529,68 +3529,6 @@ module ts { return []; } - function escapeRegExp(str: string): string { - return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); - } - - function getTodoCommentsRegExp(descriptors: TodoCommentDescriptor[]): RegExp { - // NOTE: ?: means 'non-capture group'. It allows us to have groups without having to - // filter them out later in the final result array. - - // TODO comments can appear in one of the following forms: - // - // 1) // TODO or /////////// TODO - // - // 2) /* TODO or /********** TODO - // - // 3) /* - // * TODO - // */ - // - // The following three regexps are used to match the start of the text up to the TODO - // comment portion. - var singleLineCommentStart = /(?:\/\/+\s*)/.source; - var multiLineCommentStart = /(?:\/\*+\s*)/.source; - var anyNumberOfSpacesAndAsterixesAtStartOfLine = /(?:^(?:\s|\*)*)/.source; - - // Match any of the above three TODO comment start regexps. - // Note that the outermost group *is* a capture group. We want to capture the preamble - // so that we can determine the starting position of the TODO comment match. - var preamble = "(" + anyNumberOfSpacesAndAsterixesAtStartOfLine + "|" + singleLineCommentStart + "|" + multiLineCommentStart + ")"; - - // Takes the descriptors and forms a regexp that matches them as if they were literals. - // For example, if the descriptors are "TODO(jason)" and "HACK", then this will be: - // - // (?:(TODO\(jason\))|(HACK)) - // - // Note that the outermost group is *not* a capture group, but the innermost groups - // *are* capture groups. By capturing the inner literals we can determine after - // matching which descriptor we are dealing with. - var literals = "(?:" + descriptors.map(d => "(" + escapeRegExp(d.text) + ")").join("|") + ")"; - - // After matching a descriptor literal, the following regexp matches the rest of the - // text up to the end of the line (or */). - var endOfLineOrEndOfComment = /(?:$|\*\/)/.source - var messageRemainder = /(?:.*?)/.source - - // This is the portion of the match we'll return as part of the TODO comment result. We - // match the literal portion up to the end of the line or end of comment. - var messagePortion = "(" + literals + messageRemainder + ")"; - var regExpString = preamble + messagePortion + endOfLineOrEndOfComment; - - // The final regexp will look like this: - // /((?:\/\/+\s*)|(?:\/\*+\s*)|(?:^(?:\s|\*)*))((?:(TODO\(jason\))|(HACK))(?:.*?))(?:$|\*\/)/gim - - // The flags of the regexp are important here. - // 'g' is so that we are doing a global search and can find matches several times - // in the input. - // - // 'i' is for case insensitivity (We do this to match C# TODO comment code). - // - // 'm' is so we can find matches in a multi-line input. - return new RegExp(regExpString, "gim"); - } - function getTodoComments(filename: string, descriptors: TodoCommentDescriptor[]): TodoComment[] { filename = TypeScript.switchToForwardSlashes(filename); @@ -3605,7 +3543,7 @@ module ts { var result: TodoComment[] = []; if (descriptors.length > 0) { - var regExp = getTodoCommentsRegExp(descriptors); + var regExp = getTodoCommentsRegExp(); var matchArray: RegExpExecArray; while (matchArray = regExp.exec(fileContents)) { @@ -3670,6 +3608,68 @@ module ts { return result; + function escapeRegExp(str: string): string { + return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); + } + + function getTodoCommentsRegExp(): RegExp { + // NOTE: ?: means 'non-capture group'. It allows us to have groups without having to + // filter them out later in the final result array. + + // TODO comments can appear in one of the following forms: + // + // 1) // TODO or /////////// TODO + // + // 2) /* TODO or /********** TODO + // + // 3) /* + // * TODO + // */ + // + // The following three regexps are used to match the start of the text up to the TODO + // comment portion. + var singleLineCommentStart = /(?:\/\/+\s*)/.source; + var multiLineCommentStart = /(?:\/\*+\s*)/.source; + var anyNumberOfSpacesAndAsterixesAtStartOfLine = /(?:^(?:\s|\*)*)/.source; + + // Match any of the above three TODO comment start regexps. + // Note that the outermost group *is* a capture group. We want to capture the preamble + // so that we can determine the starting position of the TODO comment match. + var preamble = "(" + anyNumberOfSpacesAndAsterixesAtStartOfLine + "|" + singleLineCommentStart + "|" + multiLineCommentStart + ")"; + + // Takes the descriptors and forms a regexp that matches them as if they were literals. + // For example, if the descriptors are "TODO(jason)" and "HACK", then this will be: + // + // (?:(TODO\(jason\))|(HACK)) + // + // Note that the outermost group is *not* a capture group, but the innermost groups + // *are* capture groups. By capturing the inner literals we can determine after + // matching which descriptor we are dealing with. + var literals = "(?:" + descriptors.map(d => "(" + escapeRegExp(d.text) + ")").join("|") + ")"; + + // After matching a descriptor literal, the following regexp matches the rest of the + // text up to the end of the line (or */). + var endOfLineOrEndOfComment = /(?:$|\*\/)/.source + var messageRemainder = /(?:.*?)/.source + + // This is the portion of the match we'll return as part of the TODO comment result. We + // match the literal portion up to the end of the line or end of comment. + var messagePortion = "(" + literals + messageRemainder + ")"; + var regExpString = preamble + messagePortion + endOfLineOrEndOfComment; + + // The final regexp will look like this: + // /((?:\/\/+\s*)|(?:\/\*+\s*)|(?:^(?:\s|\*)*))((?:(TODO\(jason\))|(HACK))(?:.*?))(?:$|\*\/)/gim + + // The flags of the regexp are important here. + // 'g' is so that we are doing a global search and can find matches several times + // in the input. + // + // 'i' is for case insensitivity (We do this to match C# TODO comment code). + // + // 'm' is so we can find matches in a multi-line input. + return new RegExp(regExpString, "gim"); + } + function getContainingComment(comments: Comment[], position: number): Comment { if (comments) { for (var i = 0, n = comments.length; i < n; i++) { From a1ca10d3806e486596169074babac224b1dbe873 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 17 Sep 2014 12:33:32 -0700 Subject: [PATCH 25/31] Address CR feedback. --- src/services/services.ts | 67 ++-------------------------------------- 1 file changed, 3 insertions(+), 64 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index 7572423047..ce0ccf1048 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -3687,76 +3687,15 @@ module ts { // Only allow a symbol to be renamed if it actually has at least one declaration. if (symbol && symbol.getDeclarations() && symbol.getDeclarations().length > 0) { - var kind = getKind(symbol); + var kind = getSymbolKind(symbol); if (kind) { - return RenameInfo.Create(symbol.name, typeInfoResolver.getFullyQualifiedName(symbol), kind, getKindModifiers(symbol), + return RenameInfo.Create(symbol.name, typeInfoResolver.getFullyQualifiedName(symbol), kind, + getNodeModifiers(symbol.getDeclarations()[0]), new TypeScript.TextSpan(node.getStart(), node.getWidth())); } } } - function getKindModifiers(symbol: Symbol): string { - var modifiers: string[] = []; - var decl = symbol.getDeclarations()[0]; - - if (decl.flags & NodeFlags.Ambient) { - modifiers.push(ScriptElementKindModifier.ambientModifier); - } - if (decl.flags & NodeFlags.Export) { - modifiers.push(ScriptElementKindModifier.exportedModifier); - } - if (decl.flags & NodeFlags.Private) { - modifiers.push(ScriptElementKindModifier.privateMemberModifier); - } - if (decl.flags & NodeFlags.Public) { - modifiers.push(ScriptElementKindModifier.publicMemberModifier); - } - if (decl.flags & NodeFlags.Static) { - modifiers.push(ScriptElementKindModifier.staticModifier); - } - - return modifiers.length == 0 ? ScriptElementKindModifier.none : modifiers.join(','); - } - - function getKind(symbol: Symbol): string { - if (symbol.flags & SymbolFlags.Module) { - return ScriptElementKind.moduleElement; - } - else if (symbol.flags & SymbolFlags.Class) { - return ScriptElementKind.classElement; - } - else if (symbol.flags & SymbolFlags.Interface) { - return ScriptElementKind.interfaceElement; - } - else if (symbol.flags & SymbolFlags.Enum) { - return ScriptElementKind.enumElement; - } - else if (symbol.flags & SymbolFlags.Variable) { - return ScriptElementKind.variableElement; - } - else if (symbol.flags & SymbolFlags.Function) { - return ScriptElementKind.functionElement; - } - else if (symbol.flags & SymbolFlags.Method) { - return ScriptElementKind.memberFunctionElement; - } - else if (symbol.flags & SymbolFlags.GetAccessor) { - return ScriptElementKind.memberGetAccessorElement; - } - else if (symbol.flags & SymbolFlags.SetAccessor) { - return ScriptElementKind.memberSetAccessorElement; - } - else if (symbol.flags & SymbolFlags.Property) { - return ScriptElementKind.memberVariableElement; - } - else if (symbol.flags & SymbolFlags.TypeParameter) { - return ScriptElementKind.typeParameterElement; - } - else if (symbol.flags & SymbolFlags.EnumMember) { - return ScriptElementKind.memberVariableElement; - } - } - return RenameInfo.CreateError(getLocaleSpecificMessage(Diagnostics.You_cannot_rename_this_element.key)); } From 7320a189f17beedc05f377e7e1491904d052b2bf Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 17 Sep 2014 15:19:20 -0700 Subject: [PATCH 26/31] Adding rename tests. --- src/harness/fourslash.ts | 38 ++++++++++++++++++++ tests/cases/fourslash/fourslash.ts | 8 +++++ tests/cases/fourslash/getRenameInfoTests1.ts | 8 +++++ tests/cases/fourslash/getRenameInfoTests2.ts | 8 +++++ 4 files changed, 62 insertions(+) create mode 100644 tests/cases/fourslash/getRenameInfoTests1.ts create mode 100644 tests/cases/fourslash/getRenameInfoTests2.ts diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 0bcea9367e..26af0a77b3 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -832,6 +832,44 @@ module FourSlash { } } + private validate(name: string, expected: string, actual: string) { + if (expected && expected !== actual) { + throw new Error("Expected " + name + " '" + expected + "'. Got '" + actual + "' instead."); + } + } + + public verifyRenameInfoSucceeded(displayName?: string, fullDisplayName?: string, kind?: string, kindModifiers?: string) { + var renameInfo = this.languageService.getRenameInfo(this.activeFile.fileName, this.currentCaretPosition); + if (!renameInfo.canRename) { + throw new Error("Rename did not succeed"); + } + + this.validate("displayName", displayName, renameInfo.displayName); + this.validate("fullDisplayName", fullDisplayName, renameInfo.fullDisplayName); + this.validate("kind", kind, renameInfo.kind); + this.validate("kindModifiers", kindModifiers, renameInfo.kindModifiers); + + if (this.getRanges().length !== 1) { + throw new Error("Expected a single range to be selected in the test file."); + } + + var expectedRange = this.getRanges()[0]; + if (renameInfo.triggerSpan.start() !== expectedRange.start || + renameInfo.triggerSpan.end() !== expectedRange.end) { + throw new Error("Expected triggerSpan [" + expectedRange.start + "," + expectedRange.end + "). Got [" + + renameInfo.triggerSpan.start() + "," + renameInfo.triggerSpan.end() + ") instead."); + } + } + + public verifyRenameInfoFailed(message?: string) { + var renameInfo = this.languageService.getRenameInfo(this.activeFile.fileName, this.currentCaretPosition); + if (renameInfo.canRename) { + throw new Error("Rename was expected to fail"); + } + + this.validate("error", message, renameInfo.localizedErrorMessage); + } + //private getFormalParameter() { // var help = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition); // return help.formal; diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index e1b1e26c3c..09ca70134f 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -390,6 +390,14 @@ module FourSlashInterface { public semanticClassificationsAre(...classifications: { classificationType: string; text: string }[]) { FourSlash.currentTestState.verifySemanticClassifications(classifications); } + + public renameInfoSucceeded(displayName?: string, fullDisplayName?: string, kind?: string, kindModifiers?: string) { + FourSlash.currentTestState.verifyRenameInfoSucceeded(displayName, fullDisplayName, kind, kindModifiers) + } + + public renameInfoFailed(message?: string) { + FourSlash.currentTestState.verifyRenameInfoFailed(message) + } } export class edit { diff --git a/tests/cases/fourslash/getRenameInfoTests1.ts b/tests/cases/fourslash/getRenameInfoTests1.ts new file mode 100644 index 0000000000..6f4300282d --- /dev/null +++ b/tests/cases/fourslash/getRenameInfoTests1.ts @@ -0,0 +1,8 @@ +/// + +////class [|/**/C|] { +//// +////} + +goTo.marker(""); +verify.renameInfoSucceeded("C"); \ No newline at end of file diff --git a/tests/cases/fourslash/getRenameInfoTests2.ts b/tests/cases/fourslash/getRenameInfoTests2.ts new file mode 100644 index 0000000000..93e8e451b4 --- /dev/null +++ b/tests/cases/fourslash/getRenameInfoTests2.ts @@ -0,0 +1,8 @@ +/// + +/////**/class C { +//// +////} + +goTo.marker(""); +verify.renameInfoFailed(); \ No newline at end of file From 9e00693163e7198f694161be62c92a7dd94b479e Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 17 Sep 2014 17:28:03 -0700 Subject: [PATCH 27/31] respond to code review comments --- src/services/services.ts | 8 ++++++-- .../fourslash/completionListPrivateMembers2.ts | 17 +++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 tests/cases/fourslash/completionListPrivateMembers2.ts diff --git a/src/services/services.ts b/src/services/services.ts index 1d9da5d93c..163414a1fc 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1844,7 +1844,11 @@ module ts { function isVisibleWithinClassDeclaration(symbol: Symbol, containingClass: Declaration): boolean { var declaration = symbol.declarations && symbol.declarations[0]; - return !(declaration && (declaration.flags & NodeFlags.Private) && containingClass !== declaration.parent); + if (declaration && (declaration.flags & NodeFlags.Private)) { + var declarationClass = getAncestor(declaration, SyntaxKind.ClassDeclaration); + return containingClass === declarationClass; + } + return true; } function filterContextualMembersList(contextualMemberSymbols: Symbol[], existingMembers: Declaration[]): Symbol[] { @@ -1966,7 +1970,7 @@ module ts { } var type = typeInfoResolver.getTypeOfNode(mappedNode); - var apparentType: ApparentType = type && typeInfoResolver.getApparentType(type); + var apparentType = type && typeInfoResolver.getApparentType(type); if (apparentType) { // Filter private properties forEach(apparentType.getApparentProperties(), symbol => { diff --git a/tests/cases/fourslash/completionListPrivateMembers2.ts b/tests/cases/fourslash/completionListPrivateMembers2.ts new file mode 100644 index 0000000000..1b19d042cb --- /dev/null +++ b/tests/cases/fourslash/completionListPrivateMembers2.ts @@ -0,0 +1,17 @@ +/// + +////class Foo { +//// private y; +//// constructor(private x) {} +//// method() { this./*1*/; } +////} +////var f:Foo; +////f./*2*/ + +goTo.marker("1"); +verify.memberListContains("y"); +verify.memberListContains("x"); + +goTo.marker("2"); +verify.not.memberListContains("x"); +verify.not.memberListContains("y"); \ No newline at end of file From eb01e92442be8ebbabb51b1db77ec3d95e983bb6 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 17 Sep 2014 17:42:03 -0700 Subject: [PATCH 28/31] respond to code review comments --- src/services/services.ts | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index 042b3ac748..265e250b07 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1959,6 +1959,7 @@ module ts { } } + /** Get the token whose text contains the position, or the containing node. */ function getNodeAtPosition(sourceFile: SourceFile, position: number) { var current: Node = sourceFile; outer: while (true) { @@ -1969,14 +1970,14 @@ module ts { current = child; continue outer; } - if (child.end > position) { - break; - } } return current; } } + /** Get a token that contains the position. This is guaranteed to return a token, the position can be in the + * leading trivia or within the token text. + */ function getTokenAtPosition(sourceFile: SourceFile, position: number) { var current: Node = sourceFile; outer: while (true) { @@ -1986,10 +1987,7 @@ module ts { if (child.getFullStart() <= position && position < child.getEnd()) { current = child; continue outer; - } - if (child.end > position) { - break; - } + } } return current; } @@ -3577,7 +3575,8 @@ module ts { var token = getTokenAtPosition(sourceFile, matchPosition); if (token.getStart() <= matchPosition && matchPosition < token.getEnd()) { - // match was within the token itself. Not in the comment. Keep searching // descriptor. + // match was within the token itself. Not in the comment. Keep searching + // descriptor. continue; } From b64316396b33a8d989e6d7e2cad303f44d933ec4 Mon Sep 17 00:00:00 2001 From: Adam Freidin Date: Wed, 17 Sep 2014 19:48:29 -0700 Subject: [PATCH 29/31] fix documentation for {Ui,I}nt{8,16,32}Array --- src/lib/extensions.d.ts | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/lib/extensions.d.ts b/src/lib/extensions.d.ts index 87b78018c7..82cc129ecb 100644 --- a/src/lib/extensions.d.ts +++ b/src/lib/extensions.d.ts @@ -63,14 +63,14 @@ interface Int8Array extends ArrayBufferView { /** * Sets a value or an array of values. - * @param A typed or untyped array of values to set. + * @param array A typed or untyped array of values to set. * @param offset The index in the current array at which the values are to be written. */ set(array: Int8Array, offset?: number): void; /** * Sets a value or an array of values. - * @param A typed or untyped array of values to set. + * @param array A typed or untyped array of values to set. * @param offset The index in the current array at which the values are to be written. */ set(array: number[], offset?: number): void; @@ -121,14 +121,14 @@ interface Uint8Array extends ArrayBufferView { /** * Sets a value or an array of values. - * @param A typed or untyped array of values to set. + * @param array A typed or untyped array of values to set. * @param offset The index in the current array at which the values are to be written. */ set(array: Uint8Array, offset?: number): void; /** * Sets a value or an array of values. - * @param A typed or untyped array of values to set. + * @param array A typed or untyped array of values to set. * @param offset The index in the current array at which the values are to be written. */ set(array: number[], offset?: number): void; @@ -179,14 +179,14 @@ interface Int16Array extends ArrayBufferView { /** * Sets a value or an array of values. - * @param A typed or untyped array of values to set. + * @param array A typed or untyped array of values to set. * @param offset The index in the current array at which the values are to be written. */ set(array: Int16Array, offset?: number): void; /** * Sets a value or an array of values. - * @param A typed or untyped array of values to set. + * @param array A typed or untyped array of values to set. * @param offset The index in the current array at which the values are to be written. */ set(array: number[], offset?: number): void; @@ -237,14 +237,14 @@ interface Uint16Array extends ArrayBufferView { /** * Sets a value or an array of values. - * @param A typed or untyped array of values to set. + * @param array A typed or untyped array of values to set. * @param offset The index in the current array at which the values are to be written. */ set(array: Uint16Array, offset?: number): void; /** * Sets a value or an array of values. - * @param A typed or untyped array of values to set. + * @param array A typed or untyped array of values to set. * @param offset The index in the current array at which the values are to be written. */ set(array: number[], offset?: number): void; @@ -295,14 +295,14 @@ interface Int32Array extends ArrayBufferView { /** * Sets a value or an array of values. - * @param A typed or untyped array of values to set. + * @param array A typed or untyped array of values to set. * @param offset The index in the current array at which the values are to be written. */ set(array: Int32Array, offset?: number): void; /** * Sets a value or an array of values. - * @param A typed or untyped array of values to set. + * @param array A typed or untyped array of values to set. * @param offset The index in the current array at which the values are to be written. */ set(array: number[], offset?: number): void; @@ -353,14 +353,14 @@ interface Uint32Array extends ArrayBufferView { /** * Sets a value or an array of values. - * @param A typed or untyped array of values to set. + * @param array A typed or untyped array of values to set. * @param offset The index in the current array at which the values are to be written. */ set(array: Uint32Array, offset?: number): void; /** * Sets a value or an array of values. - * @param A typed or untyped array of values to set. + * @param array A typed or untyped array of values to set. * @param offset The index in the current array at which the values are to be written. */ set(array: number[], offset?: number): void; @@ -411,14 +411,14 @@ interface Float32Array extends ArrayBufferView { /** * Sets a value or an array of values. - * @param A typed or untyped array of values to set. + * @param array A typed or untyped array of values to set. * @param offset The index in the current array at which the values are to be written. */ set(array: Float32Array, offset?: number): void; /** * Sets a value or an array of values. - * @param A typed or untyped array of values to set. + * @param array A typed or untyped array of values to set. * @param offset The index in the current array at which the values are to be written. */ set(array: number[], offset?: number): void; @@ -469,14 +469,14 @@ interface Float64Array extends ArrayBufferView { /** * Sets a value or an array of values. - * @param A typed or untyped array of values to set. + * @param array A typed or untyped array of values to set. * @param offset The index in the current array at which the values are to be written. */ set(array: Float64Array, offset?: number): void; /** * Sets a value or an array of values. - * @param A typed or untyped array of values to set. + * @param array A typed or untyped array of values to set. * @param offset The index in the current array at which the values are to be written. */ set(array: number[], offset?: number): void; From 7188ab69b277fdaa3a8c19548ea87ecd1aed73e4 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Wed, 17 Sep 2014 23:59:53 -0700 Subject: [PATCH 30/31] add 'skipTrivia' parameter to scanner --- src/compiler/parser.ts | 2 +- src/compiler/scanner.ts | 43 +++++++++++++++++++++++++++++++++++----- src/compiler/types.ts | 4 ++++ src/services/services.ts | 4 ++-- 4 files changed, 45 insertions(+), 8 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 921a34d389..61cb6628f2 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -3815,7 +3815,7 @@ module ts { : undefined); } - scanner = createScanner(languageVersion, sourceText, scanError, onComment); + scanner = createScanner(languageVersion, /*skipTrivia*/ true, sourceText, scanError, onComment); var rootNodeFlags: NodeFlags = 0; if (fileExtensionIs(filename, ".d.ts")) { rootNodeFlags = NodeFlags.DeclarationFile; diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 59c7913e24..f627bee6c5 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -460,7 +460,7 @@ module ts { ch > CharacterCodes.maxAsciiCharacter && isUnicodeIdentifierPart(ch, languageVersion); } - export function createScanner(languageVersion: ScriptTarget, text?: string, onError?: ErrorCallback, onComment?: CommentCallback): Scanner { + export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean, text?: string, onError?: ErrorCallback, onComment?: CommentCallback): Scanner { var pos: number; // Current position (end position of text of current token) var len: number; // Length of text var startPos: number; // Start position of whitespace before current token @@ -694,12 +694,34 @@ module ts { case CharacterCodes.lineFeed: case CharacterCodes.carriageReturn: precedingLineBreak = true; + if (skipTrivia) { + pos++; + continue; + } + else { + if (ch === CharacterCodes.carriageReturn && pos + 1 < len && text.charCodeAt(pos + 1) === CharacterCodes.lineFeed) { + // consume both CR and LF + pos += 2; + } + else { + pos++; + } + return token = SyntaxKind.NewLineTrivia; + } case CharacterCodes.tab: case CharacterCodes.verticalTab: case CharacterCodes.formFeed: case CharacterCodes.space: - pos++; - continue; + if (skipTrivia) { + pos++; + continue; + } + else { + while (pos < len && isWhiteSpace(text.charCodeAt(pos))) { + pos++; + } + return token = SyntaxKind.WhitespaceTrivia; + } case CharacterCodes.exclamation: if (text.charCodeAt(pos + 1) === CharacterCodes.equals) { if (text.charCodeAt(pos + 2) === CharacterCodes.equals) { @@ -776,7 +798,13 @@ module ts { if (onComment) { onComment(tokenPos, pos); } - continue; + + if (skipTrivia) { + continue; + } + else { + return token = SyntaxKind.SingleLineCommentTrivia; + } } // Multi-line comment if (text.charCodeAt(pos + 1) === CharacterCodes.asterisk) { @@ -806,7 +834,12 @@ module ts { onComment(tokenPos, pos); } - continue; + if (skipTrivia) { + continue; + } + else { + return token = SyntaxKind.MultiLineCommentTrivia; + } } if (text.charCodeAt(pos + 1) === CharacterCodes.equals) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 82fac6b891..e1116150e3 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -12,6 +12,10 @@ module ts { export enum SyntaxKind { Unknown, EndOfFileToken, + SingleLineCommentTrivia, + MultiLineCommentTrivia, + NewLineTrivia, + WhitespaceTrivia, // Literals NumericLiteral, StringLiteral, diff --git a/src/services/services.ts b/src/services/services.ts index ac7d761a61..4a64aee191 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -75,7 +75,7 @@ module ts { update(scriptSnapshot: TypeScript.IScriptSnapshot, version: string, isOpen: boolean, textChangeRange: TypeScript.TextChangeRange): SourceFile; } - var scanner: Scanner = createScanner(ScriptTarget.ES5); + var scanner: Scanner = createScanner(ScriptTarget.ES5, /*skipTrivia*/ true); var emptyArray: any[] = []; @@ -4070,7 +4070,7 @@ module ts { entries: [] }; - scanner = createScanner(ScriptTarget.ES5, text, onError, processComment); + scanner = createScanner(ScriptTarget.ES5, /*skipTrivia*/ true, text, onError, processComment); var token = SyntaxKind.Unknown; do { From 831d26f3dd9b31df0a633501f8b84778307fef8a Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Thu, 18 Sep 2014 13:59:59 -0700 Subject: [PATCH 31/31] respond to code review comments --- src/services/services.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/services.ts b/src/services/services.ts index 265e250b07..8f5ca3c386 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -3644,7 +3644,7 @@ module ts { // Note that the outermost group is *not* a capture group, but the innermost groups // *are* capture groups. By capturing the inner literals we can determine after // matching which descriptor we are dealing with. - var literals = "(?:" + descriptors.map(d => "(" + escapeRegExp(d.text) + ")").join("|") + ")"; + var literals = "(?:" + map(descriptors, d => "(" + escapeRegExp(d.text) + ")").join("|") + ")"; // After matching a descriptor literal, the following regexp matches the rest of the // text up to the end of the line (or */).