Merge pull request babel/babel-eslint#109 from hzoo/i-108
visit flow types - fixes babel/babel-eslint#108
This commit is contained in:
parent
866a77a8cc
commit
a4f6edab85
@ -117,7 +117,7 @@ function convertTemplateType(tokens) {
|
|||||||
// create Template token
|
// create Template token
|
||||||
function replaceWithTemplateType(start, end) {
|
function replaceWithTemplateType(start, end) {
|
||||||
var templateToken = {
|
var templateToken = {
|
||||||
type: 'Template',
|
type: "Template",
|
||||||
value: createTemplateValue(start, end),
|
value: createTemplateValue(start, end),
|
||||||
range: [tokens[start].start, tokens[end].end],
|
range: [tokens[start].start, tokens[end].end],
|
||||||
loc: {
|
loc: {
|
||||||
@ -183,18 +183,37 @@ var astTransformVisitor = {
|
|||||||
delete node.argument;
|
delete node.argument;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.isTypeCastExpression()) {
|
|
||||||
return node.expression;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.isFlow()) {
|
|
||||||
return this.remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.isRestElement()) {
|
if (this.isRestElement()) {
|
||||||
return node.argument;
|
return node.argument;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// prevent "no-undef"
|
||||||
|
// for "Component" in: "let x: React.Component"
|
||||||
|
if (this.isQualifiedTypeIdentifier()) {
|
||||||
|
delete node.id;
|
||||||
|
}
|
||||||
|
// for "b" in: "var a: { b: Foo }"
|
||||||
|
if (this.isObjectTypeProperty()) {
|
||||||
|
delete node.key;
|
||||||
|
}
|
||||||
|
// for "indexer" in: "var a: {[indexer: string]: number}"
|
||||||
|
if (this.isObjectTypeIndexer()) {
|
||||||
|
delete node.id;
|
||||||
|
}
|
||||||
|
// for "param" in: "var a: { func(param: Foo): Bar };"
|
||||||
|
if (this.isFunctionTypeParam()) {
|
||||||
|
delete node.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// flow
|
||||||
|
|
||||||
|
if (this.isDeclareModule() ||
|
||||||
|
this.isDeclareClass() ||
|
||||||
|
this.isDeclareFunction() ||
|
||||||
|
this.isDeclareVariable()) {
|
||||||
|
return this.remove();
|
||||||
|
}
|
||||||
|
|
||||||
// modules
|
// modules
|
||||||
|
|
||||||
if (this.isImportDeclaration()) {
|
if (this.isImportDeclaration()) {
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
var acornToEsprima = require("./acorn-to-esprima");
|
var acornToEsprima = require("./acorn-to-esprima");
|
||||||
var traverse = require("babel-core").traverse;
|
var traverse = require("babel-core").traverse;
|
||||||
var assign = require("lodash.assign");
|
var assign = require("lodash.assign");
|
||||||
|
var pick = require("lodash.pick");
|
||||||
var Module = require("module");
|
var Module = require("module");
|
||||||
var parse = require("babel-core").parse;
|
var parse = require("babel-core").parse;
|
||||||
var path = require("path");
|
var path = require("path");
|
||||||
@ -46,12 +47,7 @@ function monkeypatch() {
|
|||||||
escope.analyze = function (ast, opts) {
|
escope.analyze = function (ast, opts) {
|
||||||
opts.ecmaVersion = 6;
|
opts.ecmaVersion = 6;
|
||||||
opts.sourceType = "module";
|
opts.sourceType = "module";
|
||||||
// Don't visit TypeAlias when analyzing scope, but retain them for other
|
|
||||||
// eslint rules.
|
|
||||||
var TypeAliasKeys = estraverse.VisitorKeys.TypeAlias;
|
|
||||||
estraverse.VisitorKeys.TypeAlias = [];
|
|
||||||
var results = analyze.call(this, ast, opts);
|
var results = analyze.call(this, ast, opts);
|
||||||
estraverse.VisitorKeys.TypeAlias = TypeAliasKeys;
|
|
||||||
return results;
|
return results;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -62,8 +58,18 @@ function monkeypatch() {
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw new ReferenceError("couldn't resolve escope/referencer");
|
throw new ReferenceError("couldn't resolve escope/referencer");
|
||||||
}
|
}
|
||||||
|
var referencerMod = createModule(referencerLoc);
|
||||||
var referencer = require(referencerLoc);
|
var referencer = require(referencerLoc);
|
||||||
|
|
||||||
|
// reference Definition
|
||||||
|
var definitionLoc;
|
||||||
|
try {
|
||||||
|
var definitionLoc = Module._resolveFilename("./definition", referencerMod);
|
||||||
|
} catch (err) {
|
||||||
|
throw new ReferenceError("couldn't resolve escope/definition");
|
||||||
|
}
|
||||||
|
var Definition = require(definitionLoc).Definition;
|
||||||
|
|
||||||
// if there are decotators, then visit each
|
// if there are decotators, then visit each
|
||||||
function visitDecorators(node) {
|
function visitDecorators(node) {
|
||||||
if (!node.decorators) {
|
if (!node.decorators) {
|
||||||
@ -76,18 +82,182 @@ function monkeypatch() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// monkeypatch referencer methods to visit decorators
|
// iterate through part of t.VISITOR_KEYS
|
||||||
|
var visitorKeysMap = pick(t.VISITOR_KEYS, function(k) {
|
||||||
|
return t.FLIPPED_ALIAS_KEYS.Flow.concat([
|
||||||
|
"ArrayPattern",
|
||||||
|
"ClassDeclaration",
|
||||||
|
"ClassExpression",
|
||||||
|
"FunctionDeclaration",
|
||||||
|
"FunctionExpression",
|
||||||
|
"Identifier",
|
||||||
|
"ObjectPattern",
|
||||||
|
"RestElement"
|
||||||
|
]).indexOf(k) === -1;
|
||||||
|
});
|
||||||
|
|
||||||
|
var propertyTypes = {
|
||||||
|
// loops
|
||||||
|
callProperties: { type: "loop", values: ["value"] },
|
||||||
|
indexers: { type: "loop", values: ["key", "value"] },
|
||||||
|
properties: { type: "loop", values: ["value"] },
|
||||||
|
types: { type: "loop" },
|
||||||
|
params: { type: "loop" },
|
||||||
|
// single property
|
||||||
|
argument: { type: "single" },
|
||||||
|
elementType: { type: "single" },
|
||||||
|
qualification: { type: "single" },
|
||||||
|
rest: { type: "single" },
|
||||||
|
returnType: { type: "single" },
|
||||||
|
// others
|
||||||
|
typeAnnotation: { type: "typeAnnotation" },
|
||||||
|
typeParameters: { type: "typeParameters" },
|
||||||
|
id: { type: "id" }
|
||||||
|
};
|
||||||
|
|
||||||
|
function visitTypeAnnotation(node) {
|
||||||
|
// get property to check (params, id, etc...)
|
||||||
|
var visitorValues = visitorKeysMap[node.type];
|
||||||
|
if (!visitorValues) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// can have multiple properties
|
||||||
|
for (var i = 0; i < visitorValues.length; i++) {
|
||||||
|
var visitorValue = visitorValues[i];
|
||||||
|
var propertyType = propertyTypes[visitorValue];
|
||||||
|
var nodeProperty = node[visitorValue];
|
||||||
|
// check if property or type is defined
|
||||||
|
if (propertyType == null || nodeProperty == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (propertyType.type === "loop") {
|
||||||
|
for (var j = 0; j < nodeProperty.length; j++) {
|
||||||
|
if (Array.isArray(propertyType.values)) {
|
||||||
|
for (var k = 0; k < propertyType.values.length; k++) {
|
||||||
|
checkIdentifierOrVisit.call(this, nodeProperty[j][propertyType.values[k]]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
checkIdentifierOrVisit.call(this, nodeProperty[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (propertyType.type === "single") {
|
||||||
|
checkIdentifierOrVisit.call(this, nodeProperty);
|
||||||
|
} else if (propertyType.type === "typeAnnotation") {
|
||||||
|
visitTypeAnnotation.call(this, node.typeAnnotation);
|
||||||
|
} else if (propertyType.type === "typeParameters") {
|
||||||
|
for (var j = 0; j < node.typeParameters.params.length; j++) {
|
||||||
|
checkIdentifierOrVisit.call(this, node.typeParameters.params[j]);
|
||||||
|
}
|
||||||
|
} else if (propertyType.type === "id") {
|
||||||
|
if (node.id.type === "Identifier") {
|
||||||
|
checkIdentifierOrVisit.call(this, node.id);
|
||||||
|
} else {
|
||||||
|
visitTypeAnnotation.call(this, node.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkIdentifierOrVisit(node) {
|
||||||
|
if (node.typeAnnotation) {
|
||||||
|
visitTypeAnnotation.call(this, node.typeAnnotation);
|
||||||
|
} else if (node.type === "Identifier") {
|
||||||
|
this.visit(node);
|
||||||
|
} else {
|
||||||
|
visitTypeAnnotation.call(this, node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// visit decorators that are in: ClassDeclaration / ClassExpression
|
||||||
var visitClass = referencer.prototype.visitClass;
|
var visitClass = referencer.prototype.visitClass;
|
||||||
referencer.prototype.visitClass = function(node) {
|
referencer.prototype.visitClass = function(node) {
|
||||||
// visit decorators that are in: Class Declaration
|
|
||||||
visitDecorators.call(this, node);
|
visitDecorators.call(this, node);
|
||||||
visitClass.call(this, node);
|
// visit class
|
||||||
|
if (node.id) {
|
||||||
|
this.visit(node.id);
|
||||||
}
|
}
|
||||||
|
// visit flow type: ClassImplements
|
||||||
|
if (node.implements) {
|
||||||
|
for (var i = 0; i < node.implements.length; i++) {
|
||||||
|
checkIdentifierOrVisit.call(this, node.implements[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (node.typeParameters) {
|
||||||
|
for (var i = 0; i < node.typeParameters.params.length; i++) {
|
||||||
|
checkIdentifierOrVisit.call(this, node.typeParameters.params[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (node.superTypeParameters) {
|
||||||
|
for (var i = 0; i < node.superTypeParameters.params.length; i++) {
|
||||||
|
checkIdentifierOrVisit.call(this, node.superTypeParameters.params[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
visitClass.call(this, node);
|
||||||
|
};
|
||||||
|
// visit decorators that are in: Property / MethodDefinition
|
||||||
var visitProperty = referencer.prototype.visitProperty;
|
var visitProperty = referencer.prototype.visitProperty;
|
||||||
referencer.prototype.visitProperty = function(node) {
|
referencer.prototype.visitProperty = function(node) {
|
||||||
// visit decorators that are in: Visit Property / MethodDefinition
|
if (node.value.type === 'TypeCastExpression') {
|
||||||
|
visitTypeAnnotation.call(this, node.value);
|
||||||
|
}
|
||||||
visitDecorators.call(this, node);
|
visitDecorators.call(this, node);
|
||||||
visitProperty.call(this, node);
|
visitProperty.call(this, node);
|
||||||
|
};
|
||||||
|
|
||||||
|
// visit flow type in FunctionDeclaration, FunctionExpression, ArrowFunctionExpression
|
||||||
|
var visitFunction = referencer.prototype.visitFunction;
|
||||||
|
referencer.prototype.visitFunction = function(node) {
|
||||||
|
if (node.returnType) {
|
||||||
|
checkIdentifierOrVisit.call(this, node.returnType);
|
||||||
|
}
|
||||||
|
// only visit if function parameters have types
|
||||||
|
if (node.params) {
|
||||||
|
for (var i = 0; i < node.params.length; i++) {
|
||||||
|
if (node.params[i].typeAnnotation) {
|
||||||
|
checkIdentifierOrVisit.call(this, node.params[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (node.typeParameters) {
|
||||||
|
for (var i = 0; i < node.typeParameters.params.length; i++) {
|
||||||
|
checkIdentifierOrVisit.call(this, node.typeParameters.params[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
visitFunction.call(this, node);
|
||||||
|
};
|
||||||
|
|
||||||
|
// visit flow type in VariableDeclaration
|
||||||
|
var variableDeclaration = referencer.prototype.VariableDeclaration;
|
||||||
|
referencer.prototype.VariableDeclaration = function(node) {
|
||||||
|
if (node.declarations) {
|
||||||
|
for (var i = 0; i < node.declarations.length; i++) {
|
||||||
|
checkIdentifierOrVisit.call(this, node.declarations[i].id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
variableDeclaration.call(this, node);
|
||||||
|
};
|
||||||
|
|
||||||
|
referencer.prototype.TypeAlias = function(node) {
|
||||||
|
this.currentScope().__define(
|
||||||
|
node.id,
|
||||||
|
new Definition(
|
||||||
|
"Variable",
|
||||||
|
node.id,
|
||||||
|
node,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
)
|
||||||
|
);
|
||||||
|
if (node.right) {
|
||||||
|
visitTypeAnnotation.call(this, node.right);
|
||||||
|
}
|
||||||
|
if (node.typeParameters) {
|
||||||
|
for (var i = 0; i < node.typeParameters.params.length; i++) {
|
||||||
|
checkIdentifierOrVisit.call(this, node.typeParameters.params[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,8 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"babel-core": "^5.1.8",
|
"babel-core": "^5.1.8",
|
||||||
"lodash.assign": "^3.0.0"
|
"lodash.assign": "^3.0.0",
|
||||||
|
"lodash.pick": "^3.1.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "mocha"
|
"test": "mocha"
|
||||||
|
|||||||
@ -124,10 +124,20 @@ describe("verify", function () {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("flow type", function () {
|
describe("flow", function () {
|
||||||
|
it("check regular function", function () {
|
||||||
|
verifyAndAssertMessages([
|
||||||
|
"function a(b, c) { b += 1; c += 1; } a;",
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("type alias", function () {
|
||||||
verifyAndAssertMessages(
|
verifyAndAssertMessages(
|
||||||
"type SomeNewType = any;",
|
"type SomeNewType = any;",
|
||||||
{},
|
{ "no-undef": 1 },
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@ -140,6 +150,733 @@ describe("verify", function () {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("multiple nullable type annotations and return #108", function () {
|
||||||
|
verifyAndAssertMessages([
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"import type Foo2 from 'foo';",
|
||||||
|
"import type Foo3 from 'foo';",
|
||||||
|
"function log(foo: ?Foo, foo2: ?Foo2): ?Foo3 {",
|
||||||
|
"console.log(foo, foo2);",
|
||||||
|
"}",
|
||||||
|
"log(1, 2);"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("type parameters", function () {
|
||||||
|
verifyAndAssertMessages([
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"import type Foo2 from 'foo';",
|
||||||
|
"function log<Foo, Foo2>() {}",
|
||||||
|
"log();"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("nested type annotations", function () {
|
||||||
|
verifyAndAssertMessages([
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"function foo(callback: () => Foo) {",
|
||||||
|
"return callback();",
|
||||||
|
"}",
|
||||||
|
"foo();"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("type in var declaration", function () {
|
||||||
|
verifyAndAssertMessages([
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"var x: Foo = 1;",
|
||||||
|
"x;"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("object type annotation", function () {
|
||||||
|
verifyAndAssertMessages([
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"var a: {numVal: Foo};",
|
||||||
|
"a;"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("object property types", function () {
|
||||||
|
verifyAndAssertMessages([
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"import type Foo2 from 'foo';",
|
||||||
|
"var a = {",
|
||||||
|
"circle: (null : ?{ setNativeProps(props: Foo): Foo2 })",
|
||||||
|
"};",
|
||||||
|
"a;"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("namespaced types", function () {
|
||||||
|
verifyAndAssertMessages([
|
||||||
|
"var React = require('react-native');",
|
||||||
|
"var b = {",
|
||||||
|
"openExternalExample: (null: ?React.Component)",
|
||||||
|
"};",
|
||||||
|
"var c = {",
|
||||||
|
"render(): React.Component {}",
|
||||||
|
"};",
|
||||||
|
"b;",
|
||||||
|
"c;"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("ArrayTypeAnnotation", function () {
|
||||||
|
verifyAndAssertMessages([
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"var x: Foo[]; x;"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("ClassImplements", function () {
|
||||||
|
verifyAndAssertMessages([
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"import type Bar from 'foo';",
|
||||||
|
"class Foo implements Bar {}"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("type alias creates declaration + usage", function () {
|
||||||
|
verifyAndAssertMessages([
|
||||||
|
"type Foo = any;",
|
||||||
|
"var x : Foo = 1; x;"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("type alias with type parameters", function () {
|
||||||
|
verifyAndAssertMessages([
|
||||||
|
"import type Bar from 'foo';",
|
||||||
|
"import type Foo2 from 'foo';",
|
||||||
|
"import type Foo3 from 'foo';",
|
||||||
|
"type Foo<Foo2> = Bar<Foo3>",
|
||||||
|
"var x : Foo = 1; x;"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("export type alias", function () {
|
||||||
|
verifyAndAssertMessages([
|
||||||
|
"import type Foo2 from 'foo';",
|
||||||
|
"export type Foo = Foo2;"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("1", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"import type Foo2 from 'foo';",
|
||||||
|
"export default function(a: Foo, b: ?Foo2, c){ a; b; c; }"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("2", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"export default function(a: () => Foo){ a; }"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("3", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"import type Foo2 from 'foo';",
|
||||||
|
"export default function(a: (_:Foo) => Foo2){ a; }"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("4", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"import type Foo2 from 'foo';",
|
||||||
|
"import type Foo3 from 'foo';",
|
||||||
|
"export default function(a: (_1:Foo, _2:Foo2) => Foo3){ a; }"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("5", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"import type Foo2 from 'foo';",
|
||||||
|
"export default function(a: (_1:Foo, ...foo:Array<Foo2>) => number){ a; }"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("6", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"export default function(): Foo {}"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("7", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"export default function():() => Foo {}"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("8", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"import type Foo2 from 'foo';",
|
||||||
|
"export default function():(_?:Foo) => Foo2{}"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("9", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"import type Foo2 from 'foo';",
|
||||||
|
"export default function <Foo, Foo2>() {}"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
})
|
||||||
|
|
||||||
|
it("10", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"import type Foo2 from 'foo';",
|
||||||
|
"var a=function<Foo,Foo2>() {}; a;"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("11", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"import type Foo2 from 'foo';",
|
||||||
|
"import type Foo3 from 'foo';",
|
||||||
|
"var a={*id<Foo>(x: Foo2): Foo3 { x; }}; a;"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("12", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"import type Foo2 from 'foo';",
|
||||||
|
"import type Foo3 from 'foo';",
|
||||||
|
"var a={async id<Foo>(x: Foo2): Foo3 { x; }}; a;"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("13", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"import type Foo2 from 'foo';",
|
||||||
|
"import type Foo3 from 'foo';",
|
||||||
|
"var a={123<Foo>(x: Foo2): Foo3 { x; }}; a;"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("14", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"import type Foo2 from 'foo';",
|
||||||
|
"class Bar {set fooProp(value:Foo):Foo2{ value; }}"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("15", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"class Foo {get fooProp():Foo{}}"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("16", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"var numVal:Foo; numVal;"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("17", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"var a: {numVal: Foo;}; a;"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("18", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"import type Foo2 from 'foo';",
|
||||||
|
"import type Foo3 from 'foo';",
|
||||||
|
"var a: ?{numVal: Foo; [indexer: Foo2]: Foo3}; a;"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("19", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"import type Foo2 from 'foo';",
|
||||||
|
"var a: {numVal: Foo; subObj?: ?{strVal: Foo2}}; a;"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("20", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"import type Foo2 from 'foo';",
|
||||||
|
"import type Foo3 from 'foo';",
|
||||||
|
"import type Foo4 from 'foo';",
|
||||||
|
"var a: { [a: Foo]: Foo2; [b: Foo3]: Foo4; }; a;"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("21", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"import type Foo2 from 'foo';",
|
||||||
|
"import type Foo3 from 'foo';",
|
||||||
|
"var a: {add(x:Foo, ...y:Array<Foo2>): Foo3}; a;"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("22", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"import type Foo2 from 'foo';",
|
||||||
|
"import type Foo3 from 'foo';",
|
||||||
|
"var a: { id<Foo>(x: Foo2): Foo3; }; a;"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("23", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"var a:Array<Foo> = [1, 2, 3]; a;"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("24", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"import type Foo2 from 'foo';",
|
||||||
|
"import Baz from 'foo';",
|
||||||
|
"class Bar<Foo> extends Baz<Foo2> { };"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("25", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"import type Foo2 from 'foo';",
|
||||||
|
"import type Foo3 from 'foo';",
|
||||||
|
"class Bar<Foo> { bar<Foo2>():Foo3 { return 42; }}"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("26", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"import type Foo2 from 'foo';",
|
||||||
|
"class Bar { static prop1:Foo; prop2:Foo2; }"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("27", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"import type Foo2 from 'foo';",
|
||||||
|
"var x : Foo | Foo2 = 4; x;"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("28", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"import type Foo2 from 'foo';",
|
||||||
|
"var x : () => Foo | () => Foo2; x;"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("29", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"import type Foo2 from 'foo';",
|
||||||
|
"var x: typeof Foo | number = Foo2; x;"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("30", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
'var {x}: {x: Foo; } = { x: "hello" }; x;'
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("31", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
'var [x]: Array<Foo> = [ "hello" ]; x;'
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("32", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"export default function({x}: { x: Foo; }) {}"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("33", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"function foo([x]: Array<Foo>) { x; } foo();"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("34", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"import type Foo2 from 'foo';",
|
||||||
|
"var a: Map<Foo, Array<Foo2> >; a;"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("35", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"var a: ?Promise<Foo>[]; a;"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("36", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"import type Foo2 from 'foo';",
|
||||||
|
"var a:(...rest:Array<Foo>) => Foo2; a;"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("37", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"import type Foo2 from 'foo';",
|
||||||
|
"import type Foo3 from 'foo';",
|
||||||
|
"import type Foo4 from 'foo';",
|
||||||
|
"var a: <Foo>(x: Foo2, ...y:Foo3[]) => Foo4; a;"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("38", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
'import type {foo, bar} from "baz";',
|
||||||
|
'foo; bar;'
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("39", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
'import type {foo as bar} from "baz";',
|
||||||
|
'bar;'
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("40", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
'import type from "foo";',
|
||||||
|
'type;'
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("41", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
'import type, {foo} from "bar";',
|
||||||
|
'type; foo;'
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("42", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
'import type * as namespace from "bar";',
|
||||||
|
'namespace;'
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("43", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"var a: Foo[]; a;"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("44", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"var a: ?Foo[]; a;"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("45", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"var a: (?Foo)[]; a;"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("46", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"var a: () => Foo[]; a;"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("47", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"var a: (() => Foo)[]; a;"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("48", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"var a: typeof Foo[]; a;"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("49", function () {
|
||||||
|
verifyAndAssertMessages(
|
||||||
|
[
|
||||||
|
"import type Foo from 'foo';",
|
||||||
|
"import type Foo2 from 'foo';",
|
||||||
|
"import type Foo3 from 'foo';",
|
||||||
|
"var a : [Foo, Foo2<Foo3>,] = [123, 'duck',]; a;"
|
||||||
|
].join("\n"),
|
||||||
|
{ "no-unused-vars": 1, "no-undef": 1 },
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it("class usage", function () {
|
it("class usage", function () {
|
||||||
verifyAndAssertMessages(
|
verifyAndAssertMessages(
|
||||||
"class Lol {} module.exports = Lol;",
|
"class Lol {} module.exports = Lol;",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user