Skip to content

Commit bef83f9

Browse files
committed
String Capital <- Capital now treated as local field (previously uppercase were left as default, only lowercase)
1 parent 05ef31e commit bef83f9

File tree

1 file changed

+58
-23
lines changed

1 file changed

+58
-23
lines changed

src/main/java/noppes/npcs/client/gui/util/script/JavaTextContainer.java

Lines changed: 58 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -272,45 +272,54 @@ private void highlightVariableReferences(List<Mark> marks) {
272272
String name = m.group(1);
273273
int position = m.start(1);
274274

275-
// Skip known keywords and types
275+
// Skip known keywords
276276
if (knownIdentifiers.contains(name)) continue;
277-
278-
// Skip type names (first letter uppercase)
279-
if (Character.isUpperCase(name.charAt(0))) continue;
280-
277+
281278
// Skip field access (identifier preceded by a dot) - these should be gray/default
282-
// e.g., in "container.lines", the "lines" part should not be marked
283279
if (isFieldAccess(position)) continue;
284280

285281
// Never treat parts of import/package statements as undefined variables
286-
// (otherwise the first package segment like "noppes" gets marked red and overrides import highlighting)
287282
if (isInImportOrPackageStatement(position)) continue;
288-
283+
289284
// Check if inside a method
290285
MethodBlock methodBlock = findMethodBlockAtPosition(position);
291-
286+
292287
if (methodBlock != null) {
293-
// Inside a method - check in order: parameter, local (position-aware), global
288+
// Inside a method - first check parameters, locals, and globals (respecting registrations)
294289
if (methodBlock.parameters.contains(name)) {
295290
marks.add(new Mark(m.start(1), m.end(1), TokenType.PARAMETER));
296-
} else if (methodBlock.isLocalDeclaredAtPosition(name, position)) {
297-
// Local variable is declared at or before this position
291+
continue;
292+
}
293+
294+
if (methodBlock.isLocalDeclaredAtPosition(name, position) || localFields.contains(name)) {
298295
marks.add(new Mark(m.start(1), m.end(1), TokenType.LOCAL_FIELD));
299-
} else if (globalFields.contains(name)) {
296+
continue;
297+
}
298+
299+
if (globalFields.contains(name)) {
300300
marks.add(new Mark(m.start(1), m.end(1), TokenType.GLOBAL_FIELD));
301-
} else {
302-
// Unknown variable - mark as undefined (Bug 11)
303-
// But only if it looks like a variable reference (not a method call)
304-
if (!isMethodCall(position) && !isTypeReference(name, position)) {
305-
marks.add(new Mark(m.start(1), m.end(1), TokenType.UNDEFINED_VAR));
306-
}
301+
continue;
302+
}
303+
304+
// If it's an uppercase identifier that hasn't been registered as a local/param/global,
305+
// treat it as a type reference (skip) rather than an undefined variable.
306+
if (Character.isUpperCase(name.charAt(0))) continue;
307+
308+
// Unknown variable - mark as undefined but only if it's not a method call or type reference
309+
if (!isMethodCall(position) && !isTypeReference(name, position)) {
310+
marks.add(new Mark(m.start(1), m.end(1), TokenType.UNDEFINED_VAR));
307311
}
308312
} else {
309-
// Outside any method - check global fields
310-
if (globalFields.contains(name)) {
313+
// Outside any method - check global fields first
314+
if (globalFields.contains(name) || localFields.contains(name)) {
311315
marks.add(new Mark(m.start(1), m.end(1), TokenType.GLOBAL_FIELD));
312-
} else if (!isMethodCall(position) && !isTypeReference(name, position)) {
313-
// Mark as undefined if it's not a method call or type reference
316+
continue;
317+
}
318+
319+
// Uppercase unregistered identifiers are likely type names; skip them
320+
if (Character.isUpperCase(name.charAt(0))) continue;
321+
322+
if (!isMethodCall(position) && !isTypeReference(name, position)) {
314323
marks.add(new Mark(m.start(1), m.end(1), TokenType.UNDEFINED_VAR));
315324
}
316325
}
@@ -805,6 +814,32 @@ private void collectTypeDeclarations(List<Mark> marks) {
805814
int contentStart = lineStart + genericStart + 1;
806815
highlightGenericTypes(genericContent, contentStart, marks, excluded);
807816
}
817+
818+
// If followed by a variable name, detect it and register uppercase-starting
819+
// variable names as locals so subsequent identifier scanning treats them
820+
// as variables (not types). This handles declarations like:
821+
// MyType Capital = new MyType();
822+
if (followedByVarName) {
823+
int v = posAfterType;
824+
// skip whitespace
825+
while (v < s.length() && Character.isWhitespace(s.charAt(v))) v++;
826+
int varStart = v;
827+
while (v < s.length() && (Character.isLetterOrDigit(s.charAt(v)) || s.charAt(v) == '_')) v++;
828+
int varEnd = v;
829+
if (varEnd > varStart) {
830+
String varName = s.substring(varStart, varEnd);
831+
int absVarStart = lineStart + varStart;
832+
int absVarEnd = lineStart + varEnd;
833+
if (Character.isUpperCase(varName.charAt(0))) {
834+
MethodBlock mb = findMethodBlockAtPosition(absVarStart);
835+
if (mb != null) {
836+
if (!mb.localVariables.contains(varName)) mb.localVariables.add(varName);
837+
if (!localFields.contains(varName)) localFields.add(varName);
838+
marks.add(new Mark(absVarStart, absVarEnd, TokenType.LOCAL_FIELD));
839+
}
840+
}
841+
}
842+
}
808843
}
809844

810845
searchFrom = m.end();

0 commit comments

Comments
 (0)