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 9dda7846a..eb9367eae 100644 Binary files a/libsrc/ffdec_lib/testdata/decimal/bin/decimal.abc and b/libsrc/ffdec_lib/testdata/decimal/bin/decimal.abc differ diff --git a/libsrc/ffdec_lib/testdata/decimal/bin/decimal.cpp b/libsrc/ffdec_lib/testdata/decimal/bin/decimal.cpp index 976b382d9..05310d937 100644 --- a/libsrc/ffdec_lib/testdata/decimal/bin/decimal.cpp +++ b/libsrc/ffdec_lib/testdata/decimal/bin/decimal.cpp @@ -30,7 +30,7 @@ const unsigned char decimal_abc_data[895] = { 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x06, 0x01, 0x00, 0x09, 0x03, 0x00, 0x01, 0x00, 0x02, 0x01, 0x09, 0x05, 0x00, 0x03, 0x00, 0x03, 0x01, 0x09, 0x07, 0x00, 0x05, 0x00, 0x04, 0x01, 0x09, -0x09, 0x00, 0x07, 0x00, 0x05, 0x01, 0x09, 0x0c, 0x00, 0x09, 0x00, 0x16, 0x01, 0x09, 0x10, 0x00, +0x09, 0x00, 0x07, 0x00, 0x05, 0x01, 0x09, 0x0c, 0x00, 0x09, 0x00, 0x16, 0x01, 0x19, 0x10, 0x00, 0x0d, 0x03, 0x13, 0x00, 0x01, 0x04, 0x00, 0x14, 0x00, 0x02, 0x03, 0x00, 0x15, 0x01, 0x02, 0x0c, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x06, 0x00, 0x08, 0x00, 0x0b, 0x00, 0x02, 0x0e, 0x01, 0x16, 0x04, 0x01, 0x05, 0x0a, 0x09, 0x11, 0x06, 0x00, 0x00, 0x0d, 0x08, 0x01, 0x04, 0x00, 0x00, 0x02, @@ -38,12 +38,12 @@ const unsigned char decimal_abc_data[895] = { 0x06, 0x00, 0x02, 0x01, 0x06, 0x0e, 0x06, 0x00, 0x02, 0x02, 0x06, 0x10, 0x06, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x01, 0x01, 0x02, 0x03, 0x03, 0xd0, 0x30, 0x47, 0x00, 0x00, 0x01, 0x01, 0x01, 0x03, 0x04, 0x03, 0xd0, 0x30, 0x47, 0x00, 0x00, 0x02, 0x01, 0x01, 0x03, 0x04, 0x03, 0xd0, 0x30, 0x47, -0x00, 0x00, 0x03, 0x01, 0x01, 0x04, 0x05, 0x06, 0xd0, 0x30, 0xd0, 0x49, 0x00, 0x47, 0x00, 0x00, +0x00, 0x00, 0x03, 0x01, 0x01, 0x04, 0x05, 0x06, 0xd0, 0x49, 0x00, 0xd0, 0x30, 0x47, 0x00, 0x00, 0x04, 0x01, 0x01, 0x03, 0x04, 0x03, 0xd0, 0x30, 0x47, 0x00, 0x00, 0x05, 0x01, 0x01, 0x04, 0x05, -0x06, 0xd0, 0x30, 0xd0, 0x49, 0x00, 0x47, 0x00, 0x00, 0x06, 0x01, 0x01, 0x03, 0x04, 0x03, 0xd0, -0x30, 0x47, 0x00, 0x00, 0x07, 0x01, 0x01, 0x04, 0x05, 0x06, 0xd0, 0x30, 0xd0, 0x49, 0x00, 0x47, +0x06, 0xd0, 0x49, 0x00, 0xd0, 0x30, 0x47, 0x00, 0x00, 0x06, 0x01, 0x01, 0x03, 0x04, 0x03, 0xd0, +0x30, 0x47, 0x00, 0x00, 0x07, 0x01, 0x01, 0x04, 0x05, 0x06, 0xd0, 0x49, 0x00, 0xd0, 0x30, 0x47, 0x00, 0x00, 0x08, 0x01, 0x01, 0x03, 0x04, 0x03, 0xd0, 0x30, 0x47, 0x00, 0x00, 0x09, 0x01, 0x01, -0x04, 0x05, 0x06, 0xd0, 0x30, 0xd0, 0x49, 0x00, 0x47, 0x00, 0x00, 0x0a, 0x03, 0x01, 0x01, 0x03, +0x04, 0x05, 0x06, 0xd0, 0x49, 0x00, 0xd0, 0x30, 0x47, 0x00, 0x00, 0x0a, 0x03, 0x01, 0x01, 0x03, 0x61, 0xd0, 0x30, 0x5d, 0x06, 0x20, 0x58, 0x00, 0x68, 0x01, 0x5d, 0x07, 0x5d, 0x01, 0x66, 0x01, 0x30, 0x5d, 0x01, 0x66, 0x01, 0x58, 0x01, 0x1d, 0x68, 0x02, 0x5d, 0x08, 0x5d, 0x01, 0x66, 0x01, 0x30, 0x5d, 0x01, 0x66, 0x01, 0x58, 0x02, 0x1d, 0x68, 0x03, 0x5d, 0x09, 0x5d, 0x01, 0x66, 0x01, @@ -56,6 +56,6 @@ const unsigned char decimal_abc_data[895] = { 0x05, 0x82, 0x63, 0x04, 0xd2, 0xd3, 0xb8, 0x81, 0x05, 0x82, 0x63, 0x04, 0xd2, 0xd3, 0xb9, 0x81, 0x05, 0x82, 0x63, 0x04, 0xd2, 0xd3, 0xb7, 0x81, 0x05, 0x82, 0x63, 0x04, 0x62, 0x04, 0x9c, 0x81, 0x05, 0x82, 0x63, 0x04, 0x62, 0x04, 0x9e, 0x81, 0x05, 0x82, 0x63, 0x04, 0xd2, 0x8f, 0x81, 0x05, -0x82, 0x63, 0x04, 0x47, 0x00, 0x00, 0x0d, 0x01, 0x01, 0x04, 0x05, 0x06, 0xd0, 0x30, 0xd0, 0x49, -0x00, 0x47, 0x00, 0x00, 0x0e, 0x02, 0x01, 0x01, 0x03, 0x13, 0xd0, 0x30, 0x65, 0x00, 0x5d, 0x01, +0x82, 0x63, 0x04, 0x47, 0x00, 0x00, 0x0d, 0x01, 0x01, 0x04, 0x05, 0x06, 0xd0, 0x49, 0x00, 0xd0, +0x30, 0x47, 0x00, 0x00, 0x0e, 0x02, 0x01, 0x01, 0x03, 0x13, 0xd0, 0x30, 0x65, 0x00, 0x5d, 0x01, 0x66, 0x01, 0x30, 0x5d, 0x01, 0x66, 0x01, 0x58, 0x05, 0x1d, 0x68, 0x16, 0x47, 0x00, 0x00 }; diff --git a/libsrc/ffdec_lib/testdata/decimal/src/mypkg/MyClass.as b/libsrc/ffdec_lib/testdata/decimal/src/mypkg/MyClass.as index 57ebebca2..410194690 100644 --- a/libsrc/ffdec_lib/testdata/decimal/src/mypkg/MyClass.as +++ b/libsrc/ffdec_lib/testdata/decimal/src/mypkg/MyClass.as @@ -2,7 +2,7 @@ package mypkg { use decimal, rounding CEILING, precision 10; - public class MyClass + public class MyClass! { private var attr_dec:decimal; private var attr_int:int;