From 68dc6468c75a11ccf9d44e2c6ead05418f995ef6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Sat, 31 May 2025 11:43:03 +0200 Subject: [PATCH] Highlighter - handling this variables in nested functions --- .../script/ActionScript3SimpleParser.java | 18 ++++-- .../script/ActionScript2SimpleParser.java | 6 +- .../flash/simpleparser/MethodScope.java | 31 ++++++++++ .../flash/simpleparser/SimpleParser.java | 60 +++++++++++++++++-- 4 files changed, 103 insertions(+), 12 deletions(-) create mode 100644 libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/MethodScope.java diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3SimpleParser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3SimpleParser.java index a05c2ff3d..fc69241f5 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3SimpleParser.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3SimpleParser.java @@ -22,6 +22,7 @@ import com.jpexs.decompiler.flash.simpleparser.CatchScope; import com.jpexs.decompiler.flash.simpleparser.ClassScope; import com.jpexs.decompiler.flash.simpleparser.FunctionScope; import com.jpexs.decompiler.flash.simpleparser.Import; +import com.jpexs.decompiler.flash.simpleparser.MethodScope; import com.jpexs.decompiler.flash.simpleparser.Namespace; import com.jpexs.decompiler.flash.simpleparser.SimpleParseException; import com.jpexs.decompiler.flash.simpleparser.SimpleParser; @@ -472,8 +473,13 @@ public class ActionScript3SimpleParser implements SimpleParser { expectedType(errors, SymbolType.SEMICOLON); } - FunctionScope fs = new FunctionScope(subvariables, isStatic); - variables.add(fs); + if (isMethod) { + MethodScope ms = new MethodScope(subvariables, isStatic); + variables.add(ms); + } else { + FunctionScope fs = new FunctionScope(subvariables, isStatic); + variables.add(fs); + } } private void parseMetadata(List errors) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException { @@ -1227,7 +1233,7 @@ public class ActionScript3SimpleParser implements SimpleParser { s = lexer.lex(); expected(errors, s, lexer.yyline(), SymbolGroup.IDENTIFIER); needsActivation.setVal(true); - function(errors, false, false, needsActivation, importedClasses, thisType, openedNamespaces, s.value.toString(), false, variables, abc, s.position, true /*???*/); + function(errors, false, false, needsActivation, importedClasses, thisType, openedNamespaces, s.value.toString(), false, variables, abc, s.position, false); ret = true; break; case VAR: @@ -1849,7 +1855,7 @@ public class ActionScript3SimpleParser implements SimpleParser { lexer.pushback(s); } needsActivation.setVal(true); - function(errors, false, false, needsActivation, importedClasses, thisType, openedNamespaces, fname, false, variables, abc, fnamePos, true /*???*/); + function(errors, false, false, needsActivation, importedClasses, thisType, openedNamespaces, fname, false, variables, abc, fnamePos, false); ret = true; allowMemberOrCall = true; break; @@ -1933,7 +1939,7 @@ public class ActionScript3SimpleParser implements SimpleParser { lexer.pushback(s); } needsActivation.setVal(true); - function(errors, false, false, needsActivation, importedClasses, thisType, openedNamespaces, ffname, false, variables, abc, ffnamePos, isStatic); + function(errors, false, false, needsActivation, importedClasses, thisType, openedNamespaces, ffname, false, variables, abc, ffnamePos, false); ret = true; } else if (s.type == SymbolType.LOWER_THAN) { type(errors, thisType, needsActivation, importedClasses, openedNamespaces, variables, abc); @@ -2166,7 +2172,7 @@ public class ActionScript3SimpleParser implements SimpleParser { //Logger.getLogger(ActionScript3SimpleParser.class.getName()).log(Level.SEVERE, null, ex); throw new SimpleParseException(str, ex.line); } - SimpleParser.parseVariablesList(new ArrayList<>(), vars, definitionPosToReferences, referenceToDefinition, errors); + SimpleParser.parseVariablesList(new ArrayList<>(), vars, definitionPosToReferences, referenceToDefinition, errors, true); } /** diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/ActionScript2SimpleParser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/ActionScript2SimpleParser.java index b4689dd75..b34ec6200 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/ActionScript2SimpleParser.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/ActionScript2SimpleParser.java @@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.action.parser.ActionParseException; import com.jpexs.decompiler.flash.simpleparser.CatchScope; import com.jpexs.decompiler.flash.simpleparser.ClassScope; import com.jpexs.decompiler.flash.simpleparser.FunctionScope; +import com.jpexs.decompiler.flash.simpleparser.MethodScope; import com.jpexs.decompiler.flash.simpleparser.SimpleParseException; import com.jpexs.decompiler.flash.simpleparser.SimpleParser; import com.jpexs.decompiler.flash.simpleparser.TraitVarConstValueScope; @@ -210,6 +211,9 @@ public class ActionScript2SimpleParser implements SimpleParser { hasEval.setVal(true); } + if (isMethod) { + return new MethodScope(subvariables, isStatic); + } return new FunctionScope(subvariables, isStatic); } @@ -1642,7 +1646,7 @@ public class ActionScript2SimpleParser implements SimpleParser { } catch (ActionParseException ex) { errors.add(new SimpleParseException(ex.getMessage(), ex.line, ex.position)); } - SimpleParser.parseVariablesList(new ArrayList<>(), vars, definitionPosToReferences, referenceToDefinition, errors); + SimpleParser.parseVariablesList(new ArrayList<>(), vars, definitionPosToReferences, referenceToDefinition, errors, false); } private void versionRequired(List errors, ParsedSymbol s, int min) throws SimpleParseException { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/MethodScope.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/MethodScope.java new file mode 100644 index 000000000..4f7da63f6 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/MethodScope.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2010-2025 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.simpleparser; + +import java.util.List; + +/** + * + * @author JPEXS + */ +public class MethodScope extends FunctionScope { + + public MethodScope(List functionBody, boolean isStatic) { + super(functionBody, isStatic); + } + +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/SimpleParser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/SimpleParser.java index 0ccb0ef80..6c39bb081 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/SimpleParser.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/SimpleParser.java @@ -18,9 +18,12 @@ package com.jpexs.decompiler.flash.simpleparser; import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Set; /** * @@ -51,9 +54,10 @@ public interface SimpleParser { List sharedVariables, Map> definitionPosToReferences, Map referenceToDefinition, - List errors + List errors, + boolean innerFunctionCanUseTraits ) { - parseVariablesList(privateVariables, sharedVariables, definitionPosToReferences, referenceToDefinition, new LinkedHashMap<>(), new LinkedHashMap<>(), new LinkedHashMap<>(), true, errors); + parseVariablesList(privateVariables, sharedVariables, definitionPosToReferences, referenceToDefinition, new LinkedHashMap<>(), new LinkedHashMap<>(), new LinkedHashMap<>(), true, errors, null, innerFunctionCanUseTraits); } public static void parseVariablesList( @@ -65,7 +69,9 @@ public interface SimpleParser { Map parentVarNameToDefinitionPosition, Map positionToStatic, boolean isStatic, - List errors + List errors, + Scope scope, + boolean innerFunctionCanUseTraits ) { Map privateVarNameToDefinitionPosition = new LinkedHashMap<>(); privateVarNameToDefinitionPosition.putAll(parentVarNameToDefinitionPosition); @@ -122,7 +128,29 @@ public interface SimpleParser { if (vs instanceof TraitVarConstValueScope) { subStatic = ((TraitVarConstValueScope) vs).isStatic(); } - parseVariablesList(vs.getPrivateItems(), vs.getSharedItems(), definitionPosToReferences, referenceToDefinition, privateVarFullNameToDefinitionPosition, privateVarNameToDefinitionPosition, positionToStatic, subStatic, errors); + + //if its inner function (not a method), remove all this variables + Map subPrivateVarFullNameToDefinitionPosition = privateVarFullNameToDefinitionPosition; + Map subPrivateVarNameToDefinitionPosition = privateVarNameToDefinitionPosition; + if ((vs instanceof FunctionScope) &&(!(vs instanceof MethodScope))) { + subPrivateVarFullNameToDefinitionPosition = new LinkedHashMap<>(subPrivateVarFullNameToDefinitionPosition); + subPrivateVarNameToDefinitionPosition = new LinkedHashMap<>(subPrivateVarNameToDefinitionPosition); + Set keys = new HashSet<>(subPrivateVarFullNameToDefinitionPosition.keySet()); + for (String vName : keys) { + if (vName.equals("this") || vName.startsWith("this.")) { + subPrivateVarFullNameToDefinitionPosition.remove(vName); + if (vName.equals("this")) { + subPrivateVarNameToDefinitionPosition.remove("this"); + } + if (!innerFunctionCanUseTraits) { + String lastName = vName.contains(".") ? vName.substring(vName.lastIndexOf(".") + 1) : vName; + subPrivateVarNameToDefinitionPosition.remove(lastName); + } + } + } + } + + parseVariablesList(vs.getPrivateItems(), vs.getSharedItems(), definitionPosToReferences, referenceToDefinition, subPrivateVarFullNameToDefinitionPosition, subPrivateVarNameToDefinitionPosition, positionToStatic, subStatic, errors, vs, innerFunctionCanUseTraits); } } for (VariableOrScope vt : sharedVariables) { @@ -176,7 +204,29 @@ public interface SimpleParser { if (vs instanceof TraitVarConstValueScope) { subStatic = ((TraitVarConstValueScope) vs).isStatic(); } - parseVariablesList(vs.getPrivateItems(), vs.getSharedItems(), definitionPosToReferences, referenceToDefinition, privateVarFullNameToDefinitionPosition, privateVarNameToDefinitionPosition, positionToStatic, subStatic, errors); + + //if its inner function (not a method), remove all this variables + Map subPrivateVarFullNameToDefinitionPosition = privateVarFullNameToDefinitionPosition; + Map subPrivateVarNameToDefinitionPosition = privateVarNameToDefinitionPosition; + if ((vs instanceof FunctionScope) &&(!(vs instanceof MethodScope))) { + subPrivateVarFullNameToDefinitionPosition = new LinkedHashMap<>(subPrivateVarFullNameToDefinitionPosition); + subPrivateVarNameToDefinitionPosition = new LinkedHashMap<>(subPrivateVarNameToDefinitionPosition); + Set keys = new HashSet<>(subPrivateVarFullNameToDefinitionPosition.keySet()); + for (String vName : keys) { + if (vName.equals("this") || vName.startsWith("this.")) { + subPrivateVarFullNameToDefinitionPosition.remove(vName); + if (vName.equals("this")) { + subPrivateVarNameToDefinitionPosition.remove("this"); + } + if (!innerFunctionCanUseTraits) { + String lastName = vName.contains(".") ? vName.substring(vName.lastIndexOf(".") + 1) : vName; + subPrivateVarNameToDefinitionPosition.remove(lastName); + } + } + } + } + + parseVariablesList(vs.getPrivateItems(), vs.getSharedItems(), definitionPosToReferences, referenceToDefinition, privateVarFullNameToDefinitionPosition, privateVarNameToDefinitionPosition, positionToStatic, subStatic, errors, vs, innerFunctionCanUseTraits); } } }