ifc-language-server/node_modules/@stylistic/eslint-plugin/dist/rules/no-extra-semi.js
Ryan Schultz 8afacf268a Implemented a working Language Server Protocol (LSP) for IFC files with:
- Hover provider showing entity information and type
- Go-to-definition (F12) for entity references
- Basic IFC file validation (ISO-10303-21 header check)
- Entity parsing with regex-based detection
- Proper CommonJS module system (avoiding ES module issues)

This replaces the broken baseline from ifc-developer-tools which had:
- Non-functional ES module configuration
- Circular dependency issues
- Parser crashes
- Non-working PositionVisitor

Built on Microsoft's LSP example template for a clean, maintainable foundation.

Next: Add hierarchical entity dependency tree in hover tooltip."
2025-12-07 10:20:07 -06:00

108 lines
3.3 KiB
JavaScript

'use strict';
var utils = require('../utils.js');
require('eslint-visitor-keys');
require('espree');
require('estraverse');
var _baseRule = utils.createRule({
name: "no-extra-semi",
package: "js",
meta: {
type: "layout",
docs: {
description: "Disallow unnecessary semicolons"
},
fixable: "code",
schema: [],
messages: {
unexpected: "Unnecessary semicolon."
}
},
create(context) {
const sourceCode = context.sourceCode;
function isFixable(nodeOrToken) {
const nextToken = sourceCode.getTokenAfter(nodeOrToken);
if (!nextToken || nextToken.type !== "String")
return true;
const stringNode = sourceCode.getNodeByRangeIndex(nextToken.range[0]);
return !utils.isTopLevelExpressionStatement(stringNode.parent);
}
function report(nodeOrToken) {
context.report({
node: nodeOrToken,
messageId: "unexpected",
fix: isFixable(nodeOrToken) ? (fixer) => new utils.FixTracker(fixer, context.sourceCode).retainSurroundingTokens(nodeOrToken).remove(nodeOrToken) : null
});
}
function checkForPartOfClassBody(firstToken) {
for (let token = firstToken; token.type === "Punctuator" && !utils.isClosingBraceToken(token); token = sourceCode.getTokenAfter(token)) {
if (utils.isSemicolonToken(token))
report(token);
}
}
return {
/**
* Reports this empty statement, except if the parent node is a loop.
* @param node A EmptyStatement node to be reported.
*/
EmptyStatement(node) {
const parent = node.parent;
const allowedParentTypes = [
"ForStatement",
"ForInStatement",
"ForOfStatement",
"WhileStatement",
"DoWhileStatement",
"IfStatement",
"LabeledStatement",
"WithStatement"
];
if (!allowedParentTypes.includes(parent.type))
report(node);
},
/**
* Checks tokens from the head of this class body to the first MethodDefinition or the end of this class body.
* @param node A ClassBody node to check.
*/
ClassBody(node) {
checkForPartOfClassBody(sourceCode.getFirstToken(node, 1));
},
/**
* Checks tokens from this MethodDefinition to the next MethodDefinition or the end of this class body.
* @param node A MethodDefinition node of the start point.
*/
"MethodDefinition, PropertyDefinition, StaticBlock": function(node) {
checkForPartOfClassBody(sourceCode.getTokenAfter(node));
}
};
}
});
const baseRule = /* @__PURE__ */ utils.castRuleModule(_baseRule);
var noExtraSemi = utils.createRule({
name: "no-extra-semi",
package: "ts",
meta: {
type: "layout",
docs: {
description: "Disallow unnecessary semicolons"
},
fixable: "code",
hasSuggestions: baseRule.meta.hasSuggestions,
schema: baseRule.meta.schema,
messages: baseRule.meta.messages
},
defaultOptions: [],
create(context) {
const rules = baseRule.create(context);
return {
...rules,
"TSAbstractMethodDefinition, TSAbstractPropertyDefinition": function(node) {
rules["MethodDefinition, PropertyDefinition, StaticBlock"]?.(node);
}
};
}
});
module.exports = noExtraSemi;