Skip to content

Commit 6260fa9

Browse files
committed
WIP generic updates
1 parent be33e1f commit 6260fa9

30 files changed

Lines changed: 722 additions & 100 deletions

de.peeeq.wurstscript/parserspec/jass_im.parseq

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ ImConst =
142142
| ImBoolVal(boolean valB)
143143
| ImFuncRef(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ref ImFunction func)
144144
| ImNull(ref ImType type)
145+
| ImTypeRef(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ref ImClassType clazz)
145146

146147
ImTypeArguments * ImTypeArgument
147148

de.peeeq.wurstscript/parserspec/wurstscript.parseq

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ Expr =
188188
| ExprDestroy(@ignoreForEquality de.peeeq.wurstscript.parser.WPos source, Expr destroyedObj)
189189
| ExprIfElse(@ignoreForEquality de.peeeq.wurstscript.parser.WPos source, Expr cond, Expr ifTrue, Expr ifFalse)
190190
| ExprArrayLength(@ignoreForEquality de.peeeq.wurstscript.parser.WPos source, Expr array)
191+
| ExprTypeRef(@ignoreForEquality de.peeeq.wurstscript.parser.WPos source, TypeExpr typ)
191192

192193
ExprMember =
193194
ExprMemberVar

de.peeeq.wurstscript/src/main/antlr/de/peeeq/wurstscript/antlr/Wurst.g4

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,9 @@ indexes:
347347
'[' expr ']'
348348
;
349349

350+
exprTypeRef
351+
: typeName=ID typeArgsNonEmpty
352+
;
350353

351354
expr:
352355
exprPrimary
@@ -368,12 +371,14 @@ expr:
368371
;
369372

370373

374+
371375
exprPrimary:
372376
exprFunctionCall
373377
| exprNewObject
374378
| exprClosure
375379
| exprStatementsBlock
376380
| exprDestroy
381+
| exprTypeRef
377382
| varname=ID indexes?
378383
| atom=(INT
379384
| REAL
@@ -438,6 +443,9 @@ stmtBreak:'break';
438443
stmtSkip:'skip';
439444

440445

446+
typeArgsNonEmpty
447+
: '<' (args+=typeExpr (',' args+=typeExpr)*)? '>'
448+
;
441449

442450
typeArgs: ('<' (args+=typeExpr (',' args+=typeExpr)*)? '>')?;
443451

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstio/languageserver/requests/HoverInfo.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -782,6 +782,11 @@ public List<Either<String, MarkedString>> case_VisibilityPublic(VisibilityPublic
782782
return string("This element can be used everywhere");
783783
}
784784

785+
@Override
786+
public List<Either<String, MarkedString>> case_ExprTypeRef(ExprTypeRef exprTypeRef) {
787+
return List.of();
788+
}
789+
785790
@Override
786791
public List<Either<String, MarkedString>> case_TopLevelDeclarations(TopLevelDeclarations topLevelDeclarations) {
787792
return string("A list of declarations.");

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/WurstParser.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,9 @@ public void syntaxError(@SuppressWarnings("null") Recognizer<?, ?> recognizer, @
112112
parser.removeErrorListeners();
113113
parser.addErrorListener(l);
114114

115+
parser.setBuildParseTree(true);
115116
CompilationUnitContext cu = parser.compilationUnit(); // begin parsing at init rule
117+
System.out.println(cu.toStringTree(parser));
116118

117119
if (lexer.getTabWarning() != null) {
118120
CompileError warning = lexer.getTabWarning();

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/attributes/AttrCallSignature.java

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,30 @@
55
import de.peeeq.wurstscript.ast.ExprMemberMethod;
66
import de.peeeq.wurstscript.ast.ExprNewObject;
77
import de.peeeq.wurstscript.types.CallSignature;
8+
import de.peeeq.wurstscript.types.WurstType;
89

910
public class AttrCallSignature {
1011

1112
public static CallSignature calculate(ExprFunctionCall c) {
12-
Expr receiver = null;
13-
if (c.attrImplicitParameter() instanceof Expr) {
14-
receiver = (Expr) c.attrImplicitParameter();
15-
}
16-
return new CallSignature(receiver, c.getArgs());
13+
Expr receiver = (c.attrImplicitParameter() instanceof Expr) ? (Expr) c.attrImplicitParameter() : null;
14+
WurstType hint = receiver != null ? receiver.attrTyp() : null;
15+
return new CallSignature(receiver, hint, c.getArgs());
1716
}
1817

1918
public static CallSignature calculate(ExprMemberMethod c) {
20-
return new CallSignature(c.attrImplicitParameter(), c.getArgs());
19+
// Always keep the instantiated left type as hint (e.g. OtherBox<int>)
20+
WurstType hint = c.getLeft().attrTyp();
21+
22+
if (c.getLeft().attrTyp().isStaticRef()) {
23+
// static ref like OtherBox<int>.staticItr()
24+
return new CallSignature(null, hint, c.getArgs());
25+
}
26+
27+
// instance call: keep real receiver expression AND hint
28+
return new CallSignature(c.attrImplicitParameter(), hint, c.getArgs());
2129
}
2230

2331
public static CallSignature calculate(ExprNewObject c) {
24-
return new CallSignature(null, c.getArgs());
32+
return new CallSignature((Expr) null, null, c.getArgs());
2533
}
26-
2734
}

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/attributes/AttrExprType.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,4 +591,8 @@ public static WurstType calculate(ExprArrayLength exprArrayLength) {
591591
exprArrayLength.addError(".length is only valid on arrays.");
592592
return de.peeeq.wurstscript.types.WurstTypeUnknown.instance();
593593
}
594+
595+
public static WurstType calculate(ExprTypeRef e) {
596+
return e.getTyp().attrTyp();
597+
}
594598
}

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/attributes/AttrImplicitParameter.java

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
public class AttrImplicitParameter {
1010

1111
public static OptExpr getImplicitParameter(ExprMemberVar e) {
12-
Expr result = getImplicitParameterUsingLeft(e);
12+
Expr result = getImplicitParameterUsingLeft(e, true); // keep static refs
1313
if (result == null) {
1414
return getImplicitParamterCaseNormalVar(e);
1515
} else {
@@ -18,7 +18,7 @@ public static OptExpr getImplicitParameter(ExprMemberVar e) {
1818
}
1919

2020
public static OptExpr getImplicitParameter(ExprMemberArrayVar e) {
21-
Expr result = getImplicitParameterUsingLeft(e);
21+
Expr result = getImplicitParameterUsingLeft(e, true); // keep static refs
2222
if (result == null) {
2323
return getImplicitParamterCaseNormalVar(e);
2424
} else {
@@ -40,7 +40,7 @@ public static OptExpr getImplicitParameter(ExprFunctionCall e) {
4040
}
4141

4242
public static OptExpr getImplicitParameter(ExprMemberMethod e) {
43-
Expr result = getImplicitParameterUsingLeft(e);
43+
Expr result = getImplicitParameterUsingLeft(e, false);
4444
if (result == null) {
4545
return getImplicitParameterCaseNormalFunctionCall(e);
4646
} else {
@@ -55,14 +55,19 @@ public static OptExpr getImplicitParameter(ExprMemberMethod e) {
5555
}
5656
}
5757

58-
private static @Nullable Expr getImplicitParameterUsingLeft(HasReceiver e) {
59-
if (e.getLeft().attrTyp().isStaticRef()) {
60-
// we have a static ref like Math.sqrt()
61-
// this will be handled like if we just have sqrt()
62-
// if we have an implicit parameter depends on whether sqrt is static or not
58+
private static @Nullable Expr getImplicitParameterUsingLeft(HasReceiver e, boolean keepStaticRef) {
59+
Expr left = e.getLeft();
60+
61+
if (left.attrTyp().isStaticRef()) {
62+
// Only keep typed refs like Box<int> so we can specialize generics.
63+
// Plain identifiers like BoxInt must NOT become runtime receivers.
64+
if (keepStaticRef && left instanceof ExprTypeRef) {
65+
return left;
66+
}
6367
return null;
6468
}
65-
return e.getLeft();
69+
70+
return left;
6671
}
6772

6873
private static OptExpr getImplicitParameterCaseNormalFunctionCall(FunctionCall e) {
@@ -71,12 +76,19 @@ private static OptExpr getImplicitParameterCaseNormalFunctionCall(FunctionCall e
7176
}
7277

7378
static OptExpr getFunctionCallImplicitParameter(FunctionCall e, FuncLink calledFunc, boolean showError) {
74-
if (e instanceof HasReceiver) {
75-
HasReceiver hasReceiver = (HasReceiver) e;
76-
Expr res = getImplicitParameterUsingLeft(hasReceiver);
77-
if (res != null) {
78-
return res;
79+
if (e instanceof HasReceiver hasReceiver) {
80+
Expr left = hasReceiver.getLeft();
81+
82+
if (left.attrTyp().isStaticRef()) {
83+
// Keep ONLY typed static refs to propagate type args (Box<int>.foo()).
84+
if (left instanceof ExprTypeRef) {
85+
return left; // type-only receiver
86+
}
87+
return Ast.NoExpr(); // plain BoxInt.foo() has no receiver
7988
}
89+
90+
// normal dynamic receiver
91+
return left;
8092
}
8193
if (calledFunc == null) {
8294
return Ast.NoExpr();

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/attributes/DescriptionHtml.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,4 +425,8 @@ public static String description(NoTypeParamConstraints noTypeParamConstraints)
425425
public static String description(ExprArrayLength exprArrayLength) {
426426
return "Get the length of an array.";
427427
}
428+
429+
public static String description(ExprTypeRef exprTypeRef) {
430+
return null;
431+
}
428432
}

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/attributes/ReadVariables.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,4 +205,8 @@ public static ImmutableList<NameDef> calculate(ExprIfElse e) {
205205
public static ImmutableList<NameDef> calculate(ExprArrayLength exprArrayLength) {
206206
return ImmutableList.emptyList();
207207
}
208+
209+
public static ImmutableList<NameDef> calculate(ExprTypeRef exprTypeRef) {
210+
return ImmutableList.emptyList();
211+
}
208212
}

0 commit comments

Comments
 (0)