|
|
@@ -396,8 +396,10 @@ PROCEDURE CanDesign (n: AST.Node): BOOLEAN;
|
|
|
END CanDesign;
|
|
|
|
|
|
PROCEDURE IsMethodCall (n: AST.Node): BOOLEAN;
|
|
|
-(* n is a call whose callee is `obj.Method` on a class receiver. *)
|
|
|
+(* n is a call whose callee resolves to a class method: `obj.Method`,
|
|
|
+ `p^.Method`, or a bare sibling name inside an implementation. *)
|
|
|
VAR d, sel: AST.Node; nm, fn: SymTab.Name; k: INTEGER; t: SymTab.TypeIndex;
|
|
|
+ i: CARDINAL;
|
|
|
BEGIN
|
|
|
IF (AST.Kind(n) # AST.NkCall) OR (AST.NChild(n) < 1) THEN RETURN FALSE END;
|
|
|
d := AST.Child(n, 0);
|
|
|
@@ -408,15 +410,36 @@ PROCEDURE IsMethodCall (n: AST.Node): BOOLEAN;
|
|
|
RETURN (curImplCls # SymTab.InvalidType)
|
|
|
AND SymTab.MethodExists(curImplCls, nm)
|
|
|
END;
|
|
|
- IF AST.NChild(d) < 2 THEN RETURN FALSE END;
|
|
|
- sel := AST.Child(d, AST.NChild(d) - 1);
|
|
|
- IF AST.Op(sel) # AST.SelField THEN RETURN FALSE END;
|
|
|
Name(AST.Child(d, 0), nm);
|
|
|
IF NOT Resolve(nm, k, t) THEN RETURN FALSE END;
|
|
|
- IF t = SymTab.InvalidType THEN RETURN FALSE END;
|
|
|
- IF SymTab.ClassOf(t) # SymTab.ClClass THEN RETURN FALSE END;
|
|
|
- Name(AST.Child(sel, 0), fn);
|
|
|
- RETURN SymTab.MethodExists(t, fn)
|
|
|
+ i := 1;
|
|
|
+ WHILE i < AST.NChild(d) DO
|
|
|
+ sel := AST.Child(d, i);
|
|
|
+ IF AST.Op(sel) = AST.SelField THEN
|
|
|
+ Name(AST.Child(sel, 0), fn);
|
|
|
+ IF (t # SymTab.InvalidType) AND (SymTab.ClassOf(t) = SymTab.ClClass)
|
|
|
+ AND SymTab.MethodExists(t, fn) THEN
|
|
|
+ RETURN i = AST.NChild(d) - 1
|
|
|
+ END;
|
|
|
+ IF (t = SymTab.InvalidType) OR NOT SymTab.FieldExists(t, fn) THEN
|
|
|
+ RETURN FALSE
|
|
|
+ END;
|
|
|
+ t := SymTab.FieldType(t, fn)
|
|
|
+ ELSIF AST.Op(sel) = AST.SelIndex THEN
|
|
|
+ IF (t = SymTab.InvalidType) OR (SymTab.ClassOf(t) # SymTab.ClArray) THEN
|
|
|
+ RETURN FALSE
|
|
|
+ END;
|
|
|
+ t := SymTab.ArrayElem(t)
|
|
|
+ ELSIF AST.Op(sel) = AST.SelDeref THEN
|
|
|
+ IF (t = SymTab.InvalidType) OR (SymTab.ClassOf(t) # SymTab.ClPtr) THEN
|
|
|
+ RETURN FALSE
|
|
|
+ END;
|
|
|
+ t := SymTab.PtrBase(t)
|
|
|
+ ELSE RETURN FALSE
|
|
|
+ END;
|
|
|
+ INC(i)
|
|
|
+ END;
|
|
|
+ RETURN FALSE
|
|
|
END IsMethodCall;
|
|
|
|
|
|
PROCEDURE CanMethodCall (n: AST.Node): BOOLEAN;
|