Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ exprMemberVar:


exprVarAccess:
varname=ID indexes?
varname=(ID|IT) indexes?
;


Expand Down Expand Up @@ -375,7 +375,7 @@ exprPrimary:
| exprClosure
| exprStatementsBlock
| exprDestroy
| varname=ID indexes?
| varname=(ID|IT) indexes?
| atom=(INT
| REAL
| STRING
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.google.common.collect.ImmutableMultimap.Builder;
import de.peeeq.wurstscript.ast.*;
import de.peeeq.wurstscript.attributes.names.NameLink;
import de.peeeq.wurstscript.attributes.names.OtherLink;
import de.peeeq.wurstscript.types.WurstTypeArray;

import java.util.Map.Entry;
Expand Down Expand Up @@ -33,6 +34,10 @@ private static void collect(Builder<Element, VarDef> result, ExprClosure closure
if (e instanceof NameRef) {
NameRef nr = (NameRef) e;
NameLink def = nr.attrNameLink();
if (def instanceof OtherLink) {
// Synthetic links (e.g. implicit closure-self) are not captured locals.
return;
}

if (def != null && isLocalVariable(def.getDef())) {
VarDef v = (VarDef) def.getDef();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import de.peeeq.wurstscript.WurstOperator;
import de.peeeq.wurstscript.ast.*;
import de.peeeq.wurstscript.attributes.names.NameLink;
import de.peeeq.wurstscript.attributes.names.OtherLink;
import de.peeeq.wurstscript.intermediatelang.ILconst;
import de.peeeq.wurstscript.intermediatelang.ILconstInt;

Expand Down Expand Up @@ -31,6 +32,9 @@ public static ILconst calculate(ExprIntVal e) {

public static ILconst calculate(ExprVarAccess e) {
NameLink v = e.attrNameLink();
if (v instanceof OtherLink) {
throw new ConstantValueCalculationException(e.toString());
}
if (v != null && v.getDef() instanceof GlobalVarDef) {
GlobalVarDef g = (GlobalVarDef) v.getDef();
if (g.attrIsConstant() && g.getInitialExpr() instanceof Expr) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import de.peeeq.wurstscript.ast.*;
import de.peeeq.wurstscript.attributes.names.FuncLink;
import de.peeeq.wurstscript.attributes.names.NameLink;
import de.peeeq.wurstscript.attributes.names.OtherLink;
import de.peeeq.wurstscript.types.*;
import de.peeeq.wurstscript.utils.Utils;
import org.eclipse.jdt.annotation.Nullable;
Expand Down Expand Up @@ -68,13 +69,13 @@ public static WurstType calculate(ExprVarAccess term) {

return WurstTypeUnknown.instance();
}
if (varDef.getDef() instanceof VarDef) {
if (!(varDef instanceof OtherLink) && varDef.getDef() instanceof VarDef) {
if (Utils.getParentVarDef(Optional.of(term)) == Optional.of((VarDef) varDef.getDef())) {
term.addError("Recursive variable definition is not allowed.");
return WurstTypeUnknown.instance();
}
}
if (varDef.getDef() instanceof FunctionDefinition) {
if (!(varDef instanceof OtherLink) && varDef.getDef() instanceof FunctionDefinition) {
term.addError("Missing parantheses for function call");
}
return varDef.getTyp();
Expand Down Expand Up @@ -388,10 +389,10 @@ public static WurstType calculate(ExprMemberVarDot term) {
if (varDef == null) {
return WurstTypeUnknown.instance();
}
if (varDef.getDef() instanceof FunctionDefinition) {
if (!(varDef instanceof OtherLink) && varDef.getDef() instanceof FunctionDefinition) {
term.addError("Missing parantheses for function call");
}
if (varDef.getDef().attrIsStatic() && !term.getLeft().attrTyp().isStaticRef()) {
if (!(varDef instanceof OtherLink) && varDef.getDef().attrIsStatic() && !term.getLeft().attrTyp().isStaticRef()) {
term.addError("Cannot access static variable " + term.getVarName() + " via a dynamic reference.");
}
return varDef.getTyp(); // TODO .setTypeArgs(term.getLeft().attrTyp().getTypeArgBinding());
Expand All @@ -403,7 +404,7 @@ public static WurstType calculate(ExprMemberArrayVarDot term) {
if (varDef == null) {
return WurstTypeUnknown.instance();
}
if (varDef.getDef().attrIsStatic() && !term.getLeft().attrTyp().isStaticRef()) {
if (!(varDef instanceof OtherLink) && varDef.getDef().attrIsStatic() && !term.getLeft().attrTyp().isStaticRef()) {
term.addError("Cannot access static array variable " + term.getVarName() + " via a dynamic reference.");
}
WurstType typ = varDef.getTyp();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import de.peeeq.wurstscript.ast.*;
import de.peeeq.wurstscript.attributes.names.FuncLink;
import de.peeeq.wurstscript.attributes.names.NameLink;
import de.peeeq.wurstscript.attributes.names.OtherLink;
import de.peeeq.wurstscript.types.WurstType;
import org.eclipse.jdt.annotation.Nullable;

Expand Down Expand Up @@ -108,6 +109,9 @@ static OptExpr getFunctionCallImplicitParameter(FunctionCall e, FuncLink calledF

private static OptExpr getImplicitParamterCaseNormalVar(NameRef e) {
NameLink def = e.attrNameLink();
if (def instanceof OtherLink) {
return Ast.NoExpr();
}
if (def != null && def.getDef() instanceof VarDef) {
VarDef varDef = (VarDef) def.getDef();
if (varDef.attrIsDynamicClassMember()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
import de.peeeq.wurstscript.ast.*;
import de.peeeq.wurstscript.attributes.names.FuncLink;
import de.peeeq.wurstscript.attributes.names.NameLink;
import de.peeeq.wurstscript.attributes.names.OtherLink;
import de.peeeq.wurstscript.attributes.names.Visibility;
import de.peeeq.wurstscript.types.WurstType;
import de.peeeq.wurstscript.types.WurstTypeClassOrInterface;
import de.peeeq.wurstscript.types.WurstTypeUnknown;
import de.peeeq.wurstscript.types.WurstTypeEnum;
import de.peeeq.wurstscript.types.WurstTypeModule;
import org.eclipse.jdt.annotation.Nullable;
Expand Down Expand Up @@ -74,8 +78,52 @@ public static NameLink calculate(ExprMemberVar term) {

protected static NameLink searchNameInScope(String varName, NameRef node) {
boolean showErrors = !varName.startsWith("gg_");
NameLink result = node.lookupVar(varName, showErrors);
return result;
if (!"it".equals(varName)) {
return node.lookupVar(varName, showErrors);
}

// Normal lexical lookup wins, so user-defined names can shadow implicit closure-self.
NameLink result = node.lookupVar(varName, false);
if (result != null) {
return result;
}

NameLink implicitClosureSelf = lookupImplicitClosureSelf(node, showErrors);
if (implicitClosureSelf != null) {
return implicitClosureSelf;
}
if (node.attrNearestExprClosure() != null) {
// keep diagnostics focused on closure typing instead of "unknown variable it"
return null;
}

if (!showErrors) {
return null;
}

// Fallback to default diagnostics when no implicit closure-self is available.
return node.lookupVar(varName, true);
}

private static @Nullable NameLink lookupImplicitClosureSelf(NameRef node, boolean showErrors) {
ExprClosure closure = node.attrNearestExprClosure();
if (closure == null) {
return null;
}
WurstType expectedTyp = closure.attrExpectedTypAfterOverloading();
if (!(expectedTyp instanceof WurstTypeClassOrInterface)) {
if (showErrors && (expectedTyp instanceof WurstTypeUnknown)) {
node.addError("Cannot use implicit closure self 'it' because the closure target type is unknown.");
}
return null;
}

return new OtherLink(Visibility.LOCAL, "it", expectedTyp) {
@Override
public de.peeeq.wurstscript.jassIm.ImExpr translate(NameRef e, de.peeeq.wurstscript.translation.imtranslation.ImTranslator t, de.peeeq.wurstscript.jassIm.ImFunction f) {
return de.peeeq.wurstscript.jassIm.JassIm.ImVarAccess(t.getThisVar(closure));
}
};
}

private static boolean isWriteAccess(final NameRef node) {
Expand Down Expand Up @@ -110,7 +158,7 @@ private static boolean isWriteAccess(final NameRef node) {

public static @Nullable NameDef tryGetNameDef(NameRef e) {
NameLink link = e.attrNameLink();
if (link == null) {
if (link == null || link instanceof OtherLink) {
return null;
}
return link.getDef();
Expand Down Expand Up @@ -139,6 +187,9 @@ private static boolean isWriteAccess(final NameRef node) {

public static NameDef calculateDef(NameRef nameRef) {
NameLink l = nameRef.attrNameLink();
if (l instanceof OtherLink) {
return null;
}
return l == null ? null : l.getDef();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import de.peeeq.wurstscript.ast.*;
import de.peeeq.wurstscript.attributes.names.FuncLink;
import de.peeeq.wurstscript.attributes.names.NameLink;
import de.peeeq.wurstscript.attributes.names.OtherLink;
import de.peeeq.wurstscript.types.WurstType;
import de.peeeq.wurstscript.utils.Utils;
import org.eclipse.jdt.annotation.Nullable;
Expand Down Expand Up @@ -160,6 +161,9 @@ public static String description(NameRef nr) {
if (nameDef == null) {
return nr.getVarName() + " is not defined yet.";
}
if (nameDef instanceof OtherLink) {
return nr.getVarName() + " has type " + htmlType(nameDef.getTyp());
}
return nameDef.getDef().descriptionHtml();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ private static ImmutableList<NameDef> generic(Element e) {
}

public static ImmutableList<NameDef> calculate(ExprVarAccess e) {
if (e.attrNameLink() != null) {
if (e.attrNameLink() != null && e.attrNameDef() != null) {
return ImmutableList.of(e.attrNameDef());
} else {
return ImmutableList.emptyList();
Expand All @@ -42,7 +42,7 @@ public static ImmutableList<NameDef> calculate(ExprVarAccess e) {

public static ImmutableList<NameDef> calculate(ExprVarArrayAccess e) {
ImmutableList<NameDef> r = ImmutableList.emptyList();
if (e.attrNameLink() != null) {
if (e.attrNameLink() != null && e.attrNameDef() != null) {
r = ImmutableList.of(e.attrNameDef());
}
r = r.cons(generic(e.getIndexes()));
Expand All @@ -51,7 +51,7 @@ public static ImmutableList<NameDef> calculate(ExprVarArrayAccess e) {

public static ImmutableList<NameDef> calculate(ExprMemberArrayVar e) {
ImmutableList<NameDef> r = ImmutableList.emptyList();
if (e.attrNameLink() != null) {
if (e.attrNameLink() != null && e.attrNameDef() != null) {
r = ImmutableList.of(e.attrNameDef());
}
r = r.cons(e.getLeft().attrReadVariables());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import de.peeeq.wurstscript.ast.*;
import de.peeeq.wurstscript.attributes.names.FuncLink;
import de.peeeq.wurstscript.attributes.names.NameLink;
import de.peeeq.wurstscript.attributes.names.OtherLink;
import de.peeeq.wurstscript.types.WurstType;
import de.peeeq.wurstscript.types.WurstTypeClass;

Expand Down Expand Up @@ -36,7 +37,7 @@ public static ImmutableList<VarDef> getUsedGlobals(ExprOrStatements e) {
} else if (e instanceof NameRef) {
NameRef nameRef = (NameRef) e;
NameLink def = nameRef.attrNameLink();
if (def.getDef() instanceof GlobalVarDef) {
if (def != null && !(def instanceof OtherLink) && def.getDef() instanceof GlobalVarDef) {
GlobalVarDef varDef = (GlobalVarDef) def.getDef();
result.add(varDef);
}
Expand Down Expand Up @@ -103,7 +104,7 @@ private static void collectReadGlobals(Element e, Builder<VarDef> result) {
// write access
} else {
NameLink def = nameRef.attrNameLink();
if (def.getDef() instanceof GlobalVarDef) {
if (def != null && !(def instanceof OtherLink) && def.getDef() instanceof GlobalVarDef) {
GlobalVarDef varDef = (GlobalVarDef) def.getDef();
result.add(varDef);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import de.peeeq.wurstscript.ast.VarDef;
import de.peeeq.wurstscript.ast.WPackage;
import de.peeeq.wurstscript.attributes.names.NameLink;
import de.peeeq.wurstscript.attributes.names.OtherLink;

public class UsedPackages {

Expand All @@ -34,7 +35,7 @@ private static void processChildren(Element e,
public static ImmutableCollection<WPackage> usedPackages(NameRef e) {
ImmutableSet.Builder<WPackage> result = ImmutableSet.builder();
NameLink def = e.attrNameLink();
if (def.getDef() instanceof VarDef) {
if (def != null && !(def instanceof OtherLink) && def.getDef() instanceof VarDef) {
if (def.getDef().attrNearestPackage() instanceof WPackage) {
result.add((WPackage) e.attrNearestPackage());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,9 @@ public static ImExpr translateIntern(NameRef e, ImTranslator t, ImFunction f) {

private static ImExpr translateNameDef(NameRef e, ImTranslator t, ImFunction f) throws CompileError {
NameLink link = e.attrNameLink();
if (link instanceof OtherLink) {
return ((OtherLink) link).translate(e, t, f);
}
NameDef decl = link == null ? null : link.getDef();
if (decl == null) {
// should only happen with gg_ variables
Expand Down Expand Up @@ -303,9 +306,6 @@ private static ImExpr translateNameDef(NameRef e, ImTranslator t, ImFunction f)
EnumMember enumMember = (EnumMember) decl;
int id = t.getEnumMemberId(enumMember);
return ImIntVal(id);
} else if (link instanceof OtherLink) {
OtherLink otherLink = (OtherLink) link;
return otherLink.translate(e, t, f);
} else {
throw new CompileError(e.getSource(), "Cannot translate reference to " + Utils.printElement(decl));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -775,9 +775,12 @@ private boolean rewriteTypeCastingCompatFunction(ImFunction f, LuaFunction lf) {
if (f.getParameters().isEmpty()) {
return false;
}
String tcFunc = f.getName();
ImVar p = f.getParameters().get(0);
LuaExpr arg = LuaAst.LuaExprVarAccess(luaVar.getFor(p));
String tcFunc = getTypeCastingFunctionName(f);
if (tcFunc == null) {
return false;
}
ImVar firstParam = f.getParameters().get(0);
LuaExpr arg = LuaAst.LuaExprVarAccess(luaVar.getFor(firstParam));

if ("stringToIndex".equals(tcFunc)) {
lf.getBody().clear();
Expand Down Expand Up @@ -805,17 +808,6 @@ private boolean rewriteTypeCastingCompatFunction(ImFunction f, LuaFunction lf) {
lf.getBody().add(LuaAst.LuaReturn(LuaAst.LuaExprFunctionCall(fromIndexFunction, LuaAst.LuaExprlist(arg))));
return true;
}
// Final fallback for transformed/copied function names that may lose trace info:
if (tcFunc.endsWith("ToIndex")) {
lf.getBody().clear();
lf.getBody().add(LuaAst.LuaReturn(LuaAst.LuaExprFunctionCall(toIndexFunction, LuaAst.LuaExprlist(arg))));
return true;
}
if (tcFunc.endsWith("FromIndex")) {
lf.getBody().clear();
lf.getBody().add(LuaAst.LuaReturn(LuaAst.LuaExprFunctionCall(fromIndexFunction, LuaAst.LuaExprlist(arg))));
return true;
}
return false;
}

Expand Down Expand Up @@ -1100,13 +1092,6 @@ public String getTypeCastingFunctionName(ImFunction f) {
return fd.getName();
}
}
// Fallback: transformed/copied IM functions may lose package trace metadata.
// Keep Lua behavior stable by routing canonical *ToIndex/*FromIndex names anyway.
String name = f.getName();
if ("stringToIndex".equals(name) || "stringFromIndex".equals(name)
|| name.endsWith("ToIndex") || name.endsWith("FromIndex")) {
return name;
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import de.peeeq.wurstscript.ast.*;
import de.peeeq.wurstscript.attributes.names.NameLink;
import de.peeeq.wurstscript.attributes.names.OtherLink;

import java.util.Collection;
import java.util.HashSet;
Expand Down Expand Up @@ -42,7 +43,7 @@ public void visit(StmtSet set) {
LExpr updatedExpr = set.getUpdatedExpr();
if (updatedExpr != null) {
NameLink nameLink = updatedExpr.attrNameLink();
if (nameLink != null) {
if (nameLink != null && !(nameLink instanceof OtherLink)) {
locals.remove(nameLink.getDef());
}

Expand Down
Loading
Loading