Browse code

Merge branch '1.x'

* 1.x:
added missing phpdoc
made using Twig_SourceContextLoaderInterface required
made name required for Twig_Source

Fabien Potencier authored on 22/10/2016 00:29:34
Showing 18 changed files
... ...
@@ -19,6 +19,7 @@
19 19
 
20 20
 * 1.27.0 (2016-XX-XX)
21 21
 
22
+ * deprecated Twig_LoaderInterface::getSource() (implement Twig_SourceContextLoaderInterface instead)
22 23
  * fixed the filesystem loader with relative paths
23 24
  * deprecated Twig_Node::getLine() in favor of Twig_Node::getTemplateLine()
24 25
  * deprecated Twig_Template::getSource() in favor of Twig_Template::getSourceContext()
... ...
@@ -252,15 +252,15 @@ All loaders implement the ``Twig_LoaderInterface``::
252 252
     interface Twig_LoaderInterface
253 253
     {
254 254
         /**
255
-         * Gets the source code of a template, given its name.
255
+         * Returns the source context for a given template logical name.
256 256
          *
257
-         * @param string $name The name of the template to load
257
+         * @param string $name The template logical name
258 258
          *
259
-         * @return string The template source code
259
+         * @return Twig_Source
260 260
          *
261 261
          * @throws Twig_Error_Loader When $name is not found
262 262
          */
263
-        public function getSource($name);
263
+        public function getSourceContext($name);
264 264
 
265 265
         /**
266 266
          * Gets the cache key to use for the cache for a given template name.
... ...
@@ -298,7 +298,7 @@ All loaders implement the ``Twig_LoaderInterface``::
298 298
 The ``isFresh()`` method must return ``true`` if the current cached template
299 299
 is still fresh, given the last modification time, or ``false`` otherwise.
300 300
 
301
-The ``exists()`` method make your loader faster when used with the chain loader.
301
+The ``getSourceContext()`` method must return an instance of ``Twig_Source``.
302 302
 
303 303
 Using Extensions
304 304
 ----------------
... ...
@@ -419,13 +419,13 @@ Now, let's define a loader able to use this database::
419 419
             $this->dbh = $dbh;
420 420
         }
421 421
 
422
-        public function getSource($name)
422
+        public function getSourceContext($name)
423 423
         {
424 424
             if (false === $source = $this->getValue('source', $name)) {
425 425
                 throw new Twig_Error_Loader(sprintf('Template "%s" does not exist.', $name));
426 426
             }
427 427
 
428
-            return $source;
428
+            return new Twig_Source($source, $name);
429 429
         }
430 430
 
431 431
         public function exists($name)
... ...
@@ -325,13 +325,7 @@ class Twig_Environment
325 325
             }
326 326
 
327 327
             if (!class_exists($cls, false)) {
328
-                $loader = $this->getLoader();
329
-                if ($loader instanceof Twig_SourceContextLoaderInterface) {
330
-                    $source = $loader->getSourceContext($name);
331
-                } else {
332
-                    $source = new Twig_Source($loader->getSource($name), $name);
333
-                }
334
-                $content = $this->compileSource($source);
328
+                $content = $this->compileSource($this->getSourceContext($name));
335 329
 
336 330
                 $this->cache->write($key, $content);
337 331
 
... ...
@@ -536,6 +530,10 @@ class Twig_Environment
536 530
      */
537 531
     public function setLoader(Twig_LoaderInterface $loader)
538 532
     {
533
+        if (!$loader instanceof Twig_SourceContextLoaderInterface && 0 !== strpos(get_class($loader), 'Mock_Twig_LoaderInterface')) {
534
+            @trigger_error(sprintf('Twig loader "%s" should implement Twig_SourceContextLoaderInterface since version 1.27.', get_class($loader)), E_USER_DEPRECATED);
535
+        }
536
+
539 537
         $this->loader = $loader;
540 538
     }
541 539
 
... ...
@@ -550,6 +548,21 @@ class Twig_Environment
550 548
     }
551 549
 
552 550
     /**
551
+     * Gets the source context for the given template name.
552
+     *
553
+     * @return Twig_Source
554
+     */
555
+    public function getSourceContext($name)
556
+    {
557
+        $loader = $this->getLoader();
558
+        if (!$loader instanceof Twig_SourceContextLoaderInterface) {
559
+            return new Twig_Source($loader->getSource($name), $name);
560
+        }
561
+
562
+        return $loader->getSourceContext($name);
563
+    }
564
+
565
+    /**
553 566
      * Sets the default template charset.
554 567
      *
555 568
      * @param string $charset The default charset
... ...
@@ -1303,7 +1303,7 @@ function twig_include(Twig_Environment $env, $context, $template, $variables = a
1303 1303
 function twig_source(Twig_Environment $env, $name, $ignoreMissing = false)
1304 1304
 {
1305 1305
     try {
1306
-        return $env->getLoader()->getSource($name);
1306
+        return $env->getSourceContext($name)->getCode();
1307 1307
     } catch (Twig_Error_Loader $e) {
1308 1308
         if (!$ignoreMissing) {
1309 1309
             throw $e;
... ...
@@ -21,7 +21,7 @@
21 21
  *
22 22
  * @author Fabien Potencier <fabien@symfony.com>
23 23
  */
24
-class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
24
+class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterface, Twig_SourceContextLoaderInterface
25 25
 {
26 26
     private $templates = array();
27 27
 
... ...
@@ -51,6 +51,8 @@ class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
51 51
      */
52 52
     public function getSource($name)
53 53
     {
54
+        @trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', get_class($this)), E_USER_DEPRECATED);
55
+
54 56
         if (!isset($this->templates[$name])) {
55 57
             throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name));
56 58
         }
... ...
@@ -61,6 +63,19 @@ class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
61 63
     /**
62 64
      * {@inheritdoc}
63 65
      */
66
+    public function getSourceContext($name)
67
+    {
68
+        $name = (string) $name;
69
+        if (!isset($this->templates[$name])) {
70
+            throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name));
71
+        }
72
+
73
+        return new Twig_Source($this->templates[$name], $name);
74
+    }
75
+
76
+    /**
77
+     * {@inheritdoc}
78
+     */
64 79
     public function exists($name)
65 80
     {
66 81
         return isset($this->templates[$name]);
... ...
@@ -138,6 +138,8 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
138 138
      */
139 139
     public function getSource($name)
140 140
     {
141
+        @trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', get_class($this)), E_USER_DEPRECATED);
142
+
141 143
         return file_get_contents($this->findTemplate($name));
142 144
     }
143 145
 
... ...
@@ -24,6 +24,8 @@ interface Twig_LoaderInterface
24 24
      * @return string The template source code
25 25
      *
26 26
      * @throws Twig_Error_Loader When $name is not found
27
+     *
28
+     * @deprecated since 1.27 (to be removed in 2.0), implement Twig_SourceContextLoaderInterface
27 29
      */
28 30
     public function getSource($name);
29 31
 
... ...
@@ -25,7 +25,7 @@ class Twig_Source
25 25
      * @param string $name The template logical name
26 26
      * @param string $path The filesystem path of the template if any
27 27
      */
28
-    public function __construct($code, $name = null, $path = null)
28
+    public function __construct($code, $name, $path = '')
29 29
     {
30 30
         $this->code = $code;
31 31
         $this->name = $name;
... ...
@@ -9,6 +9,13 @@
9 9
  * file that was distributed with this source code.
10 10
  */
11 11
 
12
+/**
13
+ * Adds a getSourceContext() method for loaders.
14
+ *
15
+ * @author Fabien Potencier <fabien@symfony.com>
16
+ *
17
+ * @deprecated since 1.27 (to be removed in 3.0)
18
+ */
12 19
 interface Twig_SourceContextLoaderInterface
13 20
 {
14 21
     /**
... ...
@@ -17,6 +24,8 @@ interface Twig_SourceContextLoaderInterface
17 24
      * @param string $name The template logical name
18 25
      *
19 26
      * @return Twig_Source
27
+     *
28
+     * @throws Twig_Error_Loader When $name is not found
20 29
      */
21 30
     public function getSourceContext($name);
22 31
 }
... ...
@@ -209,8 +209,7 @@ abstract class Twig_Test_IntegrationTestCase extends PHPUnit_Framework_TestCase
209 209
 
210 210
                 foreach (array_keys($templates) as $name) {
211 211
                     echo "Template: $name\n";
212
-                    $source = $loader->getSource($name);
213
-                    echo $twig->compile($twig->parse($twig->tokenize($source, $name)));
212
+                    echo $twig->compile($twig->parse($twig->tokenize($twig->getSourceContext($name), $name)));
214 213
                 }
215 214
             }
216 215
             $this->assertEquals($expected, $output, $message.' (in '.$file.')');
... ...
@@ -35,8 +35,13 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
35 35
 
36 36
     public function testGlobals()
37 37
     {
38
+        // to be removed in 2.0
39
+        $loader = $this->getMockBuilder('Twig_EnvironmentTestLoaderInterface')->getMock();
40
+        //$loader = $this->getMockBuilder(array('Twig_LoaderInterface', 'Twig_SourceContextLoaderInterface'))->getMock();
41
+        $loader->expects($this->any())->method('getSourceContext')->will($this->returnValue(new Twig_Source('', '')));
42
+
38 43
         // globals can be added after calling getGlobals
39
-        $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
44
+        $twig = new Twig_Environment($loader);
40 45
         $twig->addGlobal('foo', 'foo');
41 46
         $twig->getGlobals();
42 47
         $twig->addGlobal('foo', 'bar');
... ...
@@ -44,7 +49,7 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
44 49
         $this->assertEquals('bar', $globals['foo']);
45 50
 
46 51
         // globals can be modified after a template has been loaded
47
-        $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
52
+        $twig = new Twig_Environment($loader);
48 53
         $twig->addGlobal('foo', 'foo');
49 54
         $twig->getGlobals();
50 55
         $twig->loadTemplate('index');
... ...
@@ -53,7 +58,7 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
53 58
         $this->assertEquals('bar', $globals['foo']);
54 59
 
55 60
         // globals can be modified after extensions init
56
-        $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
61
+        $twig = new Twig_Environment($loader);
57 62
         $twig->addGlobal('foo', 'foo');
58 63
         $twig->getGlobals();
59 64
         $twig->getFunctions();
... ...
@@ -62,7 +67,8 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
62 67
         $this->assertEquals('bar', $globals['foo']);
63 68
 
64 69
         // globals can be modified after extensions and a template has been loaded
65
-        $twig = new Twig_Environment($loader = new Twig_Loader_Array(array('index' => '{{foo}}')));
70
+        $arrayLoader = new Twig_Loader_Array(array('index' => '{{foo}}'));
71
+        $twig = new Twig_Environment($arrayLoader);
66 72
         $twig->addGlobal('foo', 'foo');
67 73
         $twig->getGlobals();
68 74
         $twig->getFunctions();
... ...
@@ -71,14 +77,14 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
71 77
         $globals = $twig->getGlobals();
72 78
         $this->assertEquals('bar', $globals['foo']);
73 79
 
74
-        $twig = new Twig_Environment($loader);
80
+        $twig = new Twig_Environment($arrayLoader);
75 81
         $twig->getGlobals();
76 82
         $twig->addGlobal('foo', 'bar');
77 83
         $template = $twig->loadTemplate('index');
78 84
         $this->assertEquals('bar', $template->render(array()));
79 85
 
80 86
         // globals cannot be added after a template has been loaded
81
-        $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
87
+        $twig = new Twig_Environment($loader);
82 88
         $twig->addGlobal('foo', 'foo');
83 89
         $twig->getGlobals();
84 90
         $twig->loadTemplate('index');
... ...
@@ -90,7 +96,7 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
90 96
         }
91 97
 
92 98
         // globals cannot be added after extensions init
93
-        $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
99
+        $twig = new Twig_Environment($loader);
94 100
         $twig->addGlobal('foo', 'foo');
95 101
         $twig->getGlobals();
96 102
         $twig->getFunctions();
... ...
@@ -102,7 +108,7 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
102 108
         }
103 109
 
104 110
         // globals cannot be added after extensions and a template has been loaded
105
-        $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
111
+        $twig = new Twig_Environment($loader);
106 112
         $twig->addGlobal('foo', 'foo');
107 113
         $twig->getGlobals();
108 114
         $twig->getFunctions();
... ...
@@ -115,7 +121,7 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
115 121
         }
116 122
 
117 123
         // test adding globals after a template has been loaded without call to getGlobals
118
-        $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
124
+        $twig = new Twig_Environment($loader);
119 125
         $twig->loadTemplate('index');
120 126
         try {
121 127
             $twig->addGlobal('bar', 'bar');
... ...
@@ -326,11 +332,13 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
326 332
 
327 333
     protected function getMockLoader($templateName, $templateContent)
328 334
     {
329
-        $loader = $this->getMockBuilder('Twig_LoaderInterface')->getMock();
335
+        // to be removed in 2.0
336
+        $loader = $this->getMockBuilder('Twig_EnvironmentTestLoaderInterface')->getMock();
337
+        //$loader = $this->getMockBuilder(array('Twig_LoaderInterface', 'Twig_SourceContextLoaderInterface'))->getMock();
330 338
         $loader->expects($this->any())
331
-          ->method('getSource')
339
+          ->method('getSourceContext')
332 340
           ->with($templateName)
333
-          ->will($this->returnValue($templateContent));
341
+          ->will($this->returnValue(new Twig_Source($templateContent, $templateName)));
334 342
         $loader->expects($this->any())
335 343
           ->method('getCacheKey')
336 344
           ->with($templateName)
... ...
@@ -478,3 +486,7 @@ class Twig_Tests_EnvironmentTest_Runtime
478 486
         return $name;
479 487
     }
480 488
 }
489
+
490
+interface Twig_EnvironmentTestLoaderInterface extends Twig_LoaderInterface, Twig_SourceContextLoaderInterface
491
+{
492
+}
... ...
@@ -47,7 +47,7 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
47 47
     public function testArrayExpression($template, $expected)
48 48
     {
49 49
         $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
50
-        $stream = $env->tokenize(new Twig_Source($template));
50
+        $stream = $env->tokenize(new Twig_Source($template, ''));
51 51
         $parser = new Twig_Parser($env);
52 52
 
53 53
         $this->assertEquals($expected, $parser->parse($stream)->getNode('body')->getNode(0)->getNode('expr'));
... ...
@@ -167,7 +167,7 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
167 167
     public function testStringExpression($template, $expected)
168 168
     {
169 169
         $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false, 'optimizations' => 0));
170
-        $stream = $env->tokenize(new Twig_Source($template));
170
+        $stream = $env->tokenize(new Twig_Source($template, ''));
171 171
         $parser = new Twig_Parser($env);
172 172
 
173 173
         $this->assertEquals($expected, $parser->parse($stream)->getNode('body')->getNode(0)->getNode('expr'));
... ...
@@ -15,7 +15,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
15 15
         $template = '{% § %}';
16 16
 
17 17
         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
18
-        $stream = $lexer->tokenize(new Twig_Source($template));
18
+        $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
19 19
 
20 20
         $stream->expect(Twig_Token::BLOCK_START_TYPE);
21 21
         $this->assertSame('§', $stream->expect(Twig_Token::NAME_TYPE)->getValue());
... ...
@@ -26,7 +26,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
26 26
         $template = '{{ §() }}';
27 27
 
28 28
         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
29
-        $stream = $lexer->tokenize(new Twig_Source($template));
29
+        $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
30 30
 
31 31
         $stream->expect(Twig_Token::VAR_START_TYPE);
32 32
         $this->assertSame('§', $stream->expect(Twig_Token::NAME_TYPE)->getValue());
... ...
@@ -43,7 +43,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
43 43
     protected function countToken($template, $type, $value = null)
44 44
     {
45 45
         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
46
-        $stream = $lexer->tokenize(new Twig_Source($template));
46
+        $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
47 47
 
48 48
         $count = 0;
49 49
         while (!$stream->isEOF()) {
... ...
@@ -68,7 +68,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
68 68
             ."}}\n";
69 69
 
70 70
         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
71
-        $stream = $lexer->tokenize(new Twig_Source($template));
71
+        $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
72 72
 
73 73
         // foo\nbar\n
74 74
         $this->assertSame(1, $stream->expect(Twig_Token::TEXT_TYPE)->getLine());
... ...
@@ -88,7 +88,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
88 88
             ."}}\n";
89 89
 
90 90
         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
91
-        $stream = $lexer->tokenize(new Twig_Source($template));
91
+        $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
92 92
 
93 93
         // foo\nbar
94 94
         $this->assertSame(1, $stream->expect(Twig_Token::TEXT_TYPE)->getLine());
... ...
@@ -103,7 +103,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
103 103
         $template = '{# '.str_repeat('*', 100000).' #}';
104 104
 
105 105
         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
106
-        $lexer->tokenize(new Twig_Source($template));
106
+        $lexer->tokenize(new Twig_Source($template, 'index'));
107 107
 
108 108
         // should not throw an exception
109 109
     }
... ...
@@ -113,7 +113,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
113 113
         $template = '{% verbatim %}'.str_repeat('*', 100000).'{% endverbatim %}';
114 114
 
115 115
         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
116
-        $lexer->tokenize(new Twig_Source($template));
116
+        $lexer->tokenize(new Twig_Source($template, 'index'));
117 117
 
118 118
         // should not throw an exception
119 119
     }
... ...
@@ -123,7 +123,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
123 123
         $template = '{{ '.str_repeat('x', 100000).' }}';
124 124
 
125 125
         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
126
-        $lexer->tokenize(new Twig_Source($template));
126
+        $lexer->tokenize(new Twig_Source($template, 'index'));
127 127
 
128 128
         // should not throw an exception
129 129
     }
... ...
@@ -133,7 +133,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
133 133
         $template = '{% '.str_repeat('x', 100000).' %}';
134 134
 
135 135
         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
136
-        $lexer->tokenize(new Twig_Source($template));
136
+        $lexer->tokenize(new Twig_Source($template, 'index'));
137 137
 
138 138
         // should not throw an exception
139 139
     }
... ...
@@ -143,7 +143,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
143 143
         $template = '{{ 922337203685477580700 }}';
144 144
 
145 145
         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
146
-        $stream = $lexer->tokenize(new Twig_Source($template));
146
+        $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
147 147
         $stream->next();
148 148
         $node = $stream->next();
149 149
         $this->assertEquals('922337203685477580700', $node->getValue());
... ...
@@ -158,7 +158,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
158 158
 
159 159
         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
160 160
         foreach ($tests as $template => $expected) {
161
-            $stream = $lexer->tokenize(new Twig_Source($template));
161
+            $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
162 162
             $stream->expect(Twig_Token::VAR_START_TYPE);
163 163
             $stream->expect(Twig_Token::STRING_TYPE, $expected);
164 164
         }
... ...
@@ -169,7 +169,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
169 169
         $template = 'foo {{ "bar #{ baz + 1 }" }}';
170 170
 
171 171
         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
172
-        $stream = $lexer->tokenize(new Twig_Source($template));
172
+        $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
173 173
         $stream->expect(Twig_Token::TEXT_TYPE, 'foo ');
174 174
         $stream->expect(Twig_Token::VAR_START_TYPE);
175 175
         $stream->expect(Twig_Token::STRING_TYPE, 'bar ');
... ...
@@ -186,7 +186,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
186 186
         $template = '{{ "bar \#{baz+1}" }}';
187 187
 
188 188
         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
189
-        $stream = $lexer->tokenize(new Twig_Source($template));
189
+        $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
190 190
         $stream->expect(Twig_Token::VAR_START_TYPE);
191 191
         $stream->expect(Twig_Token::STRING_TYPE, 'bar #{baz+1}');
192 192
         $stream->expect(Twig_Token::VAR_END_TYPE);
... ...
@@ -197,7 +197,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
197 197
         $template = '{{ "bar # baz" }}';
198 198
 
199 199
         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
200
-        $stream = $lexer->tokenize(new Twig_Source($template));
200
+        $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
201 201
         $stream->expect(Twig_Token::VAR_START_TYPE);
202 202
         $stream->expect(Twig_Token::STRING_TYPE, 'bar # baz');
203 203
         $stream->expect(Twig_Token::VAR_END_TYPE);
... ...
@@ -212,7 +212,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
212 212
         $template = '{{ "bar #{x" }}';
213 213
 
214 214
         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
215
-        $lexer->tokenize(new Twig_Source($template));
215
+        $lexer->tokenize(new Twig_Source($template, 'index'));
216 216
     }
217 217
 
218 218
     public function testStringWithNestedInterpolations()
... ...
@@ -220,7 +220,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
220 220
         $template = '{{ "bar #{ "foo#{bar}" }" }}';
221 221
 
222 222
         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
223
-        $stream = $lexer->tokenize(new Twig_Source($template));
223
+        $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
224 224
         $stream->expect(Twig_Token::VAR_START_TYPE);
225 225
         $stream->expect(Twig_Token::STRING_TYPE, 'bar ');
226 226
         $stream->expect(Twig_Token::INTERPOLATION_START_TYPE);
... ...
@@ -237,7 +237,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
237 237
         $template = '{% foo "bar #{ "foo#{bar}" }" %}';
238 238
 
239 239
         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
240
-        $stream = $lexer->tokenize(new Twig_Source($template));
240
+        $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
241 241
         $stream->expect(Twig_Token::BLOCK_START_TYPE);
242 242
         $stream->expect(Twig_Token::NAME_TYPE, 'foo');
243 243
         $stream->expect(Twig_Token::STRING_TYPE, 'bar ');
... ...
@@ -255,7 +255,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
255 255
         $template = "{{ 1 and\n0}}";
256 256
 
257 257
         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
258
-        $stream = $lexer->tokenize(new Twig_Source($template));
258
+        $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
259 259
         $stream->expect(Twig_Token::VAR_START_TYPE);
260 260
         $stream->expect(Twig_Token::NUMBER_TYPE, 1);
261 261
         $stream->expect(Twig_Token::OPERATOR_TYPE, 'and');
... ...
@@ -263,7 +263,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
263 263
 
264 264
     /**
265 265
      * @expectedException Twig_Error_Syntax
266
-     * @expectedExceptionMessage Unclosed "variable" at line 3
266
+     * @expectedExceptionMessage Unclosed "variable" in "index" at line 3
267 267
      */
268 268
     public function testUnterminatedVariable()
269 269
     {
... ...
@@ -277,12 +277,12 @@ bar
277 277
 ';
278 278
 
279 279
         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
280
-        $lexer->tokenize(new Twig_Source($template));
280
+        $lexer->tokenize(new Twig_Source($template, 'index'));
281 281
     }
282 282
 
283 283
     /**
284 284
      * @expectedException Twig_Error_Syntax
285
-     * @expectedExceptionMessage Unclosed "block" at line 3
285
+     * @expectedExceptionMessage Unclosed "block" in "index" at line 3
286 286
      */
287 287
     public function testUnterminatedBlock()
288 288
     {
... ...
@@ -296,6 +296,6 @@ bar
296 296
 ';
297 297
 
298 298
         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
299
-        $lexer->tokenize(new Twig_Source($template));
299
+        $lexer->tokenize(new Twig_Source($template, 'index'));
300 300
     }
301 301
 }
... ...
@@ -11,6 +11,9 @@
11 11
 
12 12
 class Twig_Tests_Loader_ArrayTest extends PHPUnit_Framework_TestCase
13 13
 {
14
+    /**
15
+     * @group legacy
16
+     */
14 17
     public function testGetSource()
15 18
     {
16 19
         $loader = new Twig_Loader_Array(array('foo' => 'bar'));
... ...
@@ -19,6 +22,7 @@ class Twig_Tests_Loader_ArrayTest extends PHPUnit_Framework_TestCase
19 22
     }
20 23
 
21 24
     /**
25
+     * @group legacy
22 26
      * @expectedException Twig_Error_Loader
23 27
      */
24 28
     public function testGetSourceWhenTemplateDoesNotExist()
... ...
@@ -28,6 +32,16 @@ class Twig_Tests_Loader_ArrayTest extends PHPUnit_Framework_TestCase
28 32
         $loader->getSource('foo');
29 33
     }
30 34
 
35
+    /**
36
+     * @expectedException Twig_Error_Loader
37
+     */
38
+    public function testGetSourceContextWhenTemplateDoesNotExist()
39
+    {
40
+        $loader = new Twig_Loader_Array(array());
41
+
42
+        $loader->getSourceContext('foo');
43
+    }
44
+
31 45
     public function testGetCacheKey()
32 46
     {
33 47
         $loader = new Twig_Loader_Array(array('foo' => 'bar'));
... ...
@@ -50,7 +64,7 @@ class Twig_Tests_Loader_ArrayTest extends PHPUnit_Framework_TestCase
50 64
         $loader = new Twig_Loader_Array(array());
51 65
         $loader->setTemplate('foo', 'bar');
52 66
 
53
-        $this->assertEquals('bar', $loader->getSource('foo'));
67
+        $this->assertEquals('bar', $loader->getSourceContext('foo')->getCode());
54 68
     }
55 69
 
56 70
     public function testIsFresh()
... ...
@@ -11,6 +11,9 @@
11 11
 
12 12
 class Twig_Tests_Loader_ChainTest extends PHPUnit_Framework_TestCase
13 13
 {
14
+    /**
15
+     * @group legacy
16
+     */
14 17
     public function testGetSource()
15 18
     {
16 19
         $loader = new Twig_Loader_Chain(array(
... ...
@@ -32,10 +35,10 @@ class Twig_Tests_Loader_ChainTest extends PHPUnit_Framework_TestCase
32 35
         ));
33 36
 
34 37
         $this->assertEquals('foo', $loader->getSourceContext('foo')->getName());
35
-        $this->assertNull($loader->getSourceContext('foo')->getPath());
38
+        $this->assertSame('', $loader->getSourceContext('foo')->getPath());
36 39
 
37 40
         $this->assertEquals('errors/index.html', $loader->getSourceContext('errors/index.html')->getName());
38
-        $this->assertNull($loader->getSourceContext('errors/index.html')->getPath());
41
+        $this->assertSame('', $loader->getSourceContext('errors/index.html')->getPath());
39 42
         $this->assertEquals('baz', $loader->getSourceContext('errors/index.html')->getCode());
40 43
 
41 44
         $this->assertEquals('errors/base.html', $loader->getSourceContext('errors/base.html')->getName());
... ...
@@ -46,6 +49,17 @@ class Twig_Tests_Loader_ChainTest extends PHPUnit_Framework_TestCase
46 49
     /**
47 50
      * @expectedException Twig_Error_Loader
48 51
      */
52
+    public function testGetSourceContextWhenTemplateDoesNotExist()
53
+    {
54
+        $loader = new Twig_Loader_Chain(array());
55
+
56
+        $loader->getSourceContext('foo');
57
+    }
58
+
59
+    /**
60
+     * @group legacy
61
+     * @expectedException Twig_Error_Loader
62
+     */
49 63
     public function testGetSourceWhenTemplateDoesNotExist()
50 64
     {
51 65
         $loader = new Twig_Loader_Chain(array());
... ...
@@ -79,18 +93,20 @@ class Twig_Tests_Loader_ChainTest extends PHPUnit_Framework_TestCase
79 93
         $loader = new Twig_Loader_Chain();
80 94
         $loader->addLoader(new Twig_Loader_Array(array('foo' => 'bar')));
81 95
 
82
-        $this->assertEquals('bar', $loader->getSource('foo'));
96
+        $this->assertEquals('bar', $loader->getSourceContext('foo')->getCode());
83 97
     }
84 98
 
85 99
     public function testExists()
86 100
     {
87
-        $loader1 = $this->getMockBuilder('Twig_Loader_Array')->setMethods(array('exists', 'getSource'))->disableOriginalConstructor()->getMock();
101
+        $loader1 = $this->getMockBuilder('Twig_Loader_Array')->setMethods(array('exists', 'getSourceContext'))->disableOriginalConstructor()->getMock();
88 102
         $loader1->expects($this->once())->method('exists')->will($this->returnValue(false));
89
-        $loader1->expects($this->never())->method('getSource');
103
+        $loader1->expects($this->never())->method('getSourceContext');
90 104
 
91
-        $loader2 = $this->getMockBuilder('Twig_LoaderInterface')->getMock();
105
+        // can be removed in 2.0
106
+        $loader2 = $this->getMockBuilder('Twig_ChainTestLoaderInterface')->getMock();
107
+        //$loader2 = $this->getMockBuilder(array('Twig_LoaderInterface', 'Twig_SourceContextLoaderInterface'))->getMock();
92 108
         $loader2->expects($this->once())->method('exists')->will($this->returnValue(true));
93
-        $loader2->expects($this->never())->method('getSource');
109
+        $loader2->expects($this->never())->method('getSourceContext');
94 110
 
95 111
         $loader = new Twig_Loader_Chain();
96 112
         $loader->addLoader($loader1);
... ...
@@ -99,3 +115,7 @@ class Twig_Tests_Loader_ChainTest extends PHPUnit_Framework_TestCase
99 115
         $this->assertTrue($loader->exists('foo'));
100 116
     }
101 117
 }
118
+
119
+interface Twig_ChainTestLoaderInterface extends Twig_LoaderInterface, Twig_SourceContextLoaderInterface
120
+{
121
+}
... ...
@@ -88,9 +88,9 @@ class Twig_Tests_Loader_FilesystemTest extends PHPUnit_Framework_TestCase
88 88
 
89 89
         // do not use realpath here as it would make the test unuseful
90 90
         $this->assertEquals($cacheKey, str_replace('\\', '/', $loader->getCacheKey('@named/named_absolute.html')));
91
-        $this->assertEquals("path (final)\n", $loader->getSource('index.html'));
92
-        $this->assertEquals("path (final)\n", $loader->getSource('@__main__/index.html'));
93
-        $this->assertEquals("named path (final)\n", $loader->getSource('@named/index.html'));
91
+        $this->assertEquals("path (final)\n", $loader->getSourceContext('index.html')->getCode());
92
+        $this->assertEquals("path (final)\n", $loader->getSourceContext('@__main__/index.html')->getCode());
93
+        $this->assertEquals("named path (final)\n", $loader->getSourceContext('@named/index.html')->getCode());
94 94
     }
95 95
 
96 96
     public function getBasePaths()
... ...
@@ -147,7 +147,7 @@ class Twig_Tests_Loader_FilesystemTest extends PHPUnit_Framework_TestCase
147 147
         $loader->addPath($basePath.'/named', 'named');
148 148
 
149 149
         try {
150
-            $loader->getSource('@named/nowhere.html');
150
+            $loader->getSourceContext('@named/nowhere.html');
151 151
         } catch (Exception $e) {
152 152
             $this->assertInstanceof('Twig_Error_Loader', $e);
153 153
             $this->assertContains('Unable to find template "@named/nowhere.html"', $e->getMessage());
... ...
@@ -162,11 +162,11 @@ class Twig_Tests_Loader_FilesystemTest extends PHPUnit_Framework_TestCase
162 162
         $loader->addPath($basePath.'/named', 'named');
163 163
 
164 164
         // prime the cache for index.html in the named namespace
165
-        $namedSource = $loader->getSource('@named/index.html');
165
+        $namedSource = $loader->getSourceContext('@named/index.html')->getCode();
166 166
         $this->assertEquals("named path\n", $namedSource);
167 167
 
168 168
         // get index.html from the main namespace
169
-        $this->assertEquals("path\n", $loader->getSource('index.html'));
169
+        $this->assertEquals("path\n", $loader->getSourceContext('index.html')->getCode());
170 170
     }
171 171
 
172 172
     public function testLoadTemplateAndRenderBlockWithCache()
... ...
@@ -218,6 +218,6 @@ class Twig_Tests_Loader_FilesystemTest extends PHPUnit_Framework_TestCase
218 218
         // $f = new Phar('phar-test.phar');
219 219
         // $f->addFromString('hello.twig', 'hello from phar');
220 220
         $loader->addPath('phar://'.dirname(__FILE__).'/Fixtures/phar/phar-sample.phar');
221
-        $this->assertSame('hello from phar', $loader->getSource('hello.twig'));
221
+        $this->assertSame('hello from phar', $loader->getSourceContext('hello.twig')->getCode());
222 222
     }
223 223
 }
... ...
@@ -147,7 +147,7 @@ class Twig_Tests_ParserTest extends PHPUnit_Framework_TestCase
147 147
     {{ foo }}
148 148
 {% endmacro %}
149 149
 EOF
150
-        )));
150
+        , 'index')));
151 151
     }
152 152
 
153 153
     protected function getParser()
... ...
@@ -156,7 +156,7 @@ EOF
156 156
         $parser->setParent(new Twig_Node());
157 157
 
158 158
         $stream = $this->getMockBuilder('Twig_TokenStream')->disableOriginalConstructor()->getMock();
159
-        $stream->expects($this->any())->method('getSourceContext')->will($this->returnValue(new Twig_Source('')));
159
+        $stream->expects($this->any())->method('getSourceContext')->will($this->returnValue(new Twig_Source('', '')));
160 160
 
161 161
         $p = new ReflectionProperty($parser, 'stream');
162 162
         $p->setAccessible(true);