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
1 change: 1 addition & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,4 @@ jobs:
generate_release_notes: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Binary file removed Wurstpack/wurstscript/grill.exe
Binary file not shown.
28 changes: 28 additions & 0 deletions Wurstpack/wurstscript/wurstscript
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env bash
set -euo pipefail

RUNTIME="$HOME/.wurst/wurst-runtime/bin/java"

# Resolve script dir (absolute)
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

JAR="$DIR/wurst-compiler/wurstscript.jar"
if [[ ! -f "$JAR" ]]; then
JAR="$DIR/../wurst-compiler/wurstscript.jar"
fi

if [[ ! -f "$JAR" ]]; then
echo "[wurstscript] ERROR: Missing jar. Searched:"
echo " $DIR/wurst-compiler/wurstscript.jar"
echo " $DIR/../wurst-compiler/wurstscript.jar"
exit 2
fi

if [[ ! -x "$RUNTIME" ]]; then
echo "[wurstscript] ERROR: Bundled runtime not found or not executable at:"
echo " $RUNTIME"
echo "Please reinstall wurstscript via the VSCode extension."
exit 3
fi

exec "$RUNTIME" -jar "$JAR" "$@"
30 changes: 30 additions & 0 deletions Wurstpack/wurstscript/wurstscript.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
@echo off
setlocal EnableExtensions

rem ---- shared slim runtime ----
set "RUNTIME=%USERPROFILE%\.wurst\wurst-runtime\bin\java.exe"

rem script directory (trailing backslash)
set "DIR=%~dp0"

if not exist "%RUNTIME%" (
echo [wurstscript] ERROR: Runtime not found:
echo(%RUNTIME%
echo Reinstall Wurstscript via the VSCode extension.
exit /b 1
)

rem ---- fixed jar location(s), no wildcards ----
set "JAR=%DIR%wurst-compiler\wurstscript.jar"
if not exist "%JAR%" set "JAR=%DIR%..\wurst-compiler\wurstscript.jar"
if not exist "%JAR%" (
echo [wurstscript] ERROR: Missing jar:
echo(%DIR%wurst-compiler\wurstscript.jar
echo or
echo(%DIR%..\wurst-compiler\wurstscript.jar
exit /b 1
)

rem Optional JVM flags via env var, e.g. set WURST_JAVA_OPTS=-Xmx1g
"%RUNTIME%" %WURST_JAVA_OPTS% -jar "%JAR%" %*
endlocal
Binary file removed Wurstpack/wurstscript/wurstscript.exe
Binary file not shown.
9 changes: 4 additions & 5 deletions de.peeeq.wurstscript/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ buildscript {

plugins {
id 'java'
id 'application'
id 'antlr'
id 'eclipse'
id 'idea'
Expand All @@ -27,9 +26,7 @@ import org.eclipse.jgit.lib.ObjectId

import java.util.regex.Pattern

application {
mainClass = "de.peeeq.wurstio.Main"
}
ext.mainClassName = "de.peeeq.wurstio.Main"

version = "1.8.1.0"

Expand Down Expand Up @@ -229,7 +226,9 @@ shadowJar {
archiveBaseName.set('wurstscript')
archiveClassifier.set('')
archiveVersion.set('')
manifest { attributes 'Main-Class': application.mainClass.get() }
manifest {
attributes 'Main-Class': mainClassName
}
}

def fatJar = shadowJar.archiveFile.map { it.asFile }
Expand Down
10 changes: 10 additions & 0 deletions de.peeeq.wurstscript/deploy.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,16 @@ tasks.register("assembleSlimCompilerDist", Copy) {
}
}

tasks.named("assembleSlimCompilerDist", Copy) { t ->
if (os.isWindows()) {
from("../Wurstpack/wurstscript/wurstscript.cmd") { into(".") }
} else {
from("../Wurstpack/wurstscript/wurstscript") {
into(".")
}
}
}

// 4a) Package ZIP on Windows
tasks.register("packageSlimCompilerDistZip", Zip) {
description = "Packages slim dist as a ZIP archive (Windows)."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1568,8 +1568,51 @@ private void checkCall(StmtCall call) {
call.attrCallSignature().checkSignatureCompatibility(call.attrFunctionSignature(), funcName, call);
}

/** Error when a field in this class hides a field from a superclass. */
private void checkFieldShadowing(ClassDef c) {
// Iterate only the fields *declared* in this class:
for (NameLink nl : c.attrNameLinks().values()) {
NameDef def = nl.getDef();
// consider only variables that are declared in this class body
if (!(def instanceof GlobalVarDef)) continue;
if (nl.getDefinedIn() != c) continue; // not declared here

String name = def.getName();

// Look up all visible declarations of the same name in this class scope:
ImmutableCollection<DefLink> all = c.attrNameLinks().get(name);
for (DefLink other : all) {
if (!(other instanceof NameLink)) continue;
if (other.getDefinedIn() == c) continue; // skip "self" (duplicates in same class handled elsewhere)
NameDef od = other.getDef();
if (!(od instanceof GlobalVarDef)) continue;

// Is the other definition a superclass' field?
StructureDef owner = od.attrNearestStructureDef();
if (owner instanceof ClassDef) {
ClassDef superOwner = (ClassDef) owner;
if (isStrictSuperclassOf(superOwner, c)) {
// produce the requested error text
def.addError("Variable " + name + " in class " + c.getName()
+ " hides variable " + name + " from superclass " + superOwner.getName());
// one error per conflicting ancestor is enough
break;
}
}
}
}
}

// crude cap to avoid unbounded growth; tune as needed
private static boolean isStrictSuperclassOf(ClassDef sup, ClassDef sub) {
WurstTypeClass t = sub.attrTypC();
WurstTypeClass cur = (t != null) ? t.extendedClass() : null;
while (cur != null) {
ClassDef cd = cur.getClassDef();
if (cd == sup) return true;
cur = cur.extendedClass();
}
return false;
}

private static boolean isSubtypeCached(WurstType actual, WurstType expected, Annotation site) {
if (actual == expected) return true;
Expand Down Expand Up @@ -1796,12 +1839,15 @@ private void checkReturnInFunc(StmtReturn s, FunctionImplementation func) {

private void visit(ClassDef classDef) {
checkTypeName(classDef, classDef.getName());
if (!(classDef.getExtendedClass() instanceof NoTypeExpr) && !(classDef.getExtendedClass().attrTyp() instanceof WurstTypeClass)) {
if (!(classDef.getExtendedClass() instanceof NoTypeExpr)
&& !(classDef.getExtendedClass().attrTyp() instanceof WurstTypeClass)) {
classDef.getExtendedClass().addError("Classes may only extend other classes.");
}
if (classDef.isInnerClass() && !classDef.attrIsStatic()) {
classDef.addError("At the moment only static inner classes are supported.");
}

checkFieldShadowing(classDef);
}

private void checkTypeName(Element source, String name) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1443,4 +1443,21 @@ public void minusRewrite() {
}


@Test
public void duplicateNameInClassHierachy() {
testAssertErrorsLines(false, "Variable x in class B hides variable x from superclass A",
"package test",
"native testSuccess()",
"class A",
" int x",
"class B extends A",
" int x",
"init",
" let b = new B()",
" if b != null",
" testSuccess()",
"endpackage");
}


}
Loading