Completed
Push — 2.x ( 2a04a1...0da1ca )
by Alexander
02:03
created

StreamMetaData::__construct()   B

Complexity

Conditions 5
Paths 7

Size

Total Lines 19
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 5.009

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 19
ccs 13
cts 14
cp 0.9286
rs 8.8571
cc 5
eloc 13
nc 7
nop 2
crap 5.009
1
<?php
2
/*
3
 * Go! AOP framework
4
 *
5
 * @copyright Copyright 2012, Lisachenko Alexander <[email protected]>
6
 *
7
 * This source file is subject to the license that is bundled
8
 * with this source code in the file LICENSE.
9
 */
10
11
namespace Go\Instrument\Transformer;
12
13
use Go\Instrument\PathResolver;
14
use Go\ParserReflection\ReflectionEngine;
15
use InvalidArgumentException;
16
use PhpParser\Node;
17
18
/**
19
 * Stream metadata object
20
 *
21
 * @property-read string $source
22
 */
23
class StreamMetaData
24
{
25
    /**
26
     * Mapping between array keys and properties
27
     *
28
     * @var array
29
     */
30
    private static $propertyMap = [
31
        'stream_type'  => 'streamType',
32
        'wrapper_type' => 'wrapperType',
33
        'wrapper_data' => 'wrapperData',
34
        'filters'      => 'filterList',
35
        'uri'          => 'uri',
36
    ];
37
38
    /**
39
     * A label describing the underlying implementation of the stream.
40
     *
41
     * @var string
42
     */
43
    public $streamType;
44
45
    /**
46
     * A label describing the protocol wrapper implementation layered over the stream.
47
     *
48
     * @var string
49
     */
50
    public $wrapperType;
51
52
    /**
53
     * Wrapper-specific data attached to this stream.
54
     *
55
     * @var mixed
56
     */
57
    public $wrapperData;
58
59
    /**
60
     * Array containing the names of any filters that have been stacked onto this stream.
61
     *
62
     * @var array
63
     */
64
    public $filterList;
65
66
    /**
67
     * The URI/filename associated with this stream.
68
     *
69
     * @var string
70
     */
71
    public $uri;
72
73
    /**
74
     * Information about syntax tree
75
     *
76
     * @var Node[]
77
     */
78
    public $syntaxTree;
79
80
    /**
81
     * List of source tokens
82
     *
83
     * @var array
84
     */
85
    public $tokenStream = [];
86
87
    /**
88
     * Creates metadata object from stream
89
     *
90
     * @param resource $stream Instance of stream
91
     * @param string $source Source code or null
92
     * @throws \InvalidArgumentException for invalid stream
93
     */
94 34
    public function __construct($stream, $source = null)
95
    {
96 34
        if (!is_resource($stream)) {
97
            throw new InvalidArgumentException('Stream should be valid resource');
98
        }
99 34
        $metadata = stream_get_meta_data($stream);
100 34
        if (preg_match('/resource=(.+)$/', $metadata['uri'], $matches)) {
101 9
            $metadata['uri'] = PathResolver::realpath($matches[1]);
102
        }
103 34
        foreach ($metadata as $key=>$value) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space before "=>"; 0 found
Loading history...
Coding Style introduced by
Expected 1 space after "=>"; 0 found
Loading history...
104 34
            if (!isset(self::$propertyMap[$key])) {
105 34
                continue;
106
            }
107 34
            $mappedKey = self::$propertyMap[$key];
108 34
            $this->$mappedKey = $value;
109
        }
110 34
        $this->syntaxTree = ReflectionEngine::parseFile($this->uri, $source);
111 34
        $this->setSource($source);
112 34
    }
113
114
    /**
115
     * @inheritDoc
116
     */
117 34
    public function __get($name)
118
    {
119 34
        if ($name === 'source') {
120 34
            return $this->getSource();
121
        }
122
123
        return null;
124
    }
125
126
    /**
127
     * @inheritDoc
128
     */
129
    public function __set($name, $value)
130
    {
131
        if ($name === 'source') {
132
            trigger_error('Setting StreamMetaData->source is deprecated, use tokenStream instead', E_USER_DEPRECATED);
133
            $this->setSource($value);
134
        }
135
    }
136
137
    /**
138
     * Returns source code directly from tokens
139
     *
140
     * @return string
141
     */
142 34
    private function getSource()
143
    {
144 34
        $transformedSource = '';
145 34
        foreach ($this->tokenStream as $token) {
146 34
            $transformedSource .= isset($token[1]) ? $token[1] : $token;
147
        }
148
149 34
        return $transformedSource;
150
    }
151
152
    /**
153
     * Sets the new source for this file
154
     *
155
     * @TODO: Unfortunately, AST won't be changed, so please be accurate during transformation
156
     *
157
     * @param string $newSource
158
     */
159 34
    private function setSource($newSource)
160
    {
161 34
        $rawTokens = token_get_all($newSource);
162 34
        foreach ($rawTokens as $index => $rawToken) {
163 34
            $this->tokenStream[$index] = \is_array($rawToken) ? $rawToken : [T_STRING, $rawToken];
164
        }
165 34
    }
166
}
167