22
33import de .peeeq .wurstscript .WLogger ;
44import de .peeeq .wurstscript .ast .*;
5+ import de .peeeq .wurstscript .attributes .names .FuncLink ;
56import de .peeeq .wurstscript .types .*;
67import de .peeeq .wurstscript .utils .Utils ;
78import org .eclipse .jdt .annotation .NonNull ;
@@ -46,6 +47,14 @@ public class AttrExprExpectedType {
4647 return varDef .attrTyp ();
4748 } else if (parent instanceof ExprBinary ) {
4849 ExprBinary exprBinary = (ExprBinary ) parent ;
50+ if (exprBinary .attrFuncLink () != null ) {
51+ FunctionSignature signature = FunctionSignature .fromNameLink (exprBinary .attrFuncLink ());
52+ if (exprBinary .getLeft () == expr && signature .getReceiverType () != null ) {
53+ return signature .getReceiverType ();
54+ } else if (exprBinary .getRight () == expr && !signature .getParamTypes ().isEmpty ()) {
55+ return signature .getParamType (0 );
56+ }
57+ }
4958 WurstType leftType = exprBinary .getLeft ().attrTyp ();
5059 WurstType rightType = exprBinary .getRight ().attrTyp ();
5160 if (leftType .equalsType (rightType , expr )) {
@@ -72,10 +81,44 @@ public class AttrExprExpectedType {
7281 }
7382 } else if (parent instanceof StmtReturn ) {
7483 StmtReturn stmtReturn = (StmtReturn ) parent ;
84+ if (stmtReturn .getParent () instanceof ExprStatementsBlock ) {
85+ ExprStatementsBlock block = (ExprStatementsBlock ) stmtReturn .getParent ();
86+ WurstType expectedType = block .attrExpectedTypRaw ();
87+ if (expectedType instanceof WurstTypeUnknown
88+ && block .getParent () instanceof ExprClosure ) {
89+ FuncLink abstractMethod = ((ExprClosure ) block .getParent ()).attrClosureAbstractMethod ();
90+ if (abstractMethod != null ) {
91+ return abstractMethod .getReturnType ();
92+ }
93+ }
94+ return expectedType ;
95+ }
7596 FunctionImplementation nearestFuncDef = stmtReturn .attrNearestFuncDef ();
7697 if (nearestFuncDef != null ) {
7798 return nearestFuncDef .attrReturnTyp ();
7899 }
100+ } else if (parent instanceof StmtForRange ) {
101+ StmtForRange forRange = (StmtForRange ) parent ;
102+ if (forRange .getTo () == expr || forRange .getStep () == expr ) {
103+ return WurstTypeInt .instance ();
104+ }
105+ } else if (parent instanceof ExprStatementsBlock ) {
106+ ExprStatementsBlock block = (ExprStatementsBlock ) parent ;
107+ if (block .getReturnStmt () != null && block .getReturnStmt ().getReturnedObj () == expr ) {
108+ return block .attrExpectedTypRaw ();
109+ }
110+ } else if (parent instanceof Indexes ) {
111+ return WurstTypeInt .instance ();
112+ } else if (parent instanceof SwitchStmt ) {
113+ SwitchStmt switchStmt = (SwitchStmt ) parent ;
114+ if (switchStmt .getExpr () == expr ) {
115+ for (SwitchCase switchCase : switchStmt .getCases ()) {
116+ for (Expr caseExpr : switchCase .getExpressions ()) {
117+ WurstType type = caseExpr .attrTyp ();
118+ return type instanceof WurstTypeIntLiteral ? WurstTypeInt .instance () : type ;
119+ }
120+ }
121+ }
79122 } else if (parent instanceof SwitchCase ) {
80123 SwitchCase sc = (SwitchCase ) parent ;
81124 SwitchStmt s = (SwitchStmt ) sc .getParent ().getParent ();
@@ -110,6 +153,14 @@ public class AttrExprExpectedType {
110153
111154 private static WurstType expectedTypeSuperCall (SuperConstructorCall sc , Expr expr ) {
112155 ConstructorDef constr = (ConstructorDef ) sc .getParent ();
156+ int paramIndex = SmallHelpers .superArgs (constr ).indexOf (expr );
157+ ConstructorDef selected = constr .attrSuperConstructor ();
158+ if (selected != null ) {
159+ WurstType selectedType = constructorParameterType (selected , paramIndex );
160+ if (!(selectedType instanceof WurstTypeUnknown )) {
161+ return selectedType ;
162+ }
163+ }
113164 ClassDef c = constr .attrNearestClassDef ();
114165 if (c == null ) {
115166 return WurstTypeUnknown .instance ();
@@ -125,8 +176,6 @@ private static WurstType expectedTypeSuperCall(SuperConstructorCall sc, Expr exp
125176
126177 WurstType res = WurstTypeUnknown .instance ();
127178
128- int paramIndex = SmallHelpers .superArgs (constr ).indexOf (expr );
129-
130179 for (ConstructorDef superConstr : constructors ) {
131180 if (superConstr .getParameters ().size () == SmallHelpers .superArgs (constr ).size ()) {
132181 res = res .typeUnion (superConstr .getParameters ().get (paramIndex ).getTyp ().attrTyp (), expr );
@@ -136,6 +185,19 @@ private static WurstType expectedTypeSuperCall(SuperConstructorCall sc, Expr exp
136185 return res ;
137186 }
138187
188+ public static WurstType constructorParameterType (ConstructorDef constructor , int argumentIndex ) {
189+ if (argumentIndex < 0 || constructor .getParameters ().isEmpty ()) {
190+ return WurstTypeUnknown .instance ();
191+ }
192+ int lastParameterIndex = constructor .getParameters ().size () - 1 ;
193+ WurstType parameterType = constructor .getParameters ()
194+ .get (Math .min (argumentIndex , lastParameterIndex )).attrTyp ();
195+ if (argumentIndex >= lastParameterIndex && parameterType instanceof WurstTypeVararg ) {
196+ return ((WurstTypeVararg ) parameterType ).getBaseType ();
197+ }
198+ return argumentIndex <= lastParameterIndex ? parameterType : WurstTypeUnknown .instance ();
199+ }
200+
139201 private static WurstType expectedType (Expr expr , Arguments args , StmtCall stmtCall ) {
140202 Collection <FunctionSignature > sigs = stmtCall .attrPossibleFunctionSignatures ();
141203
0 commit comments