1
2
3
4
5
6 #include <cmajor/binder/Access.hpp>
7 #include <cmajor/symbols/ClassTypeSymbol.hpp>
8 #include <cmajor/symbols/ClassTemplateSpecializationSymbol.hpp>
9 #include <cmajor/symbols/Exception.hpp>
10 #include <soulng/util/Unicode.hpp>
11
12 namespace cmajor { namespace binder {
13
14 using namespace soulng::unicode;
15
16 bool HasAccess(FunctionSymbol* fromFunction, Symbol* toSymbol)
17 {
18 if (!fromFunction) return false;
19 FunctionSymbol* toContainingFunction = toSymbol->ContainingFunctionNoThrow();
20 if (toContainingFunction)
21 {
22 if (fromFunction == toContainingFunction || FunctionSymbolsEqual()(fromFunction, toContainingFunction))
23 {
24 return true;
25 }
26 }
27 ClassTypeSymbol* toContainingClass = toSymbol->ContainingClassNoThrow();
28 if (toContainingClass)
29 {
30 if (!HasAccess(fromFunction, toContainingClass)) return false;
31 }
32 switch (toSymbol->DeclaredAccess())
33 {
34 case SymbolAccess::public_: return true;
35 case SymbolAccess::protected_:
36 {
37 ClassTypeSymbol* fromContainingClass = fromFunction->ContainingClassNoThrow();
38 if (fromContainingClass)
39 {
40 if (toContainingClass && toContainingClass->IsSameParentOrAncestorOf(fromContainingClass))
41 {
42 return true;
43 }
44 if (fromContainingClass->HasBaseClass(toContainingClass))
45 {
46 return true;
47 }
48 }
49 break;
50 }
51 case SymbolAccess::internal_:
52 {
53 if (fromFunction->GetModule() == toSymbol->GetModule())
54 {
55 return true;;
56 }
57 break;
58 }
59 case SymbolAccess::private_:
60 {
61 if (toContainingClass)
62 {
63 ClassTypeSymbol* fromContainingClass = fromFunction->ContainingClassNoThrow();
64 if (fromContainingClass)
65 {
66 if (toContainingClass->IsSameParentOrAncestorOf(fromContainingClass))
67 {
68 return true;
69 }
70 }
71 }
72 break;
73 }
74 }
75 return false;
76 }
77
78 void CheckAccess(FunctionSymbol* fromFunction, Symbol* toSymbol)
79 {
80 if (!HasAccess(fromFunction, toSymbol))
81 {
82 throw Exception(toSymbol->TypeString() + " '" + ToUtf8(toSymbol->FullName()) + "' is inaccessible due to its protection level",
83 fromFunction->GetSpan(), fromFunction->SourceModuleId(), toSymbol->GetSpan(), toSymbol->SourceModuleId());
84 }
85 }
86
87 } }