Mercurial > hg > graal-jvmci-8
comparison graal/com.oracle.truffle.api/src/com/oracle/truffle/api/source/SourceManager.java @ 13564:35f637594acc
Truffle: refinements in the management of source information: a new marker interface for empty SourceSections and fix a bug that kept modified source files from being reloaded.
author | Michael Van De Vanter <michael.van.de.vanter@oracle.com> |
---|---|
date | Tue, 07 Jan 2014 18:21:20 -0800 |
parents | f76593e3fedb |
children | f150a67b99e3 |
comparison
equal
deleted
inserted
replaced
13563:fb846424299f | 13564:35f637594acc |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. Oracle designates this | 7 * published by the Free Software Foundation. Oracle designates this |
45 * </ul> | 45 * </ul> |
46 */ | 46 */ |
47 public final class SourceManager { | 47 public final class SourceManager { |
48 | 48 |
49 // Only files and fake files are indexed. | 49 // Only files and fake files are indexed. |
50 private final Map<String, SourceImpl> sourceMap = new HashMap<>(); | 50 private final Map<String, SourceImpl> pathToSource = new HashMap<>(); |
51 | 51 |
52 public SourceManager() { | 52 public SourceManager() { |
53 | 53 |
54 } | 54 } |
55 | 55 |
56 /** | 56 /** |
57 * Gets the canonical representation of a source file, whose contents will be read lazily and | 57 * Gets the canonical representation of a source file, whose contents will be read lazily and |
58 * then cached. | 58 * then cached. |
59 * | 59 * |
60 * @param reset forces any existing {@link Source} cache to be cleared, forcing a re-read. | 60 * @param reset forces any existing {@link Source} cache to be cleared, forcing a re-read |
61 */ | 61 */ |
62 public Source get(String fileName, boolean reset) { | 62 public Source get(String fileName, boolean reset) { |
63 SourceImpl source = sourceMap.get(fileName); | 63 |
64 SourceImpl source = pathToSource.get(fileName); | |
64 if (source == null) { | 65 if (source == null) { |
65 String path = findPath(fileName); | 66 final File file = new File(fileName); |
66 if (path == null) { | 67 String path = null; |
67 throw new RuntimeException("Can't find file " + fileName); | 68 if (file.exists()) { |
68 } | 69 try { |
69 source = sourceMap.get(path); | 70 path = file.getCanonicalPath(); |
71 } catch (IOException e) { | |
72 throw new RuntimeException("Can't find file " + fileName); | |
73 } | |
74 } | |
75 source = pathToSource.get(path); | |
70 if (source == null) { | 76 if (source == null) { |
71 source = new FileSourceImpl(fileName, path); | 77 source = new FileSourceImpl(file, fileName, path); |
72 sourceMap.put(path, source); | 78 pathToSource.put(path, source); |
73 } | 79 } |
74 } else { | 80 } |
75 if (reset) { | 81 if (reset) { |
76 source.reset(); | 82 source.reset(); |
77 } | |
78 } | 83 } |
79 return source; | 84 return source; |
80 } | 85 } |
81 | 86 |
82 /** | 87 /** |
109 * Creates a source from literal text, but which acts as a file and can be retrieved by name | 114 * Creates a source from literal text, but which acts as a file and can be retrieved by name |
110 * (unlike other literal sources); intended for testing. | 115 * (unlike other literal sources); intended for testing. |
111 */ | 116 */ |
112 public Source getFakeFile(String name, String code) { | 117 public Source getFakeFile(String name, String code) { |
113 final SourceImpl source = new LiteralSourceImpl(name, code); | 118 final SourceImpl source = new LiteralSourceImpl(name, code); |
114 sourceMap.put(name, source); | 119 pathToSource.put(name, source); |
115 return source; | 120 return source; |
116 } | |
117 | |
118 // If it names a real file, get the (canonical) normalized absolute path. | |
119 private static String findPath(String name) { | |
120 final File file = new File(name); | |
121 if (file.exists()) { | |
122 try { | |
123 return file.getCanonicalPath(); | |
124 } catch (IOException e) { | |
125 } | |
126 } | |
127 return null; | |
128 } | 121 } |
129 | 122 |
130 private static String readCode(Reader reader) throws IOException { | 123 private static String readCode(Reader reader) throws IOException { |
131 final StringBuilder builder = new StringBuilder(); | 124 final StringBuilder builder = new StringBuilder(); |
132 final char[] buffer = new char[1024]; | 125 final char[] buffer = new char[1024]; |
140 } | 133 } |
141 | 134 |
142 return builder.toString(); | 135 return builder.toString(); |
143 } | 136 } |
144 | 137 |
145 // TODO (mlvdv) make this private once some related code changes propagate | 138 private abstract static class SourceImpl implements Source { |
146 public abstract static class SourceImpl implements Source { | |
147 | 139 |
148 protected TextMap textMap = null; | 140 protected TextMap textMap = null; |
149 | 141 |
150 protected abstract void reset(); | 142 protected abstract void reset(); |
151 | 143 |
265 | 257 |
266 } | 258 } |
267 | 259 |
268 private static class FileSourceImpl extends SourceImpl { | 260 private static class FileSourceImpl extends SourceImpl { |
269 | 261 |
262 private final File file; | |
270 private final String name; // Name used originally to describe the source | 263 private final String name; // Name used originally to describe the source |
271 private String code = null; | |
272 private final String path; // Normalized path description of an actual file | 264 private final String path; // Normalized path description of an actual file |
273 private boolean readAttempted; | 265 |
274 | 266 private String code = null; // A cache of the file's contents |
275 public FileSourceImpl(String name, String path) { | 267 private long timeStamp; // timestamp of the cache in the file system |
268 | |
269 public FileSourceImpl(File file, String name, String path) { | |
270 this.file = file; | |
276 this.name = name; | 271 this.name = name; |
277 this.path = path; | 272 this.path = path; |
278 this.readAttempted = false; | |
279 | |
280 } | 273 } |
281 | 274 |
282 @Override | 275 @Override |
283 public String getName() { | 276 public String getName() { |
284 return name; | 277 return name; |
285 } | 278 } |
286 | 279 |
287 @Override | 280 @Override |
288 public String getCode() { | 281 public String getCode() { |
289 if (code == null && !readAttempted) { | 282 if (code == null || timeStamp != file.lastModified()) { |
290 readAttempted = true; | |
291 try { | 283 try { |
292 code = readCode(getReader()); | 284 code = readCode(getReader()); |
285 timeStamp = file.lastModified(); | |
293 } catch (IOException e) { | 286 } catch (IOException e) { |
294 } | 287 } |
295 } | 288 } |
296 return code; | 289 return code; |
297 } | 290 } |
301 return path; | 294 return path; |
302 } | 295 } |
303 | 296 |
304 @Override | 297 @Override |
305 public Reader getReader() { | 298 public Reader getReader() { |
306 if (code != null) { | 299 if (code != null && timeStamp == file.lastModified()) { |
307 return new StringReader(code); | 300 return new StringReader(code); |
308 } | 301 } |
309 try { | 302 try { |
310 return new BufferedReader(new FileReader(path)); | 303 return new FileReader(file); |
311 } catch (FileNotFoundException e) { | 304 } catch (FileNotFoundException e) { |
312 throw new RuntimeException("Can't find file " + path); | 305 throw new RuntimeException("Can't find file " + path); |
313 } | 306 } |
314 } | 307 } |
315 | 308 |
316 @Override | 309 @Override |
317 protected void reset() { | 310 protected void reset() { |
318 this.code = null; | 311 this.code = null; |
319 this.readAttempted = false; | |
320 } | 312 } |
321 | 313 |
322 } | 314 } |
323 | 315 |
324 } | 316 } |