mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-05-29 18:34:42 +00:00
Fixed #1692 Properly distinguish obfuscated names vs namespace suffixes and attributes
This commit is contained in:
@@ -48,9 +48,9 @@ public class AVM2Deobfuscation {
|
||||
|
||||
private final Map<String, Integer> usageTypesCount = new HashMap<>();
|
||||
|
||||
public static final DottedChain FLASH_PROXY = new DottedChain(new String[]{"flash", "utils", "flash_proxy"}, "");
|
||||
public static final DottedChain FLASH_PROXY = new DottedChain(new String[]{"flash", "utils", "flash_proxy"});
|
||||
|
||||
public static final DottedChain BUILTIN = new DottedChain(new String[]{"-"}, "");
|
||||
public static final DottedChain BUILTIN = new DottedChain(new String[]{"-"});
|
||||
|
||||
public AVM2Deobfuscation(SWF swf, AVM2ConstantPool constants) {
|
||||
this.swf = swf;
|
||||
|
||||
@@ -24,5 +24,5 @@ import com.jpexs.decompiler.graph.DottedChain;
|
||||
*/
|
||||
public interface AlchemyTypeIns {
|
||||
|
||||
public static final DottedChain ALCHEMY_PACKAGE = new DottedChain(new String[]{"avm2", "intrinsics", "memory"}, DottedChain.NO_SUFFIX);
|
||||
public static final DottedChain ALCHEMY_PACKAGE = new DottedChain(new String[]{"avm2", "intrinsics", "memory"});
|
||||
}
|
||||
|
||||
@@ -44,17 +44,17 @@ import java.util.Objects;
|
||||
*/
|
||||
public class InitVectorAVM2Item extends AVM2Item {
|
||||
|
||||
public static final DottedChain VECTOR_PACKAGE = new DottedChain(new String[]{"__AS3__", "vec"}, "");
|
||||
public static final DottedChain VECTOR_PACKAGE = new DottedChain(new String[]{"__AS3__", "vec"});
|
||||
|
||||
public static final DottedChain VECTOR_FQN = new DottedChain(new String[]{"__AS3__", "vec", "Vector"}, "");
|
||||
public static final DottedChain VECTOR_FQN = new DottedChain(new String[]{"__AS3__", "vec", "Vector"});
|
||||
|
||||
public static final DottedChain VECTOR_INT = new DottedChain(new String[]{"__AS3__", "vec", "Vector$int"}, "");
|
||||
public static final DottedChain VECTOR_INT = new DottedChain(new String[]{"__AS3__", "vec", "Vector$int"});
|
||||
|
||||
public static final DottedChain VECTOR_DOUBLE = new DottedChain(new String[]{"__AS3__", "vec", "Vector$double"}, "");
|
||||
public static final DottedChain VECTOR_DOUBLE = new DottedChain(new String[]{"__AS3__", "vec", "Vector$double"});
|
||||
|
||||
public static final DottedChain VECTOR_UINT = new DottedChain(new String[]{"__AS3__", "vec", "Vector$uint"}, "");
|
||||
public static final DottedChain VECTOR_UINT = new DottedChain(new String[]{"__AS3__", "vec", "Vector$uint"});
|
||||
|
||||
public static final DottedChain VECTOR_OBJECT = new DottedChain(new String[]{"__AS3__", "vec", "Vector$object"}, "");
|
||||
public static final DottedChain VECTOR_OBJECT = new DottedChain(new String[]{"__AS3__", "vec", "Vector$object"});
|
||||
|
||||
public GraphTargetItem subtype;
|
||||
|
||||
|
||||
@@ -746,7 +746,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
|
||||
ret.add(ins(AVM2Instructions.NewObject, 0));
|
||||
ret.add(ins(AVM2Instructions.PushWith));
|
||||
scope = localData.scopeStack.size();
|
||||
localData.scopeStack.add(new PropertyAVM2Item(null, item.functionName, abcIndex, new ArrayList<>(), localData.callStack));
|
||||
localData.scopeStack.add(new PropertyAVM2Item(null, false, item.functionName, abcIndex, new ArrayList<>(), localData.callStack));
|
||||
}
|
||||
AVM2ConstantPool constants = abcIndex.getSelectedAbc().constants;
|
||||
ret.add(ins(AVM2Instructions.NewFunction, method(false, constants.getStringId(item.functionName, true), true, false, localData.callStack, localData.pkg, item.needsActivation, item.subvariables, 0 /*Set later*/, item.hasRest, item.line, localData.currentClass, null, false, localData, item.paramTypes, item.paramNames, item.paramValues, item.body, item.retType)));
|
||||
@@ -1349,7 +1349,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
|
||||
}
|
||||
*/
|
||||
List<GraphTargetItem> getterBody = new ArrayList<>();
|
||||
UnresolvedAVM2Item sp = new UnresolvedAVM2Item(new ArrayList<>(), importedClasses, false, TypeItem.UNBOUNDED, 0, new DottedChain(new String[]{"_skinParts"}, ""),
|
||||
UnresolvedAVM2Item sp = new UnresolvedAVM2Item(new ArrayList<>(), importedClasses, false, TypeItem.UNBOUNDED, 0, new DottedChain(new String[]{"_skinParts"}),
|
||||
null, openedNamespaces, abcIndex);
|
||||
getterBody.add(new ReturnValueAVM2Item(null, null, sp));
|
||||
List<AssignableAVM2Item> subvars = new ArrayList<>();
|
||||
@@ -1850,7 +1850,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
|
||||
continue;
|
||||
}
|
||||
|
||||
NameAVM2Item d = new NameAVM2Item(n.type, n.line, n.getVariableName(), NameAVM2Item.getDefaultValue("" + n.type), true, n.openedNamespaces, abcIndex);
|
||||
NameAVM2Item d = new NameAVM2Item(n.type, n.line, n.isAttribute(), n.getVariableName(), NameAVM2Item.getDefaultValue("" + n.type), true, n.openedNamespaces, abcIndex);
|
||||
//no index
|
||||
if (needsActivation) {
|
||||
if (d.getSlotNumber() <= 0) {
|
||||
@@ -1909,9 +1909,9 @@ public class AVM2SourceGenerator implements SourceGenerator {
|
||||
mbody.traits.traits.add(tsc);
|
||||
}
|
||||
for (int i = 1; i < paramRegCount; i++) {
|
||||
NameAVM2Item param = new NameAVM2Item(registerTypes.get(i), 0, registerNames.get(i), null, false, new ArrayList<>(), abcIndex);
|
||||
NameAVM2Item param = new NameAVM2Item(registerTypes.get(i), 0, false, registerNames.get(i), null, false, new ArrayList<>(), abcIndex);
|
||||
param.setRegNumber(i);
|
||||
NameAVM2Item d = new NameAVM2Item(registerTypes.get(i), 0, registerNames.get(i), param, true, new ArrayList<>(), abcIndex);
|
||||
NameAVM2Item d = new NameAVM2Item(registerTypes.get(i), 0, false, registerNames.get(i), param, true, new ArrayList<>(), abcIndex);
|
||||
d.setSlotScope(slotScope);
|
||||
d.setSlotNumber(slotNames.indexOf(registerNames.get(i)));
|
||||
declarations.add(d);
|
||||
|
||||
@@ -308,7 +308,7 @@ public class ActionScript3Parser {
|
||||
s = lex();
|
||||
GraphTargetItem ns = null;
|
||||
if (s.type == SymbolType.NAMESPACE_OP) {
|
||||
ns = new UnresolvedAVM2Item(new ArrayList<>(), importedClasses, false, null, lexer.yyline(), new DottedChain(new String[]{propName}, "" /*FIXME ???*/), null, openedNamespaces, abcIndex);
|
||||
ns = new UnresolvedAVM2Item(new ArrayList<>(), importedClasses, false, null, lexer.yyline(), new DottedChain(new String[]{propName}, new String[]{""} /*FIXME ???*/), null, openedNamespaces, abcIndex);
|
||||
variables.add((UnresolvedAVM2Item) ns);
|
||||
s = lex();
|
||||
if (s.type == SymbolType.BRACKET_OPEN) {
|
||||
@@ -326,7 +326,7 @@ public class ActionScript3Parser {
|
||||
if (ns != null) {
|
||||
ret = new NamespacedAVM2Item(ns, propName, propItem, ret, attr, openedNamespaces, null);
|
||||
} else {
|
||||
ret = new PropertyAVM2Item(ret, (attr ? "@" : "") + propName, abcIndex, openedNamespaces, new ArrayList<>());
|
||||
ret = new PropertyAVM2Item(ret, attr, propName, abcIndex, openedNamespaces, new ArrayList<>());
|
||||
}
|
||||
s = lex();
|
||||
}
|
||||
@@ -341,24 +341,31 @@ public class ActionScript3Parser {
|
||||
|
||||
private GraphTargetItem name(List<List<NamespaceItem>> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference<Boolean> needsActivation, boolean typeOnly, List<NamespaceItem> openedNamespaces, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, List<AssignableAVM2Item> variables, List<DottedChain> importedClasses) throws IOException, AVM2ParseException, InterruptedException {
|
||||
ParsedSymbol s = lex();
|
||||
DottedChain name = new DottedChain(new String[]{}, "");
|
||||
DottedChain name = new DottedChain(new String[]{}, new String[]{""});
|
||||
boolean attribute = false;
|
||||
String name2 = "";
|
||||
if (s.type == SymbolType.ATTRIBUTE) {
|
||||
name2 += "@";
|
||||
attribute = true;
|
||||
s = lex();
|
||||
}
|
||||
expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.THIS, SymbolType.SUPER, SymbolType.STRING_OP);
|
||||
name2 += s.value.toString();
|
||||
s = lex();
|
||||
boolean attrBracket = false;
|
||||
String nsSuffix = "";
|
||||
if (s.type == SymbolType.NAMESPACESUFFIX) {
|
||||
s = lex();
|
||||
nsSuffix = "#" + s.value;
|
||||
}
|
||||
|
||||
name = name.addWithSuffix(name2);
|
||||
name = name.add(attribute, name2, nsSuffix);
|
||||
while (s.isType(SymbolType.DOT)) {
|
||||
//name += s.value.toString(); //. or ::
|
||||
s = lex();
|
||||
name2 = "";
|
||||
attribute = false;
|
||||
if (s.type == SymbolType.ATTRIBUTE) {
|
||||
name2 += "@";
|
||||
attribute = true;
|
||||
s = lex();
|
||||
if (s.type == SymbolType.MULTIPLY) {
|
||||
name2 += s.value.toString();
|
||||
@@ -370,19 +377,26 @@ public class ActionScript3Parser {
|
||||
}
|
||||
attrBracket = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.NAMESPACE, SymbolType.MULTIPLY);
|
||||
name2 += s.value.toString();
|
||||
}
|
||||
name = name.addWithSuffix(name2);
|
||||
s = lex();
|
||||
nsSuffix = "";
|
||||
if (s.type == SymbolType.NAMESPACESUFFIX) {
|
||||
nsSuffix = "#" + s.value;
|
||||
s = lex();
|
||||
}
|
||||
name = name.add(attribute, name2, nsSuffix);
|
||||
}
|
||||
String nsname = null;
|
||||
String nsprop = null;
|
||||
boolean nsAtribute = false;
|
||||
GraphTargetItem nspropItem = null;
|
||||
if (s.type == SymbolType.NAMESPACE_OP) {
|
||||
nsname = name.getLast();
|
||||
nsAtribute = name.isLastAttribute();
|
||||
s = lex();
|
||||
if (s.group == SymbolGroup.IDENTIFIER) {
|
||||
nsprop = s.value.toString();
|
||||
@@ -401,14 +415,10 @@ public class ActionScript3Parser {
|
||||
variables.add(unr);
|
||||
ret = unr;
|
||||
}
|
||||
if (nsname != null) {
|
||||
boolean attr = nsname.startsWith("@");
|
||||
if (attr) {
|
||||
nsname = nsname.substring(1);
|
||||
}
|
||||
UnresolvedAVM2Item ns = new UnresolvedAVM2Item(new ArrayList<>(), importedClasses, typeOnly, null, lexer.yyline(), new DottedChain(new String[]{nsname}, ""), null, openedNamespaces, abcIndex);
|
||||
if (nsname != null) {
|
||||
UnresolvedAVM2Item ns = new UnresolvedAVM2Item(new ArrayList<>(), importedClasses, typeOnly, null, lexer.yyline(), new DottedChain(new String[]{nsname}), null, openedNamespaces, abcIndex);
|
||||
variables.add(ns);
|
||||
ret = new NamespacedAVM2Item(ns, nsprop, nspropItem, ret, attr, openedNamespaces, null);
|
||||
ret = new NamespacedAVM2Item(ns, nsprop, nspropItem, ret, nsAtribute, openedNamespaces, null);
|
||||
}
|
||||
if (s.type == SymbolType.BRACKET_OPEN) {
|
||||
lexer.pushback(s);
|
||||
@@ -543,14 +553,14 @@ public class ActionScript3Parser {
|
||||
}
|
||||
List<GraphTargetItem> body = null;
|
||||
List<AssignableAVM2Item> subvariables = new ArrayList<>();
|
||||
subvariables.add(new NameAVM2Item(thisType, lexer.yyline(), "this", null, true, openedNamespaces, abcIndex));
|
||||
subvariables.add(new NameAVM2Item(thisType, lexer.yyline(), false, "this", null, true, openedNamespaces, abcIndex));
|
||||
for (int i = 0; i < paramNames.size() - (hasRest ? 1 : 0); i++) {
|
||||
subvariables.add(new NameAVM2Item(paramTypes.get(i), lexer.yyline(), paramNames.get(i), null, true, openedNamespaces, abcIndex));
|
||||
subvariables.add(new NameAVM2Item(paramTypes.get(i), lexer.yyline(), false, paramNames.get(i), null, true, openedNamespaces, abcIndex));
|
||||
}
|
||||
if (hasRest) {
|
||||
subvariables.add(new NameAVM2Item(TypeItem.UNBOUNDED, lexer.yyline(), paramNames.get(paramNames.size() - 1), null, true, openedNamespaces, abcIndex));
|
||||
subvariables.add(new NameAVM2Item(TypeItem.UNBOUNDED, lexer.yyline(), false, paramNames.get(paramNames.size() - 1), null, true, openedNamespaces, abcIndex));
|
||||
}
|
||||
subvariables.add(new NameAVM2Item(thisType, lexer.yyline(), "arguments", null, true, openedNamespaces, abcIndex));
|
||||
subvariables.add(new NameAVM2Item(thisType, lexer.yyline(), false, "arguments", null, true, openedNamespaces, abcIndex));
|
||||
int parCnt = subvariables.size();
|
||||
Reference<Boolean> needsActivation2 = new Reference<>(false);
|
||||
if (!isInterface) {
|
||||
@@ -1467,10 +1477,10 @@ public class ActionScript3Parser {
|
||||
|
||||
if (s.type == SymbolType.ASSIGN) {
|
||||
GraphTargetItem varval = (expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables, false));
|
||||
ret = new NameAVM2Item(type, lexer.yyline(), varIdentifier, varval, true, openedNamespaces, abcIndex);
|
||||
ret = new NameAVM2Item(type, lexer.yyline(), false, varIdentifier, varval, true, openedNamespaces, abcIndex);
|
||||
variables.add((NameAVM2Item) ret);
|
||||
} else {
|
||||
ret = new NameAVM2Item(type, lexer.yyline(), varIdentifier, null, true, openedNamespaces, abcIndex);
|
||||
ret = new NameAVM2Item(type, lexer.yyline(), false, varIdentifier, null, true, openedNamespaces, abcIndex);
|
||||
variables.add((NameAVM2Item) ret);
|
||||
lexer.pushback(s);
|
||||
}
|
||||
@@ -1738,7 +1748,7 @@ public class ActionScript3Parser {
|
||||
String enamestr = s.value.toString();
|
||||
expectedType(SymbolType.COLON);
|
||||
GraphTargetItem etype = type(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables);
|
||||
NameAVM2Item e = new NameAVM2Item(etype, lexer.yyline(), enamestr, new ExceptionAVM2Item(null)/*?*/, true/*?*/, openedNamespaces, abcIndex);
|
||||
NameAVM2Item e = new NameAVM2Item(etype, lexer.yyline(), false, enamestr, new ExceptionAVM2Item(null)/*?*/, true/*?*/, openedNamespaces, abcIndex);
|
||||
variables.add(e);
|
||||
catchExceptions.add(e);
|
||||
e.setSlotNumber(1);
|
||||
@@ -2491,8 +2501,8 @@ public class ActionScript3Parser {
|
||||
}
|
||||
s = lex();
|
||||
expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER);
|
||||
DottedChain fullName = new DottedChain(new String[]{}, "");
|
||||
fullName = fullName.addWithSuffix(s.value.toString());
|
||||
DottedChain fullName = new DottedChain(new String[]{});
|
||||
fullName = fullName.add(s.value.toString(), "");
|
||||
s = lex();
|
||||
boolean isStar = false;
|
||||
while (s.type == SymbolType.DOT) {
|
||||
@@ -2504,7 +2514,7 @@ public class ActionScript3Parser {
|
||||
break;
|
||||
}
|
||||
expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER);
|
||||
fullName = fullName.addWithSuffix(s.value.toString());
|
||||
fullName = fullName.add(s.value.toString(), "");
|
||||
s = lex();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,26 +1,28 @@
|
||||
/* The following code was generated by JFlex 1.6.0 */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010-2022 JPEXS, All rights reserved.
|
||||
*
|
||||
* Copyright (C) 2010-2016 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.abc.avm2.parser.script;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.AVM2ParseException;
|
||||
import java.io.StringReader;
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
import java.math.BigInteger;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -98,11 +98,11 @@ public class CallAVM2Item extends AVM2Item {
|
||||
}
|
||||
}
|
||||
if (cname != null && AVM2SourceGenerator.searchPrototypeChain(otherNs, localData.privateNs, localData.protectedNs, true, g.abcIndex, pkgName, cname, n.getVariableName(), outName, outNs, outPropNs, outPropNsKind, outPropNsIndex, outPropType, outPropValue, outPropValueABC, isType)) {
|
||||
NameAVM2Item nobj = new NameAVM2Item(new TypeItem(localData.getFullClass()), n.line, "this", null, false, n.openedNamespaces, abcIndex);
|
||||
NameAVM2Item nobj = new NameAVM2Item(new TypeItem(localData.getFullClass()), n.line, false, "this", null, false, n.openedNamespaces, abcIndex);
|
||||
nobj.setRegNumber(0);
|
||||
obj = nobj;
|
||||
}
|
||||
PropertyAVM2Item p = new PropertyAVM2Item(obj, n.getVariableName(), g.abcIndex, n.openedNamespaces, new ArrayList<>());
|
||||
PropertyAVM2Item p = new PropertyAVM2Item(obj, n.isAttribute(), n.getVariableName(), g.abcIndex, n.openedNamespaces, new ArrayList<>());
|
||||
p.setAssignedValue(n.getAssignedValue());
|
||||
callable = p;
|
||||
}
|
||||
@@ -143,7 +143,7 @@ public class CallAVM2Item extends AVM2Item {
|
||||
}
|
||||
|
||||
if (cname != null && AVM2SourceGenerator.searchPrototypeChain(otherNs, localData.privateNs, localData.protectedNs, true, g.abcIndex, pkgName, cname, prop.propertyName, outName, outNs, outPropNs, outPropNsKind, outPropNsIndex, outPropType, outPropValue, outPropValueAbc, isType) && (localData.getFullClass().equals(outNs.getVal().addWithSuffix(outName.getVal()).toRawString()))) {
|
||||
NameAVM2Item nobj = new NameAVM2Item(new TypeItem(localData.getFullClass()), 0, "this", null, false, new ArrayList<>(), abcIndex);
|
||||
NameAVM2Item nobj = new NameAVM2Item(new TypeItem(localData.getFullClass()), 0, false, "this", null, false, new ArrayList<>(), abcIndex);
|
||||
nobj.setRegNumber(0);
|
||||
obj = nobj;
|
||||
}
|
||||
|
||||
@@ -49,6 +49,8 @@ import java.util.Objects;
|
||||
*/
|
||||
public class NameAVM2Item extends AssignableAVM2Item {
|
||||
|
||||
private boolean attribute;
|
||||
|
||||
private String variableName;
|
||||
|
||||
private boolean definition;
|
||||
@@ -77,7 +79,7 @@ public class NameAVM2Item extends AssignableAVM2Item {
|
||||
|
||||
@Override
|
||||
public AssignableAVM2Item copy() {
|
||||
NameAVM2Item c = new NameAVM2Item(type, line, variableName, assignedValue, definition, openedNamespaces, abcIndex);
|
||||
NameAVM2Item c = new NameAVM2Item(type, line, attribute, variableName, assignedValue, definition, openedNamespaces, abcIndex);
|
||||
c.setNs(ns);
|
||||
c.regNumber = regNumber;
|
||||
c.unresolved = unresolved;
|
||||
@@ -85,6 +87,12 @@ public class NameAVM2Item extends AssignableAVM2Item {
|
||||
return c;
|
||||
}
|
||||
|
||||
public boolean isAttribute() {
|
||||
return attribute;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setSlotScope(int slotScope) {
|
||||
this.slotScope = slotScope;
|
||||
}
|
||||
@@ -137,8 +145,9 @@ public class NameAVM2Item extends AssignableAVM2Item {
|
||||
return variableName;
|
||||
}
|
||||
|
||||
public NameAVM2Item(GraphTargetItem type, int line, String variableName, GraphTargetItem storeValue, boolean definition, List<NamespaceItem> openedNamespaces, AbcIndexing abcIndex) {
|
||||
public NameAVM2Item(GraphTargetItem type, int line, boolean attribute, String variableName, GraphTargetItem storeValue, boolean definition, List<NamespaceItem> openedNamespaces, AbcIndexing abcIndex) {
|
||||
super(storeValue);
|
||||
this.attribute = attribute;
|
||||
this.variableName = variableName;
|
||||
this.assignedValue = storeValue;
|
||||
this.definition = definition;
|
||||
|
||||
@@ -86,7 +86,7 @@ public class NamespaceItem {
|
||||
}
|
||||
if (kind == Namespace.KIND_NAMESPACE) {
|
||||
String custom = name.toRawString();
|
||||
PropertyAVM2Item prop = new PropertyAVM2Item(null, custom, abcIndex, openedNamespaces, new ArrayList<>());
|
||||
PropertyAVM2Item prop = new PropertyAVM2Item(null, false, custom, abcIndex, openedNamespaces, new ArrayList<>());
|
||||
Reference<ValueKind> value = new Reference<>(null);
|
||||
Reference<ABC> outAbc = new Reference<>(null);
|
||||
Reference<Boolean> isType = new Reference<>(false);
|
||||
|
||||
@@ -57,6 +57,8 @@ import java.util.logging.Logger;
|
||||
*/
|
||||
public class PropertyAVM2Item extends AssignableAVM2Item {
|
||||
|
||||
public boolean attribute;
|
||||
|
||||
public String propertyName;
|
||||
|
||||
public GraphTargetItem object;
|
||||
@@ -71,11 +73,12 @@ public class PropertyAVM2Item extends AssignableAVM2Item {
|
||||
|
||||
@Override
|
||||
public AssignableAVM2Item copy() {
|
||||
PropertyAVM2Item p = new PropertyAVM2Item(object, propertyName, abcIndex, openedNamespaces, callStack);
|
||||
PropertyAVM2Item p = new PropertyAVM2Item(object, attribute, propertyName, abcIndex, openedNamespaces, callStack);
|
||||
return p;
|
||||
}
|
||||
|
||||
public PropertyAVM2Item(GraphTargetItem object, String propertyName, AbcIndexing abcIndex, List<NamespaceItem> openedNamespaces, List<MethodBody> callStack) {
|
||||
public PropertyAVM2Item(GraphTargetItem object, boolean attribute, String propertyName, AbcIndexing abcIndex, List<NamespaceItem> openedNamespaces, List<MethodBody> callStack) {
|
||||
this.attribute = attribute;
|
||||
this.propertyName = propertyName;
|
||||
this.object = object;
|
||||
this.abcIndex = abcIndex;
|
||||
@@ -160,7 +163,7 @@ public class PropertyAVM2Item extends AssignableAVM2Item {
|
||||
int propIndex = 0;
|
||||
ABC abc = abcIndex.getSelectedAbc();
|
||||
AVM2ConstantPool constants = abc.constants;
|
||||
if (!propertyName.startsWith("@")) {
|
||||
if (!attribute) {
|
||||
|
||||
if (scopeStack.isEmpty()) { //Everything is multiname when with command
|
||||
if (objType == null) {
|
||||
@@ -417,17 +420,16 @@ public class PropertyAVM2Item extends AssignableAVM2Item {
|
||||
|
||||
if (propIndex == 0 && !mustExist) {
|
||||
String pname = propertyName;
|
||||
boolean attr = pname.startsWith("@");
|
||||
if (attr) {
|
||||
if (attribute) {
|
||||
pname = pname.substring(1);
|
||||
}
|
||||
Multiname multiname;
|
||||
if (attr && pname.isEmpty()) {
|
||||
if (attribute && pname.isEmpty()) {
|
||||
multiname = Multiname.createMultinameL(true,
|
||||
constants.getNamespaceSetId(new int[]{constants.getNamespaceId(Namespace.KIND_PACKAGE_INTERNAL, localData.pkg, 0, true)}, true));
|
||||
} else {
|
||||
int name_index = constants.getStringId("*".equals(pname) ? null : pname, true); //Note: name = * is for .@* attribute
|
||||
multiname = Multiname.createMultiname(attr, name_index, allNsSet(abcIndex));
|
||||
multiname = Multiname.createMultiname(attribute, name_index, allNsSet(abcIndex));
|
||||
}
|
||||
propIndex = constants.getMultinameId(multiname, true);
|
||||
propType = TypeItem.UNBOUNDED;
|
||||
@@ -557,7 +559,7 @@ public class PropertyAVM2Item extends AssignableAVM2Item {
|
||||
}
|
||||
}
|
||||
if (!localData.subMethod && cname != null && AVM2SourceGenerator.searchPrototypeChain(otherNs, localData.privateNs, localData.protectedNs, true, abcIndex, pkgName, cname, propertyName, outName, outNs, outPropNs, outPropNsKind, outPropNsIndex, outPropType, outPropValue, outPropValueAbc, isType) && (localData.getFullClass().equals(outNs.getVal().addWithSuffix(outName.getVal()).toRawString()))) {
|
||||
NameAVM2Item nobj = new NameAVM2Item(new TypeItem(localData.getFullClass()), 0, "this", null, false, openedNamespaces, abcIndex);
|
||||
NameAVM2Item nobj = new NameAVM2Item(new TypeItem(localData.getFullClass()), 0, false, "this", null, false, openedNamespaces, abcIndex);
|
||||
nobj.setRegNumber(0);
|
||||
obj = nobj;
|
||||
} else {
|
||||
|
||||
@@ -295,13 +295,13 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item {
|
||||
if (a instanceof NameAVM2Item) {
|
||||
NameAVM2Item n = (NameAVM2Item) a;
|
||||
if (n.isDefinition() && name.get(0).equals(n.getVariableName())) {
|
||||
NameAVM2Item ret = new NameAVM2Item(n.type, n.line, name.get(0), null, false, openedNamespaces, abcIndex);
|
||||
NameAVM2Item ret = new NameAVM2Item(n.type, n.line, name.isAttribute(0), name.get(0), null, false, openedNamespaces, abcIndex);
|
||||
ret.setSlotScope(n.getSlotScope());
|
||||
ret.setSlotNumber(n.getSlotNumber());
|
||||
ret.setRegNumber(n.getRegNumber());
|
||||
resolved = ret;
|
||||
for (int i = 1; i < name.size(); i++) {
|
||||
resolved = new PropertyAVM2Item(resolved, name.get(i), abc, openedNamespaces, new ArrayList<>());
|
||||
resolved = new PropertyAVM2Item(resolved, name.isAttribute(i), name.get(i), abc, openedNamespaces, new ArrayList<>());
|
||||
if (i == name.size() - 1) {
|
||||
((PropertyAVM2Item) resolved).assignedValue = assignedValue;
|
||||
}
|
||||
@@ -325,10 +325,10 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item {
|
||||
t = paramTypes.get(ind);
|
||||
} //else rest parameter
|
||||
|
||||
GraphTargetItem ret = new NameAVM2Item(t, line, name.get(0), null, false, openedNamespaces, abcIndex);
|
||||
GraphTargetItem ret = new NameAVM2Item(t, line, name.isAttribute(0), name.get(0), null, false, openedNamespaces, abcIndex);
|
||||
resolved = ret;
|
||||
for (int i = 1; i < name.size(); i++) {
|
||||
resolved = new PropertyAVM2Item(resolved, name.get(i), abc, openedNamespaces, new ArrayList<>());
|
||||
resolved = new PropertyAVM2Item(resolved, name.isAttribute(i), name.get(i), abc, openedNamespaces, new ArrayList<>());
|
||||
if (i == name.size() - 1) {
|
||||
((PropertyAVM2Item) resolved).assignedValue = assignedValue;
|
||||
}
|
||||
@@ -341,7 +341,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item {
|
||||
|
||||
boolean isProperty = false;
|
||||
if (localData != null) { //resolve can be called without localData
|
||||
PropertyAVM2Item resolvedx = new PropertyAVM2Item(null, name.get(0), abc, openedNamespaces, callStack);
|
||||
PropertyAVM2Item resolvedx = new PropertyAVM2Item(null, name.isAttribute(0), name.get(0), abc, openedNamespaces, callStack);
|
||||
((PropertyAVM2Item) resolvedx).scopeStack = scopeStack;
|
||||
((PropertyAVM2Item) resolvedx).setAssignedValue(assignedValue);
|
||||
Reference<GraphTargetItem> objectType = new Reference<>(null);
|
||||
@@ -362,13 +362,13 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item {
|
||||
DottedChain classChain = DottedChain.parseWithSuffix(currentClass);
|
||||
DottedChain pkg = classChain.getWithoutLast();
|
||||
|
||||
TypeItem ti = new TypeItem(pkg.addWithSuffix(name.get(0)));
|
||||
TypeItem ti = new TypeItem(pkg.addWithSuffix(name.get(0)));
|
||||
AbcIndexing.ClassIndex ci = abc.findClass(ti);
|
||||
|
||||
if (ci != null) {
|
||||
resolved = ti;
|
||||
for (int i = 1; i < name.size(); i++) {
|
||||
resolved = new PropertyAVM2Item(resolved, name.get(i), abc, openedNamespaces, new ArrayList<>());
|
||||
resolved = new PropertyAVM2Item(resolved, name.isAttribute(i), name.get(i), abc, openedNamespaces, new ArrayList<>());
|
||||
if (i == name.size() - 1) {
|
||||
((PropertyAVM2Item) resolved).assignedValue = assignedValue;
|
||||
}
|
||||
@@ -387,7 +387,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item {
|
||||
TypeItem ret = new TypeItem(imp);
|
||||
resolved = ret;
|
||||
for (int i = 1; i < name.size(); i++) {
|
||||
resolved = new PropertyAVM2Item(resolved, name.get(i), abc, openedNamespaces, new ArrayList<>());
|
||||
resolved = new PropertyAVM2Item(resolved, name.isAttribute(i), name.get(i), abc, openedNamespaces, new ArrayList<>());
|
||||
if (i == name.size() - 1) {
|
||||
((PropertyAVM2Item) resolved).assignedValue = assignedValue;
|
||||
}
|
||||
@@ -420,7 +420,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item {
|
||||
TypeItem ret = new TypeItem(fname);
|
||||
resolved = ret;
|
||||
for (int j = i + 1; j < name.size(); j++) {
|
||||
resolved = new PropertyAVM2Item(resolved, name.get(j), abc, openedNamespaces, new ArrayList<>());
|
||||
resolved = new PropertyAVM2Item(resolved, name.isAttribute(j), name.get(j), abc, openedNamespaces, new ArrayList<>());
|
||||
if (j == name.size() - 1) {
|
||||
((PropertyAVM2Item) resolved).assignedValue = assignedValue;
|
||||
}
|
||||
@@ -449,7 +449,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item {
|
||||
TypeItem ret = ti;
|
||||
resolved = ret;
|
||||
for (int i = 1; i < name.size(); i++) {
|
||||
resolved = new PropertyAVM2Item(resolved, name.get(i), abc, openedNamespaces, new ArrayList<>());
|
||||
resolved = new PropertyAVM2Item(resolved, name.isAttribute(i), name.get(i), abc, openedNamespaces, new ArrayList<>());
|
||||
if (i == name.size() - 1) {
|
||||
((PropertyAVM2Item) resolved).assignedValue = assignedValue;
|
||||
}
|
||||
@@ -483,10 +483,10 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item {
|
||||
}
|
||||
}
|
||||
|
||||
NameAVM2Item ret = new NameAVM2Item(ntype, line, name.get(0), null, false, openedNamespaces, abcIndex);
|
||||
NameAVM2Item ret = new NameAVM2Item(ntype, line, name.isAttribute(0), name.get(0), null, false, openedNamespaces, abcIndex);
|
||||
resolved = ret;
|
||||
for (int i = 1; i < name.size(); i++) {
|
||||
resolved = new PropertyAVM2Item(resolved, name.get(i), abc, openedNamespaces, new ArrayList<>());
|
||||
resolved = new PropertyAVM2Item(resolved, name.isAttribute(i), name.get(i), abc, openedNamespaces, new ArrayList<>());
|
||||
if (i == name.size() - 1) {
|
||||
((PropertyAVM2Item) resolved).assignedValue = assignedValue;
|
||||
}
|
||||
@@ -509,7 +509,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item {
|
||||
resolved = null;
|
||||
GraphTargetItem ret = null;
|
||||
for (int i = 0; i < name.size(); i++) {
|
||||
resolved = new PropertyAVM2Item(resolved, name.get(i), abc, openedNamespaces, callStack);
|
||||
resolved = new PropertyAVM2Item(resolved, name.isAttribute(i), name.get(i), abc, openedNamespaces, callStack);
|
||||
if (ret == null) {
|
||||
((PropertyAVM2Item) resolved).scopeStack = scopeStack;
|
||||
ret = resolved;
|
||||
|
||||
@@ -418,7 +418,7 @@ public class Multiname {
|
||||
if (ns != null) {
|
||||
return ns.getName(constants).add(name, withSuffix ? getNamespaceSuffix() : "");
|
||||
}
|
||||
return new DottedChain(new String[]{name}, withSuffix ? getNamespaceSuffix() : "");
|
||||
return new DottedChain(new String[]{name}, new String[]{withSuffix ? getNamespaceSuffix() : ""});
|
||||
}
|
||||
|
||||
public Namespace getNamespace(AVM2ConstantPool constants) {
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
/* The following code was generated by JFlex 1.6.0 */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010-2022 JPEXS, All rights reserved.
|
||||
*
|
||||
* Copyright (C) 2010-2016 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.
|
||||
*/
|
||||
|
||||
@@ -167,7 +167,7 @@ public class LinkReportExporter {
|
||||
|
||||
sb.append(indent(3)).append("<dep id=\"AS3\" />").append(newLineChar); //Automatic
|
||||
|
||||
tc.getDependencies(scriptIndex, -1, false, null, abc, dependencies, uses, new DottedChain(new String[]{"FAKE!PACKAGE"}, ""), new ArrayList<>());
|
||||
tc.getDependencies(scriptIndex, -1, false, null, abc, dependencies, uses, new DottedChain(new String[]{"FAKE!PACKAGE"}), new ArrayList<>());
|
||||
for (Dependency dependency : dependencies) {
|
||||
DottedChain dc = dependency.getId();
|
||||
if (!"*".equals(dc.getLast())) {
|
||||
|
||||
@@ -144,12 +144,12 @@ public class SwfToSwcExporter {
|
||||
sb.append(" <def id=\"").append(defId).append("\" />\n");
|
||||
|
||||
Set<DottedChain> allDeps = new HashSet<>();
|
||||
allDeps.add(new DottedChain(new String[]{"AS3"}, ""));
|
||||
allDeps.add(new DottedChain(new String[]{"AS3"}, new String[]{""}));
|
||||
sb.append(" <dep id=\"AS3\" type=\"").append(DEPENDENCY_NAMESPACE).append("\" />\n");
|
||||
if (!skipDependencies) {
|
||||
List<Dependency> dependencies = new ArrayList<>();
|
||||
List<String> uses = new ArrayList<>();
|
||||
pack.abc.script_info.get(pack.scriptIndex).traits.getDependencies(pack.scriptIndex, -1, false, null, pack.abc, dependencies, uses, new DottedChain(new String[]{"NO:PACKAGE"}, ""), new ArrayList<>());
|
||||
pack.abc.script_info.get(pack.scriptIndex).traits.getDependencies(pack.scriptIndex, -1, false, null, pack.abc, dependencies, uses, new DottedChain(new String[]{"NO:PACKAGE"}), new ArrayList<>());
|
||||
|
||||
for (Dependency d : dependencies) {
|
||||
if ("*".equals(d.getId().getLast())) {
|
||||
|
||||
@@ -30,41 +30,41 @@ import java.util.List;
|
||||
*/
|
||||
public class DottedChain implements Serializable, Comparable<DottedChain> {
|
||||
|
||||
public static final String NO_SUFFIX = "";
|
||||
|
||||
public static final DottedChain EMPTY = new DottedChain(true);
|
||||
|
||||
public static final DottedChain TOPLEVEL = new DottedChain(new String[]{}, NO_SUFFIX);
|
||||
public static final DottedChain TOPLEVEL = new DottedChain(new String[]{});
|
||||
|
||||
public static final DottedChain BOOLEAN = new DottedChain(new String[]{"Boolean"}, NO_SUFFIX);
|
||||
public static final DottedChain BOOLEAN = new DottedChain(new String[]{"Boolean"});
|
||||
|
||||
public static final DottedChain STRING = new DottedChain(new String[]{"String"}, NO_SUFFIX);
|
||||
public static final DottedChain STRING = new DottedChain(new String[]{"String"});
|
||||
|
||||
public static final DottedChain ARRAY = new DottedChain(new String[]{"Array"}, NO_SUFFIX);
|
||||
public static final DottedChain ARRAY = new DottedChain(new String[]{"Array"});
|
||||
|
||||
public static final DottedChain NUMBER = new DottedChain(new String[]{"Number"}, NO_SUFFIX);
|
||||
public static final DottedChain NUMBER = new DottedChain(new String[]{"Number"});
|
||||
|
||||
public static final DottedChain OBJECT = new DottedChain(new String[]{"Object"}, NO_SUFFIX);
|
||||
public static final DottedChain OBJECT = new DottedChain(new String[]{"Object"});
|
||||
|
||||
public static final DottedChain INT = new DottedChain(new String[]{"int"}, NO_SUFFIX);
|
||||
public static final DottedChain INT = new DottedChain(new String[]{"int"});
|
||||
|
||||
public static final DottedChain UINT = new DottedChain(new String[]{"uint"}, NO_SUFFIX);
|
||||
public static final DottedChain UINT = new DottedChain(new String[]{"uint"});
|
||||
|
||||
public static final DottedChain UNDEFINED = new DottedChain(new String[]{"Undefined"}, NO_SUFFIX);
|
||||
public static final DottedChain UNDEFINED = new DottedChain(new String[]{"Undefined"});
|
||||
|
||||
public static final DottedChain XML = new DottedChain(new String[]{"XML"}, NO_SUFFIX);
|
||||
public static final DottedChain XML = new DottedChain(new String[]{"XML"});
|
||||
|
||||
public static final DottedChain NULL = new DottedChain(new String[]{"null"}, NO_SUFFIX);
|
||||
public static final DottedChain NULL = new DottedChain(new String[]{"null"});
|
||||
|
||||
public static final DottedChain FUNCTION = new DottedChain(new String[]{"Function"}, NO_SUFFIX);
|
||||
public static final DottedChain FUNCTION = new DottedChain(new String[]{"Function"});
|
||||
|
||||
public static final DottedChain VOID = new DottedChain(new String[]{"void"}, NO_SUFFIX);
|
||||
public static final DottedChain VOID = new DottedChain(new String[]{"void"});
|
||||
|
||||
public static final DottedChain NAMESPACE = new DottedChain(new String[]{"Namespace"}, NO_SUFFIX);
|
||||
public static final DottedChain NAMESPACE = new DottedChain(new String[]{"Namespace"});
|
||||
|
||||
public static final DottedChain ALL = new DottedChain(new String[]{"*"}, NO_SUFFIX);
|
||||
public static final DottedChain ALL = new DottedChain(new String[]{"*"});
|
||||
|
||||
private final String[] parts;
|
||||
|
||||
private final boolean[] attributes;
|
||||
|
||||
private final int length;
|
||||
|
||||
@@ -72,25 +72,42 @@ public class DottedChain implements Serializable, Comparable<DottedChain> {
|
||||
|
||||
private boolean isNull = false;
|
||||
|
||||
private String namespaceSuffix = "";
|
||||
private String[] namespaceSuffixes;
|
||||
|
||||
public String getNamespaceSuffix() {
|
||||
return namespaceSuffix;
|
||||
public String getNamespaceSuffix(int index) {
|
||||
return namespaceSuffixes[index];
|
||||
}
|
||||
|
||||
public String getLastNamespaceSuffix() {
|
||||
if (length == 0) {
|
||||
return "";
|
||||
}
|
||||
return namespaceSuffixes[length - 1];
|
||||
}
|
||||
|
||||
|
||||
public static final DottedChain parseWithSuffix(String name) {
|
||||
if (name == null) {
|
||||
return DottedChain.EMPTY;
|
||||
} else if (name.isEmpty()) {
|
||||
return DottedChain.TOPLEVEL;
|
||||
} else {
|
||||
String nameNoSuffix = name;
|
||||
String namespaceSuffix = "";
|
||||
if (name.matches(".*#[0-9]+$")) {
|
||||
nameNoSuffix = name.substring(0, name.lastIndexOf("#"));
|
||||
namespaceSuffix = name.substring(name.lastIndexOf("#"));
|
||||
String parts[] = name.split("\\.");
|
||||
String nsSuffixes[] = new String[parts.length];
|
||||
int i = 0;
|
||||
for (String part : parts) {
|
||||
String nameNoSuffix = part;
|
||||
String namespaceSuffix = "";
|
||||
if (part.matches(".*#[0-9]+$")) {
|
||||
nameNoSuffix = part.substring(0, part.lastIndexOf("#"));
|
||||
namespaceSuffix = part.substring(part.lastIndexOf("#"));
|
||||
}
|
||||
parts[i] = nameNoSuffix;
|
||||
nsSuffixes[i] = namespaceSuffix;
|
||||
i++;
|
||||
}
|
||||
return new DottedChain(nameNoSuffix.split("\\."), namespaceSuffix);
|
||||
|
||||
return new DottedChain(parts, nsSuffixes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,37 +116,58 @@ public class DottedChain implements Serializable, Comparable<DottedChain> {
|
||||
this.parts = new String[0];
|
||||
this.length = 0;
|
||||
this.hash = 0;
|
||||
this.attributes = new boolean[0];
|
||||
this.namespaceSuffixes = new String[0];
|
||||
}
|
||||
|
||||
public DottedChain(DottedChain src) {
|
||||
this(src.parts, src.namespaceSuffix);
|
||||
this(src.parts, src.namespaceSuffixes);
|
||||
this.isNull = src.isNull;
|
||||
}
|
||||
|
||||
public DottedChain(String[] parts) {
|
||||
this(Arrays.asList(parts));
|
||||
}
|
||||
|
||||
public DottedChain(List<String> parts) {
|
||||
length = parts.size();
|
||||
this.parts = parts.toArray(new String[length]);
|
||||
attributes = new boolean[length];
|
||||
hash = calcHash();
|
||||
this.namespaceSuffixes = new String[length];
|
||||
for(int i = 0; i < length; i++) {
|
||||
namespaceSuffixes[i] = "";
|
||||
}
|
||||
}
|
||||
|
||||
/*public DottedChain(String onePart, String namespaceSuffix) {
|
||||
this(new String[]{onePart}, namespaceSuffix);
|
||||
}*/
|
||||
public DottedChain(String[] parts, String namespaceSuffix) {
|
||||
public DottedChain(String[] parts, String[] namespaceSuffixes) {
|
||||
this(new boolean[parts.length], parts, namespaceSuffixes);
|
||||
}
|
||||
|
||||
public DottedChain(boolean attributes[], String[] parts, String[] namespaceSuffixes) {
|
||||
if (parts.length == 1 && parts[0].isEmpty()) {
|
||||
length = 0;
|
||||
this.parts = new String[0];
|
||||
this.parts = new String[0];
|
||||
} else {
|
||||
length = parts.length;
|
||||
this.parts = parts;
|
||||
this.parts = parts;
|
||||
}
|
||||
this.attributes = attributes;
|
||||
hash = calcHash();
|
||||
this.namespaceSuffix = namespaceSuffix;
|
||||
this.namespaceSuffixes = namespaceSuffixes;
|
||||
}
|
||||
|
||||
private DottedChain(String[] parts, int length) {
|
||||
this.length = length;
|
||||
this.parts = parts;
|
||||
attributes = new boolean[length];
|
||||
this.namespaceSuffixes = new String[length];
|
||||
for(int i = 0; i < length; i++) {
|
||||
namespaceSuffixes[i] = "";
|
||||
}
|
||||
hash = calcHash();
|
||||
}
|
||||
|
||||
@@ -152,6 +190,13 @@ public class DottedChain implements Serializable, Comparable<DottedChain> {
|
||||
|
||||
return parts[index];
|
||||
}
|
||||
|
||||
public boolean isAttribute(int index) {
|
||||
if (index >= length) {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
return attributes[index];
|
||||
}
|
||||
|
||||
public DottedChain subChain(int count) {
|
||||
if (count > length) {
|
||||
@@ -171,6 +216,17 @@ public class DottedChain implements Serializable, Comparable<DottedChain> {
|
||||
return parts[length - 1];
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isLastAttribute() {
|
||||
if (isNull) {
|
||||
return false;
|
||||
}
|
||||
if (length == 0) {
|
||||
return false;
|
||||
} else {
|
||||
return attributes[length - 1];
|
||||
}
|
||||
}
|
||||
|
||||
public DottedChain getWithoutLast() {
|
||||
if (isNull) {
|
||||
@@ -194,16 +250,25 @@ public class DottedChain implements Serializable, Comparable<DottedChain> {
|
||||
}
|
||||
|
||||
public DottedChain add(String name, String namespaceSuffix) {
|
||||
return add(false, name, namespaceSuffix);
|
||||
}
|
||||
public DottedChain add(boolean attribute, String name, String namespaceSuffix) {
|
||||
if (name == null) {
|
||||
return new DottedChain(this);
|
||||
}
|
||||
String[] nparts = new String[length + 1];
|
||||
boolean[] nattributes = new boolean[length + 1];
|
||||
String[] nnamespaceSuffixes = new String[length + 1];
|
||||
if (length > 0) {
|
||||
System.arraycopy(parts, 0, nparts, 0, length);
|
||||
System.arraycopy(attributes, 0, nattributes, 0, length);
|
||||
System.arraycopy(namespaceSuffixes, 0, nnamespaceSuffixes, 0, length);
|
||||
}
|
||||
|
||||
|
||||
nattributes[nattributes.length - 1] = attribute;
|
||||
nparts[nparts.length - 1] = name;
|
||||
return new DottedChain(nparts, namespaceSuffix);
|
||||
nnamespaceSuffixes[nparts.length - 1] = namespaceSuffix;
|
||||
return new DottedChain(nparts, nnamespaceSuffixes);
|
||||
}
|
||||
|
||||
protected String toString(boolean as3, boolean raw, boolean withSuffix) {
|
||||
@@ -223,10 +288,11 @@ public class DottedChain implements Serializable, Comparable<DottedChain> {
|
||||
String part = parts[i];
|
||||
boolean lastStar = i == length - 1 && "*".equals(part);
|
||||
ret.append((raw || lastStar) ? part : IdentifiersDeobfuscation.printIdentifier(as3, part));
|
||||
if (withSuffix) {
|
||||
ret.append(namespaceSuffixes[i]);
|
||||
}
|
||||
}
|
||||
if (withSuffix) {
|
||||
ret.append(namespaceSuffix);
|
||||
}
|
||||
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
@@ -305,6 +371,12 @@ public class DottedChain implements Serializable, Comparable<DottedChain> {
|
||||
if (!s1.equals(s2)) {
|
||||
return false;
|
||||
}
|
||||
if (attributes[i] != other.attributes[i]) {
|
||||
return false;
|
||||
}
|
||||
if (!namespaceSuffixes[i].equals(other.namespaceSuffixes[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -43,7 +43,7 @@ public class TypeItem extends GraphTargetItem {
|
||||
public final DottedChain fullTypeName;
|
||||
|
||||
public TypeItem(String s) {
|
||||
this(s == null ? new DottedChain(new String[]{}, "") : DottedChain.parseWithSuffix(s));
|
||||
this(s == null ? new DottedChain(new String[]{}, new String[]{""}) : DottedChain.parseWithSuffix(s));
|
||||
}
|
||||
|
||||
public TypeItem(DottedChain fullTypeName) {
|
||||
|
||||
Reference in New Issue
Block a user