Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Added "base types" to extension types. #41

Closed
wants to merge 1 commit into from

1 participant

@jmalloc
Collaborator

This allows for a syntax whereby an extension type is literally an extension to an existing type.
For example, in the constraints library I am writing I would like to be able to constrain an integer to a certain range,
the syntax extension in this pull requests allows the following:

@param integer:Constraint { min: 0, max: 200 }

I think this is quite expressive and allows for even greater flexibility. The previous syntax remains:

@param :Constraint { min: 0, max: 200 }

In this case, the "base type" simply defaults to a MixedType.

@jmalloc jmalloc Added "base types" to extension types.
This allows for a syntax whereby an extension type is literally an extension to an existing type.
For example, in the constraints library I am writing I would like to be able to constrain an integer to a certain range,
the syntax extension in this pull requests allows the following:

    @param integer:Constraint { min: 0, max: 200 }

I think this is quite expressive and allows for even greater flexibility. The previous syntax remains:

    @param :Constraint { min: 0, max: 200 }

In this case, the "base type" simply defaults to a MixedType.
c9e98ea
@jmalloc
Collaborator

Closed in favour of #42.

@jmalloc jmalloc closed this
@jmalloc jmalloc deleted the unknown repository branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 23, 2013
  1. @jmalloc

    Added "base types" to extension types.

    jmalloc authored
    This allows for a syntax whereby an extension type is literally an extension to an existing type.
    For example, in the constraints library I am writing I would like to be able to constrain an integer to a certain range,
    the syntax extension in this pull requests allows the following:
    
        @param integer:Constraint { min: 0, max: 200 }
    
    I think this is quite expressive and allows for even greater flexibility. The previous syntax remains:
    
        @param :Constraint { min: 0, max: 200 }
    
    In this case, the "base type" simply defaults to a MixedType.
This page is out of date. Refresh to see the latest.
View
2  README.md
@@ -200,6 +200,8 @@ As an example, `array('foo', 1)` satisfies the constraint `tuple<string, integer
:ClassName
:ClassName {...}
+ baseType:ClassName
+ baseType:ClassName {...}
Extensions provide a means to expand the capabilies of Typhax with custom logic.
For an example of how extensions can be utilized, see the
View
12 src/Eloquent/Typhax/Parser/Parser.php
@@ -179,6 +179,11 @@ function() use (&$tokens, &$count) {
);
}
+ if ($this->currentTokenIsType($tokens, Token::TOKEN_COLON)) {
+ next($tokens);
+ $type = $this->parseExtensionType($tokens, $type);
+ }
+
return $type;
}
@@ -255,7 +260,7 @@ protected function parseTypeName(array &$tokens)
*
* @return ExtensionType
*/
- protected function parseExtensionType(array &$tokens)
+ protected function parseExtensionType(array &$tokens, Type $baseType = null)
{
$this->consumeWhitespace($tokens);
@@ -271,7 +276,12 @@ protected function parseExtensionType(array &$tokens)
$attributes = array();
}
+ if (null === $baseType) {
+ $baseType = new MixedType;
+ }
+
return new ExtensionType(
+ $baseType,
ClassName::fromString($token->content()),
$attributes
);
View
13 src/Eloquent/Typhax/Type/ExtensionType.php
@@ -17,16 +17,26 @@
class ExtensionType extends Host implements Type
{
/**
+ * @param Type $baseType
* @param ClassName $className
* @param array $attributes
*/
- public function __construct(ClassName $className, array $attributes)
+ public function __construct(Type $baseType, ClassName $className, array $attributes)
{
+ $this->baseType = $baseType;
$this->className = $className;
$this->attributes = $attributes;
}
/**
+ * @return Type
+ */
+ public function baseType()
+ {
+ return $this->baseType;
+ }
+
+ /**
* @return ClassName
*/
public function className()
@@ -42,6 +52,7 @@ public function attributes()
return $this->attributes;
}
+ private $baseType;
private $className;
private $attributes;
}
View
33 test/suite/Eloquent/Typhax/Lexer/LexerTest.php
@@ -412,6 +412,39 @@ public function tokenData()
);
$data[] = array($expected, $source);
+ // #20: Extension type with explicit base type
+ $source = 'string:Foo\Bar\Baz';
+ $expected = array(
+ new Token(Token::TOKEN_TYPE_NAME, 'string'),
+ new Token(Token::TOKEN_COLON, ':'),
+ new Token(Token::TOKEN_STRING, 'Foo\Bar\Baz'),
+ );
+ $data[] = array($expected, $source);
+
+ // #21: Extension type with explicit base type of object
+ $source = 'Baz:Foo\Bar\Baz';
+ $expected = array(
+ new Token(Token::TOKEN_STRING, 'Baz'),
+ new Token(Token::TOKEN_COLON, ':'),
+ new Token(Token::TOKEN_STRING, 'Foo\Bar\Baz'),
+ );
+ $data[] = array($expected, $source);
+
+ // #22: Extension type with explicit base type and attributes
+ $source = 'string:Foo\Bar\Baz{foo: bar}';
+ $expected = array(
+ new Token(Token::TOKEN_TYPE_NAME, 'string'),
+ new Token(Token::TOKEN_COLON, ':'),
+ new Token(Token::TOKEN_STRING, 'Foo\Bar\Baz'),
+ new Token(Token::TOKEN_BRACE_OPEN, '{'),
+ new Token(Token::TOKEN_STRING, 'foo'),
+ new Token(Token::TOKEN_COLON, ':'),
+ new Token(Token::TOKEN_WHITESPACE, ' '),
+ new Token(Token::TOKEN_STRING, 'bar'),
+ new Token(Token::TOKEN_BRACE_CLOSE, '}'),
+ );
+ $data[] = array($expected, $source);
+
return $data;
}
View
25 test/suite/Eloquent/Typhax/Parser/ParserTest.php
@@ -254,14 +254,35 @@ public function parserData()
$source = ' : Foo\Bar ';
$position = 12;
- $expected = new ExtensionType(ClassName::fromString('Foo\Bar'), array());
+ $expected = new ExtensionType(
+ new MixedType,
+ ClassName::fromString('Foo\Bar'),
+ array()
+ );
$data["Parse extension type"] = array($expected, $position, $source);
$source = ' : Foo\Bar { foo: bar }';
$position = 24;
- $expected = new ExtensionType(ClassName::fromString('Foo\Bar'), array('foo' => 'bar'));
+ $expected = new ExtensionType(
+ new MixedType,
+ ClassName::fromString('Foo\Bar'),
+ array('foo' => 'bar')
+ );
$data["Parse extension type with attributes"] = array($expected, $position, $source);
+ $source = ' tuple < foo , bar , baz > : Foo\Bar { foo: bar } ';
+ $position = 51;
+ $expected = new ExtensionType(
+ new TupleType(array(
+ new ObjectType(ClassName::fromString('foo')),
+ new ObjectType(ClassName::fromString('bar')),
+ new ObjectType(ClassName::fromString('baz')),
+ )),
+ ClassName::fromString('Foo\Bar'),
+ array('foo' => 'bar')
+ );
+ $data["Parse extension type with explicit base type"] = array($expected, $position, $source);
+
return $data;
}
View
4 test/suite/Eloquent/Typhax/Type/ExtensionTypeTest.php
@@ -18,11 +18,13 @@ class ExtensionTypeTest extends PHPUnit_Framework_TestCase
{
public function testExtensionType()
{
+ $baseType = new MixedType;
$className = ClassName::fromString('foo');
$attributes = array('foo' => 'bar');
- $type = new ExtensionType($className, $attributes);
+ $type = new ExtensionType($baseType, $className, $attributes);
+ $this->assertSame($baseType, $type->baseType());
$this->assertSame($className, $type->className());
$this->assertSame($attributes, $type->attributes());
}
Something went wrong with that request. Please try again.