@@ -747,6 +747,136 @@ defmodule TypespecTest do
747747 assert [ { :atom , _ , :is_subtype } , [ { :var , _ , :y } , { :var , _ , :x } ] ] = constraint_type
748748 end
749749
750+ test "@type, @opaque, and @typep as module attributes" do
751+ defmodule TypeModuleAttributes do
752+ @ type type1 :: boolean
753+ @ opaque opaque1 :: boolean
754+ @ typep typep1 :: boolean
755+
756+ def type1 , do: @ type
757+ def opaque1 , do: @ opaque
758+ def typep1 , do: @ typep
759+
760+ @ type type2 :: atom
761+ @ type type3 :: pid
762+ @ opaque opaque2 :: atom
763+ @ opaque opaque3 :: pid
764+ @ typep typep2 :: atom
765+
766+ def type2 , do: @ type
767+ def opaque2 , do: @ opaque
768+ def typep2 , do: @ typep
769+
770+ # Avoid unused warnings
771+ @ spec foo ( typep1 ) :: typep2
772+ def foo ( _x ) , do: :ok
773+ end
774+
775+ assert [
776+ { :type , { ::: , _ , [ { :type1 , _ , _ } , { :boolean , _ , _ } ] } ,
777+ { TypespecTest.TypeModuleAttributes , _ } }
778+ ] = TypeModuleAttributes . type1 ( )
779+
780+ assert [
781+ { :type , { ::: , _ , [ { :type3 , _ , _ } , { :pid , _ , _ } ] } ,
782+ { TypespecTest.TypeModuleAttributes , _ } } ,
783+ { :type , { ::: , _ , [ { :type2 , _ , _ } , { :atom , _ , _ } ] } ,
784+ { TypespecTest.TypeModuleAttributes , _ } } ,
785+ { :type , { ::: , _ , [ { :type1 , _ , _ } , { :boolean , _ , _ } ] } ,
786+ { TypespecTest.TypeModuleAttributes , _ } }
787+ ] = TypeModuleAttributes . type2 ( )
788+
789+ assert [
790+ { :opaque , { ::: , _ , [ { :opaque1 , _ , _ } , { :boolean , _ , _ } ] } ,
791+ { TypespecTest.TypeModuleAttributes , _ } }
792+ ] = TypeModuleAttributes . opaque1 ( )
793+
794+ assert [
795+ { :opaque , { ::: , _ , [ { :opaque3 , _ , _ } , { :pid , _ , _ } ] } ,
796+ { TypespecTest.TypeModuleAttributes , _ } } ,
797+ { :opaque , { ::: , _ , [ { :opaque2 , _ , _ } , { :atom , _ , _ } ] } ,
798+ { TypespecTest.TypeModuleAttributes , _ } } ,
799+ { :opaque , { ::: , _ , [ { :opaque1 , _ , _ } , { :boolean , _ , _ } ] } ,
800+ { TypespecTest.TypeModuleAttributes , _ } }
801+ ] = TypeModuleAttributes . opaque2 ( )
802+
803+ assert [
804+ { :typep , { ::: , _ , [ { :typep1 , _ , _ } , { :boolean , _ , _ } ] } ,
805+ { TypespecTest.TypeModuleAttributes , _ } }
806+ ] = TypeModuleAttributes . typep1 ( )
807+
808+ assert [
809+ { :typep , { ::: , _ , [ { :typep2 , _ , _ } , { :atom , _ , _ } ] } ,
810+ { TypespecTest.TypeModuleAttributes , _ } } ,
811+ { :typep , { ::: , _ , [ { :typep1 , _ , _ } , { :boolean , _ , _ } ] } ,
812+ { TypespecTest.TypeModuleAttributes , _ } }
813+ ] = TypeModuleAttributes . typep2 ( )
814+ after
815+ :code . delete ( TypeModuleAttributes )
816+ :code . purge ( TypeModuleAttributes )
817+ end
818+
819+ test "@spec, @callback, and @macrocallback as module attributes" do
820+ defmodule SpecModuleAttributes do
821+ @ callback callback1 :: integer
822+ @ macrocallback macrocallback1 :: integer
823+
824+ @ spec spec1 :: boolean
825+ def spec1 , do: @ spec
826+
827+ @ callback callback2 :: boolean
828+ @ macrocallback macrocallback2 :: boolean
829+
830+ @ spec spec2 :: atom
831+ def spec2 , do: @ spec
832+
833+ @ spec spec3 :: pid
834+ def spec3 , do: :ok
835+ def spec4 , do: @ spec
836+
837+ def callback , do: @ callback
838+ def macrocallback , do: @ macrocallback
839+ end
840+
841+ assert [
842+ { :spec , { ::: , _ , [ { :spec1 , _ , _ } , { :boolean , _ , _ } ] } ,
843+ { TypespecTest.SpecModuleAttributes , _ } }
844+ ] = SpecModuleAttributes . spec1 ( )
845+
846+ assert [
847+ { :spec , { ::: , _ , [ { :spec2 , _ , _ } , { :atom , _ , _ } ] } ,
848+ { TypespecTest.SpecModuleAttributes , _ } } ,
849+ { :spec , { ::: , _ , [ { :spec1 , _ , _ } , { :boolean , _ , _ } ] } ,
850+ { TypespecTest.SpecModuleAttributes , _ } }
851+ ] = SpecModuleAttributes . spec2 ( )
852+
853+ assert [
854+ { :spec , { ::: , _ , [ { :spec3 , _ , _ } , { :pid , _ , _ } ] } ,
855+ { TypespecTest.SpecModuleAttributes , _ } } ,
856+ { :spec , { ::: , _ , [ { :spec2 , _ , _ } , { :atom , _ , _ } ] } ,
857+ { TypespecTest.SpecModuleAttributes , _ } } ,
858+ { :spec , { ::: , _ , [ { :spec1 , _ , _ } , { :boolean , _ , _ } ] } ,
859+ { TypespecTest.SpecModuleAttributes , _ } }
860+ ] = SpecModuleAttributes . spec4 ( )
861+
862+ assert [
863+ { :callback , { ::: , _ , [ { :callback2 , _ , _ } , { :boolean , _ , _ } ] } ,
864+ { TypespecTest.SpecModuleAttributes , _ } } ,
865+ { :callback , { ::: , _ , [ { :callback1 , _ , _ } , { :integer , _ , _ } ] } ,
866+ { TypespecTest.SpecModuleAttributes , _ } }
867+ ] = SpecModuleAttributes . callback ( )
868+
869+ assert [
870+ { :macrocallback , { ::: , _ , [ { :macrocallback2 , _ , _ } , { :boolean , _ , _ } ] } ,
871+ { TypespecTest.SpecModuleAttributes , _ } } ,
872+ { :macrocallback , { ::: , _ , [ { :macrocallback1 , _ , _ } , { :integer , _ , _ } ] } ,
873+ { TypespecTest.SpecModuleAttributes , _ } }
874+ ] = SpecModuleAttributes . macrocallback ( )
875+ after
876+ :code . delete ( SpecModuleAttributes )
877+ :code . purge ( SpecModuleAttributes )
878+ end
879+
750880 test "@callback(callback)" do
751881 bytecode =
752882 test_module do
0 commit comments