Merge pull request #5086 from Microsoft/abstract-semicolon-insertion

Automatic semicolon insertion for class modifiers
This commit is contained in:
Nathan Shively-Sanders 2015-10-05 10:35:42 -07:00
commit 4ecf4f4e71
12 changed files with 309 additions and 35 deletions

View File

@ -856,7 +856,7 @@ namespace ts {
let saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode;
// Note: it is not actually necessary to save/restore the context flags here. That's
// because the saving/restorating of these flags happens naturally through the recursive
// because the saving/restoring of these flags happens naturally through the recursive
// descent nature of our parser. However, we still store this here just so we can
// assert that that invariant holds.
let saveContextFlags = contextFlags;
@ -1124,7 +1124,15 @@ namespace ts {
if (token === SyntaxKind.DefaultKeyword) {
return nextTokenIsClassOrFunction();
}
if (token === SyntaxKind.StaticKeyword) {
nextToken();
return canFollowModifier();
}
nextToken();
if (scanner.hasPrecedingLineBreak()) {
return false;
}
return canFollowModifier();
}
@ -4157,8 +4165,12 @@ namespace ts {
case SyntaxKind.ModuleKeyword:
case SyntaxKind.NamespaceKeyword:
return nextTokenIsIdentifierOrStringLiteralOnSameLine();
case SyntaxKind.AbstractKeyword:
case SyntaxKind.AsyncKeyword:
case SyntaxKind.DeclareKeyword:
case SyntaxKind.PrivateKeyword:
case SyntaxKind.ProtectedKeyword:
case SyntaxKind.PublicKeyword:
nextToken();
// ASI takes effect for this modifier.
if (scanner.hasPrecedingLineBreak()) {
@ -4178,11 +4190,7 @@ namespace ts {
}
continue;
case SyntaxKind.PublicKeyword:
case SyntaxKind.PrivateKeyword:
case SyntaxKind.ProtectedKeyword:
case SyntaxKind.StaticKeyword:
case SyntaxKind.AbstractKeyword:
nextToken();
continue;
default:

View File

@ -3683,14 +3683,20 @@ namespace ts {
// Previous token may have been a keyword that was converted to an identifier.
switch (contextToken.getText()) {
case "abstract":
case "async":
case "class":
case "interface":
case "const":
case "declare":
case "enum":
case "function":
case "var":
case "static":
case "interface":
case "let":
case "const":
case "private":
case "protected":
case "public":
case "static":
case "var":
case "yield":
return true;
}

View File

@ -0,0 +1,24 @@
tests/cases/compiler/asiAbstract.ts(1,1): error TS2304: Cannot find name 'abstract'.
tests/cases/compiler/asiAbstract.ts(3,3): error TS1244: Abstract methods can only appear within an abstract class.
==== tests/cases/compiler/asiAbstract.ts (2 errors) ====
abstract
~~~~~~~~
!!! error TS2304: Cannot find name 'abstract'.
class NonAbstractClass {
abstract s();
~~~~~~~~
!!! error TS1244: Abstract methods can only appear within an abstract class.
}
class C2 {
abstract
nonAbstractFunction() {
}
}
class C3 {
abstract
}

View File

@ -0,0 +1,36 @@
//// [asiAbstract.ts]
abstract
class NonAbstractClass {
abstract s();
}
class C2 {
abstract
nonAbstractFunction() {
}
}
class C3 {
abstract
}
//// [asiAbstract.js]
abstract;
var NonAbstractClass = (function () {
function NonAbstractClass() {
}
return NonAbstractClass;
})();
var C2 = (function () {
function C2() {
}
C2.prototype.nonAbstractFunction = function () {
};
return C2;
})();
var C3 = (function () {
function C3() {
}
return C3;
})();

View File

@ -0,0 +1,52 @@
tests/cases/compiler/asiPublicPrivateProtected.ts(1,1): error TS2304: Cannot find name 'public'.
tests/cases/compiler/asiPublicPrivateProtected.ts(12,1): error TS2304: Cannot find name 'private'.
tests/cases/compiler/asiPublicPrivateProtected.ts(23,1): error TS2304: Cannot find name 'protected'.
==== tests/cases/compiler/asiPublicPrivateProtected.ts (3 errors) ====
public
~~~~~~
!!! error TS2304: Cannot find name 'public'.
class NonPublicClass {
public s() {
}
}
class NonPublicClass2 {
public
private nonPublicFunction() {
}
}
private
~~~~~~~
!!! error TS2304: Cannot find name 'private'.
class NonPrivateClass {
private s() {
}
}
class NonPrivateClass2 {
private
public nonPrivateFunction() {
}
}
protected
~~~~~~~~~
!!! error TS2304: Cannot find name 'protected'.
class NonProtectedClass {
protected s() {
}
}
class NonProtectedClass2 {
protected
public nonProtectedFunction() {
}
}
class ClassWithThreeMembers {
public
private
protected
}

View File

@ -0,0 +1,93 @@
//// [asiPublicPrivateProtected.ts]
public
class NonPublicClass {
public s() {
}
}
class NonPublicClass2 {
public
private nonPublicFunction() {
}
}
private
class NonPrivateClass {
private s() {
}
}
class NonPrivateClass2 {
private
public nonPrivateFunction() {
}
}
protected
class NonProtectedClass {
protected s() {
}
}
class NonProtectedClass2 {
protected
public nonProtectedFunction() {
}
}
class ClassWithThreeMembers {
public
private
protected
}
//// [asiPublicPrivateProtected.js]
public;
var NonPublicClass = (function () {
function NonPublicClass() {
}
NonPublicClass.prototype.s = function () {
};
return NonPublicClass;
})();
var NonPublicClass2 = (function () {
function NonPublicClass2() {
}
NonPublicClass2.prototype.nonPublicFunction = function () {
};
return NonPublicClass2;
})();
private;
var NonPrivateClass = (function () {
function NonPrivateClass() {
}
NonPrivateClass.prototype.s = function () {
};
return NonPrivateClass;
})();
var NonPrivateClass2 = (function () {
function NonPrivateClass2() {
}
NonPrivateClass2.prototype.nonPrivateFunction = function () {
};
return NonPrivateClass2;
})();
protected;
var NonProtectedClass = (function () {
function NonProtectedClass() {
}
NonProtectedClass.prototype.s = function () {
};
return NonProtectedClass;
})();
var NonProtectedClass2 = (function () {
function NonProtectedClass2() {
}
NonProtectedClass2.prototype.nonProtectedFunction = function () {
};
return NonProtectedClass2;
})();
var ClassWithThreeMembers = (function () {
function ClassWithThreeMembers() {
}
return ClassWithThreeMembers;
})();

View File

@ -1,24 +0,0 @@
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMultiLineDecl.ts(10,1): error TS2511: Cannot create an instance of the abstract class 'A'.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMultiLineDecl.ts(11,1): error TS2511: Cannot create an instance of the abstract class 'B'.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMultiLineDecl.ts(12,1): error TS2511: Cannot create an instance of the abstract class 'C'.
==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMultiLineDecl.ts (3 errors) ====
abstract class A {}
abstract
class B {}
abstract
class C {}
new A;
~~~~~
!!! error TS2511: Cannot create an instance of the abstract class 'A'.
new B;
~~~~~
!!! error TS2511: Cannot create an instance of the abstract class 'B'.
new C;
~~~~~
!!! error TS2511: Cannot create an instance of the abstract class 'C'.

View File

@ -0,0 +1,24 @@
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractSingleLineDecl.ts(3,1): error TS2304: Cannot find name 'abstract'.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractSingleLineDecl.ts(6,1): error TS2304: Cannot find name 'abstract'.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractSingleLineDecl.ts(10,1): error TS2511: Cannot create an instance of the abstract class 'A'.
==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractSingleLineDecl.ts (3 errors) ====
abstract class A {}
abstract
~~~~~~~~
!!! error TS2304: Cannot find name 'abstract'.
class B {}
abstract
~~~~~~~~
!!! error TS2304: Cannot find name 'abstract'.
class C {}
new A;
~~~~~
!!! error TS2511: Cannot create an instance of the abstract class 'A'.
new B;
new C;

View File

@ -1,4 +1,4 @@
//// [classAbstractMultiLineDecl.ts]
//// [classAbstractSingleLineDecl.ts]
abstract class A {}
abstract
@ -12,17 +12,19 @@ new A;
new B;
new C;
//// [classAbstractMultiLineDecl.js]
//// [classAbstractSingleLineDecl.js]
var A = (function () {
function A() {
}
return A;
})();
abstract;
var B = (function () {
function B() {
}
return B;
})();
abstract;
var C = (function () {
function C() {
}

View File

@ -0,0 +1,14 @@
abstract
class NonAbstractClass {
abstract s();
}
class C2 {
abstract
nonAbstractFunction() {
}
}
class C3 {
abstract
}

View File

@ -0,0 +1,39 @@
public
class NonPublicClass {
public s() {
}
}
class NonPublicClass2 {
public
private nonPublicFunction() {
}
}
private
class NonPrivateClass {
private s() {
}
}
class NonPrivateClass2 {
private
public nonPrivateFunction() {
}
}
protected
class NonProtectedClass {
protected s() {
}
}
class NonProtectedClass2 {
protected
public nonProtectedFunction() {
}
}
class ClassWithThreeMembers {
public
private
protected
}