herb 0.9.2-arm-linux-gnu → 0.9.4-arm-linux-gnu
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +2 -0
- data/config.yml +125 -0
- data/ext/herb/error_helpers.c +172 -2
- data/ext/herb/extconf.rb +6 -0
- data/ext/herb/extension.c +16 -2
- data/ext/herb/extension_helpers.c +6 -5
- data/ext/herb/extension_helpers.h +4 -4
- data/ext/herb/nodes.c +89 -3
- data/lib/herb/3.0/herb.so +0 -0
- data/lib/herb/3.1/herb.so +0 -0
- data/lib/herb/3.2/herb.so +0 -0
- data/lib/herb/3.3/herb.so +0 -0
- data/lib/herb/3.4/herb.so +0 -0
- data/lib/herb/4.0/herb.so +0 -0
- data/lib/herb/ast/erb_content_node.rb +32 -0
- data/lib/herb/ast/nodes.rb +244 -3
- data/lib/herb/cli.rb +12 -2
- data/lib/herb/engine/compiler.rb +166 -75
- data/lib/herb/engine/validators/security_validator.rb +40 -0
- data/lib/herb/engine.rb +3 -0
- data/lib/herb/errors.rb +268 -0
- data/lib/herb/parser_options.rb +7 -2
- data/lib/herb/project.rb +58 -17
- data/lib/herb/version.rb +1 -1
- data/lib/herb/visitor.rb +82 -0
- data/lib/herb.rb +1 -0
- data/sig/herb/ast/erb_content_node.rbs +13 -0
- data/sig/herb/ast/nodes.rbs +98 -2
- data/sig/herb/engine/compiler.rbs +31 -2
- data/sig/herb/engine/validators/security_validator.rbs +4 -0
- data/sig/herb/engine.rbs +3 -0
- data/sig/herb/errors.rbs +122 -0
- data/sig/herb/parser_options.rbs +6 -2
- data/sig/herb/visitor.rbs +12 -0
- data/sig/serialized_ast_errors.rbs +29 -0
- data/sig/serialized_ast_nodes.rbs +19 -0
- data/src/analyze/action_view/attribute_extraction_helpers.c +420 -91
- data/src/analyze/action_view/image_tag.c +87 -0
- data/src/analyze/action_view/javascript_include_tag.c +22 -12
- data/src/analyze/action_view/registry.c +6 -3
- data/src/analyze/action_view/tag.c +19 -2
- data/src/analyze/action_view/tag_helper_node_builders.c +105 -36
- data/src/analyze/action_view/tag_helpers.c +792 -44
- data/src/analyze/analyze.c +167 -13
- data/src/analyze/{helpers.c → analyze_helpers.c} +1 -1
- data/src/analyze/analyzed_ruby.c +1 -1
- data/src/analyze/builders.c +11 -8
- data/src/analyze/conditional_elements.c +6 -7
- data/src/analyze/conditional_open_tags.c +6 -7
- data/src/analyze/control_type.c +4 -2
- data/src/analyze/invalid_structures.c +5 -5
- data/src/analyze/missing_end.c +2 -2
- data/src/analyze/parse_errors.c +47 -6
- data/src/analyze/prism_annotate.c +7 -7
- data/src/analyze/render_nodes.c +6 -26
- data/src/analyze/strict_locals.c +651 -0
- data/src/analyze/transform.c +7 -0
- data/src/{ast_node.c → ast/ast_node.c} +8 -8
- data/src/{ast_nodes.c → ast/ast_nodes.c} +82 -11
- data/src/{ast_pretty_print.c → ast/ast_pretty_print.c} +113 -9
- data/src/{pretty_print.c → ast/pretty_print.c} +9 -9
- data/src/errors.c +398 -8
- data/src/extract.c +5 -5
- data/src/herb.c +15 -5
- data/src/include/analyze/action_view/attribute_extraction_helpers.h +3 -1
- data/src/include/analyze/action_view/tag_helper_handler.h +3 -3
- data/src/include/analyze/action_view/tag_helper_node_builders.h +34 -5
- data/src/include/analyze/action_view/tag_helpers.h +4 -3
- data/src/include/analyze/analyze.h +12 -5
- data/src/include/analyze/analyzed_ruby.h +2 -2
- data/src/include/analyze/builders.h +4 -4
- data/src/include/analyze/conditional_elements.h +2 -2
- data/src/include/analyze/conditional_open_tags.h +2 -2
- data/src/include/analyze/control_type.h +1 -1
- data/src/include/analyze/helpers.h +2 -2
- data/src/include/analyze/invalid_structures.h +1 -1
- data/src/include/analyze/prism_annotate.h +2 -2
- data/src/include/analyze/render_nodes.h +1 -1
- data/src/include/analyze/strict_locals.h +11 -0
- data/src/include/{ast_node.h → ast/ast_node.h} +4 -4
- data/src/include/{ast_nodes.h → ast/ast_nodes.h} +38 -14
- data/src/include/{ast_pretty_print.h → ast/ast_pretty_print.h} +3 -3
- data/src/include/{pretty_print.h → ast/pretty_print.h} +4 -4
- data/src/include/errors.h +65 -7
- data/src/include/extract.h +2 -2
- data/src/include/herb.h +5 -5
- data/src/include/{lex_helpers.h → lexer/lex_helpers.h} +5 -5
- data/src/include/{lexer.h → lexer/lexer.h} +1 -1
- data/src/include/{lexer_peek_helpers.h → lexer/lexer_peek_helpers.h} +2 -2
- data/src/include/{lexer_struct.h → lexer/lexer_struct.h} +2 -2
- data/src/include/{token.h → lexer/token.h} +3 -3
- data/src/include/{token_matchers.h → lexer/token_matchers.h} +1 -1
- data/src/include/{token_struct.h → lexer/token_struct.h} +3 -3
- data/src/include/{util → lib}/hb_foreach.h +1 -1
- data/src/include/{util → lib}/hb_string.h +5 -1
- data/src/include/{location.h → location/location.h} +1 -1
- data/src/include/parser/dot_notation.h +12 -0
- data/src/include/{parser.h → parser/parser.h} +11 -4
- data/src/include/{parser_helpers.h → parser/parser_helpers.h} +6 -6
- data/src/include/{prism_context.h → prism/prism_context.h} +2 -2
- data/src/include/{prism_helpers.h → prism/prism_helpers.h} +6 -6
- data/src/include/{html_util.h → util/html_util.h} +1 -1
- data/src/include/util/ruby_util.h +9 -0
- data/src/include/{utf8.h → util/utf8.h} +1 -1
- data/src/include/{util.h → util/util.h} +1 -1
- data/src/include/version.h +1 -1
- data/src/include/visitor.h +3 -3
- data/src/{lexer_peek_helpers.c → lexer/lexer_peek_helpers.c} +3 -3
- data/src/{token.c → lexer/token.c} +8 -8
- data/src/{token_matchers.c → lexer/token_matchers.c} +2 -2
- data/src/lexer.c +6 -6
- data/src/{util → lib}/hb_allocator.c +2 -2
- data/src/{util → lib}/hb_arena.c +1 -1
- data/src/{util → lib}/hb_arena_debug.c +2 -2
- data/src/{util → lib}/hb_array.c +2 -2
- data/src/{util → lib}/hb_buffer.c +2 -2
- data/src/{util → lib}/hb_narray.c +1 -1
- data/src/{util → lib}/hb_string.c +2 -2
- data/src/{location.c → location/location.c} +2 -2
- data/src/{position.c → location/position.c} +2 -2
- data/src/{range.c → location/range.c} +1 -1
- data/src/main.c +11 -11
- data/src/parser/dot_notation.c +100 -0
- data/src/{parser_match_tags.c → parser/match_tags.c} +34 -5
- data/src/{parser_helpers.c → parser/parser_helpers.c} +10 -10
- data/src/parser.c +68 -32
- data/src/{prism_helpers.c → prism/prism_helpers.c} +7 -7
- data/src/{ruby_parser.c → prism/ruby_parser.c} +1 -1
- data/src/{html_util.c → util/html_util.c} +4 -4
- data/src/{io.c → util/io.c} +3 -3
- data/src/util/ruby_util.c +42 -0
- data/src/{utf8.c → util/utf8.c} +2 -2
- data/src/{util.c → util/util.c} +4 -4
- data/src/visitor.c +35 -3
- data/templates/ext/herb/error_helpers.c.erb +2 -2
- data/templates/ext/herb/nodes.c.erb +1 -1
- data/templates/java/error_helpers.c.erb +1 -1
- data/templates/java/error_helpers.h.erb +2 -2
- data/templates/java/nodes.c.erb +4 -4
- data/templates/java/nodes.h.erb +1 -1
- data/templates/javascript/packages/node/extension/error_helpers.cpp.erb +4 -4
- data/templates/javascript/packages/node/extension/nodes.cpp.erb +4 -4
- data/templates/lib/herb/visitor.rb.erb +14 -0
- data/templates/src/analyze/missing_end.c.erb +2 -2
- data/templates/src/{ast_nodes.c.erb → ast/ast_nodes.c.erb} +9 -9
- data/templates/src/{ast_pretty_print.c.erb → ast/ast_pretty_print.c.erb} +8 -8
- data/templates/src/errors.c.erb +8 -8
- data/templates/src/include/{ast_nodes.h.erb → ast/ast_nodes.h.erb} +11 -12
- data/templates/src/include/{ast_pretty_print.h.erb → ast/ast_pretty_print.h.erb} +2 -2
- data/templates/src/include/errors.h.erb +7 -7
- data/templates/src/{parser_match_tags.c.erb → parser/match_tags.c.erb} +4 -4
- data/templates/src/visitor.c.erb +3 -3
- data/templates/wasm/error_helpers.cpp.erb +4 -4
- data/templates/wasm/nodes.cpp.erb +5 -5
- metadata +76 -68
- data/src/include/element_source.h +0 -10
- /data/src/include/{util → lib}/hb_allocator.h +0 -0
- /data/src/include/{util → lib}/hb_arena.h +0 -0
- /data/src/include/{util → lib}/hb_arena_debug.h +0 -0
- /data/src/include/{util → lib}/hb_array.h +0 -0
- /data/src/include/{util → lib}/hb_buffer.h +0 -0
- /data/src/include/{util → lib}/hb_narray.h +0 -0
- /data/src/include/{util → lib}/string.h +0 -0
- /data/src/include/{position.h → location/position.h} +0 -0
- /data/src/include/{range.h → location/range.h} +0 -0
- /data/src/include/{herb_prism_node.h → prism/herb_prism_node.h} +0 -0
- /data/src/include/{prism_serialized.h → prism/prism_serialized.h} +0 -0
- /data/src/include/{ruby_parser.h → prism/ruby_parser.h} +0 -0
- /data/src/include/{io.h → util/io.h} +0 -0
- /data/templates/src/include/{util → lib}/hb_foreach.h.erb +0 -0
data/lib/herb/errors.rb
CHANGED
|
@@ -1258,5 +1258,273 @@ module Herb
|
|
|
1258
1258
|
end
|
|
1259
1259
|
end
|
|
1260
1260
|
|
|
1261
|
+
class StrictLocalsPositionalArgumentError < Error
|
|
1262
|
+
include Colors
|
|
1263
|
+
|
|
1264
|
+
#| name: String?,
|
|
1265
|
+
#| }
|
|
1266
|
+
|
|
1267
|
+
attr_reader :name #: String?
|
|
1268
|
+
|
|
1269
|
+
#: (String, Location?, String, String) -> void
|
|
1270
|
+
def initialize(type, location, message, name)
|
|
1271
|
+
super(type, location, message)
|
|
1272
|
+
@name = name
|
|
1273
|
+
end
|
|
1274
|
+
|
|
1275
|
+
#: () -> String
|
|
1276
|
+
def inspect
|
|
1277
|
+
tree_inspect.rstrip.gsub(/\s+$/, "")
|
|
1278
|
+
end
|
|
1279
|
+
|
|
1280
|
+
#: () -> serialized_strict_locals_positional_argument_error
|
|
1281
|
+
def to_hash
|
|
1282
|
+
super.merge(
|
|
1283
|
+
name: name
|
|
1284
|
+
) #: Herb::serialized_strict_locals_positional_argument_error
|
|
1285
|
+
end
|
|
1286
|
+
|
|
1287
|
+
#: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
|
|
1288
|
+
def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
|
|
1289
|
+
output = +""
|
|
1290
|
+
|
|
1291
|
+
output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
|
|
1292
|
+
output += white("├── message: #{green(message.inspect)}\n")
|
|
1293
|
+
output += white("└── name: #{green(name.inspect)}\n")
|
|
1294
|
+
output += %(\n)
|
|
1295
|
+
|
|
1296
|
+
output.gsub(/^/, " " * indent)
|
|
1297
|
+
end
|
|
1298
|
+
end
|
|
1299
|
+
|
|
1300
|
+
class StrictLocalsBlockArgumentError < Error
|
|
1301
|
+
include Colors
|
|
1302
|
+
|
|
1303
|
+
#| name: String?,
|
|
1304
|
+
#| }
|
|
1305
|
+
|
|
1306
|
+
attr_reader :name #: String?
|
|
1307
|
+
|
|
1308
|
+
#: (String, Location?, String, String) -> void
|
|
1309
|
+
def initialize(type, location, message, name)
|
|
1310
|
+
super(type, location, message)
|
|
1311
|
+
@name = name
|
|
1312
|
+
end
|
|
1313
|
+
|
|
1314
|
+
#: () -> String
|
|
1315
|
+
def inspect
|
|
1316
|
+
tree_inspect.rstrip.gsub(/\s+$/, "")
|
|
1317
|
+
end
|
|
1318
|
+
|
|
1319
|
+
#: () -> serialized_strict_locals_block_argument_error
|
|
1320
|
+
def to_hash
|
|
1321
|
+
super.merge(
|
|
1322
|
+
name: name
|
|
1323
|
+
) #: Herb::serialized_strict_locals_block_argument_error
|
|
1324
|
+
end
|
|
1325
|
+
|
|
1326
|
+
#: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
|
|
1327
|
+
def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
|
|
1328
|
+
output = +""
|
|
1329
|
+
|
|
1330
|
+
output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
|
|
1331
|
+
output += white("├── message: #{green(message.inspect)}\n")
|
|
1332
|
+
output += white("└── name: #{green(name.inspect)}\n")
|
|
1333
|
+
output += %(\n)
|
|
1334
|
+
|
|
1335
|
+
output.gsub(/^/, " " * indent)
|
|
1336
|
+
end
|
|
1337
|
+
end
|
|
1338
|
+
|
|
1339
|
+
class StrictLocalsSplatArgumentError < Error
|
|
1340
|
+
include Colors
|
|
1341
|
+
|
|
1342
|
+
#| name: String?,
|
|
1343
|
+
#| }
|
|
1344
|
+
|
|
1345
|
+
attr_reader :name #: String?
|
|
1346
|
+
|
|
1347
|
+
#: (String, Location?, String, String) -> void
|
|
1348
|
+
def initialize(type, location, message, name)
|
|
1349
|
+
super(type, location, message)
|
|
1350
|
+
@name = name
|
|
1351
|
+
end
|
|
1352
|
+
|
|
1353
|
+
#: () -> String
|
|
1354
|
+
def inspect
|
|
1355
|
+
tree_inspect.rstrip.gsub(/\s+$/, "")
|
|
1356
|
+
end
|
|
1357
|
+
|
|
1358
|
+
#: () -> serialized_strict_locals_splat_argument_error
|
|
1359
|
+
def to_hash
|
|
1360
|
+
super.merge(
|
|
1361
|
+
name: name
|
|
1362
|
+
) #: Herb::serialized_strict_locals_splat_argument_error
|
|
1363
|
+
end
|
|
1364
|
+
|
|
1365
|
+
#: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
|
|
1366
|
+
def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
|
|
1367
|
+
output = +""
|
|
1368
|
+
|
|
1369
|
+
output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
|
|
1370
|
+
output += white("├── message: #{green(message.inspect)}\n")
|
|
1371
|
+
output += white("└── name: #{green(name.inspect)}\n")
|
|
1372
|
+
output += %(\n)
|
|
1373
|
+
|
|
1374
|
+
output.gsub(/^/, " " * indent)
|
|
1375
|
+
end
|
|
1376
|
+
end
|
|
1377
|
+
|
|
1378
|
+
class StrictLocalsMissingParenthesisError < Error
|
|
1379
|
+
include Colors
|
|
1380
|
+
|
|
1381
|
+
#| rest: String?,
|
|
1382
|
+
#| }
|
|
1383
|
+
|
|
1384
|
+
attr_reader :rest #: String?
|
|
1385
|
+
|
|
1386
|
+
#: (String, Location?, String, String) -> void
|
|
1387
|
+
def initialize(type, location, message, rest)
|
|
1388
|
+
super(type, location, message)
|
|
1389
|
+
@rest = rest
|
|
1390
|
+
end
|
|
1391
|
+
|
|
1392
|
+
#: () -> String
|
|
1393
|
+
def inspect
|
|
1394
|
+
tree_inspect.rstrip.gsub(/\s+$/, "")
|
|
1395
|
+
end
|
|
1396
|
+
|
|
1397
|
+
#: () -> serialized_strict_locals_missing_parenthesis_error
|
|
1398
|
+
def to_hash
|
|
1399
|
+
super.merge(
|
|
1400
|
+
rest: rest
|
|
1401
|
+
) #: Herb::serialized_strict_locals_missing_parenthesis_error
|
|
1402
|
+
end
|
|
1403
|
+
|
|
1404
|
+
#: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
|
|
1405
|
+
def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
|
|
1406
|
+
output = +""
|
|
1407
|
+
|
|
1408
|
+
output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
|
|
1409
|
+
output += white("├── message: #{green(message.inspect)}\n")
|
|
1410
|
+
output += white("└── rest: #{green(rest.inspect)}\n")
|
|
1411
|
+
output += %(\n)
|
|
1412
|
+
|
|
1413
|
+
output.gsub(/^/, " " * indent)
|
|
1414
|
+
end
|
|
1415
|
+
end
|
|
1416
|
+
|
|
1417
|
+
class StrictLocalsDuplicateDeclarationError < Error
|
|
1418
|
+
include Colors
|
|
1419
|
+
|
|
1420
|
+
#: () -> String
|
|
1421
|
+
def inspect
|
|
1422
|
+
tree_inspect.rstrip.gsub(/\s+$/, "")
|
|
1423
|
+
end
|
|
1424
|
+
|
|
1425
|
+
#: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
|
|
1426
|
+
def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
|
|
1427
|
+
output = +""
|
|
1428
|
+
|
|
1429
|
+
output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
|
|
1430
|
+
output += white("└── message: #{green(message.inspect)}\n")
|
|
1431
|
+
output += %(\n)
|
|
1432
|
+
|
|
1433
|
+
output.gsub(/^/, " " * indent)
|
|
1434
|
+
end
|
|
1435
|
+
end
|
|
1436
|
+
|
|
1437
|
+
class VoidElementContentError < Error
|
|
1438
|
+
include Colors
|
|
1439
|
+
|
|
1440
|
+
#| tag_name: Herb::Token?,
|
|
1441
|
+
#| helper_name: String?,
|
|
1442
|
+
#| content_type: String?,
|
|
1443
|
+
#| }
|
|
1444
|
+
|
|
1445
|
+
attr_reader :tag_name #: Herb::Token?
|
|
1446
|
+
attr_reader :helper_name #: String?
|
|
1447
|
+
attr_reader :content_type #: String?
|
|
1448
|
+
|
|
1449
|
+
#: (String, Location?, String, Herb::Token, String, String) -> void
|
|
1450
|
+
def initialize(type, location, message, tag_name, helper_name, content_type)
|
|
1451
|
+
super(type, location, message)
|
|
1452
|
+
@tag_name = tag_name
|
|
1453
|
+
@helper_name = helper_name
|
|
1454
|
+
@content_type = content_type
|
|
1455
|
+
end
|
|
1456
|
+
|
|
1457
|
+
#: () -> String
|
|
1458
|
+
def inspect
|
|
1459
|
+
tree_inspect.rstrip.gsub(/\s+$/, "")
|
|
1460
|
+
end
|
|
1461
|
+
|
|
1462
|
+
#: () -> serialized_void_element_content_error
|
|
1463
|
+
def to_hash
|
|
1464
|
+
super.merge(
|
|
1465
|
+
tag_name: tag_name,
|
|
1466
|
+
helper_name: helper_name,
|
|
1467
|
+
content_type: content_type
|
|
1468
|
+
) #: Herb::serialized_void_element_content_error
|
|
1469
|
+
end
|
|
1470
|
+
|
|
1471
|
+
#: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
|
|
1472
|
+
def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
|
|
1473
|
+
output = +""
|
|
1474
|
+
|
|
1475
|
+
output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
|
|
1476
|
+
output += white("├── message: #{green(message.inspect)}\n")
|
|
1477
|
+
output += white("├── tag_name: ")
|
|
1478
|
+
output += tag_name ? tag_name.tree_inspect : magenta("∅")
|
|
1479
|
+
output += "\n"
|
|
1480
|
+
output += white("├── helper_name: #{green(helper_name.inspect)}\n")
|
|
1481
|
+
output += white("└── content_type: #{green(content_type.inspect)}\n")
|
|
1482
|
+
output += %(\n)
|
|
1483
|
+
|
|
1484
|
+
output.gsub(/^/, " " * indent)
|
|
1485
|
+
end
|
|
1486
|
+
end
|
|
1487
|
+
|
|
1488
|
+
class DotNotationCasingError < Error
|
|
1489
|
+
include Colors
|
|
1490
|
+
|
|
1491
|
+
#| segment: Herb::Token?,
|
|
1492
|
+
#| }
|
|
1493
|
+
|
|
1494
|
+
attr_reader :segment #: Herb::Token?
|
|
1495
|
+
|
|
1496
|
+
#: (String, Location?, String, Herb::Token) -> void
|
|
1497
|
+
def initialize(type, location, message, segment)
|
|
1498
|
+
super(type, location, message)
|
|
1499
|
+
@segment = segment
|
|
1500
|
+
end
|
|
1501
|
+
|
|
1502
|
+
#: () -> String
|
|
1503
|
+
def inspect
|
|
1504
|
+
tree_inspect.rstrip.gsub(/\s+$/, "")
|
|
1505
|
+
end
|
|
1506
|
+
|
|
1507
|
+
#: () -> serialized_dot_notation_casing_error
|
|
1508
|
+
def to_hash
|
|
1509
|
+
super.merge(
|
|
1510
|
+
segment: segment
|
|
1511
|
+
) #: Herb::serialized_dot_notation_casing_error
|
|
1512
|
+
end
|
|
1513
|
+
|
|
1514
|
+
#: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
|
|
1515
|
+
def tree_inspect(indent: 0, depth: 0, depth_limit: 25)
|
|
1516
|
+
output = +""
|
|
1517
|
+
|
|
1518
|
+
output += white("@ #{bold(red(error_name))} #{dimmed("(location: #{location&.tree_inspect})\n")}")
|
|
1519
|
+
output += white("├── message: #{green(message.inspect)}\n")
|
|
1520
|
+
output += white("└── segment: ")
|
|
1521
|
+
output += segment ? segment.tree_inspect : magenta("∅")
|
|
1522
|
+
output += "\n"
|
|
1523
|
+
output += %(\n)
|
|
1524
|
+
|
|
1525
|
+
output.gsub(/^/, " " * indent)
|
|
1526
|
+
end
|
|
1527
|
+
end
|
|
1528
|
+
|
|
1261
1529
|
end
|
|
1262
1530
|
end
|
data/lib/herb/parser_options.rb
CHANGED
|
@@ -7,6 +7,7 @@ module Herb
|
|
|
7
7
|
attr_reader :analyze #: bool
|
|
8
8
|
attr_reader :action_view_helpers #: bool
|
|
9
9
|
attr_reader :render_nodes #: bool
|
|
10
|
+
attr_reader :strict_locals #: bool
|
|
10
11
|
attr_reader :prism_program #: bool
|
|
11
12
|
attr_reader :prism_nodes #: bool
|
|
12
13
|
attr_reader :prism_nodes_deep #: bool
|
|
@@ -16,17 +17,19 @@ module Herb
|
|
|
16
17
|
DEFAULT_ANALYZE = true #: bool
|
|
17
18
|
DEFAULT_ACTION_VIEW_HELPERS = false #: bool
|
|
18
19
|
DEFAULT_RENDER_NODES = false #: bool
|
|
20
|
+
DEFAULT_STRICT_LOCALS = false #: bool
|
|
19
21
|
DEFAULT_PRISM_PROGRAM = false #: bool
|
|
20
22
|
DEFAULT_PRISM_NODES = false #: bool
|
|
21
23
|
DEFAULT_PRISM_NODES_DEEP = false #: bool
|
|
22
24
|
|
|
23
|
-
#: (?strict: bool, ?track_whitespace: bool, ?analyze: bool, ?action_view_helpers: bool, ?prism_nodes: bool, ?prism_nodes_deep: bool, ?prism_program: bool) -> void
|
|
24
|
-
def initialize(strict: DEFAULT_STRICT, track_whitespace: DEFAULT_TRACK_WHITESPACE, analyze: DEFAULT_ANALYZE, action_view_helpers: DEFAULT_ACTION_VIEW_HELPERS, render_nodes: DEFAULT_RENDER_NODES, prism_nodes: DEFAULT_PRISM_NODES, prism_nodes_deep: DEFAULT_PRISM_NODES_DEEP, prism_program: DEFAULT_PRISM_PROGRAM)
|
|
25
|
+
#: (?strict: bool, ?track_whitespace: bool, ?analyze: bool, ?action_view_helpers: bool, ?render_nodes: bool, ?strict_locals: bool, ?prism_nodes: bool, ?prism_nodes_deep: bool, ?prism_program: bool) -> void
|
|
26
|
+
def initialize(strict: DEFAULT_STRICT, track_whitespace: DEFAULT_TRACK_WHITESPACE, analyze: DEFAULT_ANALYZE, action_view_helpers: DEFAULT_ACTION_VIEW_HELPERS, render_nodes: DEFAULT_RENDER_NODES, strict_locals: DEFAULT_STRICT_LOCALS, prism_nodes: DEFAULT_PRISM_NODES, prism_nodes_deep: DEFAULT_PRISM_NODES_DEEP, prism_program: DEFAULT_PRISM_PROGRAM)
|
|
25
27
|
@strict = strict
|
|
26
28
|
@track_whitespace = track_whitespace
|
|
27
29
|
@analyze = analyze
|
|
28
30
|
@action_view_helpers = action_view_helpers
|
|
29
31
|
@render_nodes = render_nodes
|
|
32
|
+
@strict_locals = strict_locals
|
|
30
33
|
@prism_nodes = prism_nodes
|
|
31
34
|
@prism_nodes_deep = prism_nodes_deep
|
|
32
35
|
@prism_program = prism_program
|
|
@@ -40,6 +43,7 @@ module Herb
|
|
|
40
43
|
analyze: @analyze,
|
|
41
44
|
action_view_helpers: @action_view_helpers,
|
|
42
45
|
render_nodes: @render_nodes,
|
|
46
|
+
strict_locals: @strict_locals,
|
|
43
47
|
prism_nodes: @prism_nodes,
|
|
44
48
|
prism_nodes_deep: @prism_nodes_deep,
|
|
45
49
|
prism_program: @prism_program,
|
|
@@ -54,6 +58,7 @@ module Herb
|
|
|
54
58
|
"analyze=#{@analyze}\n " \
|
|
55
59
|
"action_view_helpers=#{@action_view_helpers}\n " \
|
|
56
60
|
"render_nodes=#{@render_nodes}\n " \
|
|
61
|
+
"strict_locals=#{@strict_locals}\n " \
|
|
57
62
|
"prism_nodes=#{@prism_nodes}\n " \
|
|
58
63
|
"prism_nodes_deep=#{@prism_nodes_deep}\n " \
|
|
59
64
|
"prism_program=#{@prism_program}>"
|
data/lib/herb/project.rb
CHANGED
|
@@ -71,9 +71,9 @@ module Herb
|
|
|
71
71
|
attr_reader :successful, :failed, :timeout, :template_error, :unexpected_error,
|
|
72
72
|
:strict_parse_error, :analyze_parse_error,
|
|
73
73
|
:validation_error, :compilation_failed, :strict_compilation_failed,
|
|
74
|
-
:invalid_ruby,
|
|
74
|
+
:invalid_ruby, :skipped,
|
|
75
75
|
:error_outputs, :file_contents, :parse_errors, :compilation_errors,
|
|
76
|
-
:file_diagnostics
|
|
76
|
+
:file_diagnostics, :skip_reasons
|
|
77
77
|
|
|
78
78
|
def initialize
|
|
79
79
|
@successful = []
|
|
@@ -87,11 +87,13 @@ module Herb
|
|
|
87
87
|
@compilation_failed = []
|
|
88
88
|
@strict_compilation_failed = []
|
|
89
89
|
@invalid_ruby = []
|
|
90
|
+
@skipped = []
|
|
90
91
|
@error_outputs = {}
|
|
91
92
|
@file_contents = {}
|
|
92
93
|
@parse_errors = {}
|
|
93
94
|
@compilation_errors = {}
|
|
94
95
|
@file_diagnostics = {}
|
|
96
|
+
@skip_reasons = {}
|
|
95
97
|
end
|
|
96
98
|
|
|
97
99
|
def problem_files
|
|
@@ -432,8 +434,7 @@ module Herb
|
|
|
432
434
|
nil
|
|
433
435
|
end
|
|
434
436
|
|
|
435
|
-
{ file_path: file_path, status: :timeout, file_content: file_content,
|
|
436
|
-
log: "⏱️ Parsing #{file_path} timed out after 1 second" }
|
|
437
|
+
{ file_path: file_path, status: :timeout, file_content: file_content, log: "⏱️ Parsing #{file_path} timed out after 1 second" }
|
|
437
438
|
rescue StandardError => e
|
|
438
439
|
file_content ||= begin
|
|
439
440
|
File.read(file_path)
|
|
@@ -441,8 +442,7 @@ module Herb
|
|
|
441
442
|
nil
|
|
442
443
|
end
|
|
443
444
|
|
|
444
|
-
{ file_path: file_path, status: :failed, file_content: file_content,
|
|
445
|
-
log: "⚠️ Error processing #{file_path}: #{e.message}" }
|
|
445
|
+
{ file_path: file_path, status: :failed, file_content: file_content, log: "⚠️ Error processing #{file_path}: #{e.message}" }
|
|
446
446
|
ensure
|
|
447
447
|
[stdout_file, stderr_file].each do |tempfile|
|
|
448
448
|
next unless tempfile
|
|
@@ -488,6 +488,9 @@ module Herb
|
|
|
488
488
|
Herb::Engine.new(file_content, filename: file_path, escape: true, validate_ruby: validate_ruby)
|
|
489
489
|
|
|
490
490
|
{ status: :successful, log: "✅ Compiled #{file_path} successfully" }
|
|
491
|
+
rescue Herb::Engine::GeneratorTemplateError => e
|
|
492
|
+
{ status: :skipped, skip_reason: e.message,
|
|
493
|
+
log: "⊘ Skipping #{file_path}: #{e.message}" }
|
|
491
494
|
rescue Herb::Engine::InvalidRubyError => e
|
|
492
495
|
{ status: :invalid_ruby, file_content: file_content,
|
|
493
496
|
compilation_error: { error: e.message, backtrace: e.backtrace&.first(10) || [] },
|
|
@@ -545,6 +548,7 @@ module Herb
|
|
|
545
548
|
tracker.parse_errors[file_path] = result[:parse_error] if result[:parse_error]
|
|
546
549
|
tracker.compilation_errors[file_path] = result[:compilation_error] if result[:compilation_error]
|
|
547
550
|
tracker.file_diagnostics[file_path] = result[:diagnostics] if result[:diagnostics]&.any?
|
|
551
|
+
tracker.skip_reasons[file_path] = result[:skip_reason] if result[:skip_reason]
|
|
548
552
|
end
|
|
549
553
|
|
|
550
554
|
def print_summary(results, log, duration)
|
|
@@ -563,13 +567,18 @@ module Herb
|
|
|
563
567
|
puts " #{label("Checked")} #{cyan("#{total} #{pluralize(total, "file")}")}"
|
|
564
568
|
|
|
565
569
|
if total > 1
|
|
566
|
-
|
|
567
|
-
"#{bold(green("#{passed} clean"))} | #{bold(red("#{issues} with issues"))}"
|
|
568
|
-
else
|
|
569
|
-
bold(green("#{total} clean"))
|
|
570
|
-
end
|
|
570
|
+
files_parts = []
|
|
571
571
|
|
|
572
|
-
|
|
572
|
+
if issues.positive?
|
|
573
|
+
files_parts << bold(green("#{passed} clean"))
|
|
574
|
+
files_parts << bold(red("#{issues} with issues"))
|
|
575
|
+
else
|
|
576
|
+
files_parts << bold(green("#{total - results.skipped.count} clean"))
|
|
577
|
+
end
|
|
578
|
+
|
|
579
|
+
files_parts << dimmed("#{results.skipped.count} skipped") if results.skipped.any?
|
|
580
|
+
|
|
581
|
+
puts " #{label("Files")} #{files_parts.join(" | ")}"
|
|
573
582
|
end
|
|
574
583
|
|
|
575
584
|
parser_parts = []
|
|
@@ -581,8 +590,9 @@ module Herb
|
|
|
581
590
|
parser_parts << stat(results.analyze_parse_error.count, "analyze", :yellow) if results.analyze_parse_error.any?
|
|
582
591
|
puts " #{label("Parser")} #{parser_parts.join(" | ")}"
|
|
583
592
|
|
|
584
|
-
|
|
585
|
-
|
|
593
|
+
not_compiled = total - passed - results.skipped.count - results.validation_error.count -
|
|
594
|
+
results.compilation_failed.count - results.strict_compilation_failed.count -
|
|
595
|
+
results.invalid_ruby.count
|
|
586
596
|
|
|
587
597
|
engine_parts = []
|
|
588
598
|
engine_parts << stat(passed, "compiled", :green)
|
|
@@ -590,13 +600,17 @@ module Herb
|
|
|
590
600
|
engine_parts << stat(results.compilation_failed.count, "compilation", :red) if results.compilation_failed.any?
|
|
591
601
|
engine_parts << stat(results.strict_compilation_failed.count, "strict", :yellow) if results.strict_compilation_failed.any?
|
|
592
602
|
engine_parts << stat(results.invalid_ruby.count, "produced invalid Ruby", :red) if results.invalid_ruby.any?
|
|
593
|
-
engine_parts << dimmed("#{
|
|
603
|
+
engine_parts << dimmed("#{not_compiled} not compiled") if not_compiled.positive?
|
|
594
604
|
puts " #{label("Engine")} #{engine_parts.join(" | ")}"
|
|
595
605
|
|
|
596
606
|
if results.timeout.any?
|
|
597
607
|
puts " #{label("Timeout")} #{stat(results.timeout.count, "timed out", :yellow)}"
|
|
598
608
|
end
|
|
599
609
|
|
|
610
|
+
if results.skipped.any?
|
|
611
|
+
puts " #{label("Skipped")} #{dimmed("#{results.skipped.count} #{pluralize(results.skipped.count, "file")}")}"
|
|
612
|
+
end
|
|
613
|
+
|
|
600
614
|
if duration
|
|
601
615
|
puts " #{label("Duration")} #{cyan(format_duration(duration))}"
|
|
602
616
|
end
|
|
@@ -630,6 +644,7 @@ module Herb
|
|
|
630
644
|
log.puts ""
|
|
631
645
|
log.puts "--- Other ---"
|
|
632
646
|
log.puts "⏱️ Timed out: #{results.timeout.count} (#{percentage(results.timeout.count, total)}%)"
|
|
647
|
+
log.puts "⊘ Skipped: #{results.skipped.count} (#{percentage(results.skipped.count, total)}%)"
|
|
633
648
|
|
|
634
649
|
return unless duration
|
|
635
650
|
|
|
@@ -639,10 +654,27 @@ module Herb
|
|
|
639
654
|
def print_file_lists(results, log)
|
|
640
655
|
log_file_lists(results, log)
|
|
641
656
|
|
|
642
|
-
return unless results.problem_files.any?
|
|
643
|
-
|
|
644
657
|
printed_section = false
|
|
645
658
|
|
|
659
|
+
if results.skipped.any?
|
|
660
|
+
printed_section = true
|
|
661
|
+
|
|
662
|
+
puts "\n"
|
|
663
|
+
puts " #{bold("Skipped files:")}"
|
|
664
|
+
puts " #{dimmed("These files were parsed successfully but skipped for compilation by the engine.")}"
|
|
665
|
+
|
|
666
|
+
results.skipped.each do |file|
|
|
667
|
+
relative = relative_path(file)
|
|
668
|
+
reason = results.skip_reasons[file]
|
|
669
|
+
|
|
670
|
+
puts ""
|
|
671
|
+
puts " #{cyan(relative)}:"
|
|
672
|
+
puts " #{dimmed("⊘")} #{dimmed(reason)}"
|
|
673
|
+
end
|
|
674
|
+
end
|
|
675
|
+
|
|
676
|
+
return unless results.problem_files.any?
|
|
677
|
+
|
|
646
678
|
ISSUE_TYPES.each do |type|
|
|
647
679
|
file_list = results.send(type[:key])
|
|
648
680
|
next unless file_list.any?
|
|
@@ -682,6 +714,15 @@ module Herb
|
|
|
682
714
|
end
|
|
683
715
|
|
|
684
716
|
def log_file_lists(results, log)
|
|
717
|
+
if results.skipped.any?
|
|
718
|
+
log.puts "\n#{heading("Files: Skipped")}"
|
|
719
|
+
|
|
720
|
+
results.skipped.each do |file|
|
|
721
|
+
reason = results.skip_reasons[file]
|
|
722
|
+
log.puts "#{file} - #{reason}"
|
|
723
|
+
end
|
|
724
|
+
end
|
|
725
|
+
|
|
685
726
|
ISSUE_TYPES.each do |type|
|
|
686
727
|
file_list = results.send(type[:key])
|
|
687
728
|
next unless file_list.any?
|
data/lib/herb/version.rb
CHANGED