Skip to content

Commit af896df

Browse files
committed
Update NameLinks.java
1 parent 52d96b6 commit af896df

1 file changed

Lines changed: 40 additions & 75 deletions

File tree

  • de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/attributes/names

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/attributes/names/NameLinks.java

Lines changed: 40 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
package de.peeeq.wurstscript.attributes.names;
22

33
import com.google.common.collect.HashMultimap;
4-
import com.google.common.collect.ImmutableCollection;
5-
import com.google.common.collect.ImmutableList;
64
import com.google.common.collect.ImmutableMultimap;
5+
import com.google.common.collect.ImmutableMultimap.Builder;
76
import com.google.common.collect.ImmutableSetMultimap;
87
import com.google.common.collect.Multimap;
98
import de.peeeq.wurstscript.WLogger;
@@ -21,13 +20,15 @@
2120

2221
public class NameLinks {
2322

24-
// OPTIMIZATION 1: Cache for package name links to avoid recomputation
25-
private static final Map<WPackage, ImmutableMultimap<String, DefLink>> packageNameLinksCache =
26-
new WeakHashMap<>();
27-
2823
static private class OverrideCheckResult {
24+
// does this override some other function
2925
boolean doesOverride = false;
26+
27+
// overrides a function from a class or module
28+
// (for interfaces override modifier is optional)
3029
boolean requiresOverrideMod = false;
30+
31+
// errors for functions with same name that it does not override
3132
io.vavr.collection.List<String> overrideErrors = io.vavr.collection.List.empty();
3233

3334
public void addError(String error) {
@@ -65,6 +66,7 @@ private static Map<String, Map<FuncLink, OverrideCheckResult>> initOverrideMap(M
6566
}
6667

6768
private static void reportOverrideErrors(Map<String, Map<FuncLink, OverrideCheckResult>> overrideCheckResults) {
69+
// report override errors
6870
for (Map<FuncLink, OverrideCheckResult> map : overrideCheckResults.values()) {
6971
for (Entry<FuncLink, OverrideCheckResult> e : map.entrySet()) {
7072
FunctionDefinition f = e.getKey().getDef();
@@ -83,6 +85,7 @@ private static void reportOverrideErrors(Map<String, Map<FuncLink, OverrideCheck
8385
f.addWarning("Function " + f.getName() + " should be marked with the 'override' modifier.");
8486
}
8587
}
88+
8689
}
8790
}
8891
}
@@ -102,6 +105,7 @@ private static void addNamesFromExtendedInterfaces(Multimap<String, DefLink> res
102105
}
103106
}
104107

108+
105109
private static void addNamesFromImplementedInterfaces(Multimap<String, DefLink> result, WurstTypeClass classDef, Map<String, Map<FuncLink, OverrideCheckResult>> overrideCheckResults) {
106110
for (WurstTypeInterface interfaceType : classDef.implementedInterfaces()) {
107111
addNewNameLinks(result, overrideCheckResults, interfaceType.nameLinks(), false);
@@ -126,6 +130,7 @@ private static void addNewNameLinks(Multimap<String, DefLink> result, Map<String
126130
if (def instanceof FuncLink) {
127131
FuncLink func = (FuncLink) def;
128132

133+
// check if function is overridden by any other function in
129134
Map<FuncLink, OverrideCheckResult> otherFuncs = overrideCheckResults.getOrDefault(name, Collections.emptyMap());
130135
for (Entry<FuncLink, OverrideCheckResult> e2 : otherFuncs.entrySet()) {
131136
FuncLink otherFunc = e2.getKey();
@@ -141,14 +146,18 @@ private static void addNewNameLinks(Multimap<String, DefLink> result, Map<String
141146
} else {
142147
checkResult.addError(error);
143148
}
149+
150+
144151
}
152+
145153
}
146154
if (!isOverridden) {
147155
result.put(name, def.hidingPrivate());
148156
}
149157
}
150158
}
151159

160+
152161
public static ImmutableMultimap<String, DefLink> calculate(CompilationUnit cu) {
153162
ImmutableMultimap.Builder<String, DefLink> result = ImmutableSetMultimap.builder();
154163
addJassNames(result, cu);
@@ -164,7 +173,8 @@ public static ImmutableMultimap<String, DefLink> calculate(AstElementWithBody c)
164173
return result.build();
165174
}
166175

167-
private static void addVarDefIfAny(ImmutableMultimap.Builder<String, DefLink> result, WScope s) {
176+
177+
private static void addVarDefIfAny(Builder<String, DefLink> result, WScope s) {
168178
if (s instanceof LoopStatementWithVarDef) {
169179
LoopStatementWithVarDef l = (LoopStatementWithVarDef) s;
170180
result.put(l.getLoopVar().getName(), VarLink.create(l.getLoopVar(), s));
@@ -177,8 +187,10 @@ public static ImmutableMultimap<String, DefLink> calculate(EnumDef e) {
177187
return result.build();
178188
}
179189

190+
180191
public static ImmutableMultimap<String, DefLink> calculate(@SuppressWarnings("unused") NativeFunc nativeFunc) {
181-
return ImmutableMultimap.of();
192+
ImmutableMultimap.Builder<String, DefLink> result = ImmutableSetMultimap.builder();
193+
return result.build();
182194
}
183195

184196
public static ImmutableMultimap<String, DefLink> calculate(TupleDef t) {
@@ -188,19 +200,7 @@ public static ImmutableMultimap<String, DefLink> calculate(TupleDef t) {
188200
}
189201

190202
public static ImmutableMultimap<String, DefLink> calculate(WPackage p) {
191-
// OPTIMIZATION 2: Check cache first
192-
ImmutableMultimap<String, DefLink> cached = packageNameLinksCache.get(p);
193-
if (cached != null) {
194-
return cached;
195-
}
196-
197-
// OPTIMIZATION 3: Estimate size based on imports
198-
int estimatedSize = p.getImports().size() * 50; // rough estimate
199-
ImmutableMultimap.Builder<String, DefLink> result =
200-
new ImmutableMultimap.Builder<>();
201-
202-
// OPTIMIZATION 4: Collect all imported packages first
203-
List<WPackage> importedPackages = new ArrayList<>(p.getImports().size());
203+
ImmutableMultimap.Builder<String, DefLink> result = ImmutableSetMultimap.builder();
204204
for (WImport imp : p.getImports()) {
205205
if (imp.getPackagename().equals("NoWurst")) {
206206
continue;
@@ -210,53 +210,20 @@ public static ImmutableMultimap<String, DefLink> calculate(WPackage p) {
210210
WLogger.info("could not resolve import: " + Utils.printElementWithSource(Optional.of(imp)));
211211
continue;
212212
}
213-
importedPackages.add(importedPackage);
214-
}
215-
216-
// OPTIMIZATION 5: Special handling for REPL (all names)
217-
if (p.getName().equals("WurstREPL")) {
218-
for (WPackage importedPackage : importedPackages) {
213+
if (p.getName().equals("WurstREPL")) {
214+
// the REPL is special and can use all names
219215
result.putAll(importedPackage.getElements().attrNameLinks());
220216
result.putAll(importedPackage.attrNameLinks());
221-
}
222-
} else {
223-
// OPTIMIZATION 6: Batch process exported names
224-
// Instead of calling putAll for each package, collect into intermediate structure
225-
if (importedPackages.size() == 1) {
226-
// Fast path for single import
227-
result.putAll(importedPackages.get(0).attrExportedNameLinks());
228-
} else if (!importedPackages.isEmpty()) {
229-
// OPTIMIZATION 7: Use a Set to track already added names (for deduplication)
230-
Map<String, Set<DefLink>> mergedLinks = new HashMap<>(estimatedSize);
231-
232-
for (WPackage importedPackage : importedPackages) {
233-
ImmutableMultimap<String, DefLink> exportedLinks = importedPackage.attrExportedNameLinks();
234-
235-
// OPTIMIZATION 8: Iterate entries once and merge
236-
for (Map.Entry<String, DefLink> entry : exportedLinks.entries()) {
237-
String name = entry.getKey();
238-
DefLink link = entry.getValue();
239-
240-
mergedLinks.computeIfAbsent(name, k -> new LinkedHashSet<>(4))
241-
.add(link);
242-
}
243-
}
244-
245-
// OPTIMIZATION 9: Bulk add to result
246-
for (Map.Entry<String, Set<DefLink>> entry : mergedLinks.entrySet()) {
247-
result.putAll(entry.getKey(), entry.getValue());
248-
}
217+
} else {
218+
// normal packages can only use the exported names of a package
219+
result.putAll(importedPackage.attrExportedNameLinks());
249220
}
250221
}
251222

252-
ImmutableMultimap<String, DefLink> finalResult = result.build();
253-
254-
// OPTIMIZATION 10: Cache the result
255-
packageNameLinksCache.put(p, finalResult);
256-
257-
return finalResult;
223+
return result.build();
258224
}
259225

226+
260227
public static ImmutableMultimap<String, DefLink> calculate(WEntities wEntities) {
261228
ImmutableMultimap.Builder<String, DefLink> result = ImmutableSetMultimap.builder();
262229
for (WEntity e : wEntities) {
@@ -297,22 +264,23 @@ public static ImmutableMultimap<String, DefLink> calculate(WStatements statement
297264
return result.build();
298265
}
299266

300-
private static void addParametersIfAny(ImmutableMultimap.Builder<String, DefLink> result, WScope s) {
267+
private static void addParametersIfAny(Builder<String, DefLink> result, WScope s) {
301268
if (s instanceof AstElementWithParameters) {
302269
AstElementWithParameters withParams = (AstElementWithParameters) s;
303270
for (WParameter p : withParams.getParameters()) {
304271
result.put(p.getName(), VarLink.create(p, s));
305272
}
306273
}
274+
307275
}
308276

309-
private static void addPackages(ImmutableMultimap.Builder<String, DefLink> result, CompilationUnit cu) {
277+
private static void addPackages(Builder<String, DefLink> result, CompilationUnit cu) {
310278
for (WPackage p : cu.getPackages()) {
311279
result.put(p.getName(), PackageLink.create(p, cu));
312280
}
313281
}
314282

315-
private static void addJassNames(ImmutableMultimap.Builder<String, DefLink> result, CompilationUnit cu) {
283+
private static void addJassNames(Builder<String, DefLink> result, CompilationUnit cu) {
316284
for (JassToplevelDeclaration jd : cu.getJassDecls()) {
317285
if (jd instanceof NameDef) {
318286
NameDef def = (NameDef) jd;
@@ -324,6 +292,7 @@ private static void addJassNames(ImmutableMultimap.Builder<String, DefLink> resu
324292
}
325293
}
326294

295+
327296
private static void addNameDefDefLink(Consumer<DefLink> result, NameDef def, WScope scope) {
328297
if (def instanceof VarDef) {
329298
result.accept(VarLink.create(((VarDef) def), scope));
@@ -338,14 +307,15 @@ private static void addNameDefDefLink(Consumer<DefLink> result, NameDef def, WSc
338307
}
339308
}
340309

341-
private static void addNameDefDefLink(ImmutableMultimap.Builder<String, DefLink> result, NameDef def, WScope scope) {
310+
private static void addNameDefDefLink(Builder<String, DefLink> result, NameDef def, WScope scope) {
342311
addNameDefDefLink(l -> result.put(l.getName(), l), def, scope);
343312
}
344313

345314
private static void addNameDefDefLink(Multimap<String, DefLink> result, NameDef def, WScope scope) {
346315
addNameDefDefLink(l -> result.put(l.getName(), l), def, scope);
347316
}
348317

318+
349319
private static void addNamesFromUsedModuleInstantiations(ClassOrModuleOrModuleInstanciation c,
350320
Multimap<String, DefLink> result, Map<String, Map<FuncLink, OverrideCheckResult>> overrideCheckResults) {
351321
for (ModuleInstanciation m : c.getModuleInstanciations()) {
@@ -360,7 +330,7 @@ private static void addDefinedNames(Multimap<String, DefLink> result, ClassOrMod
360330
addDefinedNames(result, c, c.getInnerClasses());
361331
}
362332

363-
private static void addDefinedNames(ImmutableMultimap.Builder<String, DefLink> result, WScope definedIn, List<? extends NameDef> slots) {
333+
private static void addDefinedNames(Builder<String, DefLink> result, WScope definedIn, List<? extends NameDef> slots) {
364334
for (NameDef n : slots) {
365335
addNameDefDefLink(result, n, definedIn);
366336
}
@@ -372,13 +342,15 @@ private static void addDefinedNames(Multimap<String, DefLink> result, WScope def
372342
}
373343
}
374344

375-
public static void addHidingPrivate(ImmutableMultimap.Builder<String, DefLink> result, Multimap<String, DefLink> adding, List<TypeParamDef> typeParams) {
345+
346+
public static void addHidingPrivate(Builder<String, DefLink> result, Multimap<String, DefLink> adding, List<TypeParamDef> typeParams) {
376347
for (Entry<String, DefLink> e : adding.entries()) {
377348
if (e.getValue().getVisibility() == Visibility.LOCAL) {
378349
continue;
379350
}
380351
result.put(e.getKey(), e.getValue().hidingPrivate().withGenericTypeParams(typeParams));
381352
}
353+
382354
}
383355

384356
public static void addHidingPrivate(Multimap<String, DefLink> result, Multimap<String, DefLink> adding) {
@@ -388,6 +360,7 @@ public static void addHidingPrivate(Multimap<String, DefLink> result, Multimap<S
388360
}
389361
result.put(e.getKey(), e.getValue().hidingPrivate());
390362
}
363+
391364
}
392365

393366
public static void addHidingPrivateAndProtected(ImmutableMultimap.Builder<String, DefLink> r, Multimap<String, ? extends DefLink> adding) {
@@ -416,12 +389,4 @@ public static ImmutableMultimap<String, DefLink> calculate(ExprClosure e) {
416389
return result.build();
417390
}
418391

419-
// OPTIMIZATION 11: Clear cache method for when packages change
420-
public static void clearPackageCache() {
421-
packageNameLinksCache.clear();
422-
}
423-
424-
public static void clearPackageCache(WPackage p) {
425-
packageNameLinksCache.remove(p);
426-
}
427392
}

0 commit comments

Comments
 (0)