From 56ec49865cf82071829f22056a6a012d20214c65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Sat, 10 Aug 2024 22:29:43 +0200 Subject: [PATCH] Non nullable flag --- .../avm2/parser/script/AVM2SourceGenerator.java | 6 ++++++ .../avm2/parser/script/ActionScript3Parser.java | 14 ++++++++++++-- .../abc/avm2/parser/script/ClassAVM2Item.java | 9 ++++++++- .../avm2/parser/script/InterfaceAVM2Item.java | 9 ++++++++- .../flash/abc/types/InstanceInfo.java | 7 +++++-- .../ffdec_lib/testdata/decimal/bin/decimal.abc | Bin 895 -> 895 bytes .../ffdec_lib/testdata/decimal/bin/decimal.cpp | 14 +++++++------- .../testdata/decimal/src/mypkg/MyClass.as | 2 +- 8 files changed, 47 insertions(+), 14 deletions(-) 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 f347be064..7f6cc2099 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 @@ -874,6 +874,9 @@ public class AVM2SourceGenerator implements SourceGenerator { if (cai.isFinal) { ii.flags |= InstanceInfo.CLASS_FINAL; } + if (!cai.isNullable) { + ii.flags |= InstanceInfo.CLASS_NON_NULLABLE; + } ii.flags |= InstanceInfo.CLASS_PROTECTEDNS; ii.protectedNS = abcIndex.getSelectedAbc().constants.getNamespaceId(Namespace.KIND_PROTECTED, pkg.toRawString().isEmpty() ? cai.classBaseName : pkg.toRawString() + ":" + cai.classBaseName, 0, true); } @@ -881,6 +884,9 @@ public class AVM2SourceGenerator implements SourceGenerator { InterfaceAVM2Item iai = (InterfaceAVM2Item) cls; ii.flags |= InstanceInfo.CLASS_INTERFACE; ii.flags |= InstanceInfo.CLASS_SEALED; + if (!iai.isNullable) { + ii.flags |= InstanceInfo.CLASS_NON_NULLABLE; + } generateClass(iai.importedClasses, new ArrayList<>(), false, new ArrayList<>(), iai.openedNamespaces, namespace, initScope, pkg, ci, ii, localData, true, iai.baseName, null, null, iai.superInterfaces, null, null, false, iai.methods, class_index 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 45e1e655a..48d6e0163 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 @@ -1059,6 +1059,16 @@ public class ActionScript3Parser { expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); subNameStr = s.value.toString(); s = lex(); + + boolean nullable = true; + + if (s.type == SymbolType.NOT) { + s = lex(); + nullable = false; + } else if (s.type == SymbolType.TERNAR) { + s = lex(); + } + if (!isInterface) { if (s.type == SymbolType.EXTENDS) { @@ -1112,9 +1122,9 @@ public class ActionScript3Parser { classTraits(allOpenedNamespaces, !inPackage, cinitVariables, cinitNeedsActivation, cinit, importedClasses, subOpenedNamespaces, ns, subNameStr, isInterface, subTraits, iinitVariables, iinitNeedsActivation, iinit); if (isInterface) { - traits.add(new InterfaceAVM2Item(metadata, importedClasses, ns, subOpenedNamespaces, isFinal, subNameStr, interfaces, subTraits)); + traits.add(new InterfaceAVM2Item(metadata, importedClasses, ns, subOpenedNamespaces, isFinal, subNameStr, interfaces, subTraits, nullable)); } else { - traits.add(new ClassAVM2Item(metadata, importedClasses, ns, subOpenedNamespaces, isFinal, isDynamic, subNameStr, extendsTypeStr, interfaces, cinit, cinitNeedsActivation.getVal(), cinitVariables, iinit.getVal(), iinitVariables, subTraits, iinitNeedsActivation.getVal())); + traits.add(new ClassAVM2Item(metadata, importedClasses, ns, subOpenedNamespaces, isFinal, isDynamic, subNameStr, extendsTypeStr, interfaces, cinit, cinitNeedsActivation.getVal(), cinitVariables, iinit.getVal(), iinitVariables, subTraits, iinitNeedsActivation.getVal(), nullable)); } expectedType(SymbolType.CURLY_CLOSE); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ClassAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ClassAVM2Item.java index d5c25f5d1..dad4dc9e3 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ClassAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ClassAVM2Item.java @@ -115,6 +115,11 @@ public class ClassAVM2Item extends AVM2Item implements Block { * Metadata */ public List>> metadata; + + /** + * Is nullable + */ + public boolean isNullable; @Override public List> getSubs() { @@ -148,8 +153,9 @@ public class ClassAVM2Item extends AVM2Item implements Block { * @param iinitVariables Instance initializer variables * @param traits Traits * @param iinitActivation Instance initializer activation + * @param isNullable Nullable */ - public ClassAVM2Item(List>> metadata, List importedClasses, NamespaceItem pkg, List openedNamespaces, boolean isFinal, boolean isDynamic, String className, GraphTargetItem extendsOp, List implementsOp, List cinit, boolean staticInitActivation, List cinitVariables, GraphTargetItem iinit, List iinitVariables, List traits, boolean iinitActivation) { + public ClassAVM2Item(List>> metadata, List importedClasses, NamespaceItem pkg, List openedNamespaces, boolean isFinal, boolean isDynamic, String className, GraphTargetItem extendsOp, List implementsOp, List cinit, boolean staticInitActivation, List cinitVariables, GraphTargetItem iinit, List iinitVariables, List traits, boolean iinitActivation, boolean isNullable) { super(null, null, NOPRECEDENCE); this.metadata = metadata; this.importedClasses = importedClasses; @@ -167,6 +173,7 @@ public class ClassAVM2Item extends AVM2Item implements Block { this.cinitActivation = staticInitActivation; this.cinitVariables = cinitVariables; this.iinitVariables = iinitVariables; + this.isNullable = isNullable; } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/InterfaceAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/InterfaceAVM2Item.java index f240d09ba..53500204d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/InterfaceAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/InterfaceAVM2Item.java @@ -72,6 +72,11 @@ public class InterfaceAVM2Item extends AVM2Item { */ public List>> metadata; + /** + * Is nullable + */ + public boolean isNullable; + /** * Constructor. * @param metadata Metadata @@ -82,8 +87,9 @@ public class InterfaceAVM2Item extends AVM2Item { * @param name Name * @param superInterfaces Super interfaces * @param traits Traits + * @param isNullable Nullable */ - public InterfaceAVM2Item(List>> metadata, List importedClasses, NamespaceItem pkg, List openedNamespaces, boolean isFinal, String name, List superInterfaces, List traits) { + public InterfaceAVM2Item(List>> metadata, List importedClasses, NamespaceItem pkg, List openedNamespaces, boolean isFinal, String name, List superInterfaces, List traits, boolean isNullable) { super(null, null, NOPRECEDENCE); this.metadata = metadata; this.importedClasses = importedClasses; @@ -93,6 +99,7 @@ public class InterfaceAVM2Item extends AVM2Item { this.methods = traits; this.isFinal = isFinal; this.openedNamespaces = openedNamespaces; + this.isNullable = isNullable; } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/InstanceInfo.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/InstanceInfo.java index d88bec1dd..9a1c6a038 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/InstanceInfo.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/InstanceInfo.java @@ -102,8 +102,7 @@ public class InstanceInfo { public static final int CLASS_PROTECTEDNS = 8; /** - * Unknown. This is somehow used in Flex, probably through annotations or - * something with Vector datatype (?) TODO: Investigate this + * Non nullable class */ public static final int CLASS_NON_NULLABLE = 16; @@ -293,6 +292,10 @@ public class InstanceInfo { String classTypeName = abc.constants.getMultiname(name_index).getNameWithNamespace(abc.constants, true).toRawString(); writer.hilightSpecial(abc.constants.getMultiname(name_index).getName(abc.constants, null/* No full names here*/, false, true), HighlightSpecialType.CLASS_NAME, classTypeName); + + if (!isNullable()) { + writer.appendNoHilight("!"); + } if (super_index > 0) { String typeName = abc.constants.getMultiname(super_index).getNameWithNamespace(abc.constants, true).toRawString(); diff --git a/libsrc/ffdec_lib/testdata/decimal/bin/decimal.abc b/libsrc/ffdec_lib/testdata/decimal/bin/decimal.abc index 9dda7846aaadebe91db53772a119f2bf176a2f78..eb9367eaef4701912a2dc9b2c53158e293596181 100644 GIT binary patch delta 90 zcmey*_MdITUPeaA$@>_q%{&<{7`QVqurM+*voM31tc;8-tZWyc5^M+wc7(*_d?ryA Pkc!D2OjjX{L}obv(@7OK delta 90 zcmey*_MdITUPeaF$@>_q%?vJhGPpA^urM+*voK#U05Vw_8Ch7_E