Highlighter - handling this variables in nested functions

This commit is contained in:
Jindra Petřík
2025-05-31 11:43:03 +02:00
parent 458214106b
commit 68dc6468c7
4 changed files with 103 additions and 12 deletions

View File

@@ -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<SimpleParseException> 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);
}
/**

View File

@@ -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<SimpleParseException> errors, ParsedSymbol s, int min) throws SimpleParseException {

View File

@@ -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<VariableOrScope> functionBody, boolean isStatic) {
super(functionBody, isStatic);
}
}

View File

@@ -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<VariableOrScope> sharedVariables,
Map<Integer, List<Integer>> definitionPosToReferences,
Map<Integer, Integer> referenceToDefinition,
List<SimpleParseException> errors
List<SimpleParseException> 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<String, Integer> parentVarNameToDefinitionPosition,
Map<Integer, Boolean> positionToStatic,
boolean isStatic,
List<SimpleParseException> errors
List<SimpleParseException> errors,
Scope scope,
boolean innerFunctionCanUseTraits
) {
Map<String, Integer> 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<String, Integer> subPrivateVarFullNameToDefinitionPosition = privateVarFullNameToDefinitionPosition;
Map<String, Integer> subPrivateVarNameToDefinitionPosition = privateVarNameToDefinitionPosition;
if ((vs instanceof FunctionScope) &&(!(vs instanceof MethodScope))) {
subPrivateVarFullNameToDefinitionPosition = new LinkedHashMap<>(subPrivateVarFullNameToDefinitionPosition);
subPrivateVarNameToDefinitionPosition = new LinkedHashMap<>(subPrivateVarNameToDefinitionPosition);
Set<String> 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<String, Integer> subPrivateVarFullNameToDefinitionPosition = privateVarFullNameToDefinitionPosition;
Map<String, Integer> subPrivateVarNameToDefinitionPosition = privateVarNameToDefinitionPosition;
if ((vs instanceof FunctionScope) &&(!(vs instanceof MethodScope))) {
subPrivateVarFullNameToDefinitionPosition = new LinkedHashMap<>(subPrivateVarFullNameToDefinitionPosition);
subPrivateVarNameToDefinitionPosition = new LinkedHashMap<>(subPrivateVarNameToDefinitionPosition);
Set<String> 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);
}
}
}