summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--heat/HeatVisitor.java121
-rw-r--r--st/ClassInstance.java4
2 files changed, 66 insertions, 59 deletions
diff --git a/heat/HeatVisitor.java b/heat/HeatVisitor.java
index 04ba0f4..8d29813 100644
--- a/heat/HeatVisitor.java
+++ b/heat/HeatVisitor.java
@@ -6,10 +6,12 @@ import st.*;
import misc.*;
import java.util.*;
-public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
+public class HeatVisitor extends GJDepthFirst<TypeBundle,ArrayList<String>> {
private SymbolTable symt;
+ private MethodInstance recentMethod = null; // the most recent method called
+
public HeatVisitor(SymbolTable symt) {
this.symt = symt;
}
@@ -17,7 +19,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
//
// Auto class visitors--probably don't need to be overridden.
//
- public TypeBundle visit(NodeList n, String argu) {
+ public TypeBundle visit(NodeList n, ArrayList<String> argu) {
TypeBundle _ret=null;
int _count=0;
for ( Enumeration<Node> e = n.elements(); e.hasMoreElements(); ) {
@@ -27,7 +29,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
return _ret;
}
- public TypeBundle visit(NodeListOptional n, String argu) {
+ public TypeBundle visit(NodeListOptional n, ArrayList<String> argu) {
if ( n.present() ) {
TypeBundle _ret=null;
int _count=0;
@@ -41,14 +43,14 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
return null;
}
- public TypeBundle visit(NodeOptional n, String argu) {
+ public TypeBundle visit(NodeOptional n, ArrayList<String> argu) {
if ( n.present() )
return n.node.accept(this,argu);
else
return null;
}
- public TypeBundle visit(NodeSequence n, String argu) {
+ public TypeBundle visit(NodeSequence n, ArrayList<String> argu) {
TypeBundle _ret=null;
int _count=0;
for ( Enumeration<Node> e = n.elements(); e.hasMoreElements(); ) {
@@ -58,7 +60,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
return _ret;
}
- public TypeBundle visit(NodeToken n, String argu) { return null; }
+ public TypeBundle visit(NodeToken n, ArrayList<String> argu) { return null; }
//
// User-generated visitor methods below
@@ -69,7 +71,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
* f1 -> ( TypeDeclaration() )*
* f2 -> <EOF>
*/
- public TypeBundle visit(Goal n, String argu) {
+ public TypeBundle visit(Goal n, ArrayList<String> argu) {
TypeBundle _ret=null;
MinimalLogger.info(String.format("-> %s",
n.getClass().getSimpleName()));
@@ -104,7 +106,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
* f16 -> "}"
* f17 -> "}"
*/
- public TypeBundle visit(MainClass n, String argu) {
+ public TypeBundle visit(MainClass n, ArrayList<String> argu) {
TypeBundle _ret=null;
String id = n.f1.f0.tokenImage;
MinimalLogger.info(String.format("-> %s (%s)",
@@ -128,7 +130,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
* f0 -> ClassDeclaration()
* | ClassExtendsDeclaration()
*/
- public TypeBundle visit(TypeDeclaration n, String argu) {
+ public TypeBundle visit(TypeDeclaration n, ArrayList<String> argu) {
TypeBundle _ret=null;
MinimalLogger.info(String.format("-> %s",
n.getClass().getSimpleName()));
@@ -149,7 +151,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
* f4 -> ( MethodDeclaration() )*
* f5 -> "}"
*/
- public TypeBundle visit(ClassDeclaration n, String argu) {
+ public TypeBundle visit(ClassDeclaration n, ArrayList<String> argu) {
TypeBundle _ret=null;
String id = n.f1.f0.tokenImage;
MinimalLogger.info(String.format("-> %s (%s)",
@@ -177,7 +179,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
* f6 -> ( MethodDeclaration() )*
* f7 -> "}"
*/
- public TypeBundle visit(ClassExtendsDeclaration n, String argu) {
+ public TypeBundle visit(ClassExtendsDeclaration n, ArrayList<String> argu) {
TypeBundle _ret=null;
String id = n.f1.f0.tokenImage;
String id0 = n.f3.f0.tokenImage;
@@ -201,14 +203,13 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
* f1 -> Identifier()
* f2 -> ";"
*/
- public TypeBundle visit(VarDeclaration n, String argu) {
+ public TypeBundle visit(VarDeclaration n, ArrayList<String> argu) {
TypeBundle _ret=null;
String id = n.f1.f0.tokenImage;
MinimalLogger.info(String.format("-> %s (%s)",
n.getClass().getSimpleName(),
id));
///////////////////////////////////////////////////////////////
- // f0.accept(this, argu);
///////////////////////////////////////////////////////////////
MinimalLogger.info(String.format("<- %s (%s)",
n.getClass().getSimpleName(),
@@ -231,7 +232,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
* f11 -> ";"
* f12 -> "}"
*/
- public TypeBundle visit(MethodDeclaration n, String argu) {
+ public TypeBundle visit(MethodDeclaration n, ArrayList<String> argu) {
TypeBundle _ret=null;
String id = n.f2.f0.tokenImage;
MinimalLogger.info(String.format("-> %s (%s)",
@@ -239,8 +240,8 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
id));
this.symt.setActive(TypeEnum.method, symt.getMethod(id));
///////////////////////////////////////////////////////////////
- n.f1.accept(this, argu);
- n.f4.accept(this, argu);
+ // n.f1.accept(this, argu);
+ // n.f4.accept(this, para);
n.f7.accept(this, argu);
n.f8.accept(this, argu);
n.f10.accept(this, argu);
@@ -256,12 +257,11 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
* f0 -> FormalParameter()
* f1 -> ( FormalParameterRest() )*
*/
- public TypeBundle visit(FormalParameterList n, String argu) {
+ public TypeBundle visit(FormalParameterList n, ArrayList<String> argu) {
TypeBundle _ret=null;
MinimalLogger.info(String.format("-> %s",
n.getClass().getSimpleName()));
///////////////////////////////////////////////////////////////
- // FIXME Check distinct!
n.f0.accept(this, argu);
n.f1.accept(this, argu);
///////////////////////////////////////////////////////////////
@@ -275,14 +275,14 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
* f0 -> Type()
* f1 -> Identifier()
*/
- public TypeBundle visit(FormalParameter n, String argu) {
+ public TypeBundle visit(FormalParameter n, ArrayList<String> argu) {
TypeBundle _ret=null;
String id = n.f1.f0.tokenImage;
MinimalLogger.info(String.format("-> %s (%s)",
n.getClass().getSimpleName(),
id));
///////////////////////////////////////////////////////////////
- _ret = n.f0.accept(this, argu);
+ n.f0.accept(this, argu);
///////////////////////////////////////////////////////////////
MinimalLogger.info(String.format("<- %s (%s)",
n.getClass().getSimpleName(),
@@ -295,12 +295,12 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
* f0 -> ","
* f1 -> FormalParameter()
*/
- public TypeBundle visit(FormalParameterRest n, String argu) {
+ public TypeBundle visit(FormalParameterRest n, ArrayList<String> argu) {
TypeBundle _ret=null;
MinimalLogger.info(String.format("-> %s",
n.getClass().getSimpleName()));
///////////////////////////////////////////////////////////////
- _ret = n.f1.accept(this, argu);
+ n.f1.accept(this, argu);
///////////////////////////////////////////////////////////////
MinimalLogger.info(String.format("<- %s with %s",
n.getClass().getSimpleName(),
@@ -314,7 +314,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
* | IntegerType()
* | Identifier()
*/
- public TypeBundle visit(Type n, String argu) {
+ public TypeBundle visit(Type n, ArrayList<String> argu) {
TypeBundle _ret=null;
MinimalLogger.info(String.format("-> %s",
n.getClass().getSimpleName()));
@@ -332,7 +332,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
* f1 -> "["
* f2 -> "]"
*/
- public TypeBundle visit(ArrayType n, String argu) {
+ public TypeBundle visit(ArrayType n, ArrayList<String> argu) {
TypeBundle _ret=null;
MinimalLogger.info(String.format("-> %s",
n.getClass().getSimpleName()));
@@ -348,7 +348,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
/**
* f0 -> "boolean"
*/
- public TypeBundle visit(BooleanType n, String argu) {
+ public TypeBundle visit(BooleanType n, ArrayList<String> argu) {
TypeBundle _ret=null;
MinimalLogger.info(String.format("-> %s",
n.getClass().getSimpleName()));
@@ -364,7 +364,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
/**
* f0 -> "int"
*/
- public TypeBundle visit(IntegerType n, String argu) {
+ public TypeBundle visit(IntegerType n, ArrayList<String> argu) {
TypeBundle _ret=null;
MinimalLogger.info(String.format("-> %s",
n.getClass().getSimpleName()));
@@ -385,7 +385,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
* | WhileStatement()
* | PrintStatement()
*/
- public TypeBundle visit(Statement n, String argu) {
+ public TypeBundle visit(Statement n, ArrayList<String> argu) {
TypeBundle _ret=null;
MinimalLogger.info(String.format("-> %s",
n.getClass().getSimpleName()));
@@ -403,7 +403,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
* f1 -> ( Statement() )*
* f2 -> "}"
*/
- public TypeBundle visit(Block n, String argu) {
+ public TypeBundle visit(Block n, ArrayList<String> argu) {
TypeBundle _ret=null;
MinimalLogger.info(String.format("-> %s",
n.getClass().getSimpleName()));
@@ -422,7 +422,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
* f2 -> Expression()
* f3 -> ";"
*/
- public TypeBundle visit(AssignmentStatement n, String argu) {
+ public TypeBundle visit(AssignmentStatement n, ArrayList<String> argu) {
TypeBundle _ret=null;
String id = n.f0.f0.tokenImage;
MinimalLogger.info(String.format("-> %s",
@@ -457,7 +457,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
* f5 -> Expression()
* f6 -> ";"
*/
- public TypeBundle visit(ArrayAssignmentStatement n, String argu) {
+ public TypeBundle visit(ArrayAssignmentStatement n, ArrayList<String> argu) {
TypeBundle _ret=null;
String id = n.f0.f0.tokenImage;
MinimalLogger.info(String.format("-> %s",
@@ -491,7 +491,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
* f5 -> "else"
* f6 -> Statement()
*/
- public TypeBundle visit(IfStatement n, String argu) {
+ public TypeBundle visit(IfStatement n, ArrayList<String> argu) {
TypeBundle _ret=null;
MinimalLogger.info(String.format("-> %s",
n.getClass().getSimpleName()));
@@ -516,7 +516,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
* f3 -> ")"
* f4 -> Statement()
*/
- public TypeBundle visit(WhileStatement n, String argu) {
+ public TypeBundle visit(WhileStatement n, ArrayList<String> argu) {
TypeBundle _ret=null;
MinimalLogger.info(String.format("-> %s",
n.getClass().getSimpleName()));
@@ -540,7 +540,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
* f3 -> ")"
* f4 -> ";"
*/
- public TypeBundle visit(PrintStatement n, String argu) {
+ public TypeBundle visit(PrintStatement n, ArrayList<String> argu) {
TypeBundle _ret=null;
MinimalLogger.info(String.format("-> %s",
n.getClass().getSimpleName()));
@@ -567,7 +567,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
* | MessageSend()
* | PrimaryExpression()
*/
- public TypeBundle visit(Expression n, String argu) {
+ public TypeBundle visit(Expression n, ArrayList<String> argu) {
TypeBundle _ret=null;
MinimalLogger.info(String.format("-> %s",
n.getClass().getSimpleName()));
@@ -585,7 +585,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
* f1 -> "&&"
* f2 -> PrimaryExpression()
*/
- public TypeBundle visit(AndExpression n, String argu) {
+ public TypeBundle visit(AndExpression n, ArrayList<String> argu) {
TypeBundle _ret=null;
MinimalLogger.info(String.format("-> %s",
n.getClass().getSimpleName()));
@@ -607,7 +607,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
* f1 -> "<"
* f2 -> PrimaryExpression()
*/
- public TypeBundle visit(CompareExpression n, String argu) {
+ public TypeBundle visit(CompareExpression n, ArrayList<String> argu) {
TypeBundle _ret=null;
MinimalLogger.info(String.format("-> %s",
n.getClass().getSimpleName()));
@@ -630,7 +630,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
* f1 -> "+"
* f2 -> PrimaryExpression()
*/
- public TypeBundle visit(PlusExpression n, String argu) {
+ public TypeBundle visit(PlusExpression n, ArrayList<String> argu) {
TypeBundle _ret=null;
MinimalLogger.info(String.format("-> %s",
n.getClass().getSimpleName()));
@@ -652,7 +652,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
* f1 -> "-"
* f2 -> PrimaryExpression()
*/
- public TypeBundle visit(MinusExpression n, String argu) {
+ public TypeBundle visit(MinusExpression n, ArrayList<String> argu) {
TypeBundle _ret=null;
MinimalLogger.info(String.format("-> %s",
n.getClass().getSimpleName()));
@@ -674,7 +674,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
* f1 -> "*"
* f2 -> PrimaryExpression()
*/
- public TypeBundle visit(TimesExpression n, String argu) {
+ public TypeBundle visit(TimesExpression n, ArrayList<String> argu) {
TypeBundle _ret=null;
MinimalLogger.info(String.format("-> %s",
n.getClass().getSimpleName()));
@@ -697,7 +697,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
* f2 -> PrimaryExpression()
* f3 -> "]"
*/
- public TypeBundle visit(ArrayLookup n, String argu) {
+ public TypeBundle visit(ArrayLookup n, ArrayList<String> argu) {
TypeBundle _ret=null;
MinimalLogger.info(String.format("-> %s",
n.getClass().getSimpleName()));
@@ -719,7 +719,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
* f1 -> "."
* f2 -> "length"
*/
- public TypeBundle visit(ArrayLength n, String argu) {
+ public TypeBundle visit(ArrayLength n, ArrayList<String> argu) {
TypeBundle _ret=null;
MinimalLogger.info(String.format("-> %s",
n.getClass().getSimpleName()));
@@ -745,16 +745,19 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
* f4 -> ( ExpressionList() )?
* f5 -> ")"
*/
- public TypeBundle visit(MessageSend n, String argu) {
+ public TypeBundle visit(MessageSend n, ArrayList<String> argu) {
TypeBundle _ret=null;
MinimalLogger.info(String.format("-> %s",
n.getClass().getSimpleName()));
///////////////////////////////////////////////////////////////
TypeInstance t;
+ n.f0.accept(this, argu);
switch (n.f0.f0.which) {
case 3:
MinimalLogger.info(String.format("Message send found IDENTIFIER"));
t = this.symt.getType(((Identifier) n.f0.f0.choice).f0.tokenImage);
+ if (t == null)
+ t = this.symt.getTypeAttr(((Identifier) n.f0.f0.choice).f0.tokenImage);
break;
case 4:
MinimalLogger.info(String.format("Message send found THIS"));
@@ -769,6 +772,10 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
case 8:
MinimalLogger.info(String.format("Message send found BRACKET"));
t = new TypeInstance("null",null,null,null);
+ ClassInstance c = this.recentMethod.getReturn();
+ MinimalLogger.info(String.format("Setting class to the most recent return: %s",
+ c.toString()));
+ t.addClassInstance(c);
break;
default:
MinimalLogger.info(String.format("Message send found UNKNOWN %s",
@@ -781,12 +788,15 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
n.getClass().getSimpleName()));
MethodInstance m = this.symt.getMethod(n.f2.f0.tokenImage, t.getClassInstance());
-
if (m == null)
throw new TypecheckException(String.format("%s called a method not part of %s!",
n.getClass().getSimpleName(),
t.getName()));
+ MinimalLogger.info(String.format("The most recently called method is now %s",
+ m.toString()));
+ this.recentMethod = m;
+
// FIXME Evaluate parameters!
n.f4.accept(this, argu);
String ret = m.getReturn().getName();
@@ -809,7 +819,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
* f0 -> Expression()
* f1 -> ( ExpressionRest() )*
*/
- public TypeBundle visit(ExpressionList n, String argu) {
+ public TypeBundle visit(ExpressionList n, ArrayList<String> argu) {
TypeBundle _ret=null;
MinimalLogger.info(String.format("-> %s",
n.getClass().getSimpleName()));
@@ -827,7 +837,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
* f0 -> ","
* f1 -> Expression()
*/
- public TypeBundle visit(ExpressionRest n, String argu) {
+ public TypeBundle visit(ExpressionRest n, ArrayList<String> argu) {
TypeBundle _ret=null;
MinimalLogger.info(String.format("-> %s",
n.getClass().getSimpleName()));
@@ -851,7 +861,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
* | NotExpression()
* | BracketExpression()
*/
- public TypeBundle visit(PrimaryExpression n, String argu) {
+ public TypeBundle visit(PrimaryExpression n, ArrayList<String> argu) {
TypeBundle _ret=null;
MinimalLogger.info(String.format("-> %s",
n.getClass().getSimpleName()));
@@ -867,7 +877,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
/**
* f0 -> <INTEGER_LITERAL>
*/
- public TypeBundle visit(IntegerLiteral n, String argu) {
+ public TypeBundle visit(IntegerLiteral n, ArrayList<String> argu) {
TypeBundle _ret=null;
MinimalLogger.info(String.format("-> %s",
n.getClass().getSimpleName()));
@@ -883,7 +893,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
/**
* f0 -> "true"
*/
- public TypeBundle visit(TrueLiteral n, String argu) {
+ public TypeBundle visit(TrueLiteral n, ArrayList<String> argu) {
TypeBundle _ret=null;
MinimalLogger.info(String.format("-> %s",
n.getClass().getSimpleName()));
@@ -899,7 +909,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
/**
* f0 -> "false"
*/
- public TypeBundle visit(FalseLiteral n, String argu) {
+ public TypeBundle visit(FalseLiteral n, ArrayList<String> argu) {
TypeBundle _ret=null;
MinimalLogger.info(String.format("-> %s",
n.getClass().getSimpleName()));
@@ -915,7 +925,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
/**
* f0 -> <IDENTIFIER>
*/
- public TypeBundle visit(Identifier n, String argu) {
+ public TypeBundle visit(Identifier n, ArrayList<String> argu) {
TypeBundle _ret=null;
MinimalLogger.info(String.format("-> %s",
n.getClass().getSimpleName()));
@@ -934,11 +944,12 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
/**
* f0 -> "this"
*/
- public TypeBundle visit(ThisExpression n, String argu) {
+ public TypeBundle visit(ThisExpression n, ArrayList<String> argu) {
TypeBundle _ret=null;
MinimalLogger.info(String.format("-> %s",
n.getClass().getSimpleName()));
///////////////////////////////////////////////////////////////
+ _ret = new TypeBundle(TypeEnum.classname, (ClassInstance) this.symt.getActive(TypeEnum.classname));
///////////////////////////////////////////////////////////////
MinimalLogger.info(String.format("<- %s with %s",
n.getClass().getSimpleName(),
@@ -953,7 +964,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
* f3 -> Expression()
* f4 -> "]"
*/
- public TypeBundle visit(ArrayAllocationExpression n, String argu) {
+ public TypeBundle visit(ArrayAllocationExpression n, ArrayList<String> argu) {
TypeBundle _ret=null;
MinimalLogger.info(String.format("-> %s",
n.getClass().getSimpleName()));
@@ -977,7 +988,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
* f2 -> "("
* f3 -> ")"
*/
- public TypeBundle visit(AllocationExpression n, String argu) {
+ public TypeBundle visit(AllocationExpression n, ArrayList<String> argu) {
TypeBundle _ret=null;
String id = n.f1.f0.tokenImage;
MinimalLogger.info(String.format("-> %s (%s)",
@@ -996,7 +1007,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
* f0 -> "!"
* f1 -> Expression()
*/
- public TypeBundle visit(NotExpression n, String argu) {
+ public TypeBundle visit(NotExpression n, ArrayList<String> argu) {
TypeBundle _ret=null;
MinimalLogger.info(String.format("-> %s",
n.getClass().getSimpleName()));
@@ -1014,7 +1025,7 @@ public class HeatVisitor extends GJDepthFirst<TypeBundle,String> {
* f1 -> Expression()
* f2 -> ")"
*/
- public TypeBundle visit(BracketExpression n, String argu) {
+ public TypeBundle visit(BracketExpression n, ArrayList<String> argu) {
TypeBundle _ret=null;
MinimalLogger.info(String.format("-> %s",
n.getClass().getSimpleName()));
diff --git a/st/ClassInstance.java b/st/ClassInstance.java
index 789571b..d96d3d5 100644
--- a/st/ClassInstance.java
+++ b/st/ClassInstance.java
@@ -13,10 +13,6 @@ public class ClassInstance extends AbstractInstance {
this.mtds = new ArrayList<>();
}
- @Override public String toString() {
- return String.format("%s", this.name);
- }
-
@Override public boolean equals(Object other) {
ClassInstance o;
return (other instanceof ClassInstance &&