diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 137cf18a2..0e5ee8a91 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -141,7 +141,6 @@ for (const func of Query.search('function')) { - `scripts/`: Build and interface generation tools **Entry Points**: -- `core.ts`: Global imports and initialization - `weaver/Weaver.ts`: Main weaver utilities - `LaraJoinPoint.ts`: Base join point implementation diff --git a/.github/workflows/ant-lara-2.0-legacy.yml b/.github/workflows/ant-lara-2.0-legacy.yml index 0d3891b64..7da0d9e06 100644 --- a/.github/workflows/ant-lara-2.0-legacy.yml +++ b/.github/workflows/ant-lara-2.0-legacy.yml @@ -11,7 +11,7 @@ on: # Daily at midnight schedule: - - cron: '0 0 * * *' + - cron: '0 0 1 * *' jobs: build: @@ -23,7 +23,7 @@ jobs: steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 # Because of scheduled runs, by default run on default branch with: ref: lara-2.0-legacy diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index 4b3da327d..89db99345 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -14,7 +14,7 @@ on: - .github/workflows/copilot-setup-steps.yml env: - LARA_FRAMEWORK_BRANCH: ${{ github.head_ref || github.ref_name }} + BRANCH_NAME: ${{ github.head_ref || github.ref_name }} jobs: # The job MUST be called `copilot-setup-steps` @@ -41,10 +41,9 @@ jobs: uses: gradle/actions/setup-gradle@v4 with: gradle-version: current - dependency-graph: generate-and-submit - name: Checkout lara-framework - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: path: lara-framework @@ -52,43 +51,58 @@ jobs: id: repo-refs shell: bash env: - BRANCH_NAME: ${{ env.LARA_FRAMEWORK_BRANCH }} + BRANCH_NAME: ${{ env.BRANCH_NAME }} + BASE_BRANCH: ${{ github.base_ref }} run: | set -euo pipefail + # For each dependency repository, determine which branch to checkout. + # Priority order: + # 1. A branch with the same name as the current branch + # 2. If this is a PR, the target branch (base_ref) + # 3. The default branch of the repository + determine_ref() { local prefix=$1 local repo=$2 local url="https://github.com/${repo}.git" + # Get the default branch local default_branch default_branch=$(git ls-remote --symref "$url" HEAD | awk '/^ref:/ {print $2}' | sed 's@refs/heads/@@') echo "${prefix}_default=${default_branch}" >> "$GITHUB_OUTPUT" echo "Default branch for ${repo} is '${default_branch}'" - if git ls-remote --heads "$url" "refs/heads/${BRANCH_NAME}" >/dev/null; then - echo "${prefix}_match=true" >> "$GITHUB_OUTPUT" - echo "${prefix}_ref=${BRANCH_NAME}" >> "$GITHUB_OUTPUT" - echo "Branch '${BRANCH_NAME}' exists in ${repo}" + local ref_to_use="" + + # Priority 1: Same branch name + if [ -n "$(git ls-remote --heads "$url" "refs/heads/${BRANCH_NAME}")" ]; then + ref_to_use="${BRANCH_NAME}" + echo "Using matching branch '${BRANCH_NAME}' in ${repo}" + # Priority 2: PR target branch (if this is a PR) + elif [ -n "${BASE_BRANCH}" ] && [ -n "$(git ls-remote --heads "$url" "refs/heads/${BASE_BRANCH}")" ]; then + ref_to_use="${BASE_BRANCH}" + echo "Using PR target branch '${BASE_BRANCH}' in ${repo}" + # Priority 3: Default branch else - echo "${prefix}_match=false" >> "$GITHUB_OUTPUT" - echo "${prefix}_ref=${default_branch}" >> "$GITHUB_OUTPUT" - echo "Branch '${BRANCH_NAME}' not found in ${repo}. Falling back to '${default_branch}'." + ref_to_use="${default_branch}" + echo "Using default branch '${default_branch}' for ${repo}" fi + + echo "${prefix}_ref=${ref_to_use}" >> "$GITHUB_OUTPUT" } determine_ref "specs" "specs-feup/specs-java-libs" - name: Echo checks run: | - echo "Lara-Framework branch: ${{ env.LARA_FRAMEWORK_BRANCH }}" - echo "Matching branch found (specs-java-libs): ${{ steps.repo-refs.outputs.specs_match }}" + echo "Lara branch: ${{ env.BRANCH_NAME }}" + echo "PR target branch (if any): ${{ github.base_ref }}" echo "Specs-java-libs ref: ${{ steps.repo-refs.outputs.specs_ref }}" - echo "Specs-java-libs default fallback: ${{ steps.repo-refs.outputs.specs_default }}" - echo "Pull request base_ref (if any): ${{ github.base_ref }}" + echo "Specs-java-libs default: ${{ steps.repo-refs.outputs.specs_default }}" - name: Checkout specs-java-libs - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: repository: specs-feup/specs-java-libs path: specs-java-libs diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 95de2d670..0ed2580c9 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -19,11 +19,6 @@ permissions: env: JAVA_VERSION: 17 BRANCH_NAME: ${{ github.head_ref || github.ref_name }} - # Setting default branch to staging assuming PRs will be done against the staging versions of the repository - # main versions will just receive what comes from the staging - DEFAULT_BRANCH: ${{ github.base_ref || 'staging' }} - #SPECS_JAVA_LIBS_BRANCH: ${{ 'master' }} - #LARA_FRAMEWORK_BRANCH: ${{ github.head_ref || github.ref_name }} jobs: build-java: @@ -31,7 +26,7 @@ jobs: runs-on: ubuntu-latest outputs: - branch-exists-specs-java-libs: ${{ steps.Branch-specs-java-libs.outputs.value }} + specs_ref: ${{ steps.repo-refs.outputs.specs_ref }} steps: - name: Setup Java @@ -47,27 +42,70 @@ jobs: dependency-graph: generate-and-submit - name: Checkout lara-framework - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: path: lara-framework - - name: Check if branch exists on specs-java-libs - id: Branch-specs-java-libs - run: echo "value=$(git ls-remote --heads https://github.com/specs-feup/specs-java-libs.git refs/heads/${{ env.BRANCH_NAME }} | wc -l)" >> $GITHUB_OUTPUT + - name: Determine repository refs + id: repo-refs + shell: bash + env: + BRANCH_NAME: ${{ env.BRANCH_NAME }} + BASE_BRANCH: ${{ github.base_ref }} + run: | + set -euo pipefail + + # For each dependency repository, determine which branch to checkout. + # Priority order: + # 1. A branch with the same name as the current branch + # 2. If this is a PR, the target branch (base_ref) + # 3. The default branch of the repository + + determine_ref() { + local prefix=$1 + local repo=$2 + local url="https://github.com/${repo}.git" + + # Get the default branch + local default_branch + default_branch=$(git ls-remote --symref "$url" HEAD | awk '/^ref:/ {print $2}' | sed 's@refs/heads/@@') + echo "${prefix}_default=${default_branch}" >> "$GITHUB_OUTPUT" + echo "Default branch for ${repo} is '${default_branch}'" + + local ref_to_use="" + + # Priority 1: Same branch name + if [ -n "$(git ls-remote --heads "$url" "refs/heads/${BRANCH_NAME}")" ]; then + ref_to_use="${BRANCH_NAME}" + echo "Using matching branch '${BRANCH_NAME}' in ${repo}" + # Priority 2: PR target branch (if this is a PR) + elif [ -n "${BASE_BRANCH}" ] && [ -n "$(git ls-remote --heads "$url" "refs/heads/${BASE_BRANCH}")" ]; then + ref_to_use="${BASE_BRANCH}" + echo "Using PR target branch '${BASE_BRANCH}' in ${repo}" + # Priority 3: Default branch + else + ref_to_use="${default_branch}" + echo "Using default branch '${default_branch}' for ${repo}" + fi + + echo "${prefix}_ref=${ref_to_use}" >> "$GITHUB_OUTPUT" + } + + determine_ref "specs" "specs-feup/specs-java-libs" - name: Echo checks run: | - echo "Branch-specs-java-libs: ${{ steps.Branch-specs-java-libs.outputs.value }}" - echo "Branch name: ${{ env.BRANCH_NAME }}" - echo "Default branch: ${{ env.DEFAULT_BRANCH }}" - echo "Branch base_ref: ${{ github.base_ref }}" + echo "Lara branch: ${{ env.BRANCH_NAME }}" + echo "PR target branch (if any): ${{ github.base_ref }}" + echo "Specs-java-libs ref: ${{ steps.repo-refs.outputs.specs_ref }}" + echo "Specs-java-libs default: ${{ steps.repo-refs.outputs.specs_default }}" - name: Checkout specs-java-libs - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: repository: specs-feup/specs-java-libs path: specs-java-libs - ref: ${{ steps.Branch-specs-java-libs.outputs.value == '1' && env.BRANCH_NAME || env.DEFAULT_BRANCH }} + ref: ${{ steps.repo-refs.outputs.specs_ref }} # Setting up gradle multi-project would be helpful - name: Build and test LanguageSpecification @@ -126,7 +164,6 @@ jobs: strategy: fail-fast: false matrix: - #node-version: ['latest', '22.x', '20.x'] node-version: ['22.x', '20.x'] os: [ubuntu-latest, windows-latest, macos-latest] @@ -146,7 +183,7 @@ jobs: registry-url: 'https://registry.npmjs.org/' - name: Checkout lara-framework - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: path: lara-framework @@ -173,7 +210,7 @@ jobs: # Only on ubuntu-latest - name: Publish JS - if: matrix.os == 'ubuntu-latest' && matrix.node-version == '22.x' + if: github.event_name == 'push' && matrix.os == 'ubuntu-latest' && matrix.node-version == '22.x' run: | cd lara-framework/Lara-JS npm whoami diff --git a/DefaultWeaver/src/org/lara/interpreter/weaver/defaultweaver/DefaultWeaver.java b/DefaultWeaver/src/org/lara/interpreter/weaver/defaultweaver/DefaultWeaver.java index 16d443411..95f646869 100644 --- a/DefaultWeaver/src/org/lara/interpreter/weaver/defaultweaver/DefaultWeaver.java +++ b/DefaultWeaver/src/org/lara/interpreter/weaver/defaultweaver/DefaultWeaver.java @@ -60,7 +60,7 @@ public DefaultWeaver() { public boolean begin(List sources, File output, DataStore args) { this.args = args; - root = new DWorkspace(); + root = new DWorkspace(this); for (File source : sources) { if (source.isDirectory()) { root.addFolder(source); @@ -140,10 +140,6 @@ public String getName() { return "LaraI"; } - public static DefaultWeaver getDefaultWeaver() { - return (DefaultWeaver) getThreadLocalWeaver(); - } - public DataStore getArgs() { return args; } diff --git a/DefaultWeaver/src/org/lara/interpreter/weaver/defaultweaver/joinpoints/DWFile.java b/DefaultWeaver/src/org/lara/interpreter/weaver/defaultweaver/joinpoints/DWFile.java index 25c37b51b..99e37bd98 100644 --- a/DefaultWeaver/src/org/lara/interpreter/weaver/defaultweaver/joinpoints/DWFile.java +++ b/DefaultWeaver/src/org/lara/interpreter/weaver/defaultweaver/joinpoints/DWFile.java @@ -13,13 +13,16 @@ package org.lara.interpreter.weaver.defaultweaver.joinpoints; import java.io.File; + +import org.lara.interpreter.weaver.defaultweaver.DefaultWeaver; import org.lara.interpreter.weaver.defaultweaver.abstracts.joinpoints.AFile; public class DWFile extends AFile { private final File file; - public DWFile(File f) { + public DWFile(File f, DefaultWeaver weaver) { + super(weaver); file = f; } diff --git a/DefaultWeaver/src/org/lara/interpreter/weaver/defaultweaver/joinpoints/DWFolder.java b/DefaultWeaver/src/org/lara/interpreter/weaver/defaultweaver/joinpoints/DWFolder.java index 896a3fdbf..c721e69da 100644 --- a/DefaultWeaver/src/org/lara/interpreter/weaver/defaultweaver/joinpoints/DWFolder.java +++ b/DefaultWeaver/src/org/lara/interpreter/weaver/defaultweaver/joinpoints/DWFolder.java @@ -16,6 +16,7 @@ import java.util.ArrayList; import java.util.List; +import org.lara.interpreter.weaver.defaultweaver.DefaultWeaver; import org.lara.interpreter.weaver.defaultweaver.abstracts.joinpoints.AFolder; public class DWFolder extends AFolder { @@ -24,7 +25,8 @@ public class DWFolder extends AFolder { private final List files; private final String path; - public DWFolder(File source) { + public DWFolder(File source, DefaultWeaver weaver) { + super(weaver); path = source.getAbsolutePath(); files = new ArrayList<>(); createFiles(source); @@ -36,7 +38,7 @@ public void createFiles(File folder) { if (f.isDirectory() && getFilesRecursively) { createFiles(f); } else if (f.getName().endsWith(".c")) { - files.add(new DWFile(f)); + files.add(new DWFile(f, getWeaverEngine())); } } } diff --git a/DefaultWeaver/src/org/lara/interpreter/weaver/defaultweaver/joinpoints/DWFunction.java b/DefaultWeaver/src/org/lara/interpreter/weaver/defaultweaver/joinpoints/DWFunction.java index e4f282d22..c4aa0c76e 100644 --- a/DefaultWeaver/src/org/lara/interpreter/weaver/defaultweaver/joinpoints/DWFunction.java +++ b/DefaultWeaver/src/org/lara/interpreter/weaver/defaultweaver/joinpoints/DWFunction.java @@ -12,6 +12,7 @@ */ package org.lara.interpreter.weaver.defaultweaver.joinpoints; +import org.lara.interpreter.weaver.defaultweaver.DefaultWeaver; import org.lara.interpreter.weaver.defaultweaver.abstracts.joinpoints.AFunction; import org.lara.interpreter.weaver.interf.JoinPoint; @@ -19,7 +20,8 @@ public class DWFunction extends AFunction { private final String name; - public DWFunction(String element) { + public DWFunction(String element, DefaultWeaver weaver) { + super(weaver); name = element; } diff --git a/DefaultWeaver/src/org/lara/interpreter/weaver/defaultweaver/joinpoints/DWorkspace.java b/DefaultWeaver/src/org/lara/interpreter/weaver/defaultweaver/joinpoints/DWorkspace.java index fa70bc460..632c72410 100644 --- a/DefaultWeaver/src/org/lara/interpreter/weaver/defaultweaver/joinpoints/DWorkspace.java +++ b/DefaultWeaver/src/org/lara/interpreter/weaver/defaultweaver/joinpoints/DWorkspace.java @@ -20,6 +20,7 @@ import java.util.HashMap; import java.util.Map; +import org.lara.interpreter.weaver.defaultweaver.DefaultWeaver; import org.lara.interpreter.weaver.defaultweaver.abstracts.joinpoints.AWorkspace; import pt.up.fe.specs.util.SpecsIo; @@ -32,14 +33,15 @@ public class DWorkspace extends AWorkspace { private final Map folders; - public DWorkspace() { + public DWorkspace(DefaultWeaver weaver) { + super(weaver); folders = new HashMap<>(); } public void addFolder(File dir) { File canonicalFile = SpecsIo.getCanonicalFile(dir.getAbsoluteFile()); if (!folders.containsKey(canonicalFile)) { - folders.put(canonicalFile, new DWFolder(canonicalFile)); + folders.put(canonicalFile, new DWFolder(canonicalFile, getWeaverEngine())); } } diff --git a/LARAI/src/org/lara/interpreter/cli/CLIOption.java b/LARAI/src/org/lara/interpreter/cli/CLIOption.java index 20f58f4b2..c40d03a39 100644 --- a/LARAI/src/org/lara/interpreter/cli/CLIOption.java +++ b/LARAI/src/org/lara/interpreter/cli/CLIOption.java @@ -24,7 +24,6 @@ public enum CLIOption implements WeaverOption { help("h", "print this message", LaraiKeys.SHOW_HELP), - version("v", "print version information and exit", null), debug("d", "show all process information", LaraiKeys.DEBUG_MODE), argv("av", OptionArguments.ONE_ARG, "arguments", "arguments for the main aspect. Supports passing a .properties file with the arguments", diff --git a/LARAI/src/org/lara/interpreter/cli/JOptionsInterface.java b/LARAI/src/org/lara/interpreter/cli/JOptionsInterface.java index 92290ce38..59285d2ed 100644 --- a/LARAI/src/org/lara/interpreter/cli/JOptionsInterface.java +++ b/LARAI/src/org/lara/interpreter/cli/JOptionsInterface.java @@ -21,7 +21,6 @@ import pt.up.fe.specs.util.SpecsEnums; import pt.up.fe.specs.util.SpecsLogs; -import java.util.EnumSet; import java.util.HashMap; import java.util.Map; import java.util.Properties; @@ -44,8 +43,6 @@ public class JOptionsInterface { } - private static final EnumSet IGNORE_SET = EnumSet.of(CLIOption.version); - public static DataStore getDataStore(String name, Properties properties) { DataStore data = DataStore.newInstance(name); @@ -59,11 +56,6 @@ public static DataStore getDataStore(String name, Properties properties) { continue; } - // Just ignore - if (JOptionsInterface.IGNORE_SET.contains(option)) { - continue; - } - DataKey datakey = JOptionsInterface.CONVERSION_MAP.get(option); // New key that forgot to be added if (datakey == null) { diff --git a/LARAI/src/org/lara/interpreter/cli/OptionsParser.java b/LARAI/src/org/lara/interpreter/cli/OptionsParser.java index 86d6e948b..0d0d42f6b 100644 --- a/LARAI/src/org/lara/interpreter/cli/OptionsParser.java +++ b/LARAI/src/org/lara/interpreter/cli/OptionsParser.java @@ -40,6 +40,7 @@ import org.suikasoft.jOptions.storedefinition.StoreDefinitionBuilder; import pt.up.fe.specs.util.SpecsIo; +import pt.up.fe.specs.util.lazy.Lazy; /** * @author Tiago @@ -53,7 +54,6 @@ public class OptionsParser { */ public static Collection