diff --git a/buildapp.xml b/buildapp.xml index 261341d9..3a52f544 100644 --- a/buildapp.xml +++ b/buildapp.xml @@ -15,8 +15,8 @@ name="Structorizer" displayname="Structorizer" identifier="lu.fisch.Structorizer" - shortversion="3.32-16" - version="3.32-16" + shortversion="3.32-17" + version="3.32-17" icon="icons/Structorizer.icns" mainclassname="Structorizer" copyright="Bob Fisch" diff --git a/src/lu/fisch/structorizer/elements/Element.java b/src/lu/fisch/structorizer/elements/Element.java index ca4988cc..ca2b5fe0 100644 --- a/src/lu/fisch/structorizer/elements/Element.java +++ b/src/lu/fisch/structorizer/elements/Element.java @@ -135,6 +135,8 @@ * Kay Gürtzig 2022-08-22 Bugfix #1068: Type inference failure for array initialisers mended * Kay Gürtzig 2023-12-14 Issue #1119: To set an empty string as text now leads to an empty StringList * Kay Gürtzig 2024-01-22 Bugfix #1125: Equality check must consider disabled state + * Kay Gürtzig 2024-03-07 Bugfix #1128 Risk of endless loop in method retrieveComponentNmes() fixed; + * Issue #1129: Limitation of error lines in the Analyser warning popup * ****************************************************************************************************** * @@ -306,7 +308,7 @@ public String toString() public static final long E_HELP_FILE_SIZE = 12300000; public static final String E_DOWNLOAD_PAGE = "https://www.fisch.lu/Php/download.php"; // END KGU#791 2020-01-20 - public static final String E_VERSION = "3.32-16"; + public static final String E_VERSION = "3.32-17"; public static final String E_THANKS = "Developed and maintained by\n"+ " - Robert Fisch \n"+ @@ -352,7 +354,7 @@ public String toString() " - DE: Klaus-Peter Reimers \n"+ " - LU: Laurent Zender \n"+ " - ES: Andres Cabrera \n"+ - " - PT/BR: Theldo Cruz \n"+ + " - PT/BR: Theldo Cruz Franqueiro \n"+ " - IT: Andrea Maiani , A. Simonetta (University of Rome Tor Vergata)\n"+ " - ZH-CN: Wang Lei \n"+ " - ZH-TW: Joe Chem \n"+ @@ -478,6 +480,9 @@ public static int getPadding() { /** Shall warning markers be drawn in flawed elements? */ public static boolean E_ANALYSER_MARKER = true; // END KGU#906 2021-01-02 + // START KGU#1116 2024-03-07: Issue #1129 + public static int E_ANALYSER_MAX_POPUP_LINES = 10; + // END KGU#1116 2024-03-07 // START KGU#123 2016-01-04: New toggle for Enh. #87 /** Is collapsing by mouse wheel rotation enabled? */ public static boolean E_WHEELCOLLAPSE = false; @@ -3853,6 +3858,11 @@ else if (prevToken.equals("[")) { path.remove(0); } } + // START KGU#1115 2024-03-07: Bugfix #1128: We must not get trapped in the loop + else { + varType = null; + } + // END KGU#1115 2024-03-07 } if (varType != null && varType.isRecord()) { // path must now be exhausted, the component names are our proposals diff --git a/src/lu/fisch/structorizer/elements/Root.java b/src/lu/fisch/structorizer/elements/Root.java index dbf14ef5..67d355a3 100644 --- a/src/lu/fisch/structorizer/elements/Root.java +++ b/src/lu/fisch/structorizer/elements/Root.java @@ -4237,7 +4237,9 @@ private boolean mayBeJavaMethod(String _var, StringList _tokens) { } } } catch (ClassNotFoundException exc) { - System.err.println(exc); + // START KGU#1115 2024-03-07: Issue #1128 Nobody wants to see this except on debugging + //System.err.println(exc); + // END KGU#1115 2024-03-07 } } } @@ -4264,7 +4266,7 @@ private void analyse_5_7_13(Element ele, Vector _errors, StringLi _myVars.addIfNew(((Try)ele).getExceptionVarName()); } // END KGU#812 2020-02-21 - for (int j=0; j<_myVars.count(); j++) + for (int j = 0; j < _myVars.count(); j++) { String myVar = _myVars.get(j); // START KGU#343 2017-02-07: Ignore pseudo-variables (markers) @@ -4274,9 +4276,9 @@ private void analyse_5_7_13(Element ele, Vector _errors, StringLi // END KGU#343 2017-02-07 // CHECK: non-uppercase var (#5) - if(!myVar.toUpperCase().equals(myVar) && !rootVars.contains(myVar)) + if (!myVar.toUpperCase().equals(myVar) && !rootVars.contains(myVar)) { - if(!((myVar.toLowerCase().equals("result") && this.isSubroutine()))) + if (!((myVar.toLowerCase().equals("result") && this.isSubroutine()))) { //error = new DetectedError("The variable «"+myVars.get(j)+"» must be written in uppercase!",(Element) _node.getElement(i)); addError(_errors, new DetectedError(errorMsg(Menu.error05, myVar), ele), 5); diff --git a/src/lu/fisch/structorizer/gui/Diagram.java b/src/lu/fisch/structorizer/gui/Diagram.java index 8398f1cb..ba7fa515 100644 --- a/src/lu/fisch/structorizer/gui/Diagram.java +++ b/src/lu/fisch/structorizer/gui/Diagram.java @@ -243,6 +243,7 @@ * Kay Gürtzig 2023-09-12 Bugfix #1086: Defective arrangement on source import with two routines * Kay Gürtzig 2023-11-09 Enh. #1114: Place the InputBox caret at the first question mark in * the default text for new Elements + * Kay Gürtzig 2024-03-07 Issue #1129: Restrict the number of lines to show in a warning popup * ****************************************************************************************************** * @@ -1115,7 +1116,10 @@ public void mouseMoved(MouseEvent e) { String text = ""; for (Entry> entry: errorMap.entrySet()) { Element errEle = entry.getKey(); - if (errorMap.size() > 1 || errEle != selEle) { + // START KGU#1116 2024-03-07: Issue #1129: Restrict the popup lines + //if (errorMap.size() > 1 || errEle != selEle) { + if ((errorMap.size() > 1 || errEle != selEle) && lines < Element.E_ANALYSER_MAX_POPUP_LINES) { + // END KGU#1116 2024-03-07 // This is a collapsed element, i.e., potentially represents several elements text = ElementNames.getElementName(errEle, false, null); StringList elText = errEle.getText(); @@ -1133,19 +1137,31 @@ public void mouseMoved(MouseEvent e) { lines++; } for (DetectedError err: entry.getValue()) { - text = err.getMessage(); - if (err.isWarning()) { - sb.append(""); - } - else { - sb.append(""); + // START KGU#1116 2024-03-07: Issue #1129: Restrict the popup lines + if (lines < Element.E_ANALYSER_MAX_POPUP_LINES) { + // END KGU#1116 2024-03-07 + text = err.getMessage(); + if (err.isWarning()) { + sb.append(""); + } + else { + sb.append(""); + } + sb.append(BString.encodeToHtml(text)); + sb.append("
"); + width = Math.max(width, fm.stringWidth(text)); + // START KGU#1116 2024-03-07: Issue #1129: Restrict the popup lines } - sb.append(BString.encodeToHtml(text)); - sb.append("

"); - width = Math.max(width, fm.stringWidth(text)); + // END KGU#1116 2024-03-07 lines++; } } + // START KGU#1116 2024-03-07: Issue #1129: Restrict the popup lines + if (lines > Element.E_ANALYSER_MAX_POPUP_LINES) { + sb.append("... (+ " + (lines - Element.E_ANALYSER_MAX_POPUP_LINES) + ")
"); + lines = Element.E_ANALYSER_MAX_POPUP_LINES + 1; + } + // END KGU#1116 2024-03-07 sb.append(""); lblPop.setText(sb.toString()); lblPop.setPreferredSize( diff --git a/src/lu/fisch/structorizer/gui/changelog.txt b/src/lu/fisch/structorizer/gui/changelog.txt index 16cbcf90..da90ac2f 100644 --- a/src/lu/fisch/structorizer/gui/changelog.txt +++ b/src/lu/fisch/structorizer/gui/changelog.txt @@ -23,7 +23,7 @@ Known issues (also see https://github.com/fesch/Structorizer.Desktop/issues): - ARM export is still experimental and relies on a specific and very restricted syntax for the element contents in order to produce meaningful results. -Current development version 3.32-16 (2024-02-28) +Current development version 3.32-17 (2024-03-10) - 01: Bugfix #987: Duplicate subroutine comment export by Pascal generator <2> - 01: Bugfix #988: Syntax error in Structorizer.bat and Arranger.bat fixed <2> - 01: Bugfix #989: Expressions in EXIT elements (e.g. return) were forgotten @@ -191,9 +191,16 @@ Current development version 3.32-16 (2024-02-28) - 16: Bugfix #1122 Defective export of INPUT instructions to Javascript <2> - 16: Issue #1123 Proper export of random(...) to C, C++, C#, Java, Js <2> - 16: Issue #1125 Diagram comparison didn't distinguish disabled state <2> -- 16: Bugfix #1126: Spanish and Italian messages for View menu were missing, +- 16: Bugfix #1126 Spanish and Italian messages for View menu were missing, the attempt to open Translator led to an error abort. <2> - 16: Completion and corrections of the Portuguese/Brazilian locale +- 17: Menu mnemonics for the PT_BR locale rectified +- 17: Bugfix #1128 Risk of getting stuck on record component retrieval (in + Analyser or Input assist) eliminated [K.-P. Reimers]<2> +- 17: Issue #1129 Analyser popup didn't open with too many error entries <2> +- 17: Bugfix #1130 C import expanded macros within char literals [csrabak]2 +- 17: Issue #1131 Handling of anonymous inner classes on Java import <2> +- 17: Bugfix #1132 Java import defect on backslashes in string literals <2> Version 3.32 (2021-09-19) requiring Java 11 or newer - 01: Bugfix #851/2: SPECIAL-NAMES sections caused COBOL parser abort <2> diff --git a/src/lu/fisch/structorizer/gui/parsers.xml b/src/lu/fisch/structorizer/gui/parsers.xml index aca3e355..625fdf36 100644 --- a/src/lu/fisch/structorizer/gui/parsers.xml +++ b/src/lu/fisch/structorizer/gui/parsers.xml @@ -22,10 +22,12 @@ - diff --git a/src/lu/fisch/structorizer/locales/de.txt b/src/lu/fisch/structorizer/locales/de.txt index d3fa8065..bfb4c194 100644 --- a/src/lu/fisch/structorizer/locales/de.txt +++ b/src/lu/fisch/structorizer/locales/de.txt @@ -142,6 +142,8 @@ * Kay Gürtzig 2023-10-06 Issue #311: Menu reorganisation (menuDiagram split) * Kay Gürtzig 2023-10-13 Issues #980,#1096: New messages for declaration syntax check (error31_*) * Kay Gürtzig 2023-11-13 Enh. #1115: New messages for C99 import option definesToConstants + * Kay Gürtzig 2024-03-04 Mnemonic changed on Find&Replace, PluginOptionDialog message added + * Kay Gürtzig 2024-03-09 Issue #1117: Messages for new PuginOptionDialog option dissect_anon_inner_class * ****************************************************************************************************** * @@ -1206,6 +1208,8 @@ PluginOptionDialog.btnOk.text=OK PluginOptionDialog.btnCancel.text=Abbrechen PluginOptionDialog.optionComponents.convert_syntax.text=Deklarationen/Ausdrücke usw. in Pascal-ähnlichen Stil wandeln PluginOptionDialog.optionComponents.convert_syntax.tooltip=Diese Einstellung vergrößert die Chancen der Ausführbarkeit oder des Re-Exports in Structorizer +PluginOptionDialog.optionComponents.dissect_anon_inner_class.text=Anonyme innere Klassen in Diagramme zerlegen +PluginOptionDialog.optionComponents.dissect_anon_inner_class.tooltip=Anderenfalls würde die en passant definierte innere Klasse einfach als sehr langer Quellcode-Ausdruck in das instanziierende Element durchgereicht. PluginOptionDialog.optionComponents.debugLines.text[getPluginKey():COBOLParser]=Debug-Zeilen als aktiven Code importieren PluginOptionDialog.optionComponents.debugLines.tooltip[getPluginKey():COBOLParser]=Falls aktiviert, werden Debug-Zeilen ggf. als gültiger Code importiert, anderenfalls in Kommentarzeilen "DEBUG ..." umgewandelt. PluginOptionDialog.optionComponents.decimalComma.text[getPluginKey():COBOLParser]=Dezimalkomma (statt Dezimalpunkt) im Quelltext @@ -1242,6 +1246,8 @@ PluginOptionDialog.optionComponents.alignArrays.text=Speicherausrichtung für Da PluginOptionDialog.optionComponents.alignArrays.tooltip=Fügt passende .align-Direktiven vor Daten-Deklarationen und am Anfang des Text-Bereichs ein (nur im GNU-Modus). PluginOptionDialog.optionComponents.terminateStrings.text=Zeichenketten mit Abschlusszeichen versehen PluginOptionDialog.optionComponents.terminateStrings.tooltip=Normalerweise werden Zeichenketten einfach als Array ihrer enthaltenen Zeichencodes generiert. Diese Option sorgt für das Anhängen eines NUL-Zeichens (wie in C). +PluginOptionDialog.optionComponents.restrictedSyntax.text=Auf Elementinhalte auf ARM-Niveau beschränken. +PluginOptionDialog.optionComponents.restrictedSyntax.tooltip=Keine erweiterten Compilerfähigkeiten anwenden, sondern Inhalte zurückweisen, die das Niveau von ARM-Befehlen übersteigen. -----[ ElementNamePreferences ]----- ElementNamePreferences.title=Elementnamen einstellen @@ -1301,7 +1307,7 @@ FindAndReplace.chkCaseSensitive.mnemonic=g FindAndReplace.chkWholeWord.text=Ganzes Wort FindAndReplace.chkWholeWord.mnemonic=w FindAndReplace.chkRegEx.text=Reguläre Ausdrücke -FindAndReplace.chkRegEx.mnemonic=x +FindAndReplace.chkRegEx.mnemonic=k FindAndReplace.rbDown.text=Abwärts FindAndReplace.rbDown.mnemonic=b FindAndReplace.rbUp.text=Aufwärts @@ -1519,7 +1525,7 @@ ArrangerIndex.msgConfirmDissolve.text=Sicher, diese Gruppe(n) aufzulösen?\n% -----> Executor -----[ Control ]----- Control.title=Diagramm-Test -Control.lblSpeed.text=Verzögerung: +Control.lblSpeed.text= Verzögerung: Control.btnCallStack.text=Aufrufstapel Control.lblCallLevel.text=Aufruftiefe: Control.chkCollectRuntimeData.text=Sammle Laufzeitdaten diff --git a/src/lu/fisch/structorizer/locales/en.txt b/src/lu/fisch/structorizer/locales/en.txt index 315bbead..eb511ca5 100644 --- a/src/lu/fisch/structorizer/locales/en.txt +++ b/src/lu/fisch/structorizer/locales/en.txt @@ -135,7 +135,8 @@ * Kay Gürtzig 2022-09-29 Bugfix #1072: New message InputBoxFor.msgIllegalWordInField added * Kay Gürtzig 2023-08-01 Enh. #1082: Function name now included in messages Menu.error13_* * Kay Gürtzig 2023-10-06 Issue #311: Menu reorganisation (menuDiagram split) - * Kay Gürtzig 2023-10-16 Issue #980/#1096: New messages for declaration syntax check (error31_*) + * Kay Gürtzig 2023-10-16 Issue #980/#1096: New messages for declaration syntax check (error31_*) + * Kay Gürtzig 2024-03-09 Issue #1117: Messages for new PuginOptionDialog option dissect_anon_inner_class * ****************************************************************************************************** * @@ -1202,6 +1203,8 @@ PluginOptionDialog.btnOk.text=OK PluginOptionDialog.btnCancel.text=Cancel PluginOptionDialog.optionComponents.convert_syntax.text= PluginOptionDialog.optionComponents.convert_syntax.tooltip= +PluginOptionDialog.optionComponents.dissect_anon_inner_class.text= +PluginOptionDialog.optionComponents.dissect_anon_inner_class.tooltip= PluginOptionDialog.optionComponents.debugLines.text[getPluginKey():COBOLParser]= PluginOptionDialog.optionComponents.debugLines.tooltip[getPluginKey():COBOLParser]= PluginOptionDialog.optionComponents.decimalComma.text[getPluginKey():COBOLParser]= @@ -1238,6 +1241,8 @@ PluginOptionDialog.optionComponents.alignArrays.text=Guarantee memory alignment PluginOptionDialog.optionComponents.alignArrays.tooltip=Inserts .align directives before any data allocation and at the beginning of the text area (GNU mode only). PluginOptionDialog.optionComponents.terminateStrings.text=Store strings with 0-termination PluginOptionDialog.optionComponents.terminateStrings.tooltip=Normally strings will be stored as arrays of only the contained characters. This option will add a terminating NUL character +PluginOptionDialog.optionComponents.restrictedSyntax.text=Restrict to Element content on ARM level +PluginOptionDialog.optionComponents.restrictedSyntax.tooltip=Don't make use of extended compiling capabilities, reject all content that exceeds ARM level. -----[ ElementNamePreferences ]----- ElementNamePreferences.title=Element Name Preferences diff --git a/src/lu/fisch/structorizer/locales/es.txt b/src/lu/fisch/structorizer/locales/es.txt index 329c4fd6..000676dc 100644 --- a/src/lu/fisch/structorizer/locales/es.txt +++ b/src/lu/fisch/structorizer/locales/es.txt @@ -142,6 +142,8 @@ * Kay Gürtzig 2023-10-13 Issue #980: New messages for declaration syntax check (error31_*) * Kay Gürtzig 2023-11-13 Enh. #1115: New messages for C99 import option definesToConstants * Kay Gürtzig 2024-01-26 Issue #311/bugfix #1126: Menu reorganisation (menuDiagram split) + * Kay Gürtzig 2024-03-04 Mnemonics for Find&Replace dialog specified. + * Kay Gürtzig 2024-03-09 Issue #1117: Messages for new PuginOptionDialog option dissect_anon_inner_class * ****************************************************************************************************** * @@ -863,7 +865,7 @@ InputBoxCase.lblDiscriminator.text=Expresión de selección InputBoxCase.lblSelectors.text=Constantes de selección InputBoxCase.btnAddRow.tooltip=Añadir nuevo renglón (y dejar rellenarlo con constantes selectores, separadas por comas) InputBoxCase.btnDelRows.tooltip=Quitar los renglones seleccionados -InputBoxCase.btnUpRow.tooltip=Mover las líneas arriva por un renglón +InputBoxCase.btnUpRow.tooltip=Mover las líneas arriba por un renglón InputBoxCase.btnDnRow.tooltip=Mover las líneas abajo por un renglón InputBoxCase.btnMergeRows.tooltip=Unir renglones seleccionados (no ofrecido con diferentes brazos asociados) InputBoxCase.btnSplitRow.tooltip=Dividir el renglón seleccionado @@ -1208,6 +1210,8 @@ PluginOptionDialog.btnOk.text=Aceptar PluginOptionDialog.btnCancel.text=Cancelar PluginOptionDialog.optionComponents.convert_syntax.text=Convertir declaraciones/expresiones a un estilo como Pascal PluginOptionDialog.optionComponents.convert_syntax.tooltip=Esta opción aumenta la probabilidad de poder ejecutar o re-exportar el resultado en Structorizer +PluginOptionDialog.optionComponents.dissect_anon_inner_class.text=Desglosar clases anónimas interiores a diagramas +PluginOptionDialog.optionComponents.dissect_anon_inner_class.tooltip=De otro modo, una clase anónima definida en pasada simplemente sería puesto como una larga expresión de código fuente al elemento que contiene su instanciación. PluginOptionDialog.optionComponents.debugLines.text[getPluginKey():COBOLParser]=Importar líneas debug como código válido PluginOptionDialog.optionComponents.debugLines.tooltip[getPluginKey():COBOLParser]=Si es activada, líneas debug serán importadas como código válido, de otro modo serían convertidas en comentarios "DEBUG ...". PluginOptionDialog.optionComponents.decimalComma.text[getPluginKey():COBOLParser]=Coma decimal (en lugar de punto decimal) en el código @@ -1244,6 +1248,8 @@ PluginOptionDialog.optionComponents.alignArrays.text=Ajustar direcciones de dato PluginOptionDialog.optionComponents.alignArrays.tooltip=Inserta directivas .align ante cada asignación de datos y antes del inicio de la región de código (para modo GNU). PluginOptionDialog.optionComponents.terminateStrings.text=Terminar cadenas con signo NUL (0) PluginOptionDialog.optionComponents.terminateStrings.tooltip=Normálmente una cadena estará generado como un campo de sólamente sus caracteres miembros. Esta opción va a apender un signo NUL (código 0) como en C. +PluginOptionDialog.optionComponents.restrictedSyntax.text=Limitar exporte a contenido en nivel ARM +PluginOptionDialog.optionComponents.restrictedSyntax.tooltip=No emplear capabilidades extendidas de compilación, rechazar contenido que excede el nivel ARM. -----[ ElementNamePreferences ]----- ElementNamePreferences.title=Preferidos nombres de elementos @@ -1299,15 +1305,15 @@ FindAndReplace.lblSearchPattern.text=Buscar: FindAndReplace.lblReplacePattern.text=Sustituir por: FindAndReplace.pnlMode.border=Modo FindAndReplace.chkCaseSensitive.text=Cuidar may./minúscula -FindAndReplace.chkCaseSensitive.mnemonic= +FindAndReplace.chkCaseSensitive.mnemonic=c FindAndReplace.chkWholeWord.text=Palabra entera -FindAndReplace.chkWholeWord.mnemonic= +FindAndReplace.chkWholeWord.mnemonic=l FindAndReplace.chkRegEx.text=Expresiones regulares -FindAndReplace.chkRegEx.mnemonic= +FindAndReplace.chkRegEx.mnemonic=x FindAndReplace.rbDown.text=Abajo -FindAndReplace.rbDown.mnemonic= -FindAndReplace.rbUp.text=Arriva -FindAndReplace.rbUp.mnemonic= +FindAndReplace.rbDown.mnemonic=j +FindAndReplace.rbUp.text=Arriba +FindAndReplace.rbUp.mnemonic=a FindAndReplace.pnlScope.border=Alcance FindAndReplace.cmbScope.item.0=Selección actual FindAndReplace.cmbScope.item.1=Diagrama actual @@ -1521,7 +1527,7 @@ ArrangerIndex.msgConfirmDissolve.text=Cierto a descomponer este grupo/estos grup -----> Executor -----[ Control ]----- Control.title=Control de Ejecución -Control.lblSpeed.text=Demora: +Control.lblSpeed.text= Demora: Control.btnCallStack.text=Lote de llamadas Control.lblCallLevel.text=Nivel: Control.chkCollectRuntimeData.text=Contar pasos de ejec. diff --git a/src/lu/fisch/structorizer/locales/fr.txt b/src/lu/fisch/structorizer/locales/fr.txt index e27529f4..c3fce50e 100644 --- a/src/lu/fisch/structorizer/locales/fr.txt +++ b/src/lu/fisch/structorizer/locales/fr.txt @@ -1438,7 +1438,7 @@ ArrangerIndex.msgConfirmDissolve.text=Êtes-vous sûr de dissoudre ce(s) groupe( -----> Executor -----[ Control ]----- Control.title= -Control.lblSpeed.text= +Control.lblSpeed.text= Décélération: Control.btnCallStack.text= Control.lblCallLevel.text= Control.chkCollectRuntimeData.text= diff --git a/src/lu/fisch/structorizer/locales/it.txt b/src/lu/fisch/structorizer/locales/it.txt index 48bddf51..c2706cd2 100644 --- a/src/lu/fisch/structorizer/locales/it.txt +++ b/src/lu/fisch/structorizer/locales/it.txt @@ -1416,7 +1416,7 @@ ArrangerIndex.msgConfirmDissolve.text= -----> Executor -----[ Control ]----- Control.title=Controllo Esecuzione -Control.lblSpeed.text=Ritardo: +Control.lblSpeed.text= Ritardo: Control.btnCallStack.text= Control.lblCallLevel.text= Control.chkCollectRuntimeData.text=Registra dati di esecuzione diff --git a/src/lu/fisch/structorizer/locales/nl.txt b/src/lu/fisch/structorizer/locales/nl.txt index d34b0247..94aac5dd 100644 --- a/src/lu/fisch/structorizer/locales/nl.txt +++ b/src/lu/fisch/structorizer/locales/nl.txt @@ -1389,7 +1389,7 @@ ArrangerIndex.msgConfirmDissolve.text=Wilt u echt deze groepen ontbinden?\n% -----> Executor -----[ Control ]----- Control.title=Besturing van uitvoereen -Control.lblSpeed.text=Vertraging: +Control.lblSpeed.text= Vertraging: Control.btnCallStack.text=Stack oproepen Control.lblCallLevel.text=Oproepdiepte: Control.chkCollectRuntimeData.text=Runtime-gegevens verzamelen diff --git a/src/lu/fisch/structorizer/locales/pt_br.txt b/src/lu/fisch/structorizer/locales/pt_br.txt index 51e8fe1c..70da0bd0 100644 --- a/src/lu/fisch/structorizer/locales/pt_br.txt +++ b/src/lu/fisch/structorizer/locales/pt_br.txt @@ -38,7 +38,7 @@ /****************************************************************************************************** * - * Author: PUC-Minas, MG - Brasil + * Author: PUC-Minas, MG - Brasil (Theldo Cruz Franqueiro) * * Description: The Brazilian Portuguese (PT-BR) language file * @@ -46,24 +46,28 @@ * * Revision List * - * Author Date Description - * ------ ---- ----------- - * PUC-Minas 2009-08-20 First Issue - * PUC-Minas 2009-10-20 Revised - * PUC-Minas 2016-07-30 Revised - * Kay Gürtzig 2016-09-04 Menu.menuPreferencesLanguage... key structure modified - * Kay Gürtzig 2016-09-13 Entries for InputBox and InputBoxFor revised (bugfix #241) - * Kay Gürtzig 2016-09-22 AnalyserPreferences numbering modified - * Kay Gürtzig 2016-10-11 Enh. 267: Menu.error15 renamed into Menu.error15_1 - * Kay Gürtzig 2016-12-14 Enh. #311: New menu "Debug" - * Kay Gürtzig 2017-04-05 Additions for enh. #388 and #390 (constant definition checks) - * Kay Gürtzig 2018-07-02 KGU#245: all Colors stuff replaced with array keys - * Kay Gürtzig 2018-12-30 Enh. #492: Element name place holders introduced - * Kay Gürtzig 2022-08-10 Enh. #56, #492: Messages / tooltips for TRY elements added - * Kay Gürtzig 2023-08-01 Enh. #1082: Function name included in messages Menu.error13_* - * Kay Gürtzig 2023-10-06 Issue #311: Menu reorganisation (menuDiagram split) - * Kay Gürtzig 2023-10-13 Issue #980: New messages for declaration syntax check (error31_*) - * Theldo Cruz Franqueira 2023-12-31 Completion and correction of the message set * + * Author Date Description + * ------ ---- ----------- + * PUC-Minas 2009-08-20 First Issue + * PUC-Minas 2009-10-20 Revised + * PUC-Minas 2016-07-30 Revised + * Kay Gürtzig 2016-09-04 Menu.menuPreferencesLanguage... key structure modified + * Kay Gürtzig 2016-09-13 Entries for InputBox and InputBoxFor revised (bugfix #241) + * Kay Gürtzig 2016-09-22 AnalyserPreferences numbering modified + * Kay Gürtzig 2016-10-11 Enh. 267: Menu.error15 renamed into Menu.error15_1 + * Kay Gürtzig 2016-12-14 Enh. #311: New menu "Debug" + * Kay Gürtzig 2017-04-05 Additions for enh. #388 and #390 (constant definition checks) + * Kay Gürtzig 2018-07-02 KGU#245: all Colors stuff replaced with array keys + * Kay Gürtzig 2018-12-30 Enh. #492: Element name place holders introduced + * Kay Gürtzig 2022-08-10 Enh. #56, #492: Messages / tooltips for TRY elements added + * Kay Gürtzig 2023-08-01 Enh. #1082: Function name included in messages Menu.error13_* + * Kay Gürtzig 2023-10-06 Issue #311: Menu reorganisation (menuDiagram split) + * Kay Gürtzig 2023-10-13 Issue #980: New messages for declaration syntax check (error31_*) + * PUC-Minas 2023-12-31 Completion and correction of the message set + * Kay Gürtzig 2024-02-28 Control.lblCallLevel.text and Control.chkCollectRuntimeData.text shortened + * Kay Gürtzig 2024-03-04 Mnemonics adapted, some PluginOptionDialog messages added. + * PUC-Minas 2024-03-09 Issue #1131: Messages for new Java import option provided + * ****************************************************************************************************** * * Comment: @@ -106,7 +110,7 @@ -----[ Menu ]----- // Menu "File" Menu.menuFile.text=Arquivo -Menu.menuFile.mnemonic=f +Menu.menuFile.mnemonic=q // Submenus of "File" Menu.menuFileNew.text=Novo Menu.menuFileOpen.text=Abrir ... @@ -155,6 +159,7 @@ Menu.menuEditBreakLines.text=(Re-)fazer quebras de linhas de texto ... Menu.menuEditBreakLines.tooltip=Permitir o ajuste de quebras de linhas de texto de elementos selecionados (e opcionalmente sua subestrutura) para um novo limite de comprimento de linha. Menu.menuEditCopyDiagramPNG.text=Copiar imagem PNG Menu.menuEditCopyDiagramEMF.text=Copiar imagem EMF + // Menu "Diagram" Menu.menuDiagram.text=Diagrama Menu.menuDiagram.mnemonic=d @@ -283,7 +288,7 @@ Menu.menuDebugDisable.text=Desativar/ativar // Menu "Help" Menu.menuHelp.text=Ajuda -Menu.menuHelp.mnemonic=h +Menu.menuHelp.mnemonic=j // Submenu of "Help" Menu.menuHelpOnline.text=Guia do Usuário Menu.menuHelpOnline.tooltip=Abrir Guia do Usuário online no navegador @@ -730,7 +735,7 @@ InputBoxFor.rbTraversing.tooltip=Selecionar esta opção se desejar percorrer to InputBoxFor.lblVariable.text=Variável de contagem InputBoxFor.lblStartVal.text=Valor inicial InputBoxFor.lblEndVal.text=Valor final -InputBoxFor.lblIncr.text=Incremento +InputBoxFor.lblIncr.text=Variação InputBoxFor.lblTraversingVariable.text=Variável de elemento InputBoxFor.lblValueList.text=Lista de valores, array ou cadeia de caracteres InputBoxFor.chkTextInput.text=Entrada de texto direta @@ -876,7 +881,7 @@ AttributeInspector.msgLicenseLoadError.text=Erro ao carregar o texto da licença -----[ License Editor ]----- LicenseEditor.titleString.text=Editor de licença do Structorizer: % LicenseEditor.menuFile.text=Arquivo -LicenseEditor.menuFile.mnemonic=f +LicenseEditor.menuFile.mnemonic=q LicenseEditor.menuEdit.text=Editar LicenseEditor.menuEdit.mnemonic=e LicenseEditor.menuProp.text=Propriedades @@ -921,7 +926,7 @@ Preferences.lblCaseRot.text=Mínimo de desvios para rotação Preferences.lblCaseRot.tooltip=Limite de contagem de desvios para tentativas de reduzir a largura rotacioando elementos (0 = desligado) Preferences.chkCaseEditor.text=Usar editor dedicado para @c Preferences.pnlRoot.border=Cabeçalho @m -Preferences.lblRoot.text=Incluir legenda da lista +Preferences.lblRoot.text=Legenda da lista de Inclusões Preferences.lblRoot.tooltip=A legenda para a lista de diagramas @p ao ser desenhada. Preferences.pnlFor.border=Repetição @d loop Preferences.pnlFor.tooltip= @@ -1127,8 +1132,10 @@ PluginOptionDialog.msgNoValidDouble.text=Valor para '%' tem de ser um número PluginOptionDialog.msgVerificationError.text=Verificação de entrada falhou PluginOptionDialog.btnOk.text=OK PluginOptionDialog.btnCancel.text=Cancelar -PluginOptionDialog.optionComponents.convert_syntax.text= -PluginOptionDialog.optionComponents.convert_syntax.tooltip= +PluginOptionDialog.optionComponents.convert_syntax.text=Converter declarações/expreções a um estilo como Pascal +PluginOptionDialog.optionComponents.convert_syntax.tooltip=Esta opção aumenta la probabilidade de poder executar ou re-exportar o resultado em Structorizer. +PluginOptionDialog.optionComponents.dissect_anon_inner_class.text=Discriminar classes anônimas interiores a diagramas +PluginOptionDialog.optionComponents.dissect_anon_inner_class.tooltip=De outro modo, uma classe anônima definida instantaneamente será passada como uma extensa expressão em código fonte ao elemento instanciador. PluginOptionDialog.optionComponents.debugLines.text[getPluginKey():COBOLParser]= PluginOptionDialog.optionComponents.debugLines.tooltip[getPluginKey():COBOLParser]= PluginOptionDialog.optionComponents.decimalComma.text[getPluginKey():COBOLParser]= @@ -1141,13 +1148,13 @@ PluginOptionDialog.optionLabels.fixedColumnText.text[getPluginKey():COBOLParser] PluginOptionDialog.optionComponents.fixedColumnText.tooltip[getPluginKey():COBOLParser]= PluginOptionDialog.optionLabels.tidyupPerformThru.text[getPluginKey():COBOLParser]= PluginOptionDialog.optionComponents.tidyupPerformThru.tooltip[getPluginKey():COBOLParser]=adas encadeadas resultantes de PERFORM THRU geralmente serão separadas, tomadas como chamadas dispensáveis e rotinas descartadas. Adaptar isso, por exemplo para perícia forense de importação. -PluginOptionDialog.optionLabels.typeNames.text[getPluginKey():C99Parser]= +PluginOptionDialog.optionLabels.typeNames.text[getPluginKey():C99Parser]=Nomes de tipos externamente definidos PluginOptionDialog.optionComponents.typeNames.tooltip[getPluginKey():C99Parser]= -PluginOptionDialog.optionLabels.redundantNames.text[getPluginKey():C99Parser]= +PluginOptionDialog.optionLabels.redundantNames.text[getPluginKey():C99Parser]=Nomes ou macros redundantes do pré-processador PluginOptionDialog.optionComponents.redundantNames.tooltip[getPluginKey():C99Parser]= -PluginOptionDialog.optionComponents.use_WINAPI_defines.text[getPluginKey():C99Parser]= +PluginOptionDialog.optionComponents.use_WINAPI_defines.text[getPluginKey():C99Parser]=Usar nomes de tipos e definições de WINAPI PluginOptionDialog.optionComponents.use_WINAPI_defines.tooltip[getPluginKey():C99Parser]= -PluginOptionDialog.optionComponents.use_MinGw_defines.text[getPluginKey():C99Parser]= +PluginOptionDialog.optionComponents.use_MinGw_defines.text[getPluginKey():C99Parser]=Usar nomes de tipos e definições de MinGw PluginOptionDialog.optionComponents.use_MinGw_defines.tooltip[getPluginKey():C99Parser]= PluginOptionDialog.optionComponents.definesToConstants.text[getPluginKey():C99Parser]=Transformar #defines a constantes PluginOptionDialog.optionComponents.definesToConstants.tooltip[getPluginKey():C99Parser]= @@ -1165,6 +1172,8 @@ PluginOptionDialog.optionComponents.alignArrays.text=Garantir o alinhamento da m PluginOptionDialog.optionComponents.alignArrays.tooltip=Inserir diretivas .align antes de qualquer alocação de dados e no início da área de texto (somente modo GNU). PluginOptionDialog.optionComponents.terminateStrings.text=Armazenar cadeias de caracteres com terminação-0 PluginOptionDialog.optionComponents.terminateStrings.tooltip=Normalmente, as cadeias de caracteres serão armazenadas como arranjos apenas com os caracteres nela contidos. Esta opção adicionará um caractere NUL para terminação +PluginOptionDialog.optionComponents.restrictedSyntax.text=Limitar exportação a conteúdo em nível ARM +PluginOptionDialog.optionComponents.restrictedSyntax.tooltip=Não aplicar capacidades ampliadas de compilação, rejeitar conteúdo que excede o nível ARM. -----[ ElementNamePreferences ]----- ElementNamePreferences.title=Preferências para nome de elemento @@ -1179,7 +1188,7 @@ ElementNamePreferences.btnOK.tooltip=Aceitar estas configurações. -----[ DiagramControllerAliases ]----- // Also consider Menu.msgTabHdrSignature and Menu.msgTabHdrAlias -DiagramControllerAliases.title=Alternativas para rotina do Controlador +DiagramControllerAliases.title=Nomes alternativos para rotina do Controlador DiagramControllerAliases.lblHeader.text=Especificar nomes alternativos para as rotinas de complementos controláveis. DiagramControllerAliases.lblRemark.text=(Observar que maiúsculas/minúsculas serão ignoradas em nomes de rotina do controlador!) DiagramControllerAliases.chkApplyAliases.text=Aplicar alternativas especificadas na exibição etc. @@ -1220,15 +1229,15 @@ FindAndReplace.lblSearchPattern.text=Procurar: FindAndReplace.lblReplacePattern.text=Substituir por: FindAndReplace.pnlMode.border=Modo FindAndReplace.chkCaseSensitive.text=Maiúsculas e minúsculas -FindAndReplace.chkCaseSensitive.mnemonic=c +FindAndReplace.chkCaseSensitive.mnemonic=m FindAndReplace.chkWholeWord.text=Palavra inteira -FindAndReplace.chkWholeWord.mnemonic=w +FindAndReplace.chkWholeWord.mnemonic=v FindAndReplace.chkRegEx.text=Expressões regulares FindAndReplace.chkRegEx.mnemonic=x FindAndReplace.rbDown.text=Para baixo -FindAndReplace.rbDown.mnemonic=o +FindAndReplace.rbDown.mnemonic=b FindAndReplace.rbUp.text=Para cima -FindAndReplace.rbUp.mnemonic=u +FindAndReplace.rbUp.mnemonic=c FindAndReplace.pnlScope.border=Escopo FindAndReplace.cmbScope.item.0=Seleção atual FindAndReplace.cmbScope.item.1=Diagrama atual @@ -1243,7 +1252,7 @@ FindAndReplace.chkRootTypes.2.mnemonic=i FindAndReplace.chkInTexts.text=Em textos FindAndReplace.chkInTexts.mnemonic=t FindAndReplace.chkInComments.text=Em comentários -FindAndReplace.chkInComments.mnemonic=m +FindAndReplace.chkInComments.mnemonic=o FindAndReplace.pnlElements.border=Tipos de elementos FindAndReplace.btnAll.text=Todos FindAndReplace.btnNone.text=Nenhum @@ -1266,13 +1275,13 @@ FindAndReplace.txtComm.border=Comentário FindAndReplace.chkElementwise.text=Elemento por elemento FindAndReplace.chkElementwise.mnemonic=e FindAndReplace.btnFind.text=Procurar -FindAndReplace.btnFind.mnemonic=n +FindAndReplace.btnFind.mnemonic=a FindAndReplace.btnReplace.text=Substituir -FindAndReplace.btnReplace.mnemonic=r +FindAndReplace.btnReplace.mnemonic=u FindAndReplace.btnReplaceFind.text=Substituir/Procurar -FindAndReplace.btnReplaceFind.mnemonic=d +FindAndReplace.btnReplaceFind.mnemonic=r FindAndReplace.btnReplaceAll.text=Substituir tudo -FindAndReplace.btnReplaceAll.mnemonic=a +FindAndReplace.btnReplaceAll.mnemonic=d FindAndReplace.btnReplaceAll.tooltip=Substituir todas as ocorrências restantes do padrão de pesquisa na direção especificada a partir da posição atual. FindAndReplace.btnClose.text=Fechar FindAndReplace.msgRegexCorrupt.text=Expressão regular «%1» parece inválida: %2 @@ -1442,10 +1451,10 @@ ArrangerIndex.msgConfirmDissolve.text=Quer mesmo dissolver este(s) grupo(s)?\n% -----> Executor -----[ Control ]----- Control.title=Controle do Executor -Control.lblSpeed.text=Atraso: +Control.lblSpeed.text= Atraso: Control.btnCallStack.text=Pilha de chamadas -Control.lblCallLevel.text=Profundidade da chamada: -Control.chkCollectRuntimeData.text=Coletar dados de tempo de execução +Control.lblCallLevel.text=Profundidade: +Control.chkCollectRuntimeData.text=Coletar dados de execução Control.cbRunDataDisplay.item.0=sem cor Control.cbRunDataDisplay.item.1=cobertura de teste simples Control.cbRunDataDisplay.item.2=cobertura de testes profunda @@ -1475,7 +1484,7 @@ Control.ttlContent.text=Conteúdo Control.msgTitleError.text=Erro Control.msgTitleQuestion.text=Pergunta Control.msgTitleParallel.text=Problema com execução em paralelo -Control.msgNoSubroutine.text=Um diagrama @o "%1" (parâmetros %2) não foi encontrado!\nConsiderar reiniciar o Organizador e colocar os diagramas @o necessários lá primeiro. +Control.msgNoSubroutine.text=Um diagrama @o "%1" (%2 parâmetros) não foi encontrado!\nConsiderar reiniciar o Organizador e colocar os diagramas @o necessários lá primeiro. Control.msgNoInclDiagram.text=Um diagrama @p "%" não foi encontrado!\nConsiderar reiniciar o Organizador e colocar o diagrama necessário lá primeiro. Control.msgAmbiguousCall.text=Ambíguo @j: Diferentes diagramas de sub-rotina Control.msgInvalidExpr.text=«%1» não é uma expressão correta ou existente. diff --git a/src/lu/fisch/structorizer/locales/ru.txt b/src/lu/fisch/structorizer/locales/ru.txt index 2a2536e4..06f64503 100644 --- a/src/lu/fisch/structorizer/locales/ru.txt +++ b/src/lu/fisch/structorizer/locales/ru.txt @@ -1339,7 +1339,7 @@ ArrangerIndex.msgNewGroupName.text= -----> Executor -----[ Control ]----- Control.title=Управление выполнения -Control.lblSpeed.text=Замедление +Control.lblSpeed.text= Замедление: Control.btnCallStack.text=Вывозный стек Control.lblCallLevel.text=Глубина стека: Control.chkCollectRuntimeData.text=Счесть выполнения diff --git a/src/lu/fisch/structorizer/parsers/CPreParser.java b/src/lu/fisch/structorizer/parsers/CPreParser.java index 74cc10dc..0a83bcc0 100644 --- a/src/lu/fisch/structorizer/parsers/CPreParser.java +++ b/src/lu/fisch/structorizer/parsers/CPreParser.java @@ -53,6 +53,7 @@ * Kay Gürtzig 2023-11-08 Bugfix #1108: Defective handling of nested comments in checComments() * Kay Gürtzig 2023-11-13 Enh. #1115 + bugfix #1116: New option to convert #defines into constants, * array typedef preparation repaired + * Kay Gürtzig 2024-03-08 Bugfix #1130: Macro expansion had to suppressed in string/char literals * ****************************************************************************************************** * @@ -1599,6 +1600,11 @@ private String replaceDefinedEntries(String toReplace, HashMap Matcher matcher = Pattern.compile("(^|.*?\\W)" + entry.getKey() + "(\\s*)\\((.*)\\)(.*?)").matcher(""); //while (toReplace.matches("(^|.*?\\W)" + entry.getKey() + "\\s*\\(.*\\).*?")) { while (matcher.reset(toReplace).matches()) { + // START KGU#1118 2024-03-08: Bugfix #1130 We must not apply macro expansion within literals + if (startsStrLiteral(matcher.group(1))) { + continue; + } + // END KGU#1118 2024-03-08 if (entry.getValue()[0].isEmpty()) { //toReplace = toReplace.replaceAll("(^|.*?\\W)" + entry.getKey() + "(\\s*)\\((.*)\\)(.*?)", "$1$2$4"); toReplace = matcher.replaceAll("$1$2$4"); @@ -1671,7 +1677,7 @@ else if (prevPart.endsWith("#")) { StringList argsPlusTail = Element.splitExpressionList(argsRaw, ",", true); if (argsPlusTail.count() > args.count()) { String tail = argsPlusTail.get(args.count()).trim(); - // With high probability tail stars with a closing parenthesis, which has to be dropped if so + // With high probability tail starts with a closing parenthesis, which has to be dropped if so // whereas the consumed parenthesis at the end has to be restored. if (tail.startsWith(")")) { tail = tail.substring(1) + ")"; @@ -1684,7 +1690,25 @@ else if (prevPart.endsWith("#")) { } } } - } else { + } + // START KGU#1118 2024-03-08: Bugfix #1130 Avoid expansions within literals + else if (toReplace.indexOf('\'') >= 0 || toReplace.indexOf('"') >= 0) { + Matcher matcher = Pattern.compile("(^|.*?\\W)" + entry.getKey() + "(\\W.*?|$)").matcher(""); + String expanded = ""; + while (matcher.reset(toReplace).matches()) { + if (startsStrLiteral(expanded + matcher.group(1))) { + // Skip this occurrence - it starts within a string/character literal + expanded += matcher.group(1) + entry.getKey(); + } + else { + expanded += matcher.group(1) + entry.getValue()[0]; + } + toReplace = matcher.group(2); + } + toReplace = expanded + toReplace; + } + // END KGU#1118 2024-03-08 + else { // from: #define a b, b can also be empty toReplace = toReplace.replaceAll("(^|.*?\\W)" + entry.getKey() + "(\\W.*?|$)", "$1" + Matcher.quoteReplacement((String) entry.getValue()[0]) + "$2"); @@ -1696,6 +1720,44 @@ else if (prevPart.endsWith("#")) { // END KGU#519 2018-06-17 } + // START KGU#1118 2024-03-08: Bugfix #1130 + /** + * Checks whether the passed-in source code snippet {@code prefix} ends within + * a string or character literal such that a macro expansion would have to be + * suppressed. Assumes that {@code prefix} does not itself starts within a literal. + * + * @param prefix + * @return {@code true} if a string or character literal started (and and not ended) + * before the end of {@code prefix}. + */ + private boolean startsStrLiteral(String prefix) { + int pos0 = -1; + int posQ1 = -1, posQ2 = -1; + int len = prefix.length(); + char quote = '\0'; + while ((posQ1 = prefix.indexOf('\'', pos0+1)) >= 0 + || (posQ2 = prefix.indexOf('"', pos0+1)) >= 0) { + pos0 = posQ2; + if (posQ1 > 0 && (posQ2 < 0 || posQ1 < posQ2)) { + pos0 = posQ1; + } + quote = prefix.charAt(pos0++); + while (pos0 < len && quote != '\0') { + char ch = prefix.charAt(pos0); + if (ch == '\\') { + // Ignore the next character + pos0++; + } + else if (ch == quote) { + quote = '\0'; + } + pos0++; + } + } + return quote != '\0'; + } + // END KGU#1118 2024-03-08 + //---------------------- Build helpers for structograms --------------------------- /** diff --git a/src/lu/fisch/structorizer/parsers/JavaParser.java b/src/lu/fisch/structorizer/parsers/JavaParser.java index 51e85bb2..b1d7bbc9 100644 --- a/src/lu/fisch/structorizer/parsers/JavaParser.java +++ b/src/lu/fisch/structorizer/parsers/JavaParser.java @@ -58,6 +58,8 @@ * Kay Gürtzig 2021-03-06 Bugfix #962: Constructor bodies had not been imported, * KGU#961: Array initialiser conversion in declarations improved * Kay Gürtzig 2023-11-08 Bugfix #1110 method translateContent() returned the argument instead of the result + * Kay Gürtzig 2024-03-08 KGU#1117: Missing backward replacement of c_l_a_s_s in one case mended. + * Kay Gürtzig 2024-03-09 Issue #1131: Handling of anonymous inner class instantiations * ****************************************************************************************************** * @@ -835,8 +837,8 @@ private interface RuleConstants // final int PROD_PRIMARYNONEWARRAY6 = 355; // ::= final int PROD_CLASSINSTANCECREATIONEXPRESSION_NEW_LPAREN_RPAREN = 356; // ::= new '(' ')' final int PROD_CLASSINSTANCECREATIONEXPRESSION_NEW_LPAREN_RPAREN2 = 357; // ::= new '(' ')' -// final int PROD_CLASSINSTANCECREATIONEXPRESSION_NEW_LPAREN_RPAREN3 = 358; // ::= new '(' ')' -// final int PROD_CLASSINSTANCECREATIONEXPRESSION_NEW_LPAREN_RPAREN4 = 359; // ::= new '(' ')' + final int PROD_CLASSINSTANCECREATIONEXPRESSION_NEW_LPAREN_RPAREN3 = 358; // ::= new '(' ')' + final int PROD_CLASSINSTANCECREATIONEXPRESSION_NEW_LPAREN_RPAREN4 = 359; // ::= new '(' ')' // final int PROD_ARGUMENTLIST = 360; // ::= final int PROD_ARGUMENTLIST_COMMA = 361; // ::= ',' final int PROD_ARRAYCREATIONEXPRESSION_NEW = 362; // ::= new @@ -949,7 +951,7 @@ private interface RuleConstants /** Rule ids representing statements, used as stoppers for comment retrieval (enh. #420) */ private static final int[] statementIds = new int[]{ - /* TODO: Fill in the RuleConstants members of those productions that are + /* RuleConstants members of those productions that are * to be associated with comments found in their syntax subtrees or their * immediate environment. */ RuleConstants.PROD_NORMALCLASSDECLARATION, @@ -1160,7 +1162,12 @@ protected void doExtraPreparations(StringBuilder _srcCode, File _file) throws Pa /** Represents the class definitions in the hierarchical class context */ private Stack includables = null; + /** Holds the value of the Java-specific import option "convert_syntax" */ private boolean optionConvertSyntax = false; + // START KGU#1117 2024-03-09: Issue #1131 Handle anonymous inne class instantiations properly + /** Holds the value of the Java-specific import option "dissect_anon_inner_class" */ + private boolean optionDissectInnerClass = true; + // END KGU#1117 2024-03-09 /** Maps the labels of labelled statements to the respective first element of the statement */ private HashMap labels = new HashMap(); @@ -1206,6 +1213,9 @@ protected void initializeBuildNSD() throws ParserCancelled root.children.addElement(new Forever()); optionConvertSyntax = (Boolean)this.getPluginOption("convert_syntax", false); + // START KGU#1117 2024-03-09: Issue #1131 Allow to construct diagrams from anonymous classes + optionDissectInnerClass = (Boolean)this.getPluginOption("dissect_anon_inner_class", true); + // END KGU#1117 2024-03-09 // START KGU#407 2018-03-26: Enh. #420: Configure the lookup table for comment retrieval this.registerStatementRuleIds(statementIds); @@ -2317,15 +2327,20 @@ else if (exprs.count() == 1) { * the expression such that embedded implicit or explicit assignments are extracted * to an own preceding line, combined assignment operator expressions are also * decomposed, e.g. {@code += } to {@code <- + }. + * + * @param exprToken - the {@link Token} representing the top-level expression. * @param isStatement - whether the expression represents a statement * @param leftHandSide - indicates whether the expression represents an assignment - * target expression. - * @param redExpr - the top-level expression {@link Reduction}. + * target expression. + * @param optInstNameSubst - optionally a name substitution pair (in case of an + * anonymous inner class instantiation + * * @return a {@code StringList} each elements of which contain an expression, all - * but the very last one are necessarily expression statements. + * but the very last one are necessarily expression statements. * @throws ParserCancelled */ - protected StringList decomposeExpression(Token exprToken, boolean isStatement, boolean leftHandSide) throws ParserCancelled { + protected StringList decomposeExpression(Token exprToken, boolean isStatement, boolean leftHandSide) + throws ParserCancelled { // We expect redExpr to represent one of the following // // @@ -2341,7 +2356,8 @@ protected StringList decomposeExpression(Token exprToken, boolean isStatement, b StringList exprs = new StringList(); if (exprToken.getType() == SymbolType.NON_TERMINAL) { Reduction exprRed = exprToken.asReduction(); - switch (exprRed.getParent().getTableIndex()) { + int ruleIx = exprRed.getParent().getTableIndex(); + switch (ruleIx) { case RuleConstants.PROD_ASSIGNMENT: { // ::= @@ -2736,9 +2752,33 @@ else if (!optionConvertSyntax) { exprs.set(ixLast, cast + exprs.get(ixLast)); } break; - + // START KGU#1117 2024-03-09: Issue #1131: Handle anonymous inner classes + // ATTENTION: THIS CASE MUST REMAIN AT LAST POSITION BEFORE DEFAULT! + case RuleConstants.PROD_CLASSINSTANCECREATIONEXPRESSION_NEW_LPAREN_RPAREN3: + case RuleConstants.PROD_CLASSINSTANCECREATIONEXPRESSION_NEW_LPAREN_RPAREN4: + // ::= new '(' ')' + // ::= new '(' ')' + if (this.optionDissectInnerClass) { + String className = this.deriveAnonInnerClass(exprRed); + StringList result = new StringList(); + result.add("new"); + result.add(className); + if (ruleIx == RuleConstants.PROD_CLASSINSTANCECREATIONEXPRESSION_NEW_LPAREN_RPAREN3) { + Token argListToken = exprRed.get(3); + processArguments(argListToken, result, exprs); + } + else { + exprs.add(result.concatenate(null) + "()"); + } + break; + } + // No break; here (or an else branch with the content of default would have to be added)! + // END KGU#1117 2024-03-09 default: - exprs.add(this.getContent_R(exprToken)); + // START KGU#1117 2024-03-08: Some expressions slipped through without replacement + //exprs.add(this.getContent_R(exprToken)); + exprs.add(this.getContent_R(exprToken).replace(".c_l_a_s_s", ".class")); + // END KGU#1117 2024-03-08 } } @@ -2748,10 +2788,69 @@ else if (!optionConvertSyntax) { return exprs; } + // START KGU#1117 2024-03-09: Issue #1131 Handle anonymous inner classes + /** + * Creates the diagrams defining an anonymous inner class and its methods and + * returns a name mapping from the instantiated super class to the made-up + * generic class name of the anonymous class. + * + * @param instCreaRed - the instance creation expression {@link Reduction} + * @return the made-up name for the instantiated anonymous inner class. + * @throws ParserCancelled + */ + private String deriveAnonInnerClass(Reduction instCreaRed) throws ParserCancelled { + // ::= new '(' ')' + // ::= new '(' ')' + // FIXME Try to delegate as much as possible to a submethod shared with ClassDeclaration section + String className0 = getContent_R(instCreaRed.get(1).asReduction(), ""); + String qualifier = packageStr; + Root classRoot = root; + if (!this.includables.isEmpty()) { + // (Should always be the case here) + qualifier = this.includables.peek().getQualifiedName(); + classRoot = new Root(); + classRoot.setInclude(); + classRoot.addToIncludeList(includables.peek()); + // Add temporary dummy loops in order to gather fields and method signatures + classRoot.children.addElement(new Forever()); + classRoot.children.addElement(new Forever()); + this.addRoot(classRoot); + } + includables.push(classRoot); + classRoot.setNamespace(qualifier); + String className = className0 + "_" + Integer.toHexString(classRoot.hashCode()); + classRoot.setText(className); + // FIXME: Is this necessary here? + if (this.includables.size() == 1 && packageStr != null) { + classRoot.comment.add("==== package: " + packageStr); + if (!imports.isEmpty()) { + imports.insert("==== imports:", 0); + classRoot.comment.add(imports); + } + } + classRoot.comment.insert("CLASS" + + (this.includables.size() > 1 ? " in class " + qualifier : ""), 0); + classRoot.getComment().add(("Anonymous inner class").trim()); + classRoot.comment.add("==== extends or implements " + className0); + + // Now descend into the body + int ixBody = 4; + if (instCreaRed.getParent().getTableIndex() == RuleConstants.PROD_CLASSINSTANCECREATIONEXPRESSION_NEW_LPAREN_RPAREN3) { + ixBody++; + } + this.buildNSD_R(instCreaRed.get(ixBody).asReduction(), classRoot.children); + // Dissolve the field and method containers + dissolveDummyContainers(classRoot); + this.includables.pop(); + return className; + } + // END KGU#1117 2024-03-09 + // START KGU#957 2021-03-05: Issue #959 - Processing conversion function handling /** * Processes a conversion function of the "Processing" language. The JavaParser base * code won't do anything here. + * * @param exprRed - a {@code } reduction * @return a StringList containing the necessary sequence of Structorizer instructions * and expressions to achieve the same effect. diff --git a/src/lu/fisch/structorizer/parsers/JavaSE8.egt b/src/lu/fisch/structorizer/parsers/JavaSE8.egt index 6c5e8dcb..035ca4a3 100644 Binary files a/src/lu/fisch/structorizer/parsers/JavaSE8.egt and b/src/lu/fisch/structorizer/parsers/JavaSE8.egt differ diff --git a/src/lu/fisch/structorizer/parsers/JavaSE8.grm b/src/lu/fisch/structorizer/parsers/JavaSE8.grm index 9afa1584..56added6 100644 --- a/src/lu/fisch/structorizer/parsers/JavaSE8.grm +++ b/src/lu/fisch/structorizer/parsers/JavaSE8.grm @@ -1,4 +1,4 @@ -! ----------------------------------------------------------------------- +! ----------------------------------------------------------------------- ! Java SE 8 Edition grammar ! ----------------------------------------------------------------------- ! @@ -56,14 +56,15 @@ ! modelled ! V 0.5 2021-03-04 Kay Gürtzig Some additions to support "Processing" ! code +! V 0.6 2024-03-08 Kay Gürtzig {String Char} revised (backslash handling) ! ----------------------------------------------------------------------- "Name" = 'Java SE 8' -"Version" = '0.5, March 2021' +"Version" = '0.6, March 2024' "Author" = 'Kay Gürtzig' "About" = 'Simplified Java SE 8 grammar, based on a partial conversion of Sun Java 1.0-2.0 specification by Dmitry Gazko and the Oracle Java SE 8 specification.' -{String Char} = {all printable} - ["] +{String Char} = {all printable} - ["] - [\] {Quote} = [''] {IdLetter} = {Letter} + [_$] {IdAlphaNumeric} = {Alphanumeric} + [_$] @@ -75,7 +76,7 @@ {ExponentPartIndicator} = [eE] {Sign} = [-+] {CharSign} = [abtnfr"\] + {Quote} -{CharSign1} = {String Char} + ["] - [\] +{CharSign1} = {String Char} + ["] {HexEscapeSign} =[uUxX] Identifier = {IdLetter}{IdAlphaNumeric}*