Skip to content

Abstract Classes and methods #3579

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 72 commits into from
Jul 1, 2015
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
dd1f982
Parse abstract keyword
DickvdBrink Apr 30, 2015
0e72677
Accept baseline changes
DickvdBrink Apr 30, 2015
b42e447
Error on creating a new instance of an abstract class
DickvdBrink Apr 30, 2015
3aeae55
Output abstract keyword in declaration files (for classes)
DickvdBrink Apr 30, 2015
9436934
Added test for abstract-classes
DickvdBrink Apr 30, 2015
0ed7898
Accepted baselines
DickvdBrink Apr 30, 2015
3bc2aa9
fix merge conflicts with master
Jun 9, 2015
cd06627
Fixed Some indentation
Jun 10, 2015
5316d0d
Abstract keyword: Added parsing and some checks
Jun 15, 2015
506349f
Fix merge conflicts with master
Jun 15, 2015
1954322
Fixed some indentation issues
Jun 16, 2015
864a28a
forbid abstract methods from having an implementation
Jun 16, 2015
388e2fd
merge with extendsExpressions
Jun 16, 2015
a07f862
forbid calling abstract member foo() via super.foo()
Jun 17, 2015
5ca3955
check for inheriting abstract member functions
Jun 18, 2015
6dc430d
constructor cannot have modifier 'abstract'
Jun 18, 2015
4c1002e
removed premature parser check
Jun 18, 2015
10c8b6a
removed comment
Jun 18, 2015
326036d
write to declaration file
Jun 18, 2015
d596bb7
declarations of abstract methods must be consecutive
Jun 18, 2015
8681388
added tests
Jun 18, 2015
8f1790d
Simplified checkClassPropertyAccess -- fixed bug in super access
Jun 19, 2015
df3560f
moved tests, added a test
Jun 19, 2015
b448310
accepted baselines
Jun 19, 2015
b7f4ee5
Merge branch 'master' into abstract-classes2
Jun 19, 2015
933a2fa
updated baseline for new __extends impl
Jun 19, 2015
24da34c
fixed some indentation quirks, comments
Jun 19, 2015
d0924f4
moved abstract-method-inheritance test to checkKindsOfPropertyMemberO…
Jun 22, 2015
31b627a
moved comment
Jun 22, 2015
92ef6f5
responded to some of Daniel's comments
Jun 22, 2015
5c0b913
changed error messages and fixed comments
Jun 22, 2015
0daa9eb
updated baselines for new error messages
Jun 22, 2015
a8d205a
new tests
Jun 22, 2015
676f4a1
added baselines for new tests
Jun 22, 2015
9451aa6
Fixed order of arguments in error message
Jun 23, 2015
1068890
Moved tests to classAbstractKeyword folder
Jun 23, 2015
74d248e
Changed error message
Jun 23, 2015
3eea717
Fixed some error messages.
Jun 23, 2015
1f6637b
Added check to test
Jun 23, 2015
771e487
Re-fixed error message.
Jun 23, 2015
36b1dba
accepted baselines
Jun 23, 2015
d34b23a
Merge branch 'master' into abstract-classes2
Jun 23, 2015
b332727
updated comment in test and baseline
Jun 23, 2015
15c6842
consolidated looping through class members into one loop
Jun 24, 2015
5930052
cleaner loop
Jun 24, 2015
f8b95a5
Drafting constructor assignability restrictions
Jun 25, 2015
4640148
added context flag
Jun 25, 2015
a7ec1c4
merged master
Jun 25, 2015
31b8ff6
Merge branch 'contextSensitiveIsRelatedTo' into abstract-classes2
Jun 25, 2015
a183ba9
added flag as argument to checkTypeRelatedTo
Jun 29, 2015
2a9ea48
Merge branch 'master' into contextSensitiveIsRelatedTo
Jun 29, 2015
d8fe237
merged in master
Jun 29, 2015
ded2441
fixed a conflict
Jun 29, 2015
d932618
merged with contextSensitiveRelatedTo
Jun 29, 2015
e47e5bc
fixed a comment
Jun 29, 2015
b445f90
Merge branch 'contextSensitiveIsRelatedTo' into abstract-classes2
Jun 29, 2015
12383af
Responding to Jason
Jun 30, 2015
18d6e73
Revert isRelatedFlags changes
Jun 30, 2015
5864a66
updated baselines on classAbstract tests
Jun 30, 2015
994b73f
fixed an erroneous assertion
Jun 30, 2015
feb7e1d
Fixed generic abstract class inheritance and some comments
Jun 30, 2015
a1877ef
fexed comment and initialization
Jul 1, 2015
4dd369f
moved initialization and changed a comment
Jul 1, 2015
1608845
merged with master
Jul 1, 2015
1efff28
fixed union-type determination, moved abstract implementation test, a…
Jul 1, 2015
c93bde6
added tests
Jul 1, 2015
139d0f4
updated baselines
Jul 1, 2015
27ebd5c
removed a prototype
Jul 1, 2015
a0bd465
Appeasing Jason
Jul 1, 2015
07142a4
Revert "Appeasing Jason"
Jul 1, 2015
f3b1321
Appeasing Jason lite
Jul 1, 2015
6d0c7c9
removed a comment
Jul 1, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
updated baselines on classAbstract tests
  • Loading branch information
Arthur Ozga committed Jun 30, 2015
commit 5864a66fbcc2af1d3fb4af6ad0d8ad047163dfba
146 changes: 73 additions & 73 deletions tests/baselines/reference/APISample_linter.js
Original file line number Diff line number Diff line change
@@ -1,67 +1,67 @@
//// [APISample_linter.ts]
/*
* Note: This test is a public API sample. The sample sources can be found
at: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#traversing-the-ast-with-a-little-linter
* Please log a "breaking change" issue for any API breaking change affecting this issue
*/
declare var process: any;
declare var console: any;
declare var readFileSync: any;
import * as ts from "typescript";
export function delint(sourceFile: ts.SourceFile) {
delintNode(sourceFile);
function delintNode(node: ts.Node) {
switch (node.kind) {
case ts.SyntaxKind.ForStatement:
case ts.SyntaxKind.ForInStatement:
case ts.SyntaxKind.WhileStatement:
case ts.SyntaxKind.DoStatement:
if ((<ts.IterationStatement>node).statement.kind !== ts.SyntaxKind.Block) {
report(node, "A looping statement's contents should be wrapped in a block body.");
}
break;
case ts.SyntaxKind.IfStatement:
let ifStatement = (<ts.IfStatement>node);
if (ifStatement.thenStatement.kind !== ts.SyntaxKind.Block) {
report(ifStatement.thenStatement, "An if statement's contents should be wrapped in a block body.");
}
if (ifStatement.elseStatement &&
ifStatement.elseStatement.kind !== ts.SyntaxKind.Block &&
ifStatement.elseStatement.kind !== ts.SyntaxKind.IfStatement) {
report(ifStatement.elseStatement, "An else statement's contents should be wrapped in a block body.");
}
break;
case ts.SyntaxKind.BinaryExpression:
let op = (<ts.BinaryExpression>node).operatorToken.kind;
if (op === ts.SyntaxKind.EqualsEqualsToken || op == ts.SyntaxKind.ExclamationEqualsToken) {
report(node, "Use '===' and '!=='.")
}
break;
}
ts.forEachChild(node, delintNode);
}
function report(node: ts.Node, message: string) {
let { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
console.log(`${sourceFile.fileName} (${line + 1},${character + 1}): ${message}`);
}
}
const fileNames = process.argv.slice(2);
fileNames.forEach(fileName => {
// Parse a file
let sourceFile = ts.createSourceFile(fileName, readFileSync(fileName).toString(), ts.ScriptTarget.ES6, /*setParentNodes */ true);
// delint it
delint(sourceFile);

/*
* Note: This test is a public API sample. The sample sources can be found
at: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#traversing-the-ast-with-a-little-linter
* Please log a "breaking change" issue for any API breaking change affecting this issue
*/

declare var process: any;
declare var console: any;
declare var readFileSync: any;

import * as ts from "typescript";

export function delint(sourceFile: ts.SourceFile) {
delintNode(sourceFile);

function delintNode(node: ts.Node) {
switch (node.kind) {
case ts.SyntaxKind.ForStatement:
case ts.SyntaxKind.ForInStatement:
case ts.SyntaxKind.WhileStatement:
case ts.SyntaxKind.DoStatement:
if ((<ts.IterationStatement>node).statement.kind !== ts.SyntaxKind.Block) {
report(node, "A looping statement's contents should be wrapped in a block body.");
}
break;

case ts.SyntaxKind.IfStatement:
let ifStatement = (<ts.IfStatement>node);
if (ifStatement.thenStatement.kind !== ts.SyntaxKind.Block) {
report(ifStatement.thenStatement, "An if statement's contents should be wrapped in a block body.");
}
if (ifStatement.elseStatement &&
ifStatement.elseStatement.kind !== ts.SyntaxKind.Block &&
ifStatement.elseStatement.kind !== ts.SyntaxKind.IfStatement) {
report(ifStatement.elseStatement, "An else statement's contents should be wrapped in a block body.");
}
break;

case ts.SyntaxKind.BinaryExpression:
let op = (<ts.BinaryExpression>node).operatorToken.kind;
if (op === ts.SyntaxKind.EqualsEqualsToken || op == ts.SyntaxKind.ExclamationEqualsToken) {
report(node, "Use '===' and '!=='.")
}
break;
}

ts.forEachChild(node, delintNode);
}

function report(node: ts.Node, message: string) {
let { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
console.log(`${sourceFile.fileName} (${line + 1},${character + 1}): ${message}`);
}
}

const fileNames = process.argv.slice(2);
fileNames.forEach(fileName => {
// Parse a file
let sourceFile = ts.createSourceFile(fileName, readFileSync(fileName).toString(), ts.ScriptTarget.ES6, /*setParentNodes */ true);

// delint it
delint(sourceFile);
});

//// [APISample_linter.js]
Expand All @@ -75,26 +75,26 @@ function delint(sourceFile) {
delintNode(sourceFile);
function delintNode(node) {
switch (node.kind) {
case 191 /* ForStatement */:
case 192 /* ForInStatement */:
case 190 /* WhileStatement */:
case 189 /* DoStatement */:
if (node.statement.kind !== 184 /* Block */) {
case 192 /* ForStatement */:
case 193 /* ForInStatement */:
case 191 /* WhileStatement */:
case 190 /* DoStatement */:
if (node.statement.kind !== 185 /* Block */) {
report(node, "A looping statement's contents should be wrapped in a block body.");
}
break;
case 188 /* IfStatement */:
case 189 /* IfStatement */:
var ifStatement = node;
if (ifStatement.thenStatement.kind !== 184 /* Block */) {
if (ifStatement.thenStatement.kind !== 185 /* Block */) {
report(ifStatement.thenStatement, "An if statement's contents should be wrapped in a block body.");
}
if (ifStatement.elseStatement &&
ifStatement.elseStatement.kind !== 184 /* Block */ &&
ifStatement.elseStatement.kind !== 188 /* IfStatement */) {
ifStatement.elseStatement.kind !== 185 /* Block */ &&
ifStatement.elseStatement.kind !== 189 /* IfStatement */) {
report(ifStatement.elseStatement, "An else statement's contents should be wrapped in a block body.");
}
break;
case 173 /* BinaryExpression */:
case 174 /* BinaryExpression */:
var op = node.operatorToken.kind;
if (op === 29 /* EqualsEqualsToken */ || op == 30 /* ExclamationEqualsToken */) {
report(node, "Use '===' and '!=='.");
Expand Down
4 changes: 2 additions & 2 deletions tests/baselines/reference/classAbstractConstructor.errors.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractConstructor.ts(2,5): error TS1236: 'abstract' modifier can only appear on a class or method declaration.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractConstructor.ts(2,5): error TS1242: 'abstract' modifier can only appear on a class or method declaration.


==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractConstructor.ts (1 errors) ====
abstract class A {
abstract constructor() {}
~~~~~~~~
!!! error TS1236: 'abstract' modifier can only appear on a class or method declaration.
!!! error TS1242: 'abstract' modifier can only appear on a class or method declaration.
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractDeclarations.d.ts(2,5): error TS1236: 'abstract' modifier can only appear on a class or method declaration.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractDeclarations.d.ts(2,5): error TS1242: 'abstract' modifier can only appear on a class or method declaration.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractDeclarations.d.ts(2,28): error TS1184: An implementation cannot be declared in ambient contexts.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractDeclarations.d.ts(11,15): error TS2515: Non-abstract class 'CC' does not implement inherited abstract member 'foo' from class 'AA'.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractDeclarations.d.ts(13,15): error TS2515: Non-abstract class 'DD' does not implement inherited abstract member 'foo' from class 'BB'.
Expand All @@ -9,7 +9,7 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst
declare abstract class A {
abstract constructor() {}
~~~~~~~~
!!! error TS1236: 'abstract' modifier can only appear on a class or method declaration.
!!! error TS1242: 'abstract' modifier can only appear on a class or method declaration.
~
!!! error TS1184: An implementation cannot be declared in ambient contexts.
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(21,1): error TS2511: Cannot create an instance of the abstract class 'B'.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(26,7): error TS2515: Non-abstract class 'C' does not implement inherited abstract member 'bar' from class 'B'.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(46,5): error TS2391: Function implementation is missing or not immediately following the declaration.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(46,5): error TS2512: Overload signatures must all be `abstract` or not `abstract.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(49,7): error TS2514: Classes containing abstract methods must be marked abstract.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(50,5): error TS1238: Abstract methods can only appear within an abstract class.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(46,5): error TS2512: Overload signatures must all be abstract or not abstract.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(50,5): error TS1244: Abstract methods can only appear within an abstract class.


==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts (8 errors) ====
==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts (7 errors) ====
class A {
// ...
}
Expand Down Expand Up @@ -66,13 +65,11 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst
~~~
!!! error TS2391: Function implementation is missing or not immediately following the declaration.
~~~
!!! error TS2512: Overload signatures must all be `abstract` or not `abstract.
!!! error TS2512: Overload signatures must all be abstract or not abstract.
}

class H { // error -- not declared abstract
~
!!! error TS2514: Classes containing abstract methods must be marked abstract.
abstract baz() : number;
~~~~~~~~
!!! error TS1238: Abstract methods can only appear within an abstract class.
!!! error TS1244: Abstract methods can only appear within an abstract class.
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMethodWithImplementation.ts(2,5): error TS1240: Method 'foo' cannot have an implementation because it is marked abstract.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMethodWithImplementation.ts(2,5): error TS1245: Method 'foo' cannot have an implementation because it is marked abstract.


==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMethodWithImplementation.ts (1 errors) ====
abstract class A {
abstract foo() {}
~~~~~~~~~~~~~~~~~
!!! error TS1240: Method 'foo' cannot have an implementation because it is marked abstract.
!!! error TS1245: Method 'foo' cannot have an implementation because it is marked abstract.
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMixedWithModifiers.ts(6,13): error TS1237: 'private' modifier cannot be used with 'abstract' modifier.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMixedWithModifiers.ts(6,13): error TS1243: 'private' modifier cannot be used with 'abstract' modifier.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMixedWithModifiers.ts(8,14): error TS1029: 'public' modifier must precede 'abstract' modifier.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMixedWithModifiers.ts(9,14): error TS1029: 'protected' modifier must precede 'abstract' modifier.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMixedWithModifiers.ts(10,14): error TS1237: 'private' modifier cannot be used with 'abstract' modifier.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMixedWithModifiers.ts(12,14): error TS1237: 'static' modifier cannot be used with 'abstract' modifier.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMixedWithModifiers.ts(14,12): error TS1237: 'static' modifier cannot be used with 'abstract' modifier.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMixedWithModifiers.ts(10,14): error TS1243: 'private' modifier cannot be used with 'abstract' modifier.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMixedWithModifiers.ts(12,14): error TS1243: 'static' modifier cannot be used with 'abstract' modifier.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMixedWithModifiers.ts(14,12): error TS1243: 'static' modifier cannot be used with 'abstract' modifier.


==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMixedWithModifiers.ts (6 errors) ====
Expand All @@ -14,7 +14,7 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst
protected abstract foo_c();
private abstract foo_d();
~~~~~~~~
!!! error TS1237: 'private' modifier cannot be used with 'abstract' modifier.
!!! error TS1243: 'private' modifier cannot be used with 'abstract' modifier.

abstract public foo_bb();
~~~~~~
Expand All @@ -24,13 +24,13 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst
!!! error TS1029: 'protected' modifier must precede 'abstract' modifier.
abstract private foo_dd();
~~~~~~~
!!! error TS1237: 'private' modifier cannot be used with 'abstract' modifier.
!!! error TS1243: 'private' modifier cannot be used with 'abstract' modifier.

abstract static foo_d();
~~~~~~
!!! error TS1237: 'static' modifier cannot be used with 'abstract' modifier.
!!! error TS1243: 'static' modifier cannot be used with 'abstract' modifier.

static abstract foo_e();
~~~~~~~~
!!! error TS1237: 'static' modifier cannot be used with 'abstract' modifier.
!!! error TS1243: 'static' modifier cannot be used with 'abstract' modifier.
}
12 changes: 6 additions & 6 deletions tests/baselines/reference/classAbstractOverloads.errors.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractOverloads.ts(7,5): error TS2512: Overload signatures must all be `abstract` or not `abstract.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractOverloads.ts(10,14): error TS2512: Overload signatures must all be `abstract` or not `abstract.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractOverloads.ts(12,14): error TS2512: Overload signatures must all be `abstract` or not `abstract.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractOverloads.ts(7,5): error TS2512: Overload signatures must all be abstract or not abstract.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractOverloads.ts(10,14): error TS2512: Overload signatures must all be abstract or not abstract.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractOverloads.ts(12,14): error TS2512: Overload signatures must all be abstract or not abstract.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractOverloads.ts(15,5): error TS2391: Function implementation is missing or not immediately following the declaration.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractOverloads.ts(20,14): error TS2516: All declarations of an abstract method must be consecutive.

Expand All @@ -14,16 +14,16 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst
abstract bar();
bar();
~~~
!!! error TS2512: Overload signatures must all be `abstract` or not `abstract.
!!! error TS2512: Overload signatures must all be abstract or not abstract.
abstract bar();

abstract baz();
~~~
!!! error TS2512: Overload signatures must all be `abstract` or not `abstract.
!!! error TS2512: Overload signatures must all be abstract or not abstract.
baz();
abstract baz();
~~~
!!! error TS2512: Overload signatures must all be `abstract` or not `abstract.
!!! error TS2512: Overload signatures must all be abstract or not abstract.
baz() {}

qux();
Expand Down
Loading