Skip to content

Commit

Permalink
[error] Check class const access.
Browse files Browse the repository at this point in the history
  • Loading branch information
pfusik committed Nov 14, 2023
1 parent 9c6accf commit 2dcd433
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 15 deletions.
6 changes: 3 additions & 3 deletions Sema.fu
Original file line number Diff line number Diff line change
Expand Up @@ -253,8 +253,6 @@ public class FuSema
scope = klass.Class;
}
FuExpr# result = Lookup(expr, scope);
if (result != expr)
return result;
if (expr.Symbol is FuMember member) {
switch (member.Visibility) {
case FuVisibility.Private:
Expand Down Expand Up @@ -297,14 +295,16 @@ public class FuSema
break;
}
if (!(member is FuMethodGroup)) {
if (left is FuSymbolReference leftContainer && leftContainer.Symbol is FuContainerType) {
if (left is FuSymbolReference leftType && leftType.Symbol is FuType) {
if (!member.IsStatic())
ReportError(expr, $"Cannot use instance member '{expr.Name}' without an object");
}
else if (member.IsStatic())
ReportError(expr, $"'{expr.Name}' is static");
}
}
if (result != expr)
return result;
return new FuSymbolReference { Line = expr.Line, Left = left, Name = expr.Name, Symbol = expr.Symbol, Type = expr.Type };
}

Expand Down
8 changes: 4 additions & 4 deletions libfut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4247,8 +4247,6 @@ std::shared_ptr<FuExpr> FuSema::visitSymbolReference(std::shared_ptr<FuSymbolRef
}
}
std::shared_ptr<FuExpr> result = lookup(expr, scope);
if (result != expr)
return result;
if (const FuMember *member = dynamic_cast<const FuMember *>(expr->symbol)) {
switch (member->visibility) {
case FuVisibility::private_:
Expand Down Expand Up @@ -4295,15 +4293,17 @@ std::shared_ptr<FuExpr> FuSema::visitSymbolReference(std::shared_ptr<FuSymbolRef
break;
}
if (!dynamic_cast<const FuMethodGroup *>(member)) {
const FuSymbolReference * leftContainer;
if ((leftContainer = dynamic_cast<const FuSymbolReference *>(left.get())) && dynamic_cast<const FuContainerType *>(leftContainer->symbol)) {
const FuSymbolReference * leftType;
if ((leftType = dynamic_cast<const FuSymbolReference *>(left.get())) && dynamic_cast<const FuType *>(leftType->symbol)) {
if (!member->isStatic())
reportError(expr.get(), std::format("Cannot use instance member '{}' without an object", expr->name));
}
else if (member->isStatic())
reportError(expr.get(), std::format("'{}' is static", expr->name));
}
}
if (result != expr)
return result;
std::shared_ptr<FuSymbolReference> futemp0 = std::make_shared<FuSymbolReference>();
futemp0->line = expr->line;
futemp0->left = left;
Expand Down
6 changes: 3 additions & 3 deletions libfut.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4541,8 +4541,6 @@ FuExpr VisitSymbolReference(FuSymbolReference expr)
scope = klass.Class;
}
FuExpr result = Lookup(expr, scope);
if (result != expr)
return result;
if (expr.Symbol is FuMember member) {
switch (member.Visibility) {
case FuVisibility.Private:
Expand Down Expand Up @@ -4584,14 +4582,16 @@ FuExpr VisitSymbolReference(FuSymbolReference expr)
break;
}
if (!(member is FuMethodGroup)) {
if (left is FuSymbolReference leftContainer && leftContainer.Symbol is FuContainerType) {
if (left is FuSymbolReference leftType && leftType.Symbol is FuType) {
if (!member.IsStatic())
ReportError(expr, $"Cannot use instance member '{expr.Name}' without an object");
}
else if (member.IsStatic())
ReportError(expr, $"'{expr.Name}' is static");
}
}
if (result != expr)
return result;
return new FuSymbolReference { Line = expr.Line, Left = left, Name = expr.Name, Symbol = expr.Symbol, Type = expr.Type };
}

Expand Down
8 changes: 4 additions & 4 deletions libfut.js
Original file line number Diff line number Diff line change
Expand Up @@ -4703,8 +4703,6 @@ export class FuSema
}
}
let result = this.#lookup(expr, scope);
if (result != expr)
return result;
let member;
if ((member = expr.symbol) instanceof FuMember) {
switch (member.visibility) {
Expand Down Expand Up @@ -4750,15 +4748,17 @@ export class FuSema
break;
}
if (!(member instanceof FuMethodGroup)) {
let leftContainer;
if ((leftContainer = left) instanceof FuSymbolReference && leftContainer.symbol instanceof FuContainerType) {
let leftType;
if ((leftType = left) instanceof FuSymbolReference && leftType.symbol instanceof FuType) {
if (!member.isStatic())
this.reportError(expr, `Cannot use instance member '${expr.name}' without an object`);
}
else if (member.isStatic())
this.reportError(expr, `'${expr.name}' is static`);
}
}
if (result != expr)
return result;
return Object.assign(new FuSymbolReference(), { line: expr.line, left: left, name: expr.name, symbol: expr.symbol, type: expr.type });
}

Expand Down
2 changes: 1 addition & 1 deletion test/error/MethodCallStaticWithInstance.fu
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public class Test
public static bool Run()
{
Test() o;
if (o.Foo) // TODO: 'Foo' is static
if (o.Foo) //ERROR: 'Foo' is static
o.StaticMethod(); //ERROR: 'StaticMethod' is static
return true;
}
Expand Down
12 changes: 12 additions & 0 deletions test/error/VisibilityPrivateConst.fu
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
static class Foo
{
const int Bar = 42;
}

public static class Test
{
public static bool Run()
{
return Foo.Bar == 42; //ERROR: Cannot access private member 'Bar'
}
}

0 comments on commit 2dcd433

Please sign in to comment.