From fc80c300a0fa01d6eec76766cb8c67d3e8d45fe2 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 25 Jul 2014 13:07:27 -0700 Subject: [PATCH] Gracefully handle accessor declarations in ambient classes. --- src/compiler/checker.ts | 2 +- src/compiler/parser.ts | 11 ++- .../reference/ambientGetters.errors.txt | 8 +-- .../gettersAndSettersErrors.errors.txt | 4 +- tests/baselines/reference/giant.errors.txt | 72 +++++++++---------- ...rSetAccessorWithTypeAnnotation1.errors.txt | 4 +- 6 files changed, 52 insertions(+), 49 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9f1b0abaecf..1cd77600a8a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4948,7 +4948,7 @@ module ts { } checkSourceElement(node.body); - if (node.type) { + if (node.type && !isAccessor(node.kind)) { checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment(node, getTypeFromTypeNode(node.type)); } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index ee0fcccb239..579aba65e19 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2902,7 +2902,16 @@ module ts { node.typeParameters = sig.typeParameters; node.parameters = sig.parameters; node.type = sig.type; - node.body = parseBody(/* ignoreMissingOpenBrace */ false); + + // A common error is to try to declare an accessor in an ambient class. + if (inAmbientContext && canParseSemicolon()) { + parseSemicolon(); + node.body = createMissingNode(); + } + else { + node.body = parseBody(/* ignoreMissingOpenBrace */ false); + } + return finishNode(node); } diff --git a/tests/baselines/reference/ambientGetters.errors.txt b/tests/baselines/reference/ambientGetters.errors.txt index a8c913b66c7..a01c146d977 100644 --- a/tests/baselines/reference/ambientGetters.errors.txt +++ b/tests/baselines/reference/ambientGetters.errors.txt @@ -1,11 +1,9 @@ -==== tests/cases/compiler/ambientGetters.ts (3 errors) ==== +==== tests/cases/compiler/ambientGetters.ts (2 errors) ==== declare class A { get length() : number; - ~ -!!! '{' expected. - ~~~~~~ -!!! A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. + ~~~~~~ +!!! An accessor cannot be declared in an ambient context. } declare class B { diff --git a/tests/baselines/reference/gettersAndSettersErrors.errors.txt b/tests/baselines/reference/gettersAndSettersErrors.errors.txt index dbd06a744f0..1cfefea5202 100644 --- a/tests/baselines/reference/gettersAndSettersErrors.errors.txt +++ b/tests/baselines/reference/gettersAndSettersErrors.errors.txt @@ -1,4 +1,4 @@ -==== tests/cases/compiler/gettersAndSettersErrors.ts (10 errors) ==== +==== tests/cases/compiler/gettersAndSettersErrors.ts (9 errors) ==== class C { public get Foo() { return "foo";} // ok ~~~ @@ -16,8 +16,6 @@ public set Goo(v:string):string {} // error - setters must not specify a return type ~~~ !!! Accessors are only available when targeting ECMAScript 5 and higher. - ~~~~~~ -!!! A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. } class E { diff --git a/tests/baselines/reference/giant.errors.txt b/tests/baselines/reference/giant.errors.txt index f6b6dd5c796..9f15a5061a3 100644 --- a/tests/baselines/reference/giant.errors.txt +++ b/tests/baselines/reference/giant.errors.txt @@ -374,34 +374,34 @@ !!! A function implementation cannot be declared in an ambient context. public get pgF() ~~~ +!!! Accessors are only available when targeting ECMAScript 5 and higher. + ~~~ !!! Duplicate identifier 'pgF'. public psF(param:any) { } - ~~~~~~ -!!! '{' expected. ~ !!! A function implementation cannot be declared in an ambient context. public set psF(param:any) ~~~ +!!! Accessors are only available when targeting ECMAScript 5 and higher. + ~~~ !!! Duplicate identifier 'psF'. private rgF() { } - ~~~~~~~ -!!! '{' expected. ~ !!! A function implementation cannot be declared in an ambient context. private get rgF() ~~~ +!!! Accessors are only available when targeting ECMAScript 5 and higher. + ~~~ !!! Duplicate identifier 'rgF'. private rsF(param:any) { } - ~~~~~~~ -!!! '{' expected. ~ !!! A function implementation cannot be declared in an ambient context. private set rsF(param:any) ~~~ +!!! Accessors are only available when targeting ECMAScript 5 and higher. + ~~~ !!! Duplicate identifier 'rsF'. static tV; - ~~~~~~ -!!! '{' expected. static tF() { } ~ !!! A function implementation cannot be declared in an ambient context. @@ -410,18 +410,18 @@ !!! A function implementation cannot be declared in an ambient context. static set tsF(param:any) ~~~ +!!! Accessors are only available when targeting ECMAScript 5 and higher. + ~~~ !!! Duplicate identifier 'tsF'. static tgF() { } - ~~~~~~ -!!! '{' expected. ~ !!! A function implementation cannot be declared in an ambient context. static get tgF() ~~~ +!!! Accessors are only available when targeting ECMAScript 5 and higher. + ~~~ !!! Duplicate identifier 'tgF'. } - ~ -!!! '{' expected. export declare module eaM { var V; function F() { }; @@ -804,34 +804,34 @@ !!! A function implementation cannot be declared in an ambient context. public get pgF() ~~~ +!!! Accessors are only available when targeting ECMAScript 5 and higher. + ~~~ !!! Duplicate identifier 'pgF'. public psF(param:any) { } - ~~~~~~ -!!! '{' expected. ~ !!! A function implementation cannot be declared in an ambient context. public set psF(param:any) ~~~ +!!! Accessors are only available when targeting ECMAScript 5 and higher. + ~~~ !!! Duplicate identifier 'psF'. private rgF() { } - ~~~~~~~ -!!! '{' expected. ~ !!! A function implementation cannot be declared in an ambient context. private get rgF() ~~~ +!!! Accessors are only available when targeting ECMAScript 5 and higher. + ~~~ !!! Duplicate identifier 'rgF'. private rsF(param:any) { } - ~~~~~~~ -!!! '{' expected. ~ !!! A function implementation cannot be declared in an ambient context. private set rsF(param:any) ~~~ +!!! Accessors are only available when targeting ECMAScript 5 and higher. + ~~~ !!! Duplicate identifier 'rsF'. static tV; - ~~~~~~ -!!! '{' expected. static tF() { } ~ !!! A function implementation cannot be declared in an ambient context. @@ -840,18 +840,18 @@ !!! A function implementation cannot be declared in an ambient context. static set tsF(param:any) ~~~ +!!! Accessors are only available when targeting ECMAScript 5 and higher. + ~~~ !!! Duplicate identifier 'tsF'. static tgF() { } - ~~~~~~ -!!! '{' expected. ~ !!! A function implementation cannot be declared in an ambient context. static get tgF() ~~~ +!!! Accessors are only available when targeting ECMAScript 5 and higher. + ~~~ !!! Duplicate identifier 'tgF'. } - ~ -!!! '{' expected. export declare module eaM { var V; function F() { }; @@ -894,34 +894,34 @@ !!! A function implementation cannot be declared in an ambient context. public get pgF() ~~~ +!!! Accessors are only available when targeting ECMAScript 5 and higher. + ~~~ !!! Duplicate identifier 'pgF'. public psF(param:any) { } - ~~~~~~ -!!! '{' expected. ~ !!! A function implementation cannot be declared in an ambient context. public set psF(param:any) ~~~ +!!! Accessors are only available when targeting ECMAScript 5 and higher. + ~~~ !!! Duplicate identifier 'psF'. private rgF() { } - ~~~~~~~ -!!! '{' expected. ~ !!! A function implementation cannot be declared in an ambient context. private get rgF() ~~~ +!!! Accessors are only available when targeting ECMAScript 5 and higher. + ~~~ !!! Duplicate identifier 'rgF'. private rsF(param:any) { } - ~~~~~~~ -!!! '{' expected. ~ !!! A function implementation cannot be declared in an ambient context. private set rsF(param:any) ~~~ +!!! Accessors are only available when targeting ECMAScript 5 and higher. + ~~~ !!! Duplicate identifier 'rsF'. static tV; - ~~~~~~ -!!! '{' expected. static tF() { } ~ !!! A function implementation cannot be declared in an ambient context. @@ -930,18 +930,18 @@ !!! A function implementation cannot be declared in an ambient context. static set tsF(param:any) ~~~ +!!! Accessors are only available when targeting ECMAScript 5 and higher. + ~~~ !!! Duplicate identifier 'tsF'. static tgF() { } - ~~~~~~ -!!! '{' expected. ~ !!! A function implementation cannot be declared in an ambient context. static get tgF() ~~~ +!!! Accessors are only available when targeting ECMAScript 5 and higher. + ~~~ !!! Duplicate identifier 'tgF'. } - ~ -!!! '{' expected. export declare module eaM { var V; function F() { }; diff --git a/tests/baselines/reference/parserSetAccessorWithTypeAnnotation1.errors.txt b/tests/baselines/reference/parserSetAccessorWithTypeAnnotation1.errors.txt index f4898163e0f..135f06cf304 100644 --- a/tests/baselines/reference/parserSetAccessorWithTypeAnnotation1.errors.txt +++ b/tests/baselines/reference/parserSetAccessorWithTypeAnnotation1.errors.txt @@ -1,9 +1,7 @@ -==== tests/cases/conformance/parser/ecmascript5/Accessors/parserSetAccessorWithTypeAnnotation1.ts (2 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/Accessors/parserSetAccessorWithTypeAnnotation1.ts (1 errors) ==== class C { set foo(v): number { ~~~ !!! A 'set' accessor cannot have a return type annotation. - ~~~~~~ -!!! A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. } } \ No newline at end of file