aspect NullObjects { // the actual unknown declaration null object is created in PredefinedTypes.jrag // explicit check if declaration is null object syn boolean Decl.isUnknown() = false; eq UnknownDecl.isUnknown() = true; // all types are compatible with the unknown type eq UnknownDecl.isSubtypeOf(TypeDecl typeDecl) = true; eq UnknownDecl.isSuperTypeOf(TypeDecl typeDecl) = true; eq UnknownDecl.isSuperTypeOfClassDecl(ClassDecl typeDecl) = true; // broadcast the unknown declaration null object to useful places in the AST syn lazy UnknownDecl Program.unknownDecl() = (UnknownDecl) localLookup("$unknown"); eq Program.getBlock().unknownDecl() = unknownDecl(); eq Program.getPredefinedType().unknownDecl() = unknownDecl(); inh Decl TypeDecl.unknownDecl(); inh Decl Block.unknownDecl(); }