All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.prorefactor.macrolevel.MacroRef Maven / Gradle / Ivy

There is a newer version: 2.29.1
Show newest version
/********************************************************************************
 * Copyright (c) 2003-2015 John Green
 * Copyright (c) 2015-2024 Riverside Software
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the Eclipse
 * Public License, v. 2.0 are satisfied: GNU Lesser General Public License v3.0
 * which is available at https://www.gnu.org/licenses/lgpl-3.0.txt
 *
 * SPDX-License-Identifier: EPL-2.0 OR LGPL-3.0
 ********************************************************************************/
package org.prorefactor.macrolevel;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * Abstract class for a macro reference. There are two subclasses:
    *
  • one for references to named macros (i.e. those named with &global, &scoped, or an include argument) *
  • one for references to include files. *
*/ public abstract class MacroRef implements MacroEvent { private final MacroRef parent; private final int refColumn; private final int refLine; private final int refEndLine; private final int refEndColumn; /** A list of macro references and defines that are in this macro's source */ public final List macroEventList = new ArrayList<>(); MacroRef(MacroRef parent, int line, int column, int endLine, int endColumn) { this.parent = parent; this.refLine = line; this.refColumn = column; this.refEndLine = endLine; this.refEndColumn = endColumn; } @Override public MacroRef getParent() { return parent; } public int getLine() { return refLine; } public int getColumn() { return refColumn; } public int getEndLine() { return refEndLine; } public int getEndColumn() { return refEndColumn; } /** * Find external macro references. An external macro is an include file, a &GLOBAL or a &SCOPED from * another file, and include args. * * &UNDEFINE of a &GLOBAL or of a &SCOPED from another file is considered a reference. &UNDEFINE of an * include argument is considered a reference. * * The subroutine is recursive, because a local define may incur an external reference. * * @return An array of objects: MacroRef and MacroDef (for UNDEFINE). */ public List findExternalMacroReferences() { List ret = new ArrayList<>(); for (Iterator it = macroEventList.iterator(); it.hasNext();) { findExternalMacroReferences(it.next(), ret); } return ret; } /** * @see #findExternalMacroReferences() * @param begin An array of two integers to indicate the beginning line/column. May be null to indicate the beginning * of the range is open ended. * @param end An array of two integers to indicate the ending line/column. May be null to indicate the ending of the * range is open ended. */ public List findExternalMacroReferences(int[] begin, int[] end) { List ret = new ArrayList<>(); for (Iterator it = macroEventList.iterator(); it.hasNext();) { MacroEvent next = it.next(); MacroPosition pos = next.getPosition(); if (isInRange(pos.getLine(), pos.getColumn(), begin, end)) { findExternalMacroReferences(next, ret); } } return ret; } private void findExternalMacroReferences(MacroEvent obj, List list) { if (obj == null) return; if (obj instanceof IncludeRef) { list.add(obj); return; } if (obj instanceof MacroDef) { MacroDef def = (MacroDef) obj; if (def.getType() == MacroDefinitionType.UNDEFINE) { if (def.getUndefWhat().getType() == MacroDefinitionType.NAMEDARG) { list.add(def); return; } if (!isMine(def.getUndefWhat().getParent())) list.add(def); } return; } // Only one last type we're interested in... if (!(obj instanceof NamedMacroRef)) return; NamedMacroRef ref = (NamedMacroRef) obj; if (!isMine(ref)) { list.add(ref); return; } // It's possible for an internal macro to refer to an external macro for (Iterator it = ref.macroEventList.iterator(); it.hasNext();) { findExternalMacroReferences(it.next(), list); } } /** * Find references to an include file by the include file's file index number. Search is recursive, beginning at this * MacroRef object. * * @param fileIndex The fileIndex for the include file we want references to. * @return An array of IncludeRef objects. */ public List findIncludeReferences(int fileIndex) { List ret = new ArrayList<>(); findIncludeReferences(fileIndex, this, ret); return ret; } private void findIncludeReferences(int fileIndex, MacroRef ref, List list) { if (ref == null) return; if (ref instanceof IncludeRef) { IncludeRef incl = (IncludeRef) ref; if (incl.getFileIndex() == fileIndex) list.add(incl); } for (Iterator it = ref.macroEventList.iterator(); it.hasNext();) { MacroEvent next = it.next(); if (next instanceof MacroRef) findIncludeReferences(fileIndex, (MacroRef) next, list); } } public abstract int getFileIndex(); @Override public MacroPosition getPosition() { return new MacroPosition(parent == null ? 0 : parent.getFileIndex(), refLine, refColumn); } /** * Check if line/column are within this macro reference */ public boolean contains(int x, int y) { if ((x < refLine) || ((x == refLine) && (y < refColumn))) { return false; } if ((x > refEndLine) || ((x == refEndLine) && (y > refEndColumn))) { return false; } return true; } /** * Assuming an x,y range, this function returns whether an input x and y are within the specified range of x,y begin * and x,y end. We use this primarily for checking if a line/column are within the specified range. The "range" may be * open ended, see parameter descriptions. * * @param x The x value to check that it is within range * @param y The y value to check that it is within range * @param begin An array of 2 integers to specify the beginning of the x,y range. May be null to indicate that the * beginning is open ended. * @param end An array of 2 integers to specify the ending of the x,y range. May be null to indicate that the * beginning is open ended. * @return */ public static boolean isInRange(int x, int y, int[] begin, int[] end) { if ((begin != null) && ((x < begin[0]) || ((x == begin[0]) && (y < begin[1])))) { return false; } if ((end != null) && ((x > end[0]) || ((x == end[0]) && (y > end[1])))) { return false; } return true; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy