From 8f60f20a8ab137e54868ded6b8a600253700d09f Mon Sep 17 00:00:00 2001 From: Kyle Micallef Bonnici Date: Sun, 26 Jan 2025 19:16:48 +0100 Subject: [PATCH] Add support for /include/ --- CHANGELOG.md | 6 ++ package.json | 2 +- server/package.json | 2 +- server/src/cPreprocessorParser.ts | 31 +++++- server/src/test/parser.test.ts | 151 +++++++++++++++++++++--------- 5 files changed, 139 insertions(+), 53 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a565043..63ef8f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +# 0.0.9 - 2025-01-26 + +### Fixed + +- Support for `/include/` syntax + # 0.0.8 - 2025-01-26 ### Added diff --git a/package.json b/package.json index de98ed3..b9b0dfd 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "author": "Microsoft Corporation", "license": "Apache-2.0", "icon": "images/icon.png", - "version": "0.0.8", + "version": "0.0.9", "repository": { "type": "git", "url": "https://github.com/kylebonnici/dts-lsp" diff --git a/server/package.json b/server/package.json index c022150..3ea3c68 100644 --- a/server/package.json +++ b/server/package.json @@ -4,7 +4,7 @@ "author": "Kyle Micallef Bonnici", "package-name": "devicetree-language-server", "main": "dist/server.js", - "version": "0.0.8", + "version": "0.0.9", "keywords": [ "dts", "devicetree", diff --git a/server/src/cPreprocessorParser.ts b/server/src/cPreprocessorParser.ts index 877fc60..74de67f 100644 --- a/server/src/cPreprocessorParser.ts +++ b/server/src/cPreprocessorParser.ts @@ -20,6 +20,7 @@ import { genIssue, sameLine, validateToken, + validateValue, validToken, } from "./helpers"; import { ASTBase } from "./ast/base"; @@ -401,15 +402,35 @@ export class CPreprocessorParser extends BaseParser { this.enqueueToStack(); const startIndex = this.peekIndex(); - const start = this.moveToNextToken; - let token = start; - if (!token || !validToken(token, LexerToken.C_INCLUDE)) { + let token = this.currentToken; + + if (!token) { this.popStack(); return false; } - const line = start?.pos.line; - const keyword = new Keyword(createTokenIndex(token)); + let keywordStart = token; + let keywordEnd: Token | undefined = token; + if (!validToken(token, LexerToken.C_INCLUDE)) { + const valid = this.checkConcurrentTokens([ + validateToken(LexerToken.FORWARD_SLASH), + validateValue("include"), + validateToken(LexerToken.FORWARD_SLASH), + ]); + + if (valid.length !== 3) { + this.popStack(); + return false; + } + + keywordStart = valid[0]; + keywordEnd = valid.at(-1); + } else { + this.moveToNextToken; + } + + const line = keywordStart?.pos.line; + const keyword = new Keyword(createTokenIndex(keywordStart, keywordEnd)); token = this.moveToNextToken; const pathStart = token; diff --git a/server/src/test/parser.test.ts b/server/src/test/parser.test.ts index f82016f..d955fa4 100644 --- a/server/src/test/parser.test.ts +++ b/server/src/test/parser.test.ts @@ -2102,59 +2102,118 @@ describe("Parser", () => { }); describe("Includes", () => { - test("Include relative", async () => { - mockReadFilesSync({ - "/folder/dts.dts": '#include "some.dtsi"', - "/folder/some.dtsi": "", + describe("#include", () => { + test("Include relative", async () => { + mockReadFilesSync({ + "/folder/dts.dts": '#include "some.dtsi"', + "/folder/some.dtsi": "", + }); + const parser = new CPreprocessorParser("/folder/dts.dts", []); + await parser.stable; + expect(parser.issues.length).toEqual(0); + expect(parser.dtsIncludes.length).toEqual(1); + expect(parser.dtsIncludes[0].path.path).toEqual("some.dtsi"); + + expect(fs.existsSync).toBeCalledWith("/folder/some.dtsi"); + expect(fs.readFileSync).nthCalledWith(2, "/folder/some.dtsi"); }); - const parser = new CPreprocessorParser("/folder/dts.dts", []); - await parser.stable; - expect(parser.issues.length).toEqual(0); - expect(parser.dtsIncludes.length).toEqual(1); - expect(parser.dtsIncludes[0].path.path).toEqual("some.dtsi"); + test("Include absolute", async () => { + mockReadFilesSync({ + "/folder/dts.dts": "#include ", + "/my/includes/my_includes/some.dtsi": "", + }); + const parser = new CPreprocessorParser("/folder/dts.dts", [ + "/my/includes", + ]); + await parser.stable; + expect(parser.issues.length).toEqual(0); + expect(parser.dtsIncludes.length).toEqual(1); + expect(parser.dtsIncludes[0].path.path).toEqual( + "my_includes/some.dtsi" + ); - expect(fs.existsSync).toBeCalledWith("/folder/some.dtsi"); - expect(fs.readFileSync).nthCalledWith(2, "/folder/some.dtsi"); - }); - test("Include absolute", async () => { - mockReadFilesSync({ - "/folder/dts.dts": "#include ", - "/my/includes/my_includes/some.dtsi": "", + expect(fs.existsSync).toBeCalledWith( + "/my/includes/my_includes/some.dtsi" + ); + expect(fs.readFileSync).nthCalledWith( + 2, + "/my/includes/my_includes/some.dtsi" + ); }); - const parser = new CPreprocessorParser("/folder/dts.dts", [ - "/my/includes", - ]); - await parser.stable; - expect(parser.issues.length).toEqual(0); - expect(parser.dtsIncludes.length).toEqual(1); - expect(parser.dtsIncludes[0].path.path).toEqual( - "my_includes/some.dtsi" - ); - expect(fs.existsSync).toBeCalledWith( - "/my/includes/my_includes/some.dtsi" - ); - expect(fs.readFileSync).nthCalledWith( - 2, - "/my/includes/my_includes/some.dtsi" - ); + test("Include absolute", async () => { + mockReadFilesSync({ + "/folder/dts.dts": "#include { - mockReadFilesSync({ - "/folder/dts.dts": "#include { + test("Include relative", async () => { + mockReadFilesSync({ + "/folder/dts.dts": '/include/ "some.dtsi"', + "/folder/some.dtsi": "", + }); + const parser = new CPreprocessorParser("/folder/dts.dts", []); + await parser.stable; + expect(parser.issues.length).toEqual(0); + expect(parser.dtsIncludes.length).toEqual(1); + expect(parser.dtsIncludes[0].path.path).toEqual("some.dtsi"); + + expect(fs.existsSync).toBeCalledWith("/folder/some.dtsi"); + expect(fs.readFileSync).nthCalledWith(2, "/folder/some.dtsi"); + }); + test("Include absolute", async () => { + mockReadFilesSync({ + "/folder/dts.dts": "/include/ ", + "/my/includes/my_includes/some.dtsi": "", + }); + const parser = new CPreprocessorParser("/folder/dts.dts", [ + "/my/includes", + ]); + await parser.stable; + expect(parser.issues.length).toEqual(0); + expect(parser.dtsIncludes.length).toEqual(1); + expect(parser.dtsIncludes[0].path.path).toEqual( + "my_includes/some.dtsi" + ); + + expect(fs.existsSync).toBeCalledWith( + "/my/includes/my_includes/some.dtsi" + ); + expect(fs.readFileSync).nthCalledWith( + 2, + "/my/includes/my_includes/some.dtsi" + ); + }); + + test("Include absolute", async () => { + mockReadFilesSync({ + "/folder/dts.dts": "/include/