Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on Jul 19, 2025. It is now read-only.

Commit 89e795a

Browse files
Revert "Integrate PHP parser server"
This reverts commit 26e244d.
1 parent 065ee38 commit 89e795a

File tree

6 files changed

+404
-106
lines changed

6 files changed

+404
-106
lines changed

‎lib/cc/engine/analyzers/php/ast.rb‎

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# frozen_string_literal: true
2+
3+
require "cc/engine/analyzers/php/nodes"
4+
5+
module CC
6+
module Engine
7+
module Analyzers
8+
module Php
9+
class AST
10+
def self.json_to_ast(ast, filename)
11+
return nil unless ast
12+
13+
if ast.is_a?(Array)
14+
return ast.map { |v| json_to_ast(v, filename) }
15+
end
16+
17+
unless ast.is_a?(Hash)
18+
return ast
19+
end
20+
21+
prefix_re = /^(Expr|Scalar|Stmt)_?/
22+
suffix_re = /_$/
23+
24+
node_attrs = {
25+
file: filename,
26+
}
27+
if (node_type = ast.delete("nodeType"))
28+
node_attrs[:node_type] = node_type.
29+
sub(prefix_re, "").
30+
sub(suffix_re, "")
31+
end
32+
ast.each do |key, value|
33+
unless key == "nodeAttributes"
34+
case value
35+
when Hash
36+
value = json_to_ast(value, filename)
37+
when Array
38+
value = value.map { |v| json_to_ast(v, filename) }
39+
end
40+
41+
node_attrs[key.to_sym] = value
42+
end
43+
end
44+
45+
Nodes::Node.new(node_attrs)
46+
end
47+
end
48+
end
49+
end
50+
end
51+
end

‎lib/cc/engine/analyzers/php/main.rb‎

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# frozen_string_literal: true
22

3+
require "cc/engine/analyzers/php/parser"
34
require "cc/engine/analyzers/analyzer_base"
5+
require "flay"
6+
require "json"
47

58
module CC
69
module Engine
@@ -11,16 +14,14 @@ class Main < CC::Engine::Analyzers::Base
1114
PATTERNS = [
1215
"**/*.php",
1316
].freeze
14-
DEFAULT_MASS_THRESHOLD = 75
17+
DEFAULT_MASS_THRESHOLD = 28
1518
DEFAULT_FILTERS = [
16-
"(Stmt_Use ___)",
19+
"(use ___)".freeze,
1720
].freeze
18-
POINTS_PER_OVERAGE = 40_000
19-
REQUEST_PATH = "/php"
20-
COMMENT_MATCHER = Sexp::Matcher.parse("(_ (comments ___) ___)")
21+
POINTS_PER_OVERAGE = 100_000
2122

2223
def transform_sexp(sexp)
23-
delete_comments!(sexp)
24+
sexp.flatter
2425
end
2526

2627
def use_sexp_lines?
@@ -29,16 +30,18 @@ def use_sexp_lines?
2930

3031
private
3132

32-
def process_file(file)
33-
parse(file, REQUEST_PATH)
33+
def process_file(path)
34+
code = File.binread(path)
35+
ast = php_parser.new(code, path).parse
36+
ast.syntax_tree&.to_sexp if ast
3437
end
3538

36-
def default_filters
37-
DEFAULT_FILTERS.map{ |filter| Sexp::Matcher.parsefilter}
39+
def php_parser
40+
::CC::Engine::Analyzers::Php::Parser
3841
end
3942

40-
def delete_comments!(sexp)
41-
sexp.search_each(COMMENT_MATCHER) { |node| node.delete_at(1) }
43+
def default_filters
44+
DEFAULT_FILTERS.map { |filter| Sexp::Matcher.parsefilter }
4245
end
4346
end
4447
end

‎lib/cc/engine/analyzers/php/nodes.rb‎

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# frozen_string_literal: true
2+
3+
require "cc/engine/analyzers/php/visitor"
4+
5+
module CC
6+
module Engine
7+
module Analyzers
8+
module Php
9+
module Nodes
10+
class Node
11+
def initialize(attrs)
12+
@attrs = attrs
13+
end
14+
15+
def accept(visitor)
16+
node_type = @attrs[:node_type]
17+
visit_method = :"visit_#{node_type}Node"
18+
19+
if visitor.respond_to?(visit_method)
20+
visitor.send(visit_method, self)
21+
end
22+
end
23+
24+
def line
25+
@attrs[:startLine]
26+
end
27+
28+
def file
29+
@attrs[:file]
30+
end
31+
32+
def identifier
33+
@attrs[:name] || @attrs[:value]
34+
end
35+
36+
def to_sexp
37+
CC::Engine::Analyzers::Php::Visitor.new.accept(self)
38+
end
39+
40+
def each_pair(&block)
41+
@attrs.each_pair(&block)
42+
end
43+
44+
def sub_nodes
45+
[].tap do |nodes|
46+
each_pair do |_, value|
47+
case value
48+
when Hash
49+
value.each do |_, v|
50+
nodes << v if v.is_a?(Node)
51+
end
52+
when Array
53+
value.each do |e|
54+
nodes << e if e.is_a?(Node)
55+
end
56+
when Node
57+
nodes << value
58+
end
59+
end
60+
end
61+
end
62+
end
63+
end
64+
end
65+
end
66+
end
67+
end
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# frozen_string_literal: true
2+
3+
require "cc/engine/analyzers/command_line_runner"
4+
require "cc/engine/analyzers/parser_base"
5+
require "cc/engine/analyzers/php/ast"
6+
require "cc/engine/analyzers/php/nodes"
7+
8+
module CC
9+
module Engine
10+
module Analyzers
11+
module Php
12+
class Parser < ParserBase
13+
TIMEOUT = 10
14+
15+
attr_reader :code, :filename, :syntax_tree
16+
17+
def initialize(code, filename)
18+
@code = code
19+
@filename = filename
20+
end
21+
22+
def parse
23+
cmd = "php -d 'display_errors = Off' #{parser_path}"
24+
runner = CommandLineRunner.new(cmd, TIMEOUT)
25+
runner.run(code) do |output|
26+
json = parse_json(output)
27+
28+
@syntax_tree = CC::Engine::Analyzers::Php::Nodes::Node.new(
29+
stmts: CC::Engine::Analyzers::Php::AST.json_to_ast(json, filename),
30+
node_type: "AST",
31+
)
32+
end
33+
34+
self
35+
rescue Timeout::Error
36+
CC.logger.warn("TIMEOUT parsing #{filename}. Skipping.")
37+
end
38+
39+
private
40+
41+
def parser_path
42+
relative_path = "../../../../../vendor/php-parser/parser.php"
43+
File.expand_path(
44+
File.join(File.dirname(__FILE__), relative_path),
45+
)
46+
end
47+
end
48+
end
49+
end
50+
end
51+
end

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /