Skip to content

Commit 3d88433

Browse files
stronger types for different string types
1 parent 5e2768f commit 3d88433

File tree

7 files changed

+78
-64
lines changed

7 files changed

+78
-64
lines changed

luceedebug/src/main/java/luceedebug/DapServer.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -376,11 +376,11 @@ public CompletableFuture<VariablesResponse> variables(VariablesArguments args) {
376376

377377
@Override
378378
public CompletableFuture<SetBreakpointsResponse> setBreakpoints(SetBreakpointsArguments args) {
379-
final var path = new OriginalAndTransformedString(
380-
args.getSource().getPath(),
381-
applyPathTransformsIdeToCf(args.getSource().getPath())
382-
);
383-
logger.finest("bp for " + path.original + " -> " + path.transformed);
379+
final var idePath = new StrongString.RawIdePath(args.getSource().getPath());
380+
final var serverAbsPath = new StrongString.CanonicalServerAbsPath(applyPathTransformsIdeToCf(args.getSource().getPath()));
381+
382+
logger.finest("bp for " + idePath.v + " -> " + serverAbsPath.v);
383+
384384
final int size = args.getBreakpoints().length;
385385
final int[] lines = new int[size];
386386
final String[] exprs = new String[size];
@@ -390,7 +390,7 @@ public CompletableFuture<SetBreakpointsResponse> setBreakpoints(SetBreakpointsAr
390390
}
391391

392392
var result = new ArrayList<Breakpoint>();
393-
for (IBreakpoint bp : luceeVm_.bindBreakpoints(path, lines, exprs)) {
393+
for (IBreakpoint bp : luceeVm_.bindBreakpoints(idePath, serverAbsPath, lines, exprs)) {
394394
result.add(map_cfBreakpoint_to_lsp4jBreakpoint(bp));
395395
}
396396

luceedebug/src/main/java/luceedebug/ILuceeVm.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55

66
import com.sun.jdi.*;
77

8+
import luceedebug.StrongString.CanonicalServerAbsPath;
9+
import luceedebug.StrongString.RawIdePath;
10+
811
public interface ILuceeVm {
912
public void registerStepEventCallback(Consumer</*threadID*/Long> cb);
1013
public void registerBreakpointEventCallback(BiConsumer</*threadID*/Long, /*bpID*/Integer> cb);
@@ -37,7 +40,7 @@ public static BreakpointsChangedEvent justChanges(IBreakpoint[] changes) {
3740
public IDebugEntity[] getNamedVariables(long ID);
3841
public IDebugEntity[] getIndexedVariables(long ID);
3942

40-
public IBreakpoint[] bindBreakpoints(OriginalAndTransformedString absPath, int[] lines, String[] exprs);
43+
public IBreakpoint[] bindBreakpoints(RawIdePath idePath, CanonicalServerAbsPath serverAbsPath, int[] lines, String[] exprs);
4144

4245
public void continue_(long jdwpThreadID);
4346

luceedebug/src/main/java/luceedebug/OriginalAndTransformedString.java

Lines changed: 0 additions & 19 deletions
This file was deleted.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package luceedebug;
2+
3+
public class StrongString {
4+
public final String v;
5+
private StrongString(String v) {
6+
this.v = v;
7+
}
8+
9+
@Override
10+
public int hashCode() {
11+
return v.hashCode();
12+
}
13+
14+
@Override
15+
public boolean equals(Object other) {
16+
return v.equals(other);
17+
}
18+
19+
public static class RawIdePath extends StrongString {
20+
public RawIdePath(String v) {
21+
super(v);
22+
}
23+
}
24+
25+
public static class CanonicalServerAbsPath extends StrongString {
26+
public CanonicalServerAbsPath(String v) {
27+
super(v);
28+
}
29+
}
30+
}

luceedebug/src/main/java/luceedebug/coreinject/KlassMap.java

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,13 @@
33
import java.util.HashMap;
44

55
import luceedebug.Config;
6-
import luceedebug.OriginalAndTransformedString;
6+
import luceedebug.StrongString.CanonicalServerAbsPath;
77

88
import com.sun.jdi.*;
99

1010
class KlassMap {
11-
/**
12-
* original -> original
13-
*
14-
* transformed -> canonicalized as per fs config
15-
*/
16-
final public OriginalAndTransformedString sourceName;
11+
12+
final public CanonicalServerAbsPath sourceName;
1713
final public HashMap<Integer, Location> lineMap;
1814
private final ClassObjectReference objRef;
1915

@@ -29,10 +25,8 @@ private KlassMap(Config config, ReferenceType refType) throws AbsentInformationE
2925
lineMap.put(loc.lineNumber(), loc);
3026
}
3127

32-
this.sourceName = new OriginalAndTransformedString(
33-
sourceName,
34-
Config.canonicalizeFileName(sourceName)
35-
);
28+
this.sourceName = new CanonicalServerAbsPath(Config.canonicalizeFileName(sourceName));
29+
3630
this.lineMap = lineMap;
3731
this.refType = refType;
3832
}

luceedebug/src/main/java/luceedebug/coreinject/LuceeVm.java

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import static luceedebug.coreinject.Iife.iife;
2929

3030
import luceedebug.*;
31+
import luceedebug.StrongString.CanonicalServerAbsPath;
32+
import luceedebug.StrongString.RawIdePath;
3133

3234
public class LuceeVm implements ILuceeVm {
3335
// This is a key into a map stored on breakpointRequest objects; the value should always be of Integer type
@@ -109,8 +111,8 @@ public void unregister(ThreadReference threadRef) {
109111
}
110112

111113
private static class ReplayableCfBreakpointRequest {
112-
final String ideAbsPath;
113-
final String serverAbsPath;
114+
final RawIdePath ideAbsPath;
115+
final CanonicalServerAbsPath serverAbsPath;
114116
final int line;
115117
final int id;
116118
/**
@@ -140,7 +142,7 @@ public boolean equals(Object vv) {
140142
&& expr.equals(v.expr);
141143
}
142144

143-
ReplayableCfBreakpointRequest(String ideAbsPath, String serverAbsPath, int line, int id, String expr) {
145+
ReplayableCfBreakpointRequest(RawIdePath ideAbsPath, CanonicalServerAbsPath serverAbsPath, int line, int id, String expr) {
144146
this.ideAbsPath = ideAbsPath;
145147
this.serverAbsPath = serverAbsPath;
146148
this.line = line;
@@ -149,7 +151,7 @@ public boolean equals(Object vv) {
149151
this.maybeNull_jdwpBreakpointRequest = null;
150152
}
151153

152-
ReplayableCfBreakpointRequest(String ideAbsPath, String serverAbsPath, int line, int id, String expr, BreakpointRequest jdwpBreakpointRequest) {
154+
ReplayableCfBreakpointRequest(RawIdePath ideAbsPath, CanonicalServerAbsPath serverAbsPath, int line, int id, String expr, BreakpointRequest jdwpBreakpointRequest) {
153155
this.ideAbsPath = ideAbsPath;
154156
this.serverAbsPath = serverAbsPath;
155157
this.line = line;
@@ -176,7 +178,7 @@ static BpLineAndId[] getLineInfo(Collection<ReplayableCfBreakpointRequest> vs) {
176178

177179
private final ThreadMap threadMap_ = new ThreadMap();
178180
private final ExecutorService stepHandlerExecutor = Executors.newSingleThreadExecutor();
179-
private final ConcurrentHashMap</*canonical sourceAbsPath*/ String, Set<ReplayableCfBreakpointRequest>> replayableBreakpointRequestsByAbsPath_ = new ConcurrentHashMap<>();
181+
private final ConcurrentHashMap<CanonicalServerAbsPath, Set<ReplayableCfBreakpointRequest>> replayableBreakpointRequestsByAbsPath_ = new ConcurrentHashMap<>();
180182

181183
/**
182184
* Mapping of "abspath on disk" -> "class file info"
@@ -185,7 +187,7 @@ static BpLineAndId[] getLineInfo(Collection<ReplayableCfBreakpointRequest> vs) {
185187
* like "/app/foo.cfc" maps to "myapp.foo" as well as "someOtherMapping.foo", where each mapping
186188
* is represented by a separate classfile.
187189
*/
188-
private final ConcurrentHashMap</*canonical absPath*/ String, Set<KlassMap>> klassMap_ = new ConcurrentHashMap<>();
190+
private final ConcurrentHashMap<CanonicalServerAbsPath, Set<KlassMap>> klassMap_ = new ConcurrentHashMap<>();
189191
private long JDWP_WORKER_CLASS_ID = 0;
190192
private ThreadReference JDWP_WORKER_THREADREF = null;
191193

@@ -595,14 +597,14 @@ private void trackClassRef(ReferenceType refType) {
595597

596598
final var klassMap = maybeNull_klassMap; // definitely non-null
597599

598-
Set<ReplayableCfBreakpointRequest> replayableBreakpointRequests = replayableBreakpointRequestsByAbsPath_.get(klassMap.sourceName.transformed);
600+
Set<ReplayableCfBreakpointRequest> replayableBreakpointRequests = replayableBreakpointRequestsByAbsPath_.get(klassMap.sourceName);
599601

600602
klassMap_
601-
.computeIfAbsent(klassMap.sourceName.transformed, _z -> new HashSet<>())
603+
.computeIfAbsent(klassMap.sourceName, _z -> new HashSet<>())
602604
.add(klassMap);
603605

604606
if (replayableBreakpointRequests != null) {
605-
rebindBreakpoints(klassMap.sourceName.transformed, replayableBreakpointRequests);
607+
rebindBreakpoints(klassMap.sourceName, replayableBreakpointRequests);
606608
}
607609
}
608610
catch (Throwable e) {
@@ -724,7 +726,7 @@ private int nextBreakpointID() {
724726
return breakpointID.incrementAndGet();
725727
}
726728

727-
public void rebindBreakpoints(String serverAbsPath, Collection<ReplayableCfBreakpointRequest> cfBpRequests) {
729+
public void rebindBreakpoints(CanonicalServerAbsPath serverAbsPath, Collection<ReplayableCfBreakpointRequest> cfBpRequests) {
728730
var changedBreakpoints = __internal__bindBreakpoints(serverAbsPath, ReplayableCfBreakpointRequest.getLineInfo(cfBpRequests));
729731

730732
if (breakpointsChangedCallback != null) {
@@ -733,30 +735,29 @@ public void rebindBreakpoints(String serverAbsPath, Collection<ReplayableCfBreak
733735
}
734736

735737
static class BpLineAndId {
736-
final String ideAbsPath;
737-
final String serverAbsPath;
738+
final RawIdePath ideAbsPath;
739+
final CanonicalServerAbsPath serverAbsPath;
738740
final int line;
739741
final int id;
740742
final String expr;
741743

742-
public BpLineAndId(String ideAbsPath, String serverAbsPath, int line, int id, String expr) {
744+
public BpLineAndId(RawIdePath ideAbsPath, CanonicalServerAbsPath serverAbsPath, int line, int id, String expr) {
743745
this.ideAbsPath = ideAbsPath;
744746
this.serverAbsPath = serverAbsPath;
745747
this.line = line;
746748
this.id = id;
747749
this.expr = expr;
748750
}
749-
750751
}
751752

752-
private BpLineAndId[] freshBpLineAndIdRecordsFromLines(OriginalAndTransformedString absPath, int[] lines, String[] exprs) {
753+
private BpLineAndId[] freshBpLineAndIdRecordsFromLines(RawIdePath idePath, CanonicalServerAbsPath serverPath, int[] lines, String[] exprs) {
753754
if (lines.length != exprs.length) { // really this should be some kind of aggregate
754755
throw new AssertionError("lines.length != exprs.length");
755756
}
756757

757758
var result = new BpLineAndId[lines.length];
758759

759-
Set<ReplayableCfBreakpointRequest> bpInfo = replayableBreakpointRequestsByAbsPath_.get(absPath.transformed);
760+
Set<ReplayableCfBreakpointRequest> bpInfo = replayableBreakpointRequestsByAbsPath_.get(serverPath);
760761

761762
for (var i = 0; i < lines.length; ++i) {
762763
final int line = lines[i];
@@ -773,20 +774,20 @@ private BpLineAndId[] freshBpLineAndIdRecordsFromLines(OriginalAndTransformedStr
773774
return nextBreakpointID();
774775
});
775776

776-
result[i] = new BpLineAndId(absPath.original, absPath.transformed, line, id, exprs[i]);
777+
result[i] = new BpLineAndId(idePath, serverPath, line, id, exprs[i]);
777778
}
778779
return result;
779780
}
780781

781-
public IBreakpoint[] bindBreakpoints(OriginalAndTransformedString absPath, int[] lines, String[] exprs) {
782-
return __internal__bindBreakpoints(absPath.transformed, freshBpLineAndIdRecordsFromLines(absPath, lines, exprs));
782+
public IBreakpoint[] bindBreakpoints(RawIdePath idePath, CanonicalServerAbsPath serverPath, int[] lines, String[] exprs) {
783+
return __internal__bindBreakpoints(serverPath, freshBpLineAndIdRecordsFromLines(idePath, serverPath, lines, exprs));
783784
}
784785

785786
/**
786787
* caller is responsible for transforming the source path into a cf path,
787788
* i.e. the IDE might say "/foo/bar/baz.cfc" but we are only aware of "/app-host-container/foo/bar/baz.cfc" or etc.
788789
*/
789-
private IBreakpoint[] __internal__bindBreakpoints(String serverAbsPath, BpLineAndId[] lineInfo) {
790+
private IBreakpoint[] __internal__bindBreakpoints(CanonicalServerAbsPath serverAbsPath, BpLineAndId[] lineInfo) {
790791
final Set<KlassMap> klassMapSet = klassMap_.get(serverAbsPath);
791792

792793
if (klassMapSet == null) {
@@ -830,10 +831,9 @@ private IBreakpoint[] __internal__bindBreakpoints(String serverAbsPath, BpLineAn
830831
}
831832

832833
garbageCollectedKlassMaps.forEach(klassMap -> {
833-
Set<ReplayableCfBreakpointRequest> z = replayableBreakpointRequestsByAbsPath_.get(klassMap.sourceName.transformed);
834+
Set<ReplayableCfBreakpointRequest> z = replayableBreakpointRequestsByAbsPath_.get(klassMap.sourceName);
834835
if (z != null) {
835-
// TODO: stronger types WRT "transformed" and "non-transformed" paths, they shouldn't both be String they should be some distinct wrapper type
836-
z.removeIf(bpReq -> bpReq.serverAbsPath.equals(klassMap.sourceName.transformed));
836+
z.removeIf(bpReq -> bpReq.serverAbsPath.equals(klassMap.sourceName));
837837
}
838838

839839
klassMapSet.remove(klassMap);
@@ -849,7 +849,7 @@ private IBreakpoint[] __internal__bindBreakpoints(String serverAbsPath, BpLineAn
849849
* Seems we're not allowed to inspect the jdwp-native id, but we can attach our own
850850
*/
851851
private IBreakpoint[] __internal__idempotentBindBreakpoints(KlassMap klassMap, BpLineAndId[] lineInfo) {
852-
final var replayable = replayableBreakpointRequestsByAbsPath_.computeIfAbsent(klassMap.sourceName.transformed, _z -> new HashSet<>());
852+
final var replayable = replayableBreakpointRequestsByAbsPath_.computeIfAbsent(klassMap.sourceName, _z -> new HashSet<>());
853853
final var result = new ArrayList<IBreakpoint>();
854854

855855
for (int i = 0; i < lineInfo.length; ++i) {
@@ -879,15 +879,15 @@ private IBreakpoint[] __internal__idempotentBindBreakpoints(KlassMap klassMap, B
879879
}
880880
}
881881

882-
replayableBreakpointRequestsByAbsPath_.put(klassMap.sourceName.transformed, replayable);
882+
replayableBreakpointRequestsByAbsPath_.put(klassMap.sourceName, replayable);
883883

884884
return result.toArray(size -> new IBreakpoint[size]);
885885
}
886886

887887
/**
888888
* returns an array of the line numbers the old breakpoints were bound to
889889
*/
890-
private void clearExistingBreakpoints(String absPath) {
890+
private void clearExistingBreakpoints(CanonicalServerAbsPath absPath) {
891891
Set<ReplayableCfBreakpointRequest> replayable = replayableBreakpointRequestsByAbsPath_.get(absPath);
892892

893893
// "just do it" in all cases
@@ -1055,7 +1055,7 @@ public String[] getTrackedCanonicalFileNames() {
10551055
final var result = new ArrayList<String>();
10561056
for (var klassMap : klassMap_.values()) {
10571057
for (var mapping : klassMap) {
1058-
result.add(mapping.sourceName.transformed);
1058+
result.add(mapping.sourceName.v);
10591059
}
10601060
}
10611061
return result.toArray(size -> new String[size]);

luceedebug/src/test/java/luceedebug/EvaluatesAnExpression.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ void a(LuceeAndDockerInfo dockerInfo) throws Throwable {
3232
.buildOrGetImage(dockerClient, dockerInfo.dockerFile)
3333
.getImageID();
3434

35+
System.out.println("container ID is ....");
3536
final String containerID = DockerUtils
3637
.getFreshDefaultContainer(
3738
dockerClient,
@@ -45,14 +46,19 @@ void a(LuceeAndDockerInfo dockerInfo) throws Throwable {
4546
)
4647
.getContainerID();
4748

49+
System.out.println(" ...." + containerID);
50+
4851
dockerClient
4952
.startContainerCmd(containerID)
5053
.exec();
5154

55+
System.out.println("started...");
5256
HostPortBindings portBindings = DockerUtils.getPublishedHostPortBindings(dockerClient, containerID);
57+
System.out.println("pbs..." + portBindings.dap + "," + portBindings.http);
5358

5459
try {
5560
LuceeUtils.pollForServerIsActive("http://localhost:" + portBindings.http + "/heartbeat.cfm");
61+
System.out.println("poll OK");
5662

5763
final var dapClient = new DapUtils.MockClient();
5864

0 commit comments

Comments
 (0)