Renamed restricted access to opaque access
This commit is contained in:
parent
a9c85bf017
commit
a8fd79991c
|
@ -14,13 +14,13 @@ type strictness int; const (
|
|||
strict strictness = iota
|
||||
// Like strict, but the root types specifically are compared as if they
|
||||
// were not named. analyzer.ReduceToBase() is used to accomplish this.
|
||||
// Assignment to private/restricted types is not allowed.
|
||||
// Assignment to private/opaque types is not allowed.
|
||||
weak
|
||||
// Full structural equivalence, and named types are always reduced.
|
||||
// Assignment to private/restricted types is not allowed.
|
||||
// Assignment to private/opaque types is not allowed.
|
||||
structural
|
||||
// Data of the source type must be convert-able to the destination type.
|
||||
// This is used in value casts. Assignment to private/restricted types
|
||||
// This is used in value casts. Assignment to private/opaque types
|
||||
// is not allowed.
|
||||
coerce
|
||||
// All assignment rules are ignored. This is only used in bit casts.
|
||||
|
@ -62,9 +62,9 @@ func (this *Tree) canAssign (
|
|||
if destination != nil && source != nil &&
|
||||
mode != strict && mode != force {
|
||||
|
||||
err := this.typeRestricted(pos, destination)
|
||||
err := this.typeOpaque(pos, destination)
|
||||
if err != nil { return err }
|
||||
err = this.typeRestricted(pos, source)
|
||||
err = this.typeOpaque(pos, source)
|
||||
if err != nil { return err }
|
||||
}
|
||||
|
||||
|
|
|
@ -159,7 +159,7 @@ func (this *Tree) analyzeMethodCall (
|
|||
|
||||
// since this is a behavior, check access permissions of the
|
||||
// interface
|
||||
err = this.typeRestricted(call.Position, source.Type())
|
||||
err = this.typeOpaque(call.Position, source.Type())
|
||||
if err != nil { return nil, err }
|
||||
|
||||
case *entity.Method:
|
||||
|
@ -225,7 +225,7 @@ func (this *Tree) analyzeSubscript (
|
|||
subscript.Ty = into
|
||||
|
||||
// check permissions
|
||||
err = this.typeRestricted(subscript.Position, slice.Type())
|
||||
err = this.typeOpaque(subscript.Position, slice.Type())
|
||||
if err != nil { return nil, err }
|
||||
|
||||
offset, err := this.analyzeExpression (
|
||||
|
@ -264,7 +264,7 @@ func (this *Tree) analyzeSlice (
|
|||
slice.Slice = value
|
||||
|
||||
// check permissions
|
||||
err = this.typeRestricted(slice.Position, value.Type())
|
||||
err = this.typeOpaque(slice.Position, value.Type())
|
||||
if err != nil { return nil, err }
|
||||
|
||||
if slice.Start != nil {
|
||||
|
@ -414,7 +414,7 @@ func (this *Tree) analyzeOperation (
|
|||
error,
|
||||
) {
|
||||
// check permissions
|
||||
err := this.typeRestricted(operation.Position, into)
|
||||
err := this.typeOpaque(operation.Position, into)
|
||||
if err != nil { return nil, err }
|
||||
|
||||
intoUntrustworthy := into == nil || mode == force || mode == coerce
|
||||
|
@ -654,7 +654,7 @@ func (this *Tree) analyzeMemberAccess (
|
|||
}
|
||||
|
||||
// check permissions
|
||||
err = this.typeRestricted(access.Position, qualifiedSourceType)
|
||||
err = this.typeOpaque(access.Position, qualifiedSourceType)
|
||||
if err != nil { return nil, err }
|
||||
|
||||
// get member
|
||||
|
|
|
@ -26,9 +26,9 @@ func (this *Tree) analyzeFunction (
|
|||
// set unit
|
||||
function.Unit = key.Unit
|
||||
|
||||
// functions cannot be marked as restricted
|
||||
if function.Acc == entity.AccessRestricted {
|
||||
return nil, errors.Errorf(pos, "cannot mark function as restricted")
|
||||
// functions cannot be marked as opaque
|
||||
if function.Acc == entity.AccessOpaque {
|
||||
return nil, errors.Errorf(pos, "cannot mark function as opaque")
|
||||
}
|
||||
|
||||
// create a new scope context for this function
|
||||
|
|
|
@ -12,7 +12,7 @@ func (this *Tree) analyzeLiteralInt (
|
|||
entity.Expression,
|
||||
error,
|
||||
) {
|
||||
err := this.typeRestricted(literal.Position, into)
|
||||
err := this.typeOpaque(literal.Position, into)
|
||||
if err != nil { return nil, err }
|
||||
|
||||
if !isNumeric(into) {
|
||||
|
@ -39,7 +39,7 @@ func (this *Tree) analyzeLiteralFloat (
|
|||
entity.Expression,
|
||||
error,
|
||||
) {
|
||||
err := this.typeRestricted(literal.Position, into)
|
||||
err := this.typeOpaque(literal.Position, into)
|
||||
if err != nil { return nil, err }
|
||||
|
||||
if !isFloat(into) {
|
||||
|
@ -60,7 +60,7 @@ func (this *Tree) analyzeLiteralString (
|
|||
entity.Expression,
|
||||
error,
|
||||
) {
|
||||
err := this.typeRestricted(literal.Position, into)
|
||||
err := this.typeOpaque(literal.Position, into)
|
||||
if err != nil { return nil, err }
|
||||
|
||||
base := ReduceToBase(into)
|
||||
|
@ -163,7 +163,7 @@ func (this *Tree) analyzeLiteralArray (
|
|||
entity.Expression,
|
||||
error,
|
||||
) {
|
||||
err := this.typeRestricted(literal.Position, into)
|
||||
err := this.typeOpaque(literal.Position, into)
|
||||
if err != nil { return nil, err }
|
||||
|
||||
base := ReduceToBase(into)
|
||||
|
@ -209,7 +209,7 @@ func (this *Tree) analyzeLiteralStruct (
|
|||
entity.Expression,
|
||||
error,
|
||||
) {
|
||||
err := this.typeRestricted(literal.Position, into)
|
||||
err := this.typeOpaque(literal.Position, into)
|
||||
if err != nil { return nil, err }
|
||||
|
||||
base, ok := ReduceToBase(into).(*entity.TypeStruct)
|
||||
|
@ -247,7 +247,7 @@ func (this *Tree) analyzeLiteralBoolean (
|
|||
entity.Expression,
|
||||
error,
|
||||
) {
|
||||
err := this.typeRestricted(literal.Position, into)
|
||||
err := this.typeOpaque(literal.Position, into)
|
||||
if err != nil { return nil, err }
|
||||
|
||||
if !isBoolean(into) {
|
||||
|
@ -268,7 +268,7 @@ func (this *Tree) analyzeLiteralNil (
|
|||
entity.Expression,
|
||||
error,
|
||||
) {
|
||||
err := this.typeRestricted(literal.Position, into)
|
||||
err := this.typeOpaque(literal.Position, into)
|
||||
if err != nil { return nil, err }
|
||||
|
||||
literal.Ty = into
|
||||
|
|
|
@ -32,9 +32,9 @@ func (this *Tree) analyzeMethod (
|
|||
// set method's unit, very important information yes
|
||||
method.Unit = owner.Unit
|
||||
|
||||
// methods cannot be marked as restricted
|
||||
if method.Acc == entity.AccessRestricted {
|
||||
return nil, errors.Errorf(pos, "cannot mark method as restricted")
|
||||
// methods cannot be marked as opaque
|
||||
if method.Acc == entity.AccessOpaque {
|
||||
return nil, errors.Errorf(pos, "cannot mark method as opaque")
|
||||
}
|
||||
|
||||
// create a new scope context for this method
|
||||
|
|
|
@ -39,95 +39,95 @@ testUnitsErr (test,
|
|||
- T.[x]:Int = 5`,
|
||||
)}
|
||||
|
||||
func TestUnitAssignRestricted (test *testing.T) {
|
||||
func TestUnitAssignOpaque (test *testing.T) {
|
||||
testUnits (test,
|
||||
`[main] = {
|
||||
x:other::RestrictedInt
|
||||
y:other::RestrictedInt
|
||||
x:other::OpaqueInt
|
||||
y:other::OpaqueInt
|
||||
x = y
|
||||
}`,
|
||||
|
||||
"other.fspl",
|
||||
`# RestrictedInt:Int`,
|
||||
`# OpaqueInt:Int`,
|
||||
)}
|
||||
|
||||
func TestUnitAssignLiteralRestrictedErr (test *testing.T) {
|
||||
func TestUnitAssignLiteralOpaqueErr (test *testing.T) {
|
||||
testUnitsErr (test,
|
||||
"main.fspl", "type other::RestrictedInt is restricted", 1, 31,
|
||||
`[main]:other::RestrictedInt = 5`,
|
||||
"main.fspl", "type other::OpaqueInt is opaque", 1, 27,
|
||||
`[main]:other::OpaqueInt = 5`,
|
||||
|
||||
"other.fspl",
|
||||
`# RestrictedInt:Int`,
|
||||
`# OpaqueInt:Int`,
|
||||
)}
|
||||
|
||||
func TestAssignLiteralRestricted (test *testing.T) {
|
||||
func TestAssignLiteralOpaque (test *testing.T) {
|
||||
testString (test,
|
||||
`# RestrictedInt:Int
|
||||
[main]:RestrictedInt = 5`,
|
||||
`# OpaqueInt:Int
|
||||
[main]:OpaqueInt = 5`,
|
||||
)}
|
||||
|
||||
func TestUnitMemberAccessRestrictedErr (test *testing.T) {
|
||||
func TestUnitMemberAccessOpaqueErr (test *testing.T) {
|
||||
testUnitsErr (test,
|
||||
"main.fspl", "type other::RestrictedStruct is restricted", 3, 3,
|
||||
"main.fspl", "type other::OpaqueStruct is opaque", 3, 3,
|
||||
`[main] = {
|
||||
x:other::RestrictedStruct
|
||||
x:other::OpaqueStruct
|
||||
x.x = 5
|
||||
}`,
|
||||
|
||||
"other.fspl",
|
||||
`# RestrictedStruct:(. x:Int y:Int)`,
|
||||
`# OpaqueStruct:(. x:Int y:Int)`,
|
||||
)}
|
||||
|
||||
func TestMemberAccessRestricted (test *testing.T) {
|
||||
func TestMemberAccessOpaque (test *testing.T) {
|
||||
testString (test,
|
||||
`# RestrictedStruct:(. x:Int y:Int)
|
||||
`# OpaqueStruct:(. x:Int y:Int)
|
||||
[main] = {
|
||||
x:RestrictedStruct
|
||||
x:OpaqueStruct
|
||||
x.x = 5
|
||||
}`,
|
||||
)}
|
||||
|
||||
func TestUnitSubscriptRestrictedErr (test *testing.T) {
|
||||
func TestUnitSubscriptOpaqueErr (test *testing.T) {
|
||||
testUnitsErr (test,
|
||||
"main.fspl", "type other::RestrictedArr is restricted", 3, 4,
|
||||
"main.fspl", "type other::OpaqueArr is opaque", 3, 4,
|
||||
`[main] = {
|
||||
x:other::RestrictedArr
|
||||
x:other::OpaqueArr
|
||||
[.x 0] = 5
|
||||
}`,
|
||||
|
||||
"other.fspl",
|
||||
`# RestrictedArr:5:Int`,
|
||||
`# OpaqueArr:5:Int`,
|
||||
)}
|
||||
|
||||
func TestSubscriptRestricted (test *testing.T) {
|
||||
func TestSubscriptOpaque (test *testing.T) {
|
||||
testString (test,
|
||||
`# RestrictedArr:5:Int
|
||||
`# OpaqueArr:5:Int
|
||||
[main] = {
|
||||
x:RestrictedArr
|
||||
x:OpaqueArr
|
||||
[.x 0] = 5
|
||||
}`,
|
||||
)}
|
||||
|
||||
func TestUnitMathRestrictedErr (test *testing.T) {
|
||||
func TestUnitMathOpaqueErr (test *testing.T) {
|
||||
testUnitsErr (test,
|
||||
"main.fspl", "type other::RestrictedInt is restricted", 2, 27,
|
||||
"main.fspl", "type other::OpaqueInt is opaque", 2, 23,
|
||||
`[main] = {
|
||||
x:other::RestrictedInt = [+
|
||||
y:other::RestrictedInt
|
||||
z:other::RestrictedInt]
|
||||
x:other::OpaqueInt = [+
|
||||
y:other::OpaqueInt
|
||||
z:other::OpaqueInt]
|
||||
}`,
|
||||
|
||||
"other.fspl",
|
||||
`# RestrictedInt:Int`,
|
||||
`# OpaqueInt:Int`,
|
||||
)}
|
||||
|
||||
func TestMathRestricted (test *testing.T) {
|
||||
func TestMathOpaque (test *testing.T) {
|
||||
testString (test,
|
||||
`# RestrictedInt:Int
|
||||
`# OpaqueInt:Int
|
||||
[main] = {
|
||||
x:RestrictedInt = [+
|
||||
y:RestrictedInt
|
||||
z:RestrictedInt]
|
||||
x:OpaqueInt = [+
|
||||
y:OpaqueInt
|
||||
z:OpaqueInt]
|
||||
}`,
|
||||
)}
|
||||
|
||||
|
@ -142,55 +142,55 @@ testUnits (test,
|
|||
`+ X:layer0::X`,
|
||||
)}
|
||||
|
||||
func TestUnitBehaviorCallRestrictedErr (test *testing.T) {
|
||||
func TestUnitBehaviorCallOpaqueErr (test *testing.T) {
|
||||
testUnitsErr (test,
|
||||
"main.fspl", "type other::RestrictedInterface is restricted", 3, 3,
|
||||
"main.fspl", "type other::OpaqueInterface is opaque", 3, 3,
|
||||
`[main] = {
|
||||
x:other::RestrictedInterface
|
||||
x:other::OpaqueInterface
|
||||
x.[y]
|
||||
}`,
|
||||
|
||||
"other.fspl",
|
||||
`# RestrictedInterface:(& [y])`,
|
||||
`# OpaqueInterface:(& [y])`,
|
||||
)}
|
||||
|
||||
func TestBehaviorCallRestricted (test *testing.T) {
|
||||
func TestBehaviorCallOpaque (test *testing.T) {
|
||||
testString (test,
|
||||
`[main] = {
|
||||
x:RestrictedInterface
|
||||
x:OpaqueInterface
|
||||
x.[y]
|
||||
}
|
||||
# RestrictedInterface:(& [y])`,
|
||||
# OpaqueInterface:(& [y])`,
|
||||
)}
|
||||
|
||||
func TestUnitCastRestrictedErr (test *testing.T) {
|
||||
func TestUnitCastOpaqueErr (test *testing.T) {
|
||||
testUnitsErr (test,
|
||||
"main.fspl", "type other::RestrictedInt is restricted", 2, 16,
|
||||
"main.fspl", "type other::OpaqueInt is opaque", 2, 16,
|
||||
`[main] = {
|
||||
x:Int = [~Int y:other::RestrictedInt]
|
||||
x:Int = [~Int y:other::OpaqueInt]
|
||||
}`,
|
||||
|
||||
"other.fspl",
|
||||
`# RestrictedInt:Int`,
|
||||
`# OpaqueInt:Int`,
|
||||
)}
|
||||
|
||||
func TestCastRestricted (test *testing.T) {
|
||||
func TestCastOpaque (test *testing.T) {
|
||||
testString (test,
|
||||
`[main] = {
|
||||
x:Int = [~Int y:RestrictedInt]
|
||||
x:Int = [~Int y:OpaqueInt]
|
||||
}
|
||||
# RestrictedInt:Int`,
|
||||
# OpaqueInt:Int`,
|
||||
)}
|
||||
|
||||
func TestFunctionRestrictedErr (test *testing.T) {
|
||||
func TestFunctionOpaqueErr (test *testing.T) {
|
||||
testStringErr (test,
|
||||
"cannot mark function as restricted", 1, 1,
|
||||
"cannot mark function as opaque", 1, 1,
|
||||
`# [f]`,
|
||||
)}
|
||||
|
||||
func TestMethodRestrictedErr (test *testing.T) {
|
||||
func TestMethodOpaqueErr (test *testing.T) {
|
||||
testStringErr (test,
|
||||
"cannot mark method as restricted", 2, 1,
|
||||
"cannot mark method as opaque", 2, 1,
|
||||
`T:Int
|
||||
# T.[f]`,
|
||||
)}
|
||||
|
|
|
@ -223,8 +223,8 @@ func (this *Tree) typePrivate (pos errors.Position, ty entity.Type) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// typeRestricted checks if the given type is restricted or private.
|
||||
func (this *Tree) typeRestricted (pos errors.Position, ty entity.Type) error {
|
||||
// typeOpaque checks if the given type is opaque or private.
|
||||
func (this *Tree) typeOpaque (pos errors.Position, ty entity.Type) error {
|
||||
if ty == nil { return nil }
|
||||
|
||||
err := this.typePrivate(pos, ty)
|
||||
|
@ -234,8 +234,8 @@ func (this *Tree) typeRestricted (pos errors.Position, ty entity.Type) error {
|
|||
if named, ok := ty.(*entity.TypeNamed); ok {
|
||||
ty = named.Type
|
||||
}
|
||||
if ty.Unit() != this.unit && ty.Access() == entity.AccessRestricted {
|
||||
return errors.Errorf(pos, "type %v is restricted", entity.FormatType(original))
|
||||
if ty.Unit() != this.unit && ty.Access() == entity.AccessOpaque {
|
||||
return errors.Errorf(pos, "type %v is opaque", entity.FormatType(original))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -79,12 +79,12 @@ type Access int; const (
|
|||
// AccessPublic allows other modules to access an entity normally.
|
||||
AccessPublic Access = iota
|
||||
|
||||
// AccessRestricted causes a top-level entity to appear opaque to other
|
||||
// modules. Values of restricted types can be passed around, assigned
|
||||
// to eachother, and their methods can be called, but the implementation
|
||||
// of the type is entirely hidden. This access mode cannot be applied to
|
||||
// functions.
|
||||
AccessRestricted
|
||||
// AccessOpaque causes a top-level entity to appear opaque to other
|
||||
// units. Values of restricted types can be passed around, assigned to
|
||||
// eachother, and their methods can be called, but the implementation of
|
||||
// the type is entirely hidden. This access mode cannot be applied to
|
||||
// functions or methods.
|
||||
AccessOpaque
|
||||
|
||||
// AccessPrivate disallows other modules from accessing a top-level
|
||||
// entity.
|
||||
|
@ -93,9 +93,9 @@ type Access int; const (
|
|||
|
||||
func (this Access) String () string {
|
||||
switch this {
|
||||
case AccessPrivate: return "-"
|
||||
case AccessRestricted: return "#"
|
||||
case AccessPublic: return "+"
|
||||
case AccessPrivate: return "-"
|
||||
case AccessOpaque: return "#"
|
||||
case AccessPublic: return "+"
|
||||
default: return fmt.Sprintf("entity.Access(%d)", this)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -156,31 +156,31 @@ func TestAccess (test *testing.T) {
|
|||
testString (test,
|
||||
// correct
|
||||
`+ PublicType: Int
|
||||
# RestrictedType: (. x:Int y:Int)
|
||||
# OpaqueType: (. x:Int y:Int)
|
||||
- PrivateType: String
|
||||
- AlsoPrivateType: Byte
|
||||
+ [publicFn]:Int = 0
|
||||
# [restrictedFn]:(. x:Int y:Int) = (. x:0 y:0)
|
||||
# [opaqueFn]:(. x:Int y:Int) = (. x:0 y:0)
|
||||
- [privateFn]:Rune = 'a'
|
||||
- [alsoPrivateFn]:Byte = 0
|
||||
- T: Int
|
||||
+ T.[publicFn]:Int = 0
|
||||
# T.[restrictedFn]:(. x:Int y:Int) = (. x:0 y:0)
|
||||
# T.[opaqueFn]:(. x:Int y:Int) = (. x:0 y:0)
|
||||
- T.[privateFn]:Rune = 'a'
|
||||
- T.[alsoPrivateFn]:Byte = 0`,
|
||||
//input
|
||||
`
|
||||
+ PublicType: Int
|
||||
# RestrictedType: (. x:Int y:Int)
|
||||
# OpaqueType: (. x:Int y:Int)
|
||||
- PrivateType: String
|
||||
AlsoPrivateType: Byte
|
||||
+ [publicFn]: Int = 0
|
||||
# [restrictedFn]: (. x:Int y:Int) = (. x:0 y:0)
|
||||
# [opaqueFn]: (. x:Int y:Int) = (. x:0 y:0)
|
||||
- [privateFn]: Rune = 'a'
|
||||
[alsoPrivateFn]: Byte = 0
|
||||
T: Int
|
||||
+ T.[publicFn]: Int = 0
|
||||
# T.[restrictedFn]: (. x:Int y:Int) = (. x:0 y:0)
|
||||
# T.[opaqueFn]: (. x:Int y:Int) = (. x:0 y:0)
|
||||
- T.[privateFn]: Rune = 'a'
|
||||
T.[alsoPrivateFn]: Byte = 0
|
||||
`)
|
||||
|
@ -214,7 +214,7 @@ func TestSkim (test *testing.T) {
|
|||
testStringSkim (test,
|
||||
// correct
|
||||
`- PrivType: Int
|
||||
# RestrictType: Int
|
||||
# OpaqueType: Int
|
||||
+ ComplexType: (. parser:Parser tree:*Tree skim:Bool)
|
||||
+ X: Int
|
||||
+ X.[pub]:Int
|
||||
|
@ -225,7 +225,7 @@ testStringSkim (test,
|
|||
+ [pub]:X`,
|
||||
// input
|
||||
`- PrivType:Int
|
||||
# RestrictType:Int
|
||||
# OpaqueType:Int
|
||||
+ ComplexType: (.
|
||||
parser:Parser
|
||||
tree:*Tree
|
||||
|
|
|
@ -74,9 +74,9 @@ func (this *treeParser) parseAccess () (entity.Access, error) {
|
|||
defer this.Next()
|
||||
|
||||
switch this.Value() {
|
||||
case "-": return entity.AccessPrivate, nil
|
||||
case "#": return entity.AccessRestricted, nil
|
||||
case "+": return entity.AccessPublic, nil
|
||||
case "-": return entity.AccessPrivate, nil
|
||||
case "#": return entity.AccessOpaque, nil
|
||||
case "+": return entity.AccessPublic, nil
|
||||
default: panic(this.bug())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue