53
53
import java .util .HashMap ;
54
54
import java .util .Map ;
55
55
import java .util .Objects ;
56
- import java .util .function .BiConsumer ;
57
56
58
57
import com .oracle .truffle .api .CompilerDirectives ;
59
58
import com .oracle .truffle .api .TruffleSafepoint ;
@@ -451,7 +450,7 @@ protected void setTokenInfo(String name, TruffleString value) {
451
450
452
451
protected void setEncoding (TruffleString name ) {
453
452
final RubyContext context = parserSupport .getConfiguration ().getContext ();
454
- var nameString = name .toJavaStringUncached ();
453
+ String nameString = name .toJavaStringUncached ();
455
454
final Encoding newEncoding = EncodingManager .getEncoding (nameString );
456
455
457
456
if (newEncoding == null ) {
@@ -1139,24 +1138,11 @@ public static TStringWithEncoding createSourceTStringBasedOnMagicEncodingComment
1139
1138
return source ;
1140
1139
}
1141
1140
1141
+ /** Peak in source to see if there is a magic encoding comment. This is used by eval() & friends to know the actual
1142
+ * encoding of the source code, and be able to convert to a Java String faithfully. */
1142
1143
public static RubyEncoding parseMagicEncodingComment (TStringWithEncoding source ) {
1143
1144
var encoding = new Memo <RubyEncoding >(null );
1144
1145
1145
- parseMagicComment (source , (name , value ) -> {
1146
- if (RubyLexer .isMagicEncodingComment (name )) {
1147
- Encoding jcoding = EncodingManager .getEncoding (value );
1148
- if (jcoding != null ) {
1149
- encoding .set (Encodings .getBuiltInEncoding (jcoding ));
1150
- }
1151
- }
1152
- });
1153
-
1154
- return encoding .get ();
1155
- }
1156
-
1157
- /** Peak in source to see if there is a magic comment. This is used by eval() & friends to know the actual encoding
1158
- * of the source code, and be able to convert to a Java String faithfully. */
1159
- public static void parseMagicComment (TStringWithEncoding source , BiConsumer <String , String > magicCommentHandler ) {
1160
1146
var bytes = source .getInternalByteArray ();
1161
1147
final int length = bytes .getLength ();
1162
1148
int start = 0 ;
@@ -1180,12 +1166,32 @@ public static void parseMagicComment(TStringWithEncoding source, BiConsumer<Stri
1180
1166
}
1181
1167
int magicLineLength = endOfMagicLine - magicLineStart ;
1182
1168
1183
- parser_magic_comment (source , magicLineStart , magicLineLength ,
1169
+ TStringWithEncoding magicLine = source .substring (magicLineStart , magicLineLength );
1170
+
1171
+ parser_magic_comment (magicLine , 0 , magicLineLength ,
1184
1172
(name , value ) -> {
1185
- magicCommentHandler .accept (name , value .toJavaStringUncached ());
1186
- return isKnownMagicComment (name );
1173
+ if (RubyLexer .isMagicEncodingComment (name )) {
1174
+ Encoding jcoding = EncodingManager .getEncoding (value .toJavaStringUncached ());
1175
+ if (jcoding != null ) {
1176
+ encoding .set (Encodings .getBuiltInEncoding (jcoding ));
1177
+ return true ;
1178
+ }
1179
+ }
1180
+ return false ;
1187
1181
});
1182
+
1183
+ if (encoding .get () == null ) {
1184
+ TruffleString encodingName = get_file_encoding (magicLine );
1185
+ if (encodingName != null ) {
1186
+ Encoding jcoding = EncodingManager .getEncoding (encodingName .toJavaStringUncached ());
1187
+ if (jcoding != null ) {
1188
+ encoding .set (Encodings .getBuiltInEncoding (jcoding ));
1189
+ }
1190
+ }
1191
+ }
1188
1192
}
1193
+
1194
+ return encoding .get ();
1189
1195
}
1190
1196
1191
1197
// MRI: parser_magic_comment
@@ -3339,18 +3345,21 @@ public void setCurrentArg(TruffleString current_arg) {
3339
3345
3340
3346
public void setEncoding (Encoding jcoding ) {
3341
3347
if (jcoding != encoding .jcoding ) {
3342
- throw CompilerDirectives .shouldNotReachHere ("the encoding must already be set correctly in RubySource" );
3348
+ throw CompilerDirectives
3349
+ .shouldNotReachHere ("the encoding must already be set correctly in RubySource for " + getFile ());
3343
3350
}
3344
3351
}
3345
3352
3346
- protected void set_file_encoding (int str , int send ) {
3353
+ private static TruffleString get_file_encoding (TStringWithEncoding magicLine ) {
3354
+ int str = 0 ;
3355
+ int send = magicLine .byteLength ();
3347
3356
boolean sep = false ;
3348
3357
for (;;) {
3349
3358
if (send - str <= 6 ) {
3350
- return ;
3359
+ return null ;
3351
3360
}
3352
3361
3353
- switch (p (str + 6 )) {
3362
+ switch (magicLine . get (str + 6 )) {
3354
3363
case 'C' :
3355
3364
case 'c' :
3356
3365
str += 6 ;
@@ -3382,13 +3391,12 @@ protected void set_file_encoding(int str, int send) {
3382
3391
break ;
3383
3392
default :
3384
3393
str += 6 ;
3385
- if (Character .isSpaceChar (p (str ))) {
3394
+ if (Character .isSpaceChar (magicLine . get (str ))) {
3386
3395
break ;
3387
3396
}
3388
3397
continue ;
3389
3398
}
3390
- if (src .parserRopeOperations .makeShared (lexb , str - 6 , 6 ).toJavaStringUncached ()
3391
- .equalsIgnoreCase ("coding" )) {
3399
+ if (magicLine .substring (str - 6 , 6 ).toJavaString ().equalsIgnoreCase ("coding" )) {
3392
3400
break ;
3393
3401
}
3394
3402
}
@@ -3397,24 +3405,33 @@ protected void set_file_encoding(int str, int send) {
3397
3405
do {
3398
3406
str ++;
3399
3407
if (str >= send ) {
3400
- return ;
3408
+ return null ;
3401
3409
}
3402
- } while (Character .isSpaceChar (p (str )));
3410
+ } while (Character .isSpaceChar (magicLine . get (str )));
3403
3411
if (sep ) {
3404
3412
break ;
3405
3413
}
3406
3414
3407
- if (p (str ) != '=' && p (str ) != ':' ) {
3408
- return ;
3415
+ if (magicLine . get (str ) != '=' && magicLine . get (str ) != ':' ) {
3416
+ return null ;
3409
3417
}
3410
3418
sep = true ;
3411
3419
str ++;
3412
3420
}
3413
3421
3414
3422
int beg = str ;
3415
- while ((p (str ) == '-' || p (str ) == '_' || Character .isLetterOrDigit (p (str ))) && ++str < send ) {
3423
+ while ((magicLine .get (str ) == '-' || magicLine .get (str ) == '_' ||
3424
+ Character .isLetterOrDigit (magicLine .get (str ))) && ++str < send ) {
3425
+ }
3426
+ return magicLine .substring (beg , str - beg ).tstring ;
3427
+ }
3428
+
3429
+ protected void set_file_encoding (int str , int send ) {
3430
+ TStringWithEncoding magicLine = new TStringWithEncoding (lexb , encoding ).substring (str , send - str );
3431
+ TruffleString encoding = get_file_encoding (magicLine );
3432
+ if (encoding != null ) {
3433
+ setEncoding (encoding );
3416
3434
}
3417
- setEncoding (src .parserRopeOperations .makeShared (lexb , beg , str - beg ));
3418
3435
}
3419
3436
3420
3437
public void setHeredocLineIndent (int heredoc_line_indent ) {
0 commit comments