@puruslang/linter 0.3.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/index.js +27 -8
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@puruslang/linter",
3
- "version": "0.3.1",
3
+ "version": "0.5.0",
4
4
  "description": "Linter for the Purus language",
5
5
  "license": "Apache-2.0",
6
6
  "main": "src/index.js",
package/src/index.js CHANGED
@@ -10,9 +10,10 @@ const KEYWORDS = new Set([
10
10
  "import", "from", "export", "default", "require", "use", "namespace", "pub", "all",
11
11
  "add", "sub", "mul", "div", "mod", "neg", "pow",
12
12
  "eq", "neq", "lt", "gt", "le", "ge",
13
- "and", "or", "not", "pipe",
13
+ "and", "or", "not", "pipe", "coal",
14
14
  "is", "as", "of", "typeof", "instanceof", "type",
15
15
  "new", "delete", "this", "await",
16
+ "class", "extends", "super", "static", "private", "get", "set",
16
17
  "true", "false", "null", "nil", "undefined",
17
18
  "break", "continue",
18
19
  "list", "object",
@@ -80,16 +81,37 @@ function tokenize(source) {
80
81
  }
81
82
 
82
83
  // Punctuation
83
- if ("[],;.".includes(source[i])) {
84
+ if ("[],;".includes(source[i])) {
85
+ tokens.push({ type: "punct", value: source[i], line: startLine, col: startCol });
86
+ i++; col++;
87
+ continue;
88
+ }
89
+
90
+ // Optional chaining \.
91
+ if (source[i] === "\\" && source[i + 1] === ".") {
92
+ tokens.push({ type: "punct", value: "\\.", line: startLine, col: startCol });
93
+ i += 2; col += 2;
94
+ continue;
95
+ }
96
+
97
+ // Backslash (computed access prefix)
98
+ if (source[i] === "\\") {
99
+ tokens.push({ type: "punct", value: "\\", line: startLine, col: startCol });
100
+ i++; col++;
101
+ continue;
102
+ }
103
+
104
+ // Dot
105
+ if (source[i] === ".") {
84
106
  tokens.push({ type: "punct", value: source[i], line: startLine, col: startCol });
85
107
  i++; col++;
86
108
  continue;
87
109
  }
88
110
 
89
111
  // Word
90
- if (/[a-zA-Z]/.test(source[i])) {
112
+ if (/[a-zA-Z_]/.test(source[i])) {
91
113
  let start = i;
92
- while (i < len && /[a-zA-Z0-9-]/.test(source[i])) { i++; col++; }
114
+ while (i < len && /[a-zA-Z0-9_-]/.test(source[i])) { i++; col++; }
93
115
  const word = source.slice(start, i);
94
116
  tokens.push({ type: KEYWORDS.has(word) ? "keyword" : "ident", value: word, line: startLine, col: startCol });
95
117
  continue;
@@ -167,11 +189,8 @@ function lint(source, ruleOverrides = {}) {
167
189
  if (style === "kebab-case") {
168
190
  // Identifiers should be kebab-case (lowercase with hyphens)
169
191
  // Allow PascalCase for class names (starts with uppercase)
192
+ // Allow underscores (they are equivalent to hyphens)
170
193
  if (/[A-Z]/.test(tok.value[0])) continue; // Allow PascalCase
171
- if (/_/.test(tok.value)) {
172
- report("consistent-naming", tok.line, tok.col,
173
- `Use kebab-case instead of snake_case: '${tok.value}'`);
174
- }
175
194
  }
176
195
  }
177
196
  }