From 0ccacf3865a1bd83f6d9894b3d86894dbe12a8e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Sat, 28 Feb 2026 20:57:33 +0100 Subject: [PATCH] Added: AS3 ambiguous namespace detection (back again) Fixed: #2514 AS3 direct editation - problems with namespaces --- CHANGELOG.md | 3 + .../abc/avm2/model/FullMultinameAVM2Item.java | 60 ++++----- .../flash/abc/avm2/model/GetLexAVM2Item.java | 30 ++++- .../parser/script/AVM2SourceGenerator.java | 54 ++++++-- .../abc/avm2/parser/script/AbcIndexing.java | 115 +++++++++++++++--- .../parser/script/ActionScript3Parser.java | 66 +++++----- .../script/ActionScript3SimpleParser.java | 11 +- .../abc/avm2/parser/script/NamespaceItem.java | 53 ++++---- .../as3decompile/ActionScript3ClassTest.java | 2 +- .../testexpected/as3_new/tests/TestNames.as | 14 +-- .../tests_classes/mypackage1/TestClass.as | 4 +- .../tests_classes/mypackage1/TestClass2.as | 4 +- 12 files changed, 286 insertions(+), 130 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e31f1ca6..148fa068a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file. - Debugger - Button to disconnect current session (stay listening) - [#2644] Debugger - Button to sort variables alphabetically - AS3 Direct editation - Error when accessing inaccessible namespace +- AS3 ambiguous namespace detection (back again) ### Fixed - [#2643] APNG export - images containing multiple IDAT chunks @@ -15,6 +16,7 @@ All notable changes to this project will be documented in this file. - Long delay before switching critical status bar titles (Causing many actions to look slow - for example Debug listening) - AS3 goto definition missing some namespaces +- [#2514] AS3 direct editation - problems with namespaces ### Changed - Icon of Debug listen action from ear to phone receiver @@ -4180,6 +4182,7 @@ Major version of SWF to XML export changed to 2. [#2644]: https://www.free-decompiler.com/flash/issues/2644 [#2643]: https://www.free-decompiler.com/flash/issues/2643 [#2645]: https://www.free-decompiler.com/flash/issues/2645 +[#2514]: https://www.free-decompiler.com/flash/issues/2514 [#2639]: https://www.free-decompiler.com/flash/issues/2639 [#2642]: https://www.free-decompiler.com/flash/issues/2642 [#2636]: https://www.free-decompiler.com/flash/issues/2636 diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/FullMultinameAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/FullMultinameAVM2Item.java index ce5f3d82e..f8e8480d6 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/FullMultinameAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/FullMultinameAVM2Item.java @@ -225,46 +225,36 @@ public class FullMultinameAVM2Item extends AVM2Item { } else { localName = constants.getMultiname(multinameIndex).getNameAndCustomNamespace(localData.usedDeobfuscations, localData.abc, fullyQualifiedNames, false, true, customNsRef); } + DottedChain customNs = customNsRef.getVal(); - if (customNs != null) { - String nsname = customNs.getLast(); - String identifier = IdentifiersDeobfuscation.printIdentifier(localData.abc.getSwf(), localData.usedDeobfuscations, true, nsname); - writer.hilightSpecial(identifier, HighlightSpecialType.TYPE_NAME, customNs.toRawString()); - writer.appendNoHilight("::"); - } else { - //FIXME!! This is slow, should be moved to indexing - if (false && parentType instanceof TypeItem) { //not ApplyTypeAVM2Item or UnboundedTypeItem - String rawName = constants.getMultiname(multinameIndex).getName(localData.usedDeobfuscations, localData.abc, localData.abc.constants, fullyQualifiedNames, true, true); - List defs = new ArrayList<>(); - List staticRef = new ArrayList<>(); - localData.abcIndex.getClassTraits(localData.usedDeobfuscations, parentType, localData.abc, null, true, true, true, true, true, defs, staticRef); - int numStaticUsed = 0; - int numInstanceUsed = 0; - for (int i = 0; i < defs.size(); i++) { - AbcIndexing.PropertyDef def = defs.get(i); - if (Objects.equals(rawName, def.getPropertyName())) { - //cannot access instance properties via static context - if (isStatic && !staticRef.get(i)) { - continue; - } - if (staticRef.get(i)) { - numStaticUsed++; - } else { - numInstanceUsed++; - } - } - } - if (numInstanceUsed > 1 || numStaticUsed > 1) { - Namespace ns = constants.getMultiname(multinameIndex).getSingleNamespace(localData.abc.constants); - if (ns != null) { - String prefix = Namespace.kindToPrefix(ns.kind); - if (prefix != null) { - writer.append(prefix).append("::"); - } + + Boolean isAmbiguous = null; + if (parentType instanceof TypeItem) { //not ApplyTypeAVM2Item or UnboundedTypeItem + String rawName = constants.getMultiname(multinameIndex).getName(localData.usedDeobfuscations, localData.abc, localData.abc.constants, fullyQualifiedNames, true, true); + isAmbiguous = localData.abcIndex.isPropertyAmbiguous(localData.abc, rawName, parentType, true, true); + } + + /*if (customNs != null) { + isAmbiguous = true; + }*/ + + if (isAmbiguous == null || isAmbiguous) { + if (customNs != null) { + String nsname = customNs.getLast(); + String identifier = IdentifiersDeobfuscation.printIdentifier(localData.abc.getSwf(), localData.usedDeobfuscations, true, nsname); + writer.hilightSpecial(identifier, HighlightSpecialType.TYPE_NAME, customNs.toRawString()); + writer.appendNoHilight("::"); + } else if (isAmbiguous != null) { + Namespace ns = constants.getMultiname(multinameIndex).getSingleNamespace(localData.abc.constants); + if (ns != null) { + String prefix = Namespace.kindToPrefix(ns.kind); + if (prefix != null) { + writer.append(prefix).append("::"); } } } } + if (!isAttribute && afterDot && namespaceSuffix.isEmpty() && Configuration.as3QNameObfuscatedPropsInSquareBrackets.get()) { if (IdentifiersDeobfuscation.isValidName(true, localName)) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/GetLexAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/GetLexAVM2Item.java index d9d047467..694bc0d49 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/GetLexAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/GetLexAVM2Item.java @@ -18,15 +18,19 @@ package com.jpexs.decompiler.flash.abc.avm2.model; import com.jpexs.decompiler.flash.IdentifiersDeobfuscation; import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.AVM2LocalData; import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.parser.script.AbcIndexing; import com.jpexs.decompiler.flash.abc.types.Multiname; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.flash.helpers.hilight.HighlightSpecialType; import com.jpexs.decompiler.graph.DottedChain; import com.jpexs.decompiler.graph.GraphSourceItem; import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.TypeItem; import com.jpexs.decompiler.graph.model.LocalData; import com.jpexs.helpers.Reference; +import java.util.HashSet; import java.util.Objects; import java.util.Set; @@ -94,14 +98,28 @@ public class GetLexAVM2Item extends AVM2Item { public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) { Reference customNsRef = new Reference<>(null); String localName = propertyName.getNameAndCustomNamespace(localData.usedDeobfuscations, localData.abc, localData.fullyQualifiedNames, false, true, customNsRef); - DottedChain customNs = customNsRef.getVal(); - if (customNs != null) { + DottedChain customNs = customNsRef.getVal(); + if (customNs != null) { String nsname = customNs.getLast(); String identifier = IdentifiersDeobfuscation.printIdentifier(localData.abc.getSwf(), localData.usedDeobfuscations, true, nsname); - writer.hilightSpecial(identifier, HighlightSpecialType.TYPE_NAME, customNs.toRawString()); - writer.appendNoHilight("::"); - getSrcData().localName = nsname + "::" + localName; - return writer.append(localName); + + Boolean ambiguous = null; + + if (localData.classIndex > -1) { + DottedChain fullClassName = localData.abc.instance_info.get(localData.classIndex).getName(localData.abc.constants).getNameWithNamespace(new HashSet<>(), localData.abc, localData.abc.constants, false); + ambiguous = localData.abcIndex.isPropertyAmbiguous(localData.abc, localName, new TypeItem(fullClassName), true, true); + } + + + if (ambiguous == null || ambiguous == true) { + writer.hilightSpecial(identifier, HighlightSpecialType.TYPE_NAME, customNs.toRawString()); + writer.appendNoHilight("::"); + getSrcData().localName = nsname + "::" + localName; + return writer.append(localName); + } else { + getSrcData().localName = nsname + "::" + localName; + return writer.append(localName); + } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java index c21b2300a..765746dae 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java @@ -767,7 +767,7 @@ public class AVM2SourceGenerator implements SourceGenerator { List> allopns = new ArrayList<>(); allopns.add(openedNamespaces); - GetterAVM2Item getter = new GetterAVM2Item(allopns, false, false, new ArrayList<>(), new NamespaceItem(pkg.isEmpty() ? baseClassName : pkg.toRawString() + ":" + baseClassName, Namespace.KIND_PROTECTED), isInterface, false, null, false, false, 0, + GetterAVM2Item getter = new GetterAVM2Item(allopns, false, false, new ArrayList<>(), new NamespaceItem(pkg.isEmpty() ? baseClassName : pkg.toRawString() + ":" + baseClassName, Namespace.KIND_PROTECTED, -1), isInterface, false, null, false, false, 0, true, false, false, "skinParts", new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), getterBody, subvars, new TypeItem("Object")); @@ -783,7 +783,7 @@ public class AVM2SourceGenerator implements SourceGenerator { NewObjectAVM2Item sltVal = new NewObjectAVM2Item(null, null, pairs); SlotAVM2Item slt = new SlotAVM2Item( - new ArrayList<>(), new NamespaceItem(pkg.isEmpty() ? baseClassName : pkg.toRawString() + ":" + baseClassName, Namespace.KIND_PRIVATE), + new ArrayList<>(), new NamespaceItem(pkg.isEmpty() ? baseClassName : pkg.toRawString() + ":" + baseClassName, Namespace.KIND_PRIVATE, -1), null, true, "_skinParts", new TypeItem("Object"), sltVal, 0); traitItems.add(0, slt); @@ -1763,6 +1763,27 @@ public class AVM2SourceGenerator implements SourceGenerator { traits[k].name_index = traitName(((FunctionAVM2Item) item).pkg == null ? 0 : ((FunctionAVM2Item) item).pkg.getCpoolIndex(abcIndex), ((FunctionAVM2Item) item).functionName); } else if (item instanceof ConstAVM2Item) { traits[k].name_index = traitName(genNs(importedClasses, pkg, ((ConstAVM2Item) item).pkg, openedNamespaces, localData, ((ConstAVM2Item) item).line), ((ConstAVM2Item) item).var); + + ConstAVM2Item cai = (ConstAVM2Item) item; + if (cai.ns) { + TraitSlotConst tsc = (TraitSlotConst) traits[k]; + GraphTargetItem val = cai.value; + GraphTargetItem type = cai.type; + if (cai.pkg != null) { + cai.pkg.resolveCustomNs(abcIndex, importedClasses, localData.pkg, openedNamespaces, localData); + } + int namespace = cai.pkg == null ? 0 : cai.pkg.getCpoolIndex(abcIndex); + tsc.type_index = 0; + + ValueKind vk = getValueKind(namespace, type, val, cai.generatedNs); + if (vk == null) { + tsc.value_index = ValueKind.CONSTANT_Undefined; + tsc.value_kind = ValueKind.CONSTANT_Undefined; + } else { + tsc.value_kind = vk.value_kind; + tsc.value_index = vk.value_index; + } + } } else if (item instanceof SlotAVM2Item) { traits[k].name_index = traitName(genNs(importedClasses, pkg, ((SlotAVM2Item) item).pkg, openedNamespaces, localData, ((SlotAVM2Item) item).line), ((SlotAVM2Item) item).var); } @@ -1960,10 +1981,7 @@ public class AVM2SourceGenerator implements SourceGenerator { TraitSlotConst tsc = (TraitSlotConst) traits[k]; GraphTargetItem val = null; GraphTargetItem type = null; - boolean isNamespace = false; int namespace = 0; - boolean isStatic = false; - int[] metadata = new int[0]; if (item instanceof SlotAVM2Item) { SlotAVM2Item sai = (SlotAVM2Item) item; if (!isScriptTraits && sai.isStatic() != generateStatic) { @@ -1971,7 +1989,6 @@ public class AVM2SourceGenerator implements SourceGenerator { } val = sai.value; type = sai.type; - isStatic = sai.isStatic(); if (sai.pkg != null) { sai.pkg.resolveCustomNs(abcIndex, importedClasses, localData.pkg, openedNamespaces, localData); } @@ -1984,16 +2001,17 @@ public class AVM2SourceGenerator implements SourceGenerator { if (!isScriptTraits && cai.isStatic() != generateStatic) { continue; } + if (cai.ns) { + continue; + } val = cai.value; type = cai.type; if (cai.pkg != null) { cai.pkg.resolveCustomNs(abcIndex, importedClasses, localData.pkg, openedNamespaces, localData); } namespace = cai.pkg == null ? 0 : cai.pkg.getCpoolIndex(abcIndex); - isNamespace = cai.ns; - isStatic = cai.isStatic(); } - tsc.type_index = isNamespace ? 0 : (type == null ? 0 : typeName(localData, type)); + tsc.type_index = type == null ? 0 : typeName(localData, type); ValueKind vk = getValueKind(namespace, type, val, generatedNs); if (vk == null) { @@ -2299,7 +2317,7 @@ public class AVM2SourceGenerator implements SourceGenerator { * @throws AVM2ParseException On parse error * @throws CompilationException On compilation error */ - public void generateScriptInfo(List sinitVariables, boolean sinitNeedsActivation, List importedClasses, List openedNamespaces, int scriptIndex, ScriptInfo scriptInfo, List> allOpenedNamespaces, SourceGeneratorLocalData localData, List commands, int classPos) throws AVM2ParseException, CompilationException { + public void generateScriptInfo(List sinitVariables, boolean sinitNeedsActivation, List importedClasses, List openedNamespaces, int scriptIndex, ScriptInfo scriptInfo, List> allOpenedNamespaces, SourceGeneratorLocalData localData, List commands, int classPos, DottedChain pkg) throws AVM2ParseException, CompilationException { List traitsList = new ArrayList<>(); for (GraphTargetItem it : commands) { if ((it instanceof SlotAVM2Item) @@ -2316,7 +2334,21 @@ public class AVM2SourceGenerator implements SourceGenerator { localData.currentScript = scriptInfo; localData.scriptIndex = scriptIndex; Trait[] traitArr = generateTraitsPhase1(new ArrayList<>(), new ArrayList<>(), null, null, true, localData, traitsList, scriptInfo.traits, class_index, true); - generateTraitsPhase2(new ArrayList<>(), null/*FIXME*/, traitsList, traitArr, new ArrayList<>(), localData); + generateTraitsPhase2(new ArrayList<>(), null/*FIXME*/, traitsList, traitArr, new ArrayList<>(), localData); + + localData.pkg = pkg; + for (NamespaceItem ns : openedNamespaces) { + if (!ns.isResolved()) { + if (ns.kind == NamespaceItem.KIND_NAMESPACE_CUSTOM || ns.kind == Namespace.KIND_NAMESPACE) { + continue; + } + ns.getCpoolIndex(abcIndex); + } + } + for (NamespaceItem ns : openedNamespaces) { + ns.resolveCustomNs(abcIndex, importedClasses, pkg, openedNamespaces, localData); + } + abcIndex.refreshSelected(); generateTraitsPhase3(traitsList, traitArr, localData); abcIndex.refreshSelected(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AbcIndexing.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AbcIndexing.java index 6209209c2..5f4c8c969 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AbcIndexing.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AbcIndexing.java @@ -104,6 +104,44 @@ public final class AbcIndexing { this(null, null); } + private static class AmbiguousPropertyDef { + private final String propName; + + private final GraphTargetItem parent; + + public AmbiguousPropertyDef(String propName, GraphTargetItem parent) { + this.propName = propName; + this.parent = parent; + } + + @Override + public int hashCode() { + int hash = 7; + hash = 79 * hash + Objects.hashCode(this.propName); + hash = 79 * hash + Objects.hashCode(this.parent); + 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 AmbiguousPropertyDef other = (AmbiguousPropertyDef) obj; + if (!Objects.equals(this.propName, other.propName)) { + return false; + } + return Objects.equals(this.parent, other.parent); + } + + } + /** * Property key */ @@ -168,12 +206,13 @@ public final class AbcIndexing { case Namespace.KIND_PACKAGE_INTERNAL: case Namespace.KIND_PROTECTED: case Namespace.KIND_STATIC_PROTECTED: + case Namespace.KIND_NAMESPACE: //this.abc = null; //this.propNsString = abc.constants.getNamespace(propNsIndex).getRawName(abc.constants); break; - case Namespace.KIND_NAMESPACE: - this.propNsString = abc.constants.getNamespace(propNsIndex).getRawName(abc.constants); - break; + + //this.propNsString = abc.constants.getNamespace(propNsIndex).getRawName(abc.constants); + //break; default: this.abc = abc; this.propNsIndex = propNsIndex; @@ -191,7 +230,7 @@ public final class AbcIndexing { this.parent = parent; this.abc = null; if (nsKind == Namespace.KIND_NAMESPACE) { - this.propNsString = propNsString; + //this.propNsString = propNsString; } //this.propNsKind = nsKind; //this.propNsString = propNsString; @@ -281,12 +320,10 @@ public final class AbcIndexing { return; } int k = abc.constants.getNamespace(nsIndex).kind; - /*if (k != Namespace.KIND_PACKAGE) { - setPrivate(abc, nsIndex); - }*/ - - this.propNsIndex = nsIndex; - this.abc = abc; + if (k == Namespace.KIND_PRIVATE) { + this.propNsIndex = nsIndex; + this.abc = abc; + } } /** @@ -556,6 +593,12 @@ public final class AbcIndexing { private final Map classNsProperties = new HashMap<>(); private final Map scriptProperties = new HashMap<>(); + + private final Map> instanceAmbiguousProperties = new HashMap<>(); + + private final Map> classAmbiguousProperties = new HashMap<>(); + + private final Map> scriptAmbiguousProperties = new HashMap<>(); /** * Rebuilds package to objects name map. @@ -921,7 +964,7 @@ public final class AbcIndexing { if (ci != null && ci.parent != null && (prop.abc == null || prop.propNsIndex == 0)) { AbcIndexing.ClassIndex ciParent = ci.parent; DottedChain parentClass = ciParent.abc.instance_info.get(ciParent.index).getName(ciParent.abc.constants).getNameWithNamespace(new LinkedHashSet<>(), ciParent.abc, ciParent.abc.constants, true); - PropertyDef parentDef = new PropertyDef(prop.propName, new TypeItem(parentClass), prop.propNsString, prop.propNsKind); + PropertyDef parentDef = new PropertyDef(prop.propName, new TypeItem(parentClass), (ABC) null, 0); TraitIndex pti = findProperty(parentDef, findStatic, findInstance, findProtected, foundStatic); if (pti != null) { return pti; @@ -1059,13 +1102,36 @@ public final class AbcIndexing { * @param mapNs Map to index * @param scriptIndex Script index */ - protected void indexTraits(ABC abc, int name_index, Traits ts, Map map, Map mapNs, int scriptIndex) { + protected void indexTraits(ABC abc, int name_index, Traits ts, Map map, Map mapNs, Map> mapAmbiguous, int scriptIndex) { for (Trait t : ts.traits) { ValueKind propValue = null; if (t instanceof TraitSlotConst) { TraitSlotConst tsc = (TraitSlotConst) t; propValue = new ValueKind(tsc.value_index, tsc.value_kind); } + if (mapAmbiguous != null) { + AmbiguousPropertyDef dp = new AmbiguousPropertyDef(t.getName(abc).getName(new LinkedHashSet<>(), abc, abc.constants, new ArrayList<>() /*?*/, true, false), multinameToType(new LinkedHashSet<>(), name_index, abc, abc.constants)); + TraitIndex ti = new TraitIndex(t, abc, getTraitReturnType(new LinkedHashSet<>(), abc, t), getTraitCallReturnType(new LinkedHashSet<>(), abc, t), propValue, multinameToType(new LinkedHashSet<>(), name_index, abc, abc.constants), scriptIndex); + if (!mapAmbiguous.containsKey(dp)) { + mapAmbiguous.put(dp, new ArrayList<>()); + mapAmbiguous.get(dp).add(ti); + } else { + int thisNsKind = t.getName(abc).getNamespace(abc.constants).kind; + boolean onlySameNsKind = true; + for (TraitIndex ti2 : mapAmbiguous.get(dp)) { + int prevNsKind = ti2.trait.getName(ti2.abc).getNamespace(ti2.abc.constants).kind; + if (prevNsKind != thisNsKind) { + onlySameNsKind = false; + break; + } + } + if (!onlySameNsKind) { + mapAmbiguous.get(dp).add(ti); + } + } + + } + if (map != null) { PropertyDef dp = new PropertyDef(t.getName(abc).getName(new LinkedHashSet<>(), abc, abc.constants, new ArrayList<>() /*?*/, true, false), multinameToType(new LinkedHashSet<>(), name_index, abc, abc.constants), abc, abc.constants.getMultiname(t.name_index).namespace_index); map.put(dp, new TraitIndex(t, abc, getTraitReturnType(new LinkedHashSet<>(), abc, t), getTraitCallReturnType(new LinkedHashSet<>(), abc, t), propValue, multinameToType(new LinkedHashSet<>(), name_index, abc, abc.constants), scriptIndex)); @@ -1164,7 +1230,7 @@ public final class AbcIndexing { List addedClasses = new ArrayList<>(); for (int i = 0; i < abc.script_info.size(); i++) { - indexTraits(abc, 0, abc.script_info.get(i).traits, null, scriptProperties, i); + indexTraits(abc, 0, abc.script_info.get(i).traits, null, scriptProperties, scriptAmbiguousProperties, i); for (int t = 0; t < abc.script_info.get(i).traits.traits.size(); t++) { Trait tr = abc.script_info.get(i).traits.traits.get(t); if (tr instanceof TraitClass) { @@ -1181,8 +1247,8 @@ public final class AbcIndexing { GraphTargetItem cname = multinameToType(new LinkedHashSet<>(), ii.name_index, abc, abc.constants); classes.put(new ClassDef(cname, abc, classScriptIndex), cindex); - indexTraits(abc, ii.name_index, ii.instance_traits, instanceProperties, instanceNsProperties, i); - indexTraits(abc, ii.name_index, ci.static_traits, classProperties, classNsProperties, i); + indexTraits(abc, ii.name_index, ii.instance_traits, instanceProperties, instanceNsProperties, instanceAmbiguousProperties, i); + indexTraits(abc, ii.name_index, ci.static_traits, classProperties, classNsProperties, classAmbiguousProperties, i); } } } @@ -1267,4 +1333,23 @@ public final class AbcIndexing { } return isInstanceOf(ci.abc, ci.index, searchClassName); } + + public Boolean isPropertyAmbiguous(ABC abc, String propertyName, GraphTargetItem parent, boolean findStatic, boolean findInstance) { + AmbiguousPropertyDef key = new AmbiguousPropertyDef(propertyName, parent); + if (findStatic && classAmbiguousProperties.containsKey(key)) { + return classAmbiguousProperties.get(key).size() > 1; + } + if (findInstance && instanceAmbiguousProperties.containsKey(key)) { + return instanceAmbiguousProperties.get(key).size() > 1; + } + ClassIndex ci = findClass(parent, abc, null); + if (ci != null) { + if (ci.parent != null) { + ci = ci.parent; + DottedChain parentClassName = ci.abc.instance_info.get(ci.index).getName(ci.abc.constants).getNameWithNamespace(new HashSet<>(), ci.abc, ci.abc.constants, false); + return isPropertyAmbiguous(ci.abc, propertyName, new TypeItem(parentClassName), findStatic, findInstance); + } + } + return null; + } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java index 2b1c09e93..2b9523e68 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java @@ -94,6 +94,7 @@ import com.jpexs.decompiler.flash.abc.types.Float4; import com.jpexs.decompiler.flash.abc.types.MethodBody; import com.jpexs.decompiler.flash.abc.types.Namespace; import com.jpexs.decompiler.flash.abc.types.ScriptInfo; +import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst; import com.jpexs.decompiler.flash.action.swf4.ActionIf; import com.jpexs.decompiler.flash.tags.ABCContainerTag; import com.jpexs.decompiler.flash.tags.Tag; @@ -689,12 +690,12 @@ public class ActionScript3Parser { private void classTraits(List> allOpenedNamespaces, boolean outsidePackage, List cinitVariables, Reference cinitNeedsActivation, List cinit, List importedClasses, List openedNamespaces, NamespaceItem pkg, String classNameStr, boolean isInterface, List traits, List iinitVariables, Reference iinitNeedsActivation, Reference iinit, ABC abc) throws AVM2ParseException, IOException, CompilationException, InterruptedException { - NamespaceItem publicNs = new NamespaceItem("", Namespace.KIND_PACKAGE); - NamespaceItem privateNs = new NamespaceItem(pkg.name.toRawString().isEmpty() ? classNameStr : pkg.name.toRawString() + ":" + classNameStr, Namespace.KIND_PRIVATE); - NamespaceItem protectedNs = new NamespaceItem(pkg.name.toRawString().isEmpty() ? classNameStr : pkg.name.toRawString() + ":" + classNameStr, Namespace.KIND_PROTECTED); - NamespaceItem staticProtectedNs = new NamespaceItem(pkg.name.toRawString().isEmpty() ? classNameStr : pkg.name.toRawString() + ":" + classNameStr, Namespace.KIND_STATIC_PROTECTED); - NamespaceItem packageInternalNs = new NamespaceItem(pkg.name, Namespace.KIND_PACKAGE_INTERNAL); - NamespaceItem interfaceNs = new NamespaceItem(pkg.name.toRawString().isEmpty() ? classNameStr : pkg.name.toRawString() + ":" + classNameStr, Namespace.KIND_NAMESPACE); + NamespaceItem publicNs = new NamespaceItem("", Namespace.KIND_PACKAGE, -1); + NamespaceItem privateNs = new NamespaceItem(pkg.name.toRawString().isEmpty() ? classNameStr : pkg.name.toRawString() + ":" + classNameStr, Namespace.KIND_PRIVATE, -1); + NamespaceItem protectedNs = new NamespaceItem(pkg.name.toRawString().isEmpty() ? classNameStr : pkg.name.toRawString() + ":" + classNameStr, Namespace.KIND_PROTECTED, -1); + NamespaceItem staticProtectedNs = new NamespaceItem(pkg.name.toRawString().isEmpty() ? classNameStr : pkg.name.toRawString() + ":" + classNameStr, Namespace.KIND_STATIC_PROTECTED, -1); + NamespaceItem packageInternalNs = new NamespaceItem(pkg.name, Namespace.KIND_PACKAGE_INTERNAL, -1); + NamespaceItem interfaceNs = new NamespaceItem(pkg.name.toRawString().isEmpty() ? classNameStr : pkg.name.toRawString() + ":" + classNameStr, Namespace.KIND_NAMESPACE, -1); openedNamespaces = new ArrayList<>(openedNamespaces); allOpenedNamespaces.add(openedNamespaces); @@ -820,7 +821,7 @@ public class ActionScript3Parser { s = lex(); expected(s, lexer.yyline(), SymbolType.STRING); preSymbols.add(s); - namespace = new NamespaceItem((String) s.value, Namespace.KIND_NAMESPACE); + namespace = new NamespaceItem((String) s.value, Namespace.KIND_NAMESPACE, lexer.yyline()); s = lex(); expected(s, lexer.yyline(), SymbolType.PARENT_CLOSE); preSymbols.add(s); @@ -846,7 +847,7 @@ public class ActionScript3Parser { } if (namespace == null && customNs != null) { //Special: it will be resolved later: - namespace = new NamespaceItem(customNs, NamespaceItem.KIND_NAMESPACE_CUSTOM); + namespace = new NamespaceItem(customNs, NamespaceItem.KIND_NAMESPACE_CUSTOM, lexer.yyline()); } switch (s.type) { @@ -1045,7 +1046,8 @@ public class ActionScript3Parser { Reference numberPrecisionRef, ABC abc, Reference sinitNeedsActivation, - List sinitVariables + List sinitVariables, + Reference pkgRef ) throws AVM2ParseException, IOException, CompilationException, InterruptedException { Stack sinitLoops = new Stack<>(); @@ -1067,7 +1069,8 @@ public class ActionScript3Parser { sinitLoops, sinitLoopLabels, sinitRegisterVars, - sinitVariables + sinitVariables, + pkgRef )) { //empty } @@ -1088,7 +1091,8 @@ public class ActionScript3Parser { Stack sinitLoops, Map sinitLoopLabels, HashMap sinitRegisterVars, - List sinitVariables + List sinitVariables, + Reference pkgRef ) throws AVM2ParseException, IOException, CompilationException, InterruptedException { ParsedSymbol s; boolean inPackage = false; @@ -1110,20 +1114,22 @@ public class ActionScript3Parser { s = lex(); } expected(s, lexer.yyline(), SymbolType.CURLY_OPEN); - publicNs = new NamespaceItem(pkgName, Namespace.KIND_PACKAGE); - packageInternalNs = new NamespaceItem(pkgName, Namespace.KIND_PACKAGE_INTERNAL); + + pkgRef.setVal(pkgName); + publicNs = new NamespaceItem(pkgName, Namespace.KIND_PACKAGE, -1); + packageInternalNs = new NamespaceItem(pkgName, Namespace.KIND_PACKAGE_INTERNAL, -1); s = lex(); inPackage = true; } else { publicNs = null; - packageInternalNs = new NamespaceItem(scriptName + "$" + scriptIndex, Namespace.KIND_PRIVATE); + packageInternalNs = new NamespaceItem(scriptName + "$" + scriptIndex, Namespace.KIND_PRIVATE, -1); } lexer.pushback(s); allOpenedNamespaces.add(openedNamespaces); - NamespaceItem emptyNs = new NamespaceItem("", Namespace.KIND_PACKAGE); + NamespaceItem emptyNs = new NamespaceItem("", Namespace.KIND_PACKAGE, -1); openedNamespaces.add(emptyNs); - NamespaceItem as3Ns = new NamespaceItem(AS3_NAMESPACE, Namespace.KIND_NAMESPACE); + NamespaceItem as3Ns = new NamespaceItem(AS3_NAMESPACE, Namespace.KIND_NAMESPACE, -1); as3Ns.forceResolve(abcIndex); openedNamespaces.add(as3Ns); @@ -1262,7 +1268,7 @@ public class ActionScript3Parser { if (namespaces.get(i) == null || namespaces.get(i).isEmpty()) { continue; } - subOpenedNamespaces.add(new NamespaceItem(namespaces.get(i) + ":" + names.get(i), Namespace.KIND_STATIC_PROTECTED)); + subOpenedNamespaces.add(new NamespaceItem(namespaces.get(i) + ":" + names.get(i), Namespace.KIND_STATIC_PROTECTED, -1)); } } @@ -1667,8 +1673,8 @@ public class ActionScript3Parser { switch (s.type) { case USE: expectedType(SymbolType.NAMESPACE); - GraphTargetItem ns = type(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables, abc); - openedNamespaces.add(new NamespaceItem(ns.toString(), Namespace.KIND_PACKAGE /*FIXME?*/)); + GraphTargetItem ns = type(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables, abc); + openedNamespaces.add(new NamespaceItem(ns.toString(), NamespaceItem.KIND_NAMESPACE_CUSTOM, lexer.yyline())); break; case WITH: needsActivation.setVal(true); @@ -2857,7 +2863,7 @@ public class ActionScript3Parser { openedNamespaces.add(new NamespaceItem(fullName, Namespace.KIND_NAMESPACE)); } else */ if (isStar) { - openedNamespaces.add(new NamespaceItem(fullName, Namespace.KIND_PACKAGE)); + openedNamespaces.add(new NamespaceItem(fullName, Namespace.KIND_PACKAGE, -1)); } else { importedClasses.add(fullName); } @@ -2885,6 +2891,7 @@ public class ActionScript3Parser { s = lex(); } lexer.pushback(s); + openedNamespaces.add(new NamespaceItem(fullName, NamespaceItem.KIND_NAMESPACE_CUSTOM, lexer.yyline())); } else { if (!abc.hasDecimalSupport()) { throw new AVM2ParseException("Invalid use kind", lexer.yyline()); @@ -2978,7 +2985,8 @@ public class ActionScript3Parser { Reference numberContextRef, ABC abc, Reference sinitNeedsActivation, - List sinitVariables + List sinitVariables, + Reference pkgRef ) throws IOException, AVM2ParseException, CompilationException, InterruptedException { //int scriptPrivateNs; @@ -2992,7 +3000,7 @@ public class ActionScript3Parser { Reference numberUsageRef = new Reference<>(NumberContext.USE_NUMBER); Reference numberRoundingRef = new Reference<>(NumberContext.ROUND_HALF_EVEN); Reference numberPrecisionRef = new Reference<>(34); - scriptTraits(importedClasses, openedNamespaces, allOpenedNamespaces, scriptIndex, fileName, items, numberUsageRef, numberRoundingRef, numberPrecisionRef, abc, sinitNeedsActivation, sinitVariables); + scriptTraits(importedClasses, openedNamespaces, allOpenedNamespaces, scriptIndex, fileName, items, numberUsageRef, numberRoundingRef, numberPrecisionRef, abc, sinitNeedsActivation, sinitVariables, pkgRef); NumberContext nc = new NumberContext(numberUsageRef.getVal(), numberPrecisionRef.getVal(), numberRoundingRef.getVal()); if (!nc.isDefault()) { @@ -3030,11 +3038,12 @@ public class ActionScript3Parser { Reference numberContextRef, ABC abc, Reference sinitNeedsActivation, - List sinitVariables + List sinitVariables, + Reference pkgRef ) throws AVM2ParseException, IOException, CompilationException, InterruptedException { lexer = new ActionScriptLexer(str); - List ret = parseScript(importedClasses, openedNamespaces, allOpenedNamespaces, scriptIndex, fileName, numberContextRef, abc, sinitNeedsActivation, sinitVariables); + List ret = parseScript(importedClasses, openedNamespaces, allOpenedNamespaces, scriptIndex, fileName, numberContextRef, abc, sinitNeedsActivation, sinitVariables, pkgRef); if (lex().type != SymbolType.EOF) { throw new AVM2ParseException("Parsing finished before end of the file", lexer.yyline()); } @@ -3056,7 +3065,7 @@ public class ActionScript3Parser { * @throws AVM2ParseException On parsing error * @throws CompilationException On compilation error */ - public void addScriptFromTree(List sinitVariables, boolean sinitNeedsActivation, List importedClasses, List openedNamespaces, List> allOpenedNamespaces, List items, int classPos, String documentClass, Integer numberContext) throws AVM2ParseException, CompilationException { + public void addScriptFromTree(List sinitVariables, boolean sinitNeedsActivation, List importedClasses, List openedNamespaces, List> allOpenedNamespaces, List items, int classPos, String documentClass, Integer numberContext, DottedChain pkg) throws AVM2ParseException, CompilationException { AVM2SourceGenerator gen = new AVM2SourceGenerator(abcIndex); SourceGeneratorLocalData localData = new SourceGeneratorLocalData( new HashMap<>(), 0, Boolean.FALSE, 0); @@ -3066,7 +3075,7 @@ public class ActionScript3Parser { int scriptIndex = abcIndex.getSelectedAbc().script_info.size(); abcIndex.getSelectedAbc().script_info.add(si); try { - gen.generateScriptInfo(sinitVariables, sinitNeedsActivation, importedClasses, openedNamespaces, scriptIndex, si, allOpenedNamespaces, localData, items, classPos); + gen.generateScriptInfo(sinitVariables, sinitNeedsActivation, importedClasses, openedNamespaces, scriptIndex, si, allOpenedNamespaces, localData, items, classPos, pkg); } catch (Exception ex) { Logger.getLogger(ActionScript3Parser.class.getName()).log(Level.FINE, "Script generation exception", ex); abcIndex.getSelectedAbc().script_info.remove(si); @@ -3102,8 +3111,9 @@ public class ActionScript3Parser { List sinitVariables = new ArrayList<>(); List importedClasses = new ArrayList<>(); List openedNamespaces = new ArrayList<>(); - List traits = scriptTraitsFromString(importedClasses, openedNamespaces, allOpenedNamespaces, s, fileName, scriptIndex, numberContextRef, abc, sinitNeedsActivation, sinitVariables); - addScriptFromTree(sinitVariables, sinitNeedsActivation.getVal(), importedClasses, openedNamespaces, allOpenedNamespaces, traits, classPos, documentClass, numberContextRef.getVal()); + Reference pkgRef = new Reference<>(null); + List traits = scriptTraitsFromString(importedClasses, openedNamespaces, allOpenedNamespaces, s, fileName, scriptIndex, numberContextRef, abc, sinitNeedsActivation, sinitVariables, pkgRef); + addScriptFromTree(sinitVariables, sinitNeedsActivation.getVal(), importedClasses, openedNamespaces, allOpenedNamespaces, traits, classPos, documentClass, numberContextRef.getVal(), pkgRef.getVal()); } /** 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 c45cbe3d3..3699a3bdf 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 @@ -376,15 +376,24 @@ public class ActionScript3SimpleParser implements SimpleParser { continue; } } else { - if (!expected(errors, s, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.NAMESPACE, SymbolType.MULTIPLY)) { + if (!expected(errors, s, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.NAMESPACE, SymbolType.MULTIPLY, + SymbolType.PUBLIC, SymbolType.PROTECTED, SymbolType.PRIVATE, SymbolType.INTERNAL + )) { lexer.pushback(s); return new Path(); } + if (s.isType(SymbolType.PUBLIC, SymbolType.PROTECTED, SymbolType.PRIVATE, SymbolType.INTERNAL)) { + nsKeyword = s; + } + lastName = s.value.toString(); identPos = s.position; } s = lex(); if (s.type == SymbolType.NAMESPACESUFFIX) { + if (nsKeyword != null) { + errors.add(new SimpleParseException(nsKeyword.value + " not expected in this situation", lexer.yyline(), nsKeyword.position)); + } lastName += "#" + s.value; s = lex(); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NamespaceItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NamespaceItem.java index ca3821203..c7ed12a30 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NamespaceItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NamespaceItem.java @@ -55,6 +55,11 @@ public class NamespaceItem { * Namespace index */ private int nsIndex = -1; + + /** + * Line + */ + private int line; /** * Force resolves namespace. @@ -68,20 +73,24 @@ public class NamespaceItem { * Constructor. * @param name Name * @param kind Kind + * @param line Line */ - public NamespaceItem(DottedChain name, int kind) { + public NamespaceItem(DottedChain name, int kind, int line) { this.name = name; this.kind = kind; + this.line = line; } /** * Constructor. * @param name Name * @param kind Kind + * @param line Line */ - public NamespaceItem(String name, int kind) { + public NamespaceItem(String name, int kind, int line) { this.name = DottedChain.parseWithSuffix(name); this.kind = kind; + this.line = line; } /** @@ -148,35 +157,32 @@ public class NamespaceItem { resolved = false; } if (!resolved) { - DottedChain fullCustom = null; + AbcIndexing.TraitIndex ti = null; for (DottedChain imp : importedClasses) { if (imp.getLast().equals(custom)) { - fullCustom = imp; + ti = abcIndex.findScriptProperty(imp); break; } } - if (fullCustom != null) { - /*List aas = new ArrayList<>(); - aas.add(abc); - aas.addAll(allABCs);*/ - AbcIndexing.TraitIndex ti = abcIndex.findScriptProperty(fullCustom); - - if (ti != null) { - if (ti.trait instanceof TraitSlotConst) { - if (((TraitSlotConst) ti.trait).isNamespace()) { - Namespace ns = ti.abc.constants.getNamespace(((TraitSlotConst) ti.trait).value_index); - nsIndex = abcIndex.getSelectedAbc().constants.getNamespaceId(ns.kind, ns.getName(ti.abc.constants), 0, true); - return; - } + if (ti == null) { + ti = abcIndex.findScriptProperty(pkg.add(custom, "")); + } + if (ti != null) { + if (ti.trait instanceof TraitSlotConst) { + if (((TraitSlotConst) ti.trait).isNamespace()) { + Namespace ns = ti.abc.constants.getNamespace(((TraitSlotConst) ti.trait).value_index); + nsIndex = abcIndex.getSelectedAbc().constants.getNamespaceId(ns.kind, ns.getName(ti.abc.constants), 0, true); + kind = ns.kind; + return; } } } - throw new CompilationException("Namespace \"" + name + "\" not defined", -1); + throw new CompilationException("Namespace \"" + name + "\" not defined", line); } - nsIndex = abcIndex.getSelectedAbc().constants.getNamespaceId(Namespace.KIND_NAMESPACE, - outAbc.getVal().constants.getNamespace(value.getVal().value_index).getName(outAbc.getVal().constants), 0, true); - + Namespace ns = outAbc.getVal().constants.getNamespace(value.getVal().value_index); + nsIndex = abcIndex.getSelectedAbc().constants.getNamespaceId(ns.kind, ns.getName(outAbc.getVal().constants), 0, true); + kind = Namespace.KIND_NAMESPACE; } } @@ -199,7 +205,10 @@ public class NamespaceItem { return nsIndex; } if (kind == Namespace.KIND_NAMESPACE) { //must set manually - throw new CompilationException("Namespace \"" + name + "\" unresolved", -1); + throw new CompilationException("Namespace \"" + name + "\" unresolved", line); + } + if (kind == KIND_NAMESPACE_CUSTOM) { //must set manually + throw new CompilationException("Namespace \"" + name + "\" unresolved", line); } nsIndex = abcIndex.getSelectedAbc().constants.getNamespaceId(kind, name, 0, true); return nsIndex; diff --git a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassTest.java b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassTest.java index e0dcb108f..b448dab79 100644 --- a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassTest.java +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassTest.java @@ -158,7 +158,7 @@ public class ActionScript3ClassTest extends ActionScript3DecompileTestBase { + "a = new tests_classes.mypackage1.TestClass();\n" + "b = new tests_classes.mypackage2.TestClass();\n" + "c = new tests_classes.mypackage3.TestClass();\n" - + "var res:String = a.testCall() + b.testCall() + c.testCall() + this.testCall2() + this.testCall3() + this.testCall4() + testCall5() + this.testCall6() + myNamespace::testCall3();\n" + + "var res:String = a.testCall() + b.testCall() + c.testCall() + this.public::testCall2() + this.private::testCall3() + this.protected::testCall4() + protected::testCall5() + this.internal::testCall6() + myNamespace::testCall3();\n" + "trace(res);\n" + "return res;\n" + "}\n" diff --git a/libsrc/ffdec_lib/testexpected/as3_new/tests/TestNames.as b/libsrc/ffdec_lib/testexpected/as3_new/tests/TestNames.as index 3c5cc0f47..99f90e9d0 100644 --- a/libsrc/ffdec_lib/testexpected/as3_new/tests/TestNames.as +++ b/libsrc/ffdec_lib/testexpected/as3_new/tests/TestNames.as @@ -114,10 +114,10 @@ package tests getproperty RTQNameL() coerce_a setlocal 4 - findpropstrict Multiname("trace",[PackageNamespace(""),Namespace("http://adobe.com/AS3/2006/builtin"),PackageNamespace("tests"),PackageInternalNs("tests"),PrivateNamespace("tests:TestNames"),ProtectedNamespace("tests:TestNames"),StaticProtectedNs("tests:TestNames"),PrivateNamespace("TestNames.as$0")]) + findpropstrict Multiname("trace",[PackageNamespace(""),Namespace("http://adobe.com/AS3/2006/builtin"),PackageNamespace("tests"),PackageInternalNs("tests"),Namespace("http://www.adobe.com/2006/actionscript/examples"),PackageInternalNs("tests_other:myInternal2"),PrivateNamespace("tests:TestNames"),ProtectedNamespace("tests:TestNames"),StaticProtectedNs("tests:TestNames"),PrivateNamespace("TestNames.as$0")]) getlocal 4 - getproperty Multiname("c",[PackageNamespace(""),Namespace("http://adobe.com/AS3/2006/builtin"),PackageNamespace("tests"),PackageInternalNs("tests"),PrivateNamespace("tests:TestNames"),ProtectedNamespace("tests:TestNames"),StaticProtectedNs("tests:TestNames"),PrivateNamespace("TestNames.as$0")]) - callpropvoid Multiname("trace",[PackageNamespace(""),Namespace("http://adobe.com/AS3/2006/builtin"),PackageNamespace("tests"),PackageInternalNs("tests"),PrivateNamespace("tests:TestNames"),ProtectedNamespace("tests:TestNames"),StaticProtectedNs("tests:TestNames"),PrivateNamespace("TestNames.as$0")]), 1 + getproperty Multiname("c",[PackageNamespace(""),Namespace("http://adobe.com/AS3/2006/builtin"),PackageNamespace("tests"),PackageInternalNs("tests"),Namespace("http://www.adobe.com/2006/actionscript/examples"),PackageInternalNs("tests_other:myInternal2"),PrivateNamespace("tests:TestNames"),ProtectedNamespace("tests:TestNames"),StaticProtectedNs("tests:TestNames"),PrivateNamespace("TestNames.as$0")]) + callpropvoid Multiname("trace",[PackageNamespace(""),Namespace("http://adobe.com/AS3/2006/builtin"),PackageNamespace("tests"),PackageInternalNs("tests"),Namespace("http://www.adobe.com/2006/actionscript/examples"),PackageInternalNs("tests_other:myInternal2"),PrivateNamespace("tests:TestNames"),ProtectedNamespace("tests:TestNames"),StaticProtectedNs("tests:TestNames"),PrivateNamespace("TestNames.as$0")]), 1 findproperty QName(PackageNamespace("tests_other"),"myInternal") getproperty QName(PackageNamespace("tests_other"),"myInternal") coerce QName(PackageNamespace(""),"Namespace") @@ -207,9 +207,9 @@ package tests code getlocal0 pushscope - findpropstrict Multiname("trace",[PackageNamespace(""),Namespace("http://adobe.com/AS3/2006/builtin"),PackageNamespace("tests"),PackageInternalNs("tests"),PrivateNamespace("tests:TestNames"),ProtectedNamespace("tests:TestNames"),StaticProtectedNs("tests:TestNames"),PrivateNamespace("TestNames.as$0")]) + findpropstrict Multiname("trace",[PackageNamespace(""),Namespace("http://adobe.com/AS3/2006/builtin"),PackageNamespace("tests"),PackageInternalNs("tests"),Namespace("http://www.adobe.com/2006/actionscript/examples"),PackageInternalNs("tests_other:myInternal2"),PrivateNamespace("tests:TestNames"),ProtectedNamespace("tests:TestNames"),StaticProtectedNs("tests:TestNames"),PrivateNamespace("TestNames.as$0")]) pushstring "hello" - callpropvoid Multiname("trace",[PackageNamespace(""),Namespace("http://adobe.com/AS3/2006/builtin"),PackageNamespace("tests"),PackageInternalNs("tests"),PrivateNamespace("tests:TestNames"),ProtectedNamespace("tests:TestNames"),StaticProtectedNs("tests:TestNames"),PrivateNamespace("TestNames.as$0")]), 1 + callpropvoid Multiname("trace",[PackageNamespace(""),Namespace("http://adobe.com/AS3/2006/builtin"),PackageNamespace("tests"),PackageInternalNs("tests"),Namespace("http://www.adobe.com/2006/actionscript/examples"),PackageInternalNs("tests_other:myInternal2"),PrivateNamespace("tests:TestNames"),ProtectedNamespace("tests:TestNames"),StaticProtectedNs("tests:TestNames"),PrivateNamespace("TestNames.as$0")]), 1 returnvoid end ; code end ; body @@ -233,9 +233,9 @@ package tests code getlocal0 pushscope - findpropstrict Multiname("trace",[PackageNamespace(""),Namespace("http://adobe.com/AS3/2006/builtin"),PackageNamespace("tests"),PackageInternalNs("tests"),PrivateNamespace("tests:TestNames"),ProtectedNamespace("tests:TestNames"),StaticProtectedNs("tests:TestNames"),PrivateNamespace("TestNames.as$0")]) + findpropstrict Multiname("trace",[PackageNamespace(""),Namespace("http://adobe.com/AS3/2006/builtin"),PackageNamespace("tests"),PackageInternalNs("tests"),Namespace("http://www.adobe.com/2006/actionscript/examples"),PackageInternalNs("tests_other:myInternal2"),PrivateNamespace("tests:TestNames"),ProtectedNamespace("tests:TestNames"),StaticProtectedNs("tests:TestNames"),PrivateNamespace("TestNames.as$0")]) pushstring "hello" - callpropvoid Multiname("trace",[PackageNamespace(""),Namespace("http://adobe.com/AS3/2006/builtin"),PackageNamespace("tests"),PackageInternalNs("tests"),PrivateNamespace("tests:TestNames"),ProtectedNamespace("tests:TestNames"),StaticProtectedNs("tests:TestNames"),PrivateNamespace("TestNames.as$0")]), 1 + callpropvoid Multiname("trace",[PackageNamespace(""),Namespace("http://adobe.com/AS3/2006/builtin"),PackageNamespace("tests"),PackageInternalNs("tests"),Namespace("http://www.adobe.com/2006/actionscript/examples"),PackageInternalNs("tests_other:myInternal2"),PrivateNamespace("tests:TestNames"),ProtectedNamespace("tests:TestNames"),StaticProtectedNs("tests:TestNames"),PrivateNamespace("TestNames.as$0")]), 1 returnvoid end ; code end ; body diff --git a/libsrc/ffdec_lib/testexpected/as3_new/tests_classes/mypackage1/TestClass.as b/libsrc/ffdec_lib/testexpected/as3_new/tests_classes/mypackage1/TestClass.as index 5dadb7de0..d013e2de2 100644 --- a/libsrc/ffdec_lib/testexpected/as3_new/tests_classes/mypackage1/TestClass.as +++ b/libsrc/ffdec_lib/testexpected/as3_new/tests_classes/mypackage1/TestClass.as @@ -97,7 +97,7 @@ package tests_classes.mypackage1 coerce QName(PackageNamespace("tests_classes.mypackage1"),"TestInterface") setlocal1 getlocal1 - callpropvoid Multiname("testMethod1",[PackageNamespace(""),Namespace("http://adobe.com/AS3/2006/builtin"),PackageNamespace("tests_classes.mypackage1"),PackageInternalNs("tests_classes.mypackage1"),PrivateNamespace("tests_classes.mypackage1:TestClass"),ProtectedNamespace("tests_classes.mypackage1:TestClass"),StaticProtectedNs("tests_classes.mypackage1:TestClass"),PrivateNamespace("TestClass.as$0")]), 0 + callpropvoid QName(Namespace("tests_classes.mypackage1:TestInterface"),"testMethod1"), 0 getlocal0 coerce QName(PackageNamespace("tests_classes.mypackage2"),"TestInterface") setlocal2 @@ -134,7 +134,7 @@ package tests_classes.mypackage1 coerce QName(PackageNamespace("tests_classes.mypackage1"),"TestInterface") setlocal1 getlocal1 - callpropvoid Multiname("testMethod1",[PackageNamespace(""),Namespace("http://adobe.com/AS3/2006/builtin"),PackageNamespace("tests_classes.mypackage1"),PackageInternalNs("tests_classes.mypackage1"),PrivateNamespace("tests_classes.mypackage1:TestClass"),ProtectedNamespace("tests_classes.mypackage1:TestClass"),StaticProtectedNs("tests_classes.mypackage1:TestClass"),PrivateNamespace("TestClass.as$0")]), 0 + callpropvoid QName(Namespace("tests_classes.mypackage1:TestInterface"),"testMethod1"), 0 getlocal0 coerce QName(PackageNamespace("tests_classes.mypackage2"),"TestInterface") setlocal2 diff --git a/libsrc/ffdec_lib/testexpected/as3_new/tests_classes/mypackage1/TestClass2.as b/libsrc/ffdec_lib/testexpected/as3_new/tests_classes/mypackage1/TestClass2.as index ce8e8653c..2acac6042 100644 --- a/libsrc/ffdec_lib/testexpected/as3_new/tests_classes/mypackage1/TestClass2.as +++ b/libsrc/ffdec_lib/testexpected/as3_new/tests_classes/mypackage1/TestClass2.as @@ -178,9 +178,9 @@ package tests_classes.mypackage1 add coerce_s setlocal 4 - findpropstrict Multiname("trace",[PackageNamespace(""),Namespace("http://adobe.com/AS3/2006/builtin"),PackageNamespace("tests_classes.mypackage1"),PackageInternalNs("tests_classes.mypackage1"),PrivateNamespace("tests_classes.mypackage1:TestClass2"),ProtectedNamespace("tests_classes.mypackage1:TestClass2"),StaticProtectedNs("tests_classes.mypackage1:TestClass2"),PrivateNamespace("TestClass2.as$0")]) + findpropstrict Multiname("trace",[PackageNamespace(""),Namespace("http://adobe.com/AS3/2006/builtin"),PackageNamespace("tests_classes.mypackage1"),PackageInternalNs("tests_classes.mypackage1"),Namespace("https://www.free-decompiler.com/flash/test/namespace"),PrivateNamespace("tests_classes.mypackage1:TestClass2"),ProtectedNamespace("tests_classes.mypackage1:TestClass2"),StaticProtectedNs("tests_classes.mypackage1:TestClass2"),PrivateNamespace("TestClass2.as$0")]) getlocal 4 - callpropvoid Multiname("trace",[PackageNamespace(""),Namespace("http://adobe.com/AS3/2006/builtin"),PackageNamespace("tests_classes.mypackage1"),PackageInternalNs("tests_classes.mypackage1"),PrivateNamespace("tests_classes.mypackage1:TestClass2"),ProtectedNamespace("tests_classes.mypackage1:TestClass2"),StaticProtectedNs("tests_classes.mypackage1:TestClass2"),PrivateNamespace("TestClass2.as$0")]), 1 + callpropvoid Multiname("trace",[PackageNamespace(""),Namespace("http://adobe.com/AS3/2006/builtin"),PackageNamespace("tests_classes.mypackage1"),PackageInternalNs("tests_classes.mypackage1"),Namespace("https://www.free-decompiler.com/flash/test/namespace"),PrivateNamespace("tests_classes.mypackage1:TestClass2"),ProtectedNamespace("tests_classes.mypackage1:TestClass2"),StaticProtectedNs("tests_classes.mypackage1:TestClass2"),PrivateNamespace("TestClass2.as$0")]), 1 getlocal 4 returnvalue end ; code