|
18 | 18 | import java.util.regex.Pattern;
|
19 | 19 | import com.oracle.truffle.api.TruffleFile;
|
20 | 20 | import org.jcodings.Encoding;
|
| 21 | +import org.jcodings.specific.UTF8Encoding; |
21 | 22 | import org.truffleruby.core.encoding.EncodingManager;
|
22 | 23 | import org.truffleruby.core.rope.Rope;
|
23 | 24 | import org.truffleruby.core.string.StringOperations;
|
24 | 25 | import org.truffleruby.parser.lexer.RubyLexer;
|
| 26 | +import org.truffleruby.shared.TruffleRuby; |
25 | 27 |
|
26 | 28 | public class RubyFileTypeDetector implements TruffleFile.FileTypeDetector {
|
27 | 29 |
|
28 |
| - private static final String MIME_TYPE = "application/x-ruby"; |
29 |
| - |
30 |
| - private static final String[] KNOWN_RUBY_FILES = new String[]{ "Gemfile", "Rakefile", "Mavenfile" }; |
| 30 | + private static final String[] KNOWN_RUBY_FILES = new String[]{ "Gemfile", "Rakefile" }; |
31 | 31 | private static final String[] KNOWN_RUBY_SUFFIXES = new String[]{ ".rb", ".rake", ".gemspec" };
|
32 | 32 | private static final Pattern SHEBANG_REGEXP = Pattern.compile("^#! ?/usr/bin/(env +ruby|ruby).*");
|
33 | 33 |
|
34 | 34 | @Override
|
35 | 35 | public String findMimeType(TruffleFile file) throws IOException {
|
36 |
| - return findMimeAndEncodingImpl(file, null); |
37 |
| - } |
38 |
| - |
39 |
| - @Override |
40 |
| - public Charset findEncoding(TruffleFile file) throws IOException { |
41 |
| - Charset[] encodingHolder = new Charset[1]; |
42 |
| - findMimeAndEncodingImpl(file, encodingHolder); |
43 |
| - return encodingHolder[0]; |
44 |
| - } |
45 |
| - |
46 |
| - private String findMimeAndEncodingImpl(TruffleFile file, Charset[] encodingHolder) { |
47 | 36 | final String fileName = file.getName();
|
48 | 37 |
|
49 | 38 | if (fileName == null) {
|
50 | 39 | return null;
|
51 | 40 | }
|
52 | 41 |
|
53 | 42 | final String lowerCaseFileName = fileName.toLowerCase(Locale.ROOT);
|
54 |
| - String mimeType = null; |
55 | 43 |
|
56 | 44 | for (String candidate : KNOWN_RUBY_SUFFIXES) {
|
57 | 45 | if (lowerCaseFileName.endsWith(candidate)) {
|
58 |
| - mimeType = MIME_TYPE; |
59 |
| - break; |
| 46 | + return TruffleRuby.MIME_TYPE; |
60 | 47 | }
|
61 | 48 | }
|
62 | 49 |
|
63 |
| - if (mimeType == null) { |
64 |
| - for (String candidate : KNOWN_RUBY_FILES) { |
65 |
| - if (fileName.equals(candidate)) { |
66 |
| - mimeType = MIME_TYPE; |
67 |
| - break; |
68 |
| - } |
| 50 | + for (String candidate : KNOWN_RUBY_FILES) { |
| 51 | + if (fileName.equals(candidate)) { |
| 52 | + return TruffleRuby.MIME_TYPE; |
69 | 53 | }
|
70 | 54 | }
|
71 | 55 |
|
72 |
| - if (mimeType == null || encodingHolder != null) { |
73 |
| - try (BufferedReader fileContent = file.newBufferedReader(StandardCharsets.UTF_8)) { |
74 |
| - final String firstLine = fileContent.readLine(); |
75 |
| - if (firstLine != null) { |
76 |
| - String encodingCommentLine; |
77 |
| - if (SHEBANG_REGEXP.matcher(firstLine).matches()) { |
78 |
| - mimeType = mimeType == null ? MIME_TYPE : mimeType; |
79 |
| - encodingCommentLine = encodingHolder == null ? null : fileContent.readLine(); |
80 |
| - } else { |
81 |
| - encodingCommentLine = encodingHolder == null ? null : firstLine; |
82 |
| - } |
83 |
| - if (encodingCommentLine != null) { |
84 |
| - Rope encodingCommentRope = StringOperations.encodeRope(encodingCommentLine, EncodingManager.getEncoding("UTF-8")); |
85 |
| - RubyLexer.parseMagicComment(encodingCommentRope, new BiConsumer<String, Rope>() { |
86 |
| - @Override |
87 |
| - public void accept(String name, Rope value) { |
88 |
| - if (RubyLexer.isMagicEncodingComment(name)) { |
89 |
| - Encoding encoding = EncodingManager.getEncoding(value); |
90 |
| - if (encoding != null) { |
91 |
| - encodingHolder[0] = encoding.getCharset(); |
92 |
| - } |
| 56 | + try (BufferedReader fileContent = file.newBufferedReader(StandardCharsets.UTF_8)) { |
| 57 | + final String firstLine = fileContent.readLine(); |
| 58 | + if (firstLine != null && SHEBANG_REGEXP.matcher(firstLine).matches()) { |
| 59 | + return TruffleRuby.MIME_TYPE; |
| 60 | + } |
| 61 | + } catch (IOException | SecurityException e) { |
| 62 | + // Reading random files as UTF-8 could cause all sorts of errors |
| 63 | + } |
| 64 | + return null; |
| 65 | + } |
| 66 | + |
| 67 | + @Override |
| 68 | + public Charset findEncoding(TruffleFile file) throws IOException { |
| 69 | + try (BufferedReader fileContent = file.newBufferedReader(StandardCharsets.UTF_8)) { |
| 70 | + final String firstLine = fileContent.readLine(); |
| 71 | + if (firstLine != null) { |
| 72 | + String encodingCommentLine; |
| 73 | + if (SHEBANG_REGEXP.matcher(firstLine).matches()) { |
| 74 | + encodingCommentLine = fileContent.readLine(); |
| 75 | + } else { |
| 76 | + encodingCommentLine = firstLine; |
| 77 | + } |
| 78 | + if (encodingCommentLine != null) { |
| 79 | + Rope encodingCommentRope = StringOperations.encodeRope(encodingCommentLine, UTF8Encoding.INSTANCE); |
| 80 | + Charset[] encodingHolder = new Charset[1]; |
| 81 | + RubyLexer.parseMagicComment(encodingCommentRope, new BiConsumer<String, Rope>() { |
| 82 | + @Override |
| 83 | + public void accept(String name, Rope value) { |
| 84 | + if (RubyLexer.isMagicEncodingComment(name)) { |
| 85 | + Encoding encoding = EncodingManager.getEncoding(value); |
| 86 | + if (encoding != null) { |
| 87 | + encodingHolder[0] = encoding.getCharset(); |
93 | 88 | }
|
94 | 89 | }
|
95 |
| - }); |
96 |
| - } |
| 90 | + } |
| 91 | + }); |
| 92 | + return encodingHolder[0]; |
97 | 93 | }
|
98 |
| - } catch (IOException | SecurityException e) { |
99 |
| - // Reading random files as UTF-8 could cause all sorts of errors |
100 | 94 | }
|
| 95 | + } catch (IOException | SecurityException e) { |
| 96 | + // Reading random files as UTF-8 could cause all sorts of errors |
101 | 97 | }
|
102 |
| - |
103 |
| - return mimeType; |
| 98 | + return null; |
104 | 99 | }
|
105 |
| - |
106 | 100 | }
|
0 commit comments