2 // Use of this source code is governed by a BSD-style license that can be |
2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. |
3 // found in the LICENSE file. |
4 |
4 |
5 package org.chromium.sdk.internal; |
5 package org.chromium.sdk.internal; |
6 |
6 |
|
7 import java.util.Collections; |
7 import java.util.List; |
8 import java.util.List; |
8 |
9 import java.util.logging.Level; |
|
10 import java.util.logging.Logger; |
|
11 |
|
12 import org.chromium.sdk.LiveEditDebugEventListener; |
|
13 import org.chromium.sdk.LiveEditExtension; |
9 import org.chromium.sdk.Script; |
14 import org.chromium.sdk.Script; |
|
15 import org.chromium.sdk.SyncCallback; |
|
16 import org.chromium.sdk.UpdatableScript; |
|
17 import org.chromium.sdk.internal.protocol.ChangeLiveBody; |
|
18 import org.chromium.sdk.internal.protocol.SuccessCommandResponse; |
10 import org.chromium.sdk.internal.protocol.data.ScriptHandle; |
19 import org.chromium.sdk.internal.protocol.data.ScriptHandle; |
11 import org.chromium.sdk.internal.protocol.data.SomeHandle; |
20 import org.chromium.sdk.internal.protocol.data.SomeHandle; |
12 import org.chromium.sdk.internal.protocolparser.JsonProtocolParseException; |
21 import org.chromium.sdk.internal.protocolparser.JsonProtocolParseException; |
|
22 import org.chromium.sdk.internal.tools.v8.V8CommandCallbackBase; |
|
23 import org.chromium.sdk.internal.tools.v8.V8CommandProcessor; |
|
24 import org.chromium.sdk.internal.tools.v8.V8Helper; |
13 import org.chromium.sdk.internal.tools.v8.V8ProtocolUtil; |
25 import org.chromium.sdk.internal.tools.v8.V8ProtocolUtil; |
|
26 import org.chromium.sdk.internal.tools.v8.V8Helper.ScriptLoadCallback; |
|
27 import org.chromium.sdk.internal.tools.v8.request.ChangeLiveMessage; |
14 |
28 |
15 /** |
29 /** |
16 * An objects that holds data for a "script" which is a part of a resource |
30 * An objects that holds data for a "script" which is a part of a resource |
17 * loaded into the browser, identified by its original document URL, line offset |
31 * loaded into the browser, identified by its original document URL, line offset |
18 * in the original document, and the line count this script spans. |
32 * in the original document, and the line count this script spans. |
19 */ |
33 */ |
20 public class ScriptImpl implements Script { |
34 public class ScriptImpl implements Script, UpdatableScript { |
|
35 |
|
36 /** The class logger. */ |
|
37 private static final Logger LOGGER = Logger.getLogger(ScriptImpl.class.getName()); |
21 |
38 |
22 /** |
39 /** |
23 * An object containing data that uniquely identify a V8 script chunk. |
40 * An object containing data that uniquely identify a V8 script chunk. |
24 */ |
41 */ |
25 public static class Descriptor { |
42 public static class Descriptor { |
27 |
44 |
28 public final String name; |
45 public final String name; |
29 |
46 |
30 public final int lineOffset; |
47 public final int lineOffset; |
31 |
48 |
|
49 public final int columnOffset; |
|
50 |
32 public final int endLine; |
51 public final int endLine; |
33 |
52 |
34 public final long id; |
53 public final long id; |
35 |
54 |
36 public Descriptor(Type type, long id, String name, int lineOffset, int lineCount) { |
55 public Descriptor(Type type, long id, String name, int lineOffset, int columnOffset, |
|
56 int lineCount) { |
37 this.type = type; |
57 this.type = type; |
38 this.id = id; |
58 this.id = id; |
39 this.name = name; |
59 this.name = name; |
40 this.lineOffset = lineOffset; |
60 this.lineOffset = lineOffset; |
|
61 this.columnOffset = columnOffset; |
41 this.endLine = lineOffset + lineCount - 1; |
62 this.endLine = lineOffset + lineCount - 1; |
42 } |
63 } |
43 |
64 |
44 @Override |
65 @Override |
45 public int hashCode() { |
66 public int hashCode() { |
46 return |
67 return |
47 name != null ? name.hashCode() : (int) id * 0x101 + |
68 name != null ? name.hashCode() : (int) id * 0x101 + |
48 lineOffset * 0x1001 + |
69 lineOffset * 0x1001 + columnOffset * 0x10001 + |
49 endLine * 0x10001; |
70 endLine * 0x100001; |
50 } |
71 } |
51 |
72 |
52 @Override |
73 @Override |
53 public boolean equals(Object obj) { |
74 public boolean equals(Object obj) { |
54 if (obj == this) { |
75 if (obj == this) { |
59 } |
80 } |
60 Descriptor that = (Descriptor) obj; |
81 Descriptor that = (Descriptor) obj; |
61 // The id equality is stronger than the name equality. |
82 // The id equality is stronger than the name equality. |
62 return this.id == that.id && |
83 return this.id == that.id && |
63 this.lineOffset == that.lineOffset && |
84 this.lineOffset == that.lineOffset && |
|
85 this.columnOffset == that.columnOffset && |
64 this.endLine == that.endLine; |
86 this.endLine == that.endLine; |
65 } |
87 } |
66 |
88 |
67 public static Descriptor forResponse(ScriptHandle script, List<SomeHandle> refs, |
89 public static Descriptor forResponse(ScriptHandle script, List<SomeHandle> refs, |
68 V8ContextFilter contextFilter) { |
90 V8ContextFilter contextFilter) { |
76 Type type = V8ProtocolUtil.getScriptType(scriptType); |
98 Type type = V8ProtocolUtil.getScriptType(scriptType); |
77 if (type == null) { |
99 if (type == null) { |
78 return null; |
100 return null; |
79 } |
101 } |
80 int lineOffset = (int) script.lineOffset(); |
102 int lineOffset = (int) script.lineOffset(); |
|
103 int columnOffset = (int) script.columnOffset(); |
81 int lineCount = (int) script.lineCount(); |
104 int lineCount = (int) script.lineCount(); |
82 int id = V8ProtocolUtil.getScriptIdFromResponse(script).intValue(); |
105 int id = V8ProtocolUtil.getScriptIdFromResponse(script).intValue(); |
83 return new Descriptor(type, id, name, lineOffset, lineCount); |
106 return new Descriptor(type, id, name, lineOffset, columnOffset, lineCount); |
84 } catch (Exception e) { |
107 } catch (Exception e) { |
85 // not a script object has been passed in |
108 // not a script object has been passed in |
86 return null; |
109 return null; |
87 } |
110 } |
88 } |
111 } |
90 |
113 |
91 private final Descriptor descriptor; |
114 private final Descriptor descriptor; |
92 |
115 |
93 private volatile String source = null; |
116 private volatile String source = null; |
94 |
117 |
|
118 private final DebugSession debugSession; |
|
119 |
95 /** |
120 /** |
96 * @param descriptor of the script retrieved from a "scripts" response |
121 * @param descriptor of the script retrieved from a "scripts" response |
97 */ |
122 */ |
98 public ScriptImpl(Descriptor descriptor) { |
123 public ScriptImpl(Descriptor descriptor, DebugSession debugSession) { |
99 this.descriptor = descriptor; |
124 this.descriptor = descriptor; |
100 this.source = null; |
125 this.source = null; |
|
126 this.debugSession = debugSession; |
101 } |
127 } |
102 |
128 |
103 public Type getType() { |
129 public Type getType() { |
104 return this.descriptor.type; |
130 return this.descriptor.type; |
105 } |
131 } |
110 |
136 |
111 public int getStartLine() { |
137 public int getStartLine() { |
112 return descriptor.lineOffset; |
138 return descriptor.lineOffset; |
113 } |
139 } |
114 |
140 |
|
141 public int getStartColumn() { |
|
142 return descriptor.columnOffset; |
|
143 } |
|
144 |
115 public int getEndLine() { |
145 public int getEndLine() { |
116 return descriptor.endLine; |
146 return descriptor.endLine; |
117 } |
147 } |
118 |
148 |
119 public long getId() { |
149 public long getId() { |
128 return source != null; |
158 return source != null; |
129 } |
159 } |
130 |
160 |
131 public void setSource(String source) { |
161 public void setSource(String source) { |
132 this.source = source; |
162 this.source = source; |
|
163 } |
|
164 |
|
165 public void setSourceOnRemote(String newSource, UpdateCallback callback, |
|
166 SyncCallback syncCallback) { |
|
167 V8CommandProcessor.V8HandlerCallback v8Callback = createScriptUpdateCallback(callback); |
|
168 debugSession.sendMessageAsync(new ChangeLiveMessage(getId(), newSource), |
|
169 true, v8Callback, syncCallback); |
|
170 } |
|
171 |
|
172 private V8CommandProcessor.V8HandlerCallback createScriptUpdateCallback( |
|
173 final UpdateCallback callback) { |
|
174 if (callback == null) { |
|
175 return null; |
|
176 } |
|
177 return new V8CommandCallbackBase() { |
|
178 @Override |
|
179 public void success(SuccessCommandResponse successResponse) { |
|
180 ChangeLiveBody body; |
|
181 try { |
|
182 body = successResponse.getBody().asChangeLiveBody(); |
|
183 } catch (JsonProtocolParseException e) { |
|
184 throw new RuntimeException(e); |
|
185 } |
|
186 |
|
187 ScriptLoadCallback scriptCallback = new ScriptLoadCallback() { |
|
188 public void failure(String message) { |
|
189 LOGGER.log(Level.SEVERE, |
|
190 "Failed to reload script after LiveEdit script update; " + message); |
|
191 } |
|
192 public void success() { |
|
193 LiveEditDebugEventListener listener = |
|
194 LiveEditExtension.castToLiveEditListener(debugSession.getDebugEventListener()); |
|
195 if (listener != null) { |
|
196 listener.scriptContentChanged(ScriptImpl.this); |
|
197 } |
|
198 } |
|
199 }; |
|
200 V8Helper.reloadScriptAsync(debugSession, Collections.singletonList(getId()), |
|
201 scriptCallback, null); |
|
202 |
|
203 debugSession.recreateCurrentContext(); |
|
204 |
|
205 callback.success(body.getChangeLog()); |
|
206 } |
|
207 |
|
208 @Override |
|
209 public void failure(String message) { |
|
210 callback.failure(message); |
|
211 } |
|
212 }; |
133 } |
213 } |
134 |
214 |
135 @Override |
215 @Override |
136 public int hashCode() { |
216 public int hashCode() { |
137 return |
217 return |