mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-18 00:01:55 +00:00
Check referencing instance variables from static context.
This commit is contained in:
@@ -26,9 +26,15 @@ import java.util.List;
|
||||
public class FunctionScope implements Scope {
|
||||
|
||||
private final List<VariableOrScope> privateItems;
|
||||
private final boolean isStatic;
|
||||
|
||||
public FunctionScope(List<VariableOrScope> functionBody) {
|
||||
public FunctionScope(List<VariableOrScope> functionBody, boolean isStatic) {
|
||||
this.privateItems = functionBody;
|
||||
this.isStatic = isStatic;
|
||||
}
|
||||
|
||||
public boolean isStatic() {
|
||||
return isStatic;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -51,60 +51,132 @@ public interface SimpleParser {
|
||||
List<VariableOrScope> sharedVariables,
|
||||
Map<Integer, List<Integer>> definitionPosToReferences,
|
||||
Map<Integer, Integer> referenceToDefinition,
|
||||
Map<String, Integer> parentVarNameToDefinitionPosition
|
||||
List<SimpleParseException> errors
|
||||
) {
|
||||
parseVariablesList(privateVariables, sharedVariables, definitionPosToReferences, referenceToDefinition, new LinkedHashMap<>(), new LinkedHashMap<>(), new LinkedHashMap<>(), true, errors);
|
||||
}
|
||||
|
||||
public static void parseVariablesList(
|
||||
List<VariableOrScope> privateVariables,
|
||||
List<VariableOrScope> sharedVariables,
|
||||
Map<Integer, List<Integer>> definitionPosToReferences,
|
||||
Map<Integer, Integer> referenceToDefinition,
|
||||
Map<String, Integer> parentVarFullNameToDefinitionPosition,
|
||||
Map<String, Integer> parentVarNameToDefinitionPosition,
|
||||
Map<Integer, Boolean> positionToStatic,
|
||||
boolean isStatic,
|
||||
List<SimpleParseException> errors
|
||||
) {
|
||||
Map<String, Integer> privateVarNameToDefinitionPosition = new LinkedHashMap<>();
|
||||
privateVarNameToDefinitionPosition.putAll(parentVarNameToDefinitionPosition);
|
||||
|
||||
Map<String, Integer> privateVarFullNameToDefinitionPosition = new LinkedHashMap<>();
|
||||
privateVarFullNameToDefinitionPosition.putAll(parentVarFullNameToDefinitionPosition);
|
||||
|
||||
for (VariableOrScope vt : privateVariables) {
|
||||
if (vt instanceof Variable) {
|
||||
Variable v = (Variable) vt;
|
||||
if (v.definition) {
|
||||
privateVarNameToDefinitionPosition.put(v.name, v.position);
|
||||
privateVarFullNameToDefinitionPosition.put(v.name, v.position);
|
||||
privateVarNameToDefinitionPosition.put(v.getLastName(), v.position);
|
||||
definitionPosToReferences.put(v.position, new ArrayList<>());
|
||||
positionToStatic.put(v.position, v.isStatic != null ? v.isStatic : isStatic);
|
||||
} else {
|
||||
if (!privateVarNameToDefinitionPosition.containsKey(v.name)) {
|
||||
parentVarNameToDefinitionPosition.put(v.name, -v.position - 1);
|
||||
privateVarNameToDefinitionPosition.put(v.name, -v.position - 1);
|
||||
if (!privateVarFullNameToDefinitionPosition.containsKey(v.name)
|
||||
&& !privateVarNameToDefinitionPosition.containsKey(v.getFirstName())) {
|
||||
parentVarFullNameToDefinitionPosition.put(v.name, -v.position - 1);
|
||||
parentVarNameToDefinitionPosition.put(v.getLastName(), -v.position - 1);
|
||||
privateVarFullNameToDefinitionPosition.put(v.name, -v.position - 1);
|
||||
privateVarNameToDefinitionPosition.put(v.getLastName(), -v.position - 1);
|
||||
definitionPosToReferences.put(-v.position - 1, new ArrayList<>());
|
||||
definitionPosToReferences.get(-v.position - 1).add(v.position);
|
||||
referenceToDefinition.put(v.position, -v.position - 1);
|
||||
} else {
|
||||
int definitionPos = privateVarNameToDefinitionPosition.get(v.name);
|
||||
definitionPosToReferences.get(definitionPos).add(v.position);
|
||||
referenceToDefinition.put(v.position, definitionPos);
|
||||
|
||||
if ("this".equals(v.name) && isStatic) {
|
||||
errors.add(new SimpleParseException("Cannot use this in static context", -1, v.position));
|
||||
} else {
|
||||
int definitionPos;
|
||||
if (privateVarFullNameToDefinitionPosition.containsKey(v.name)) {
|
||||
definitionPos = privateVarFullNameToDefinitionPosition.get(v.name);
|
||||
} else {
|
||||
definitionPos = privateVarNameToDefinitionPosition.get(v.getFirstName());
|
||||
}
|
||||
boolean staticDefinition = definitionPos >= 0 ? positionToStatic.get(definitionPos) : true;
|
||||
if (!(!staticDefinition && isStatic)) {
|
||||
definitionPosToReferences.get(definitionPos).add(v.position);
|
||||
referenceToDefinition.put(v.position, definitionPos);
|
||||
} else {
|
||||
errors.add(new SimpleParseException("Cannot reference instance variable from static context", -1, v.position));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (vt instanceof Scope) {
|
||||
Scope vs = (Scope) vt;
|
||||
parseVariablesList(vs.getPrivateItems(), vs.getSharedItems(), definitionPosToReferences, referenceToDefinition, privateVarNameToDefinitionPosition);
|
||||
boolean subStatic = isStatic;
|
||||
if (vs instanceof FunctionScope) {
|
||||
subStatic = ((FunctionScope) vs).isStatic();
|
||||
}
|
||||
if (vs instanceof TraitVarConstValueScope) {
|
||||
subStatic = ((TraitVarConstValueScope) vs).isStatic();
|
||||
}
|
||||
parseVariablesList(vs.getPrivateItems(), vs.getSharedItems(), definitionPosToReferences, referenceToDefinition, privateVarFullNameToDefinitionPosition, privateVarNameToDefinitionPosition, positionToStatic, subStatic, errors);
|
||||
}
|
||||
}
|
||||
for (VariableOrScope vt : sharedVariables) {
|
||||
if (vt instanceof Variable) {
|
||||
Variable v = (Variable) vt;
|
||||
if (v.definition) {
|
||||
parentVarNameToDefinitionPosition.put(v.name, v.position);
|
||||
privateVarNameToDefinitionPosition.put(v.name, v.position);
|
||||
parentVarFullNameToDefinitionPosition.put(v.name, v.position);
|
||||
parentVarNameToDefinitionPosition.put(v.getLastName(), v.position);
|
||||
privateVarFullNameToDefinitionPosition.put(v.name, v.position);
|
||||
privateVarNameToDefinitionPosition.put(v.getLastName(), v.position);
|
||||
definitionPosToReferences.put(v.position, new ArrayList<>());
|
||||
positionToStatic.put(v.position, v.isStatic != null ? v.isStatic : isStatic);
|
||||
} else {
|
||||
if (!privateVarNameToDefinitionPosition.containsKey(v.name)) {
|
||||
parentVarNameToDefinitionPosition.put(v.name, -v.position - 1);
|
||||
privateVarNameToDefinitionPosition.put(v.name, -v.position - 1);
|
||||
if (!privateVarFullNameToDefinitionPosition.containsKey(v.name)
|
||||
&& !privateVarNameToDefinitionPosition.containsKey(v.getFirstName())) {
|
||||
parentVarFullNameToDefinitionPosition.put(v.name, -v.position - 1);
|
||||
parentVarNameToDefinitionPosition.put(v.getFirstName(), -v.position - 1);
|
||||
privateVarFullNameToDefinitionPosition.put(v.name, -v.position - 1);
|
||||
privateVarNameToDefinitionPosition.put(v.getFirstName(), -v.position - 1);
|
||||
definitionPosToReferences.put(-v.position - 1, new ArrayList<>());
|
||||
definitionPosToReferences.get(-v.position - 1).add(v.position);
|
||||
referenceToDefinition.put(v.position, -v.position - 1);
|
||||
} else {
|
||||
int definitionPos = privateVarNameToDefinitionPosition.get(v.name);
|
||||
definitionPosToReferences.get(definitionPos).add(v.position);
|
||||
referenceToDefinition.put(v.position, definitionPos);
|
||||
|
||||
if ("this".equals(v.name) && isStatic) {
|
||||
errors.add(new SimpleParseException("Cannot use this in static context", -1, v.position));
|
||||
} else {
|
||||
int definitionPos;
|
||||
if (privateVarFullNameToDefinitionPosition.containsKey(v.name)) {
|
||||
definitionPos = privateVarFullNameToDefinitionPosition.get(v.name);
|
||||
} else {
|
||||
definitionPos = privateVarNameToDefinitionPosition.get(v.getFirstName());
|
||||
}
|
||||
boolean staticDefinition = definitionPos >= 0 ? positionToStatic.get(definitionPos) : true;
|
||||
if (!(!staticDefinition && isStatic)) {
|
||||
definitionPosToReferences.get(definitionPos).add(v.position);
|
||||
referenceToDefinition.put(v.position, definitionPos);
|
||||
} else {
|
||||
errors.add(new SimpleParseException("Cannot reference instance variable from static context", -1, v.position));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (vt instanceof Scope) {
|
||||
Scope vs = (Scope) vt;
|
||||
parseVariablesList(vs.getPrivateItems(), vs.getSharedItems(), definitionPosToReferences, referenceToDefinition, privateVarNameToDefinitionPosition);
|
||||
boolean subStatic = isStatic;
|
||||
if (vs instanceof FunctionScope) {
|
||||
subStatic = ((FunctionScope) vs).isStatic();
|
||||
}
|
||||
if (vs instanceof TraitVarConstValueScope) {
|
||||
subStatic = ((TraitVarConstValueScope) vs).isStatic();
|
||||
}
|
||||
parseVariablesList(vs.getPrivateItems(), vs.getSharedItems(), definitionPosToReferences, referenceToDefinition, privateVarFullNameToDefinitionPosition, privateVarNameToDefinitionPosition, positionToStatic, subStatic, errors);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class TraitVarConstValueScope implements Scope {
|
||||
|
||||
private List<VariableOrScope> sharedItems;
|
||||
private final boolean isStatic;
|
||||
|
||||
public TraitVarConstValueScope(List<VariableOrScope> sharedItems, boolean isStatic) {
|
||||
this.sharedItems = sharedItems;
|
||||
this.isStatic = isStatic;
|
||||
}
|
||||
|
||||
public boolean isStatic() {
|
||||
return isStatic;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VariableOrScope> getSharedItems() {
|
||||
return sharedItems;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VariableOrScope> getPrivateItems() {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
@@ -25,15 +25,35 @@ public class Variable implements VariableOrScope {
|
||||
public boolean definition;
|
||||
public String name;
|
||||
public int position;
|
||||
public Boolean isStatic;
|
||||
|
||||
public Variable(boolean definition, String name, int position) {
|
||||
this(definition, name, position, null);
|
||||
}
|
||||
|
||||
public Variable(boolean definition, String name, int position, Boolean isStatic) {
|
||||
this.definition = definition;
|
||||
this.name = name;
|
||||
this.position = position;
|
||||
this.isStatic = isStatic;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return (definition ? "definition of " : "") + name + " at " + position;
|
||||
return (definition ? "definition of " : "") + (isStatic ? "static " : "") + name + " at " + position;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
if (name.contains(".")) {
|
||||
return name.substring(name.lastIndexOf(".") + 1);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
if (name.contains(".")) {
|
||||
return name.substring(0, name.indexOf("."));
|
||||
}
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user