mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-23 07:05:33 +00:00
A little optimization, dottedchain uses ArrayLists
This commit is contained in:
@@ -88,7 +88,19 @@ public class AVM2ConstantPool implements Cloneable {
|
||||
|
||||
@Internal
|
||||
public Map<String, DottedChain> dottedChainCache = new HashMap<>();
|
||||
|
||||
@Internal
|
||||
public Map<Multiname, DottedChain> multinameWithNamespaceCache = new HashMap<>();
|
||||
|
||||
|
||||
public DottedChain getCachedMultinameWithNamespace(Multiname multiName) {
|
||||
return multinameWithNamespaceCache.get(multiName);
|
||||
}
|
||||
|
||||
public void cacheMultinameWithNamespace(Multiname multiName, DottedChain multinameWithNamespace) {
|
||||
multinameWithNamespaceCache.put(multiName, multinameWithNamespace);
|
||||
}
|
||||
|
||||
private void ensureDefault(List<?> list) {
|
||||
if (list.isEmpty()) {
|
||||
list.add(null);
|
||||
@@ -681,6 +693,7 @@ public class AVM2ConstantPool implements Cloneable {
|
||||
ret.constant_namespace_set = new HashArrayList<>(constant_namespace_set);
|
||||
ret.constant_multiname = new HashArrayList<>(constant_multiname);
|
||||
ret.dottedChainCache = new HashMap<>();
|
||||
ret.multinameWithNamespaceCache = new HashMap<>();
|
||||
return ret;
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
throw new RuntimeException();
|
||||
|
||||
@@ -111,6 +111,7 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
@@ -2787,7 +2788,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
|
||||
if (m != null) {
|
||||
Namespace ns = ci.abc.instance_info.get(ci.index).getName(ci.abc.constants).getNamespace(ci.abc.constants);
|
||||
String n = m.getName(ci.abc.constants, new ArrayList<>(), true, true /*FIXME!!*/);
|
||||
String nsn = ns == null ? null : ns.getName(ci.abc.constants).toRawString();
|
||||
String nsn = ns == null ? null : ns.getRawName(ci.abc.constants);
|
||||
name_index = constants.getQnameId(
|
||||
n,
|
||||
ns == null ? Namespace.KIND_PACKAGE : ns.kind,
|
||||
@@ -2795,10 +2796,11 @@ public class AVM2SourceGenerator implements SourceGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
String pkgRaw = pkg.toRawString();
|
||||
for (int i = 1; i < constants.getMultinameCount(); i++) {
|
||||
Multiname mname = constants.getMultiname(i);
|
||||
if (mname != null && name.equals(mname.getName(constants, null, true, true /*FIXME!!*/))) {
|
||||
if (mname.getNamespace(constants) != null && pkg.equals(mname.getNamespace(constants).getName(constants))) {
|
||||
if (mname.getNamespace(constants) != null && Objects.equals(pkgRaw, mname.getNamespace(constants).getRawName(constants))){
|
||||
name_index = i;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -536,29 +536,29 @@ public final class AbcIndexing {
|
||||
*/
|
||||
//search all static first
|
||||
if (findStatic && classProperties.containsKey(prop)) {
|
||||
if (!classProperties.containsKey(prop)) {
|
||||
if (parent != null) {
|
||||
TraitIndex ret = parent.findProperty(prop, findStatic, findInstance, findProtected);
|
||||
if (ret != null) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return classProperties.get(prop);
|
||||
TraitIndex ti = classProperties.get(prop);
|
||||
if (ti != null) {
|
||||
return ti;
|
||||
}
|
||||
if (parent != null) {
|
||||
TraitIndex ret = parent.findProperty(prop, findStatic, findInstance, findProtected);
|
||||
if (ret != null) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//now search instance
|
||||
if (findInstance && instanceProperties.containsKey(prop)) {
|
||||
if (!instanceProperties.containsKey(prop)) {
|
||||
if (parent != null) {
|
||||
TraitIndex ret = parent.findProperty(prop, findStatic, findInstance, findProtected);
|
||||
if (ret != null) {
|
||||
return ret;
|
||||
}
|
||||
TraitIndex ti = instanceProperties.get(prop);
|
||||
if (ti != null) {
|
||||
return ti;
|
||||
}
|
||||
if (parent != null) {
|
||||
TraitIndex ret = parent.findProperty(prop, findStatic, findInstance, findProtected);
|
||||
if (ret != null) {
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
return instanceProperties.get(prop);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -406,6 +406,10 @@ public class Multiname {
|
||||
}
|
||||
|
||||
public DottedChain getNameWithNamespace(AVM2ConstantPool constants, boolean withSuffix) {
|
||||
DottedChain cached = constants.getCachedMultinameWithNamespace(this);
|
||||
if (cached != null) {
|
||||
return cached;
|
||||
}
|
||||
Namespace ns = getNamespace(constants);
|
||||
if (ns == null) {
|
||||
NamespaceSet nss = getNamespaceSet(constants);
|
||||
@@ -416,10 +420,14 @@ public class Multiname {
|
||||
}
|
||||
}
|
||||
String name = getName(constants, null, true, false);
|
||||
DottedChain ret;
|
||||
if (ns != null) {
|
||||
return ns.getName(constants).add(name, withSuffix ? getNamespaceSuffix() : "");
|
||||
ret = ns.getName(constants).add(name, withSuffix ? getNamespaceSuffix() : "");
|
||||
} else {
|
||||
ret = new DottedChain(new String[]{name}, new String[]{withSuffix ? getNamespaceSuffix() : ""});
|
||||
}
|
||||
return new DottedChain(new String[]{name}, new String[]{withSuffix ? getNamespaceSuffix() : ""});
|
||||
constants.cacheMultinameWithNamespace(this, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public Namespace getNamespace(AVM2ConstantPool constants) {
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -31,7 +32,7 @@ import java.util.List;
|
||||
public class DottedChain implements Serializable, Comparable<DottedChain> {
|
||||
|
||||
public static final DottedChain EMPTY = new DottedChain(true);
|
||||
|
||||
|
||||
public static final DottedChain UNBOUNDED = new DottedChain(new String[]{"*"});
|
||||
|
||||
public static final DottedChain TOPLEVEL = new DottedChain(new String[]{});
|
||||
@@ -64,30 +65,21 @@ public class DottedChain implements Serializable, Comparable<DottedChain> {
|
||||
|
||||
public static final DottedChain ALL = new DottedChain(new String[]{"*"});
|
||||
|
||||
private final String[] parts;
|
||||
|
||||
private final boolean[] attributes;
|
||||
|
||||
private final int length;
|
||||
|
||||
private final int hash;
|
||||
private List<PathPart> parts;
|
||||
|
||||
private boolean isNull = false;
|
||||
|
||||
private String[] namespaceSuffixes;
|
||||
|
||||
public String getNamespaceSuffix(int index) {
|
||||
return namespaceSuffixes[index];
|
||||
return parts.get(index).namespaceSuffix;
|
||||
}
|
||||
|
||||
public String getLastNamespaceSuffix() {
|
||||
if (length == 0) {
|
||||
if (parts.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
return namespaceSuffixes[length - 1];
|
||||
return parts.get(parts.size() - 1).namespaceSuffix;
|
||||
}
|
||||
|
||||
|
||||
public static final DottedChain parseNoSuffix(String name) {
|
||||
if (name == null) {
|
||||
return DottedChain.EMPTY;
|
||||
@@ -95,18 +87,15 @@ public class DottedChain implements Serializable, Comparable<DottedChain> {
|
||||
return DottedChain.TOPLEVEL;
|
||||
} else {
|
||||
String parts[] = name.split("\\.");
|
||||
String nsSuffixes[] = new String[parts.length];
|
||||
int i = 0;
|
||||
List<PathPart> newParts = new ArrayList<>();
|
||||
for (String part : parts) {
|
||||
String nameNoSuffix = part;
|
||||
parts[i] = nameNoSuffix;
|
||||
nsSuffixes[i] = "";
|
||||
i++;
|
||||
newParts.add(new PathPart(part, false, ""));
|
||||
}
|
||||
|
||||
return new DottedChain(parts, nsSuffixes);
|
||||
|
||||
return new DottedChain(newParts, false);
|
||||
}
|
||||
}
|
||||
|
||||
public static final DottedChain parseWithSuffix(String name) {
|
||||
if (name == null) {
|
||||
return DottedChain.EMPTY;
|
||||
@@ -114,86 +103,63 @@ public class DottedChain implements Serializable, Comparable<DottedChain> {
|
||||
return DottedChain.TOPLEVEL;
|
||||
} else {
|
||||
String parts[] = name.split("\\.");
|
||||
String nsSuffixes[] = new String[parts.length];
|
||||
int i = 0;
|
||||
List<PathPart> newParts = new ArrayList<>();
|
||||
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++;
|
||||
}
|
||||
newParts.add(new PathPart(nameNoSuffix, false, namespaceSuffix));
|
||||
}
|
||||
|
||||
return new DottedChain(parts, nsSuffixes);
|
||||
|
||||
return new DottedChain(newParts, false);
|
||||
}
|
||||
}
|
||||
|
||||
private DottedChain(boolean isNull) {
|
||||
this.isNull = isNull;
|
||||
this.parts = new String[0];
|
||||
this.length = 0;
|
||||
this.hash = 0;
|
||||
this.attributes = new boolean[0];
|
||||
this.namespaceSuffixes = new String[0];
|
||||
this.parts = new ArrayList<>();
|
||||
}
|
||||
|
||||
public DottedChain(DottedChain src) {
|
||||
this(src.parts, src.namespaceSuffixes);
|
||||
this.parts = new ArrayList<>(src.parts);
|
||||
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] = "";
|
||||
}
|
||||
|
||||
private DottedChain(List<PathPart> parts, boolean isNull) {
|
||||
this.parts = parts;
|
||||
this.isNull = isNull;
|
||||
}
|
||||
|
||||
public DottedChain(List<String> parts) {
|
||||
List<PathPart> newParts = new ArrayList<>();
|
||||
for (String part : parts) {
|
||||
newParts.add(new PathPart(part, false, ""));
|
||||
}
|
||||
this.parts = newParts;
|
||||
}
|
||||
|
||||
/*public DottedChain(String onePart, String namespaceSuffix) {
|
||||
this(new String[]{onePart}, 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];
|
||||
} else {
|
||||
length = parts.length;
|
||||
this.parts = parts;
|
||||
}
|
||||
this.attributes = attributes;
|
||||
hash = calcHash();
|
||||
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] = "";
|
||||
public DottedChain(boolean attributes[], String[] parts, String[] namespaceSuffixes) {
|
||||
List<PathPart> newParts = new ArrayList<>();
|
||||
for (int i = 0; i < attributes.length; i++) {
|
||||
newParts.add(new PathPart(parts[i], attributes[i], namespaceSuffixes[i]));
|
||||
}
|
||||
hash = calcHash();
|
||||
this.parts = newParts;
|
||||
|
||||
}
|
||||
|
||||
public boolean isTopLevel() {
|
||||
return !isNull && length == 0;
|
||||
return !isNull && parts.isEmpty();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
@@ -201,51 +167,51 @@ public class DottedChain implements Serializable, Comparable<DottedChain> {
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return length;
|
||||
return parts.size();
|
||||
}
|
||||
|
||||
public String get(int index) {
|
||||
if (index >= length) {
|
||||
if (index >= parts.size()) {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
return parts[index];
|
||||
return parts.get(index).name;
|
||||
}
|
||||
|
||||
|
||||
public boolean isAttribute(int index) {
|
||||
if (index >= length) {
|
||||
if (index >= parts.size()) {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
return attributes[index];
|
||||
return parts.get(index).attribute;
|
||||
}
|
||||
|
||||
public DottedChain subChain(int count) {
|
||||
if (count > length) {
|
||||
if (count > parts.size()) {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
return new DottedChain(parts, count);
|
||||
return new DottedChain(new ArrayList<>(parts.subList(0, count)), isNull);
|
||||
}
|
||||
|
||||
public String getLast() {
|
||||
if (isNull) {
|
||||
return null;
|
||||
}
|
||||
if (length == 0) {
|
||||
if (parts.isEmpty()) {
|
||||
return "";
|
||||
} else {
|
||||
return parts[length - 1];
|
||||
return parts.get(parts.size() - 1).name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public boolean isLastAttribute() {
|
||||
if (isNull) {
|
||||
return false;
|
||||
}
|
||||
if (length == 0) {
|
||||
if (parts.isEmpty()) {
|
||||
return false;
|
||||
} else {
|
||||
return attributes[length - 1];
|
||||
return parts.get(parts.size() - 1).attribute;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -253,11 +219,11 @@ public class DottedChain implements Serializable, Comparable<DottedChain> {
|
||||
if (isNull) {
|
||||
return null;
|
||||
}
|
||||
if (length < 2) {
|
||||
if (parts.size() < 2) {
|
||||
return EMPTY;
|
||||
}
|
||||
|
||||
return new DottedChain(parts, length - 1);
|
||||
return subChain(parts.size() - 1);
|
||||
}
|
||||
|
||||
public DottedChain addWithSuffix(String name) {
|
||||
@@ -273,49 +239,40 @@ 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;
|
||||
nnamespaceSuffixes[nparts.length - 1] = namespaceSuffix;
|
||||
return new DottedChain(nattributes, nparts, nnamespaceSuffixes);
|
||||
List<PathPart> newParts = new ArrayList<>(parts);
|
||||
newParts.add(new PathPart(name, attribute, namespaceSuffix));
|
||||
return new DottedChain(newParts, false);
|
||||
}
|
||||
|
||||
protected String toString(boolean as3, boolean raw, boolean withSuffix) {
|
||||
if (isNull) {
|
||||
return "";
|
||||
}
|
||||
if (length == 0) {
|
||||
if (parts.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
StringBuilder ret = new StringBuilder();
|
||||
for (int i = 0; i < length; i++) {
|
||||
for (int i = 0; i < parts.size(); i++) {
|
||||
if (i > 0) {
|
||||
ret.append(".");
|
||||
}
|
||||
if (attributes[i]) {
|
||||
if (parts.get(i).attribute) {
|
||||
ret.append("@");
|
||||
}
|
||||
String part = parts[i];
|
||||
boolean lastStar = i == length - 1 && "*".equals(part);
|
||||
String part = parts.get(i).name;
|
||||
boolean lastStar = i == parts.size() - 1 && "*".equals(part);
|
||||
ret.append((raw || lastStar) ? part : IdentifiersDeobfuscation.printIdentifier(as3, part));
|
||||
if (withSuffix) {
|
||||
ret.append(namespaceSuffixes[i]);
|
||||
ret.append(parts.get(i).namespaceSuffix);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
@@ -323,23 +280,27 @@ public class DottedChain implements Serializable, Comparable<DottedChain> {
|
||||
if (isNull) {
|
||||
return "";
|
||||
}
|
||||
if (length == 0) {
|
||||
if (parts.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
StringBuilder ret = new StringBuilder();
|
||||
for (int i = 0; i < length; i++) {
|
||||
for (int i = 0; i < parts.size(); i++) {
|
||||
if (i > 0) {
|
||||
ret.append(File.separator);
|
||||
}
|
||||
|
||||
ret.append(Helper.makeFileName(IdentifiersDeobfuscation.printIdentifier(true, parts[i])));
|
||||
ret.append(Helper.makeFileName(IdentifiersDeobfuscation.printIdentifier(true, parts.get(i).name)));
|
||||
}
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
public List<String> toList() {
|
||||
return new ArrayList<>(Arrays.asList(parts));
|
||||
List<String> ret = new ArrayList<>();
|
||||
for (PathPart p : parts) {
|
||||
ret.add(p.name);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public String toPrintableString(boolean as3) {
|
||||
@@ -357,23 +318,17 @@ public class DottedChain implements Serializable, Comparable<DottedChain> {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
hash = 41 * hash + Objects.hashCode(this.parts);
|
||||
hash = 41 * hash + (this.isNull ? 1 : 0);
|
||||
return hash;
|
||||
}
|
||||
|
||||
private int calcHash() {
|
||||
if (isNull) {
|
||||
return 0;
|
||||
}
|
||||
int result = 1;
|
||||
for (int i = 0; i < length; i++) {
|
||||
result = 31 * result + parts[i].hashCode();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
@@ -381,32 +336,57 @@ public class DottedChain implements Serializable, Comparable<DottedChain> {
|
||||
return false;
|
||||
}
|
||||
final DottedChain other = (DottedChain) obj;
|
||||
if (isNull && other.isNull) {
|
||||
return true;
|
||||
}
|
||||
if (length != other.length) {
|
||||
if (this.isNull != other.isNull) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
String s1 = parts[i];
|
||||
String s2 = other.parts[i];
|
||||
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;
|
||||
return Objects.equals(this.parts, other.parts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(DottedChain o) {
|
||||
return toRawString().compareTo(o.toRawString());
|
||||
}
|
||||
|
||||
private static class PathPart {
|
||||
|
||||
public String name;
|
||||
public boolean attribute;
|
||||
public String namespaceSuffix;
|
||||
|
||||
public PathPart(String name, boolean attribute, String namespaceSuffix) {
|
||||
this.name = name;
|
||||
this.attribute = attribute;
|
||||
this.namespaceSuffix = namespaceSuffix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 5;
|
||||
hash = 79 * hash + Objects.hashCode(this.name);
|
||||
hash = 79 * hash + (this.attribute ? 1 : 0);
|
||||
hash = 79 * hash + Objects.hashCode(this.namespaceSuffix);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final PathPart other = (PathPart) obj;
|
||||
if (this.attribute != other.attribute) {
|
||||
return false;
|
||||
}
|
||||
if (!Objects.equals(this.name, other.name)) {
|
||||
return false;
|
||||
}
|
||||
return Objects.equals(this.namespaceSuffix, other.namespaceSuffix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user