Completed
Push — 2.x ( 98b57b...8b2aa1 )
by Alexander
05:24
created

StreamMetaData   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 144
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 78.79%

Importance

Changes 0
Metric Value
wmc 15
lcom 1
cbo 2
dl 0
loc 144
ccs 26
cts 33
cp 0.7879
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __get() 0 8 2
A setSource() 0 7 3
A getSource() 0 9 3
B __construct() 0 19 5
A __set() 0 7 2
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 31
    public function __construct($stream, $source = null)
95
    {
96 31
        if (!is_resource($stream)) {
97
            throw new InvalidArgumentException('Stream should be valid resource');
98
        }
99 31
        $metadata = stream_get_meta_data($stream);
100 31
        if (preg_match('/resource=(.+)$/', $metadata['uri'], $matches)) {
101 6
            $metadata['uri'] = PathResolver::realpath($matches[1]);
102
        }
103 31
        foreach ($metadata as $key => $value) {
104 31
            if (!isset(self::$propertyMap[$key])) {
105 31
                continue;
106
            }
107 31
            $mappedKey = self::$propertyMap[$key];
108 31
            $this->$mappedKey = $value;
109
        }
110 31
        $this->syntaxTree = ReflectionEngine::parseFile($this->uri, $source);
111 31
        $this->setSource($source);
112 31
    }
113
114
    /**
115
     * @inheritDoc
116
     */
117 31
    public function __get($name)
118
    {
119 31
        if ($name === 'source') {
120 31
            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 31
    private function getSource()
143
    {
144 31
        $transformedSource = '';
145 31
        foreach ($this->tokenStream as $token) {
146 31
            $transformedSource .= isset($token[1]) ? $token[1] : $token;
147
        }
148
149 31
        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 31
    private function setSource($newSource)
160
    {
161 31
        $rawTokens = token_get_all($newSource);
162 31
        foreach ($rawTokens as $index => $rawToken) {
163 31
            $this->tokenStream[$index] = \is_array($rawToken) ? $rawToken : [T_STRING, $rawToken];
164
        }
165 31
    }
166
}
167