Skip to content

Commit a1022e4

Browse files
committed
major restructure; split rules into seperate files
1 parent 963f461 commit a1022e4

18 files changed

+523
-518
lines changed

.c8rc.json

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
{
22
"all": true,
33
"include": [
4-
"dist/plugins/**/*.js"
5-
],
6-
"exclude": [
7-
"tests/**",
8-
"node_modules/**"
4+
"dist/plugins/rules/**/*.js"
95
],
106
"reporter": ["text", "html", "lcov"],
117
"report-dir": "./coverage",

.github/workflows/ci.yml

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,14 @@ jobs:
1717
- name: Install dependencies
1818
run: npm install
1919

20-
- name: Run test script
21-
run: bash ./sanity-check.sh
20+
- name: Run build
21+
run: npm run build
22+
23+
- name: Run spell check
24+
run: npm run spell-check
25+
26+
- name: Run prettier
27+
run: npm run prettier-check
28+
29+
- name: Run test & coverage
30+
run: npm run test:coverage

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@ node_modules
33
dist/
44
sample_cases/
55
wasm-toolchain
6-
coverage
6+
coverage
7+
.vscode/settings.json
8+
reference

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
"lint": "npx eslint sample_cases/",
3333
"watch": "npx tsc --build ./tsconfig.json --watch",
3434
"spell-check": "cspell \"**/*.{ts,js,md}\"",
35+
"prettier-check": "prettier --check \"**/*.{ts,js,json,md}\"",
3536
"prettier-fix": "prettier --check --write \"**/*.{ts,js,json,md}\""
3637
},
3738
"peerDependencies": {

plugins/as-plugin.ts

Lines changed: 8 additions & 178 deletions
Original file line numberDiff line numberDiff line change
@@ -1,187 +1,17 @@
1-
import { ESLintUtils, TSESTree } from "@typescript-eslint/utils";
2-
import { RuleListener, RuleModule } from "@typescript-eslint/utils/ts-eslint";
3-
41
/**
5-
* ESlint plugin to enforce people to comply with our code guidelines
6-
* Reference: https://developer.bmwgroup.net/docs/cdc/cdc-platform-wasm/guidelines/#cdc-specific-rules
2+
* AssemblyScript ESLint Plugin
3+
*
4+
* This plugin provides rules for validating AssemblyScript code.
5+
* It detects patterns that are either not supported in AssemblyScript
6+
* or violate best practices specific to the language.
77
*/
8-
9-
const createRule = ESLintUtils.RuleCreator(
10-
(name) => `https://example.com/rule/${name}`
11-
);
12-
13-
const dontOmitElse: RuleModule<"omittedElse", [], unknown, RuleListener> =
14-
createRule({
15-
name: "dont-omit-else",
16-
meta: {
17-
type: "problem",
18-
docs: {
19-
description:
20-
"Enforce else block unless if branch contains control flow",
21-
},
22-
messages: {
23-
omittedElse:
24-
"Omitted else block is not allowed unless if branch contains control flow.",
25-
},
26-
schema: [],
27-
},
28-
defaultOptions: [],
29-
create(context) {
30-
// Check if the statement is part of an else-if chain
31-
function isElseIf(node: TSESTree.Node) {
32-
// Check parent relationship to determine if this is an else-if
33-
const ancestors = context.sourceCode.getAncestors(node);
34-
const parent = ancestors[ancestors.length - 1];
35-
return (
36-
parent && parent.type === "IfStatement" && parent.alternate === node
37-
);
38-
}
39-
40-
// Helper function to check if a node is a control flow statement
41-
function isControlFlowStatement(
42-
node: TSESTree.Node | null | undefined
43-
): boolean {
44-
// Return true if the node is a control flow statement
45-
return (
46-
node?.type === "ReturnStatement" ||
47-
node?.type === "ThrowStatement" ||
48-
node?.type === "BreakStatement" ||
49-
node?.type === "ContinueStatement"
50-
);
51-
}
52-
53-
// Check if statement or block contains control flow
54-
function checkControlFlow(node: TSESTree.Node) {
55-
// Handle different statement types
56-
if (node.type === "BlockStatement") {
57-
// For block statements, check the last statement in the block
58-
const lastStatement =
59-
node.body.length > 0 ? node.body[node.body.length - 1] : null;
60-
return isControlFlowStatement(lastStatement);
61-
} else {
62-
// For single statements (no curly braces), check the statement directly
63-
return isControlFlowStatement(node);
64-
}
65-
}
66-
67-
return {
68-
IfStatement(node) {
69-
// Skip if this is already an else-if
70-
if (isElseIf(node)) {
71-
return;
72-
}
73-
const hasElse = node.alternate !== null;
74-
const ifBlockEndsWithControlFlow = checkControlFlow(node.consequent);
75-
// Report error if no else and no control flow
76-
if (!hasElse && !ifBlockEndsWithControlFlow) {
77-
context.report({
78-
node,
79-
messageId: "omittedElse",
80-
});
81-
}
82-
},
83-
};
84-
},
85-
});
86-
87-
// reject usages of ...var: T on function definition
88-
const noRestParam: ESLintUtils.RuleModule<
89-
"noRestMsg",
90-
[],
91-
unknown,
92-
ESLintUtils.RuleListener
93-
> = createRule({
94-
name: "no-rest-params",
95-
meta: {
96-
type: "problem",
97-
docs: {
98-
description: "Rest params are not supported.",
99-
},
100-
messages: {
101-
noRestMsg: "Don't use rest params, it's not supported in assemblyscript",
102-
},
103-
schema: [],
104-
},
105-
defaultOptions: [],
106-
create(context) {
107-
return {
108-
RestElement: (node) => {
109-
context.report({
110-
messageId: "noRestMsg",
111-
node: node,
112-
});
113-
},
114-
};
115-
},
116-
});
117-
118-
// reject usages of ...var on call expressions
119-
const noSpread: ESLintUtils.RuleModule<
120-
"noSpreadMsg",
121-
[],
122-
unknown,
123-
ESLintUtils.RuleListener
124-
> = createRule({
125-
name: "no-spread",
126-
meta: {
127-
type: "problem",
128-
docs: {
129-
description: "Spreads are not supported.",
130-
},
131-
messages: {
132-
noSpreadMsg: "Spreads are not supported.",
133-
},
134-
schema: [],
135-
},
136-
defaultOptions: [],
137-
create(context) {
138-
return {
139-
SpreadElement: (node) => {
140-
context.report({ messageId: "noSpreadMsg", node: node });
141-
},
142-
};
143-
},
144-
});
145-
146-
const noUnsupportedKeyword: ESLintUtils.RuleModule<
147-
string,
148-
[],
149-
unknown,
150-
ESLintUtils.RuleListener
151-
> = createRule({
152-
name: "no-unsupported-keyword",
153-
meta: {
154-
type: "problem",
155-
docs: {
156-
description: "Some keywords are not supported in assemblyscript",
157-
},
158-
messages: {
159-
noNever: "'never' is not supported in AssemblyScript.",
160-
noAny: "'any' is not supported in AssemblyScript.",
161-
noUndefined: "'undefined' is not supported in AssemblyScript.",
162-
},
163-
schema: [],
164-
},
165-
defaultOptions: [],
166-
create(context) {
167-
return {
168-
TSNeverKeyword: (node) => {
169-
context.report({ messageId: "noNever", node: node });
170-
},
171-
TSAnyKeyword: (node) => {
172-
context.report({ messageId: "noAny", node: node });
173-
},
174-
TSUndefinedKeyword: (node) => {
175-
context.report({ messageId: "noUndefined", node: node });
176-
},
177-
};
178-
},
179-
});
8+
import dontOmitElse from "./rules/dont-omit-else.js";
9+
import noSpread from "./rules/no-spread.js";
10+
import noUnsupportedKeyword from "./rules/no-unsupported-keyword.js";
18011

18112
export default {
18213
rules: {
18314
"dont-omit-else": dontOmitElse,
184-
"no-rest-params": noRestParam,
18515
"no-spread": noSpread,
18616
"no-unsupported-keyword": noUnsupportedKeyword,
18717
},

plugins/perf-plugin.ts

Lines changed: 5 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,10 @@
1-
import {
2-
AST_NODE_TYPES,
3-
ESLintUtils,
4-
TSESTree,
5-
} from "@typescript-eslint/utils";
6-
7-
/**
8-
* ESlint plugin to detect possible issues that can have impact on performance
9-
* Reference: https://atc.bmwgroup.net/confluence/display/CDCDEV/AssemblyScript+Performance+Improvement
10-
*/
11-
const createRule = ESLintUtils.RuleCreator(
12-
(name) => `https://example.com/rule/${name}`
13-
);
14-
151
/**
16-
* Rule: Array Initializer
17-
* Avoid using [] to initialize variables
18-
* [] will create a temporary object in data section.
19-
* BAD
20-
* let v: i32[] = [];
21-
* GOOD
22-
* let v: i32[] = new Array();
2+
* Performance ESLint Plugin for AssemblyScript
3+
*
4+
* This plugin provides rules for detecting and fixing potential performance issues
5+
* in AssemblyScript code.
236
*/
24-
const arrayInitStyle: ESLintUtils.RuleModule<
25-
"preferArrayConstructor",
26-
[],
27-
unknown,
28-
ESLintUtils.RuleListener
29-
> = createRule({
30-
name: "array-init-style",
31-
meta: {
32-
type: "problem",
33-
fixable: "code",
34-
docs: {
35-
description: "Enforce using Array constructor for empty arrays",
36-
},
37-
messages: {
38-
preferArrayConstructor:
39-
"Please use new Array<{{ type }}>() to initialize an array",
40-
},
41-
schema: [],
42-
},
43-
defaultOptions: [],
44-
create(context) {
45-
return {
46-
VariableDeclarator(node) {
47-
const typeAnnotation = node.id.typeAnnotation?.typeAnnotation;
48-
if (
49-
typeAnnotation?.type === "TSArrayType" &&
50-
typeAnnotation.elementType?.type === "TSTypeReference"
51-
) {
52-
if (
53-
node.init?.type === "ArrayExpression" &&
54-
node.init.elements.length === 0
55-
) {
56-
// Ensure node.init is not null before passing to fixer
57-
const initNode = node.init;
58-
const elementType = context.sourceCode.getText(
59-
typeAnnotation.elementType.typeName
60-
);
61-
context.report({
62-
node,
63-
messageId: "preferArrayConstructor",
64-
data: {
65-
type: elementType,
66-
},
67-
fix(fixer) {
68-
// initNode is guaranteed non-null here due to the outer check
69-
return fixer.replaceText(
70-
initNode,
71-
`new Array<${elementType}>()`
72-
);
73-
},
74-
});
75-
}
76-
}
77-
},
78-
};
79-
},
80-
});
7+
import arrayInitStyle from "./rules/array-init-style.js";
818

829
export default {
8310
rules: {

0 commit comments

Comments
 (0)