From 7b878d8ca57856a8c6edb4a24acd2d9de824a15a Mon Sep 17 00:00:00 2001 From: Scott Meesseman Date: Sun, 6 Jun 2021 02:54:48 -0400 Subject: [PATCH] fix: Makefile variables assigned with := are interpreted as rules. [fixes #146] --- src/providers/make.ts | 48 +++++++++------------------------------- test-files/make/makefile | 15 +++++++++++++ 2 files changed, 25 insertions(+), 38 deletions(-) diff --git a/src/providers/make.ts b/src/providers/make.ts index da83bcaaf..e43845134 100644 --- a/src/providers/make.ts +++ b/src/providers/make.ts @@ -13,9 +13,9 @@ import { TaskExplorerDefinition } from "../taskDefinition"; export class MakeTaskProvider extends TaskExplorerProvider implements TaskExplorerProvider { - private suffixRuleTargets = /^(\.\w+|\.\w+\.\w+)$/; private patternRuleTargets = /^(%\.\w+|%)$/; + private ruleTargetExp = /^([\w-.\/ ]+)\s*:[^=]/mg; // note does not disallow leading '.', this must be checked separately. // See: https://www.gnu.org/software/make/manual/html_node/Special-Targets.html private specialTargets = new Set([ ".PHONY", @@ -36,7 +36,6 @@ export class MakeTaskProvider extends TaskExplorerProvider implements TaskExplor ".MAKE", ]); - constructor() { super("make"); } @@ -119,38 +118,22 @@ export class MakeTaskProvider extends TaskExplorerProvider implements TaskExplor log.write(logPad + "find makefile targets"); const contents = util.readFileSync(fsPath); - let idx = 0; - let eol = contents.indexOf("\n", 0); - - while (eol !== -1) + let match; + while (match = this.ruleTargetExp.exec(contents)) { - const line: string = contents.substring(idx, eol); - // - // Target names always start at position 0 of the line. - // - // TODO = Skip targets that are environment variable names, for now. Need to - // parse value if set in makefile and apply here for $() target names. - // - if (line.length > 0 && !line.startsWith("\t") && !line.startsWith(" ") && - !line.startsWith("#") && !line.startsWith("$") && line.indexOf(":") > 0) + const tgtName = match[1]; + if (tgtName.startsWith(".")) // skip special targets { - const { tgtName, dependsName } = this.parseTargetLine(line); - - // - // Don't include object targets - // - if (tgtName.indexOf("/") === -1 && tgtName.indexOf("=") === -1 && tgtName.indexOf("\\") === -1 && - tgtName.indexOf("(") === -1 && tgtName.indexOf("$") === -1 && this.isNormalTarget(tgtName)) - { + continue; + } + if (!scripts.includes(tgtName)) // avoid duplicates + { + if (this.isNormalTarget(tgtName)) { scripts.push(tgtName); log.write(logPad + " found makefile target"); log.value(logPad + " name", tgtName); - log.value(logPad + " depends target", dependsName); } } - - idx = eol + 1; - eol = contents.indexOf("\n", idx); } log.write(logPad + "find makefile targets complete", 1); @@ -193,17 +176,6 @@ export class MakeTaskProvider extends TaskExplorerProvider implements TaskExplor } - private parseTargetLine(line: string) - { - const tgtNames = line.split(":")[0].trim(); - const tgtName = tgtNames.split(" ").slice(-1)[0]; - - const dependsName = line.substring(line.indexOf(":") + 1).trim(); - - return { tgtName, dependsName }; - } - - public async readTasks(logPad = ""): Promise { log.methodStart("detect make files", 1, logPad, true); diff --git a/test-files/make/makefile b/test-files/make/makefile index 6ec1296d7..48a32a778 100644 --- a/test-files/make/makefile +++ b/test-files/make/makefile @@ -8,3 +8,18 @@ coverage: deno test --import-map=import_map.json --no-check --coverage=cov_profile deno coverage cov_profile rm -rf cov_profile + +rule1: rule2 + @echo rule1 + +rule2: + @echo rule2 + +# The ":=" referenced in ticket 146 must not be a windows nmake thing, +# get 'invalid character '='' errors when uncommented. but they are no +# longer parsed as tasks. +# VAR4:=foo +# VAR5 := foo +# else +# VAR4:=bar +# VAR5 := bar