Now handles all but 11 files

This commit is contained in:
Hackerpilot 2013-07-05 04:08:53 +00:00
parent 4edd57eb12
commit 3acdffdc6b
2 changed files with 186 additions and 249 deletions

View File

@ -60,7 +60,6 @@ abstract class ASTVisitor
/** */ void visit(AssocArrayLiteral assocArrayLiteral) { assocArrayLiteral.accept(this); }
/** */ void visit(AtAttribute atAttribute) { atAttribute.accept(this); }
/** */ void visit(Attribute attribute) { attribute.accept(this); }
/** */ void visit(AttributedDeclaration attributedDeclaration) { attributedDeclaration.accept(this); }
/** */ void visit(AutoDeclaration autoDeclaration) { autoDeclaration.accept(this); }
/** */ void visit(BlockStatement blockStatement) { blockStatement.accept(this); }
/** */ void visit(BodyStatement bodyStatement) { bodyStatement.accept(this); }
@ -548,21 +547,6 @@ public:
/** */ Token identifier;
}
///
class AttributedDeclaration : ASTNode
{
public:
override void accept(ASTVisitor visitor)
{
if (attribute !is null)
visitor.visit(attribute);
if (declaration !is null)
visitor.visit(declaration);
}
/** */ Attribute attribute;
/** */ Declaration declaration;
}
///
class Attribute : ASTNode
{
@ -571,17 +555,22 @@ public:
/** */ LinkageAttribute linkageAttribute;
/** */ AlignAttribute alignAttribute;
/** */ PragmaExpression pragmaExpression;
/** */ Deprecated deprecated_;
/** */ AtAttribute atAttribute;
/** */ StorageClass storageClass;
/** */ TokenType attribute;
}
///
class AttributeDeclaration : ASTNode
{
mixin(DEFAULT_ACCEPT);
/** */ Attribute attribute;
}
///
class AutoDeclaration : ASTNode
{
public:
mixin(DEFAULT_ACCEPT);
/** */ StorageClass storageClass;
/** */ Token[] identifiers;
/** */ Initializer[] initializers;
}
@ -734,8 +723,8 @@ class ConditionalDeclaration : ASTNode
public:
mixin(DEFAULT_ACCEPT);
/** */ CompileCondition compileCondition;
/** */ Declaration[] trueDeclarations;
/** */ Declaration[] falseDeclarations;
/** */ Declaration trueDeclaration;
/** */ Declaration falseDeclaration;
}
///
@ -801,7 +790,6 @@ public:
override void accept(ASTVisitor visitor)
{
if (attributedDeclaration !is null) visitor.visit(attributedDeclaration);
if (importDeclaration !is null) visitor.visit(importDeclaration);
if (functionDeclaration !is null) visitor.visit(functionDeclaration);
if (variableDeclaration !is null) visitor.visit(variableDeclaration);
@ -828,7 +816,8 @@ public:
if (versionSpecification !is null) visitor.visit(versionSpecification);
}
/** */ AttributedDeclaration attributedDeclaration;
/** */ Attribute[] attributes;
/** */ AttributeDeclaration attributeDeclaration;
/** */ ImportDeclaration importDeclaration;
/** */ FunctionDeclaration functionDeclaration;
/** */ VariableDeclaration variableDeclaration;
@ -1773,6 +1762,7 @@ class StorageClass : ASTNode
public:
mixin(DEFAULT_ACCEPT);
/** */ AtAttribute atAttribute;
/** */ Deprecated deprecated_;
/** */ Token token;
}

View File

@ -23,7 +23,7 @@
* definitions end with a semicolon (;).)
* )
*
* The grammar for D starts with the $(LINK2 #.module, module) rule.
* The grammar for D starts with the $(LINK2 #module, module) rule.
*
* Examples:
* ---
@ -56,7 +56,7 @@
* MACROS:
* GRAMMAR = $(D_CODE $0)
* RULEDEF = $(DDOC_ANCHOR $0) $(B $0)
* RULE = $(LINK2 #.$0, $(B $0))
* RULE = $(LINK2 #$0, $(B $0))
* LITERAL = $(D_STRING $0)
*/
@ -323,7 +323,8 @@ alias core.sys.posix.stdio.fileno fileno;
mixin(traceEnterAndExit!(__FUNCTION__));
auto node = new ArrayLiteral;
if (expect(TokenType.lBracket) is null) return null;
node.argumentList = parseArgumentList(true);
if (!currentIs(TokenType.rBracket))
node.argumentList = parseArgumentList(true);
if (expect(TokenType.rBracket) is null) return null;
return node;
}
@ -743,32 +744,15 @@ alias core.sys.posix.stdio.fileno fileno;
* Parses an Attribute
*
* $(GRAMMAR $(RULEDEF attribute):
* $(RULE linkageAttribute)
* | $(RULE alignAttribute)
* $(RULE alignAttribute)
* | $(RULE linkageAttribute)
* | $(RULE pragmaExpression)
* | $(RULE deprecated)
* | $(RULE atAttribute)
* | $(LITERAL 'private')
* | $(RULE storageClass)
* | $(LITERAL 'export')
* | $(LITERAL 'package')
* | $(LITERAL 'private')
* | $(LITERAL 'protected')
* | $(LITERAL 'public')
* | $(LITERAL 'export')
* | $(LITERAL 'extern')
* | $(LITERAL 'final')
* | $(LITERAL 'synchronized')
* | $(LITERAL 'override')
* | $(LITERAL 'abstract')
* | $(LITERAL 'const')
* | $(LITERAL 'auto')
* | $(LITERAL 'scope')
* | $(LITERAL '___gshared')
* | $(LITERAL 'shared')
* | $(LITERAL 'immutable')
* | $(LITERAL 'inout')
* | $(LITERAL 'static')
* | $(LITERAL 'pure')
* | $(LITERAL 'nothrow')
* | $(LITERAL 'enum')
* ;)
*/
Attribute parseAttribute()
@ -781,7 +765,7 @@ alias core.sys.posix.stdio.fileno fileno;
if (peekIs(TokenType.lParen))
node.linkageAttribute = parseLinkageAttribute();
else
node.attribute = advance().type;
goto default;
break;
case TokenType.align_:
node.alignAttribute = parseAlignAttribute();
@ -789,62 +773,32 @@ alias core.sys.posix.stdio.fileno fileno;
case TokenType.pragma_:
node.pragmaExpression = parsePragmaExpression();
break;
case TokenType.deprecated_:
node.deprecated_ = parseDeprecated();
break;
case TokenType.private_:
case TokenType.package_:
case TokenType.protected_:
case TokenType.public_:
case TokenType.export_:
case TokenType.final_:
case TokenType.synchronized_:
case TokenType.override_:
case TokenType.abstract_:
case TokenType.const_:
case TokenType.auto_:
case TokenType.scope_:
case TokenType.gshared:
case TokenType.shared_:
case TokenType.immutable_:
case TokenType.inout_:
case TokenType.static_:
case TokenType.pure_:
case TokenType.nothrow_:
case TokenType.enum_:
node.attribute = advance().type;
break;
case TokenType.at:
node.atAttribute = parseAtAttribute();
break;
default:
error("Attribute expected");
return null;
node.storageClass = parseStorageClass();
break;
}
return node;
}
/**
* Parses an AttributedDeclaration
* Parses an AttributeDeclaration
*
* $(GRAMMAR $(RULEDEF attributedDeclaration):
* $(RULE attribute) ($(LITERAL ':') | $(RULE declaration) | $(LITERAL '{') $(RULE declaration)* $(LITERAL '}'))
* $(GRAMMAR $(RULEDEF attributeDeclaration):
* $(RULE attribute) $(LITERAL ':')
* ;)
*/
AttributedDeclaration parseAttributedDeclaration()
AttributeDeclaration parseAttributeDeclaration(Attribute attribute = null)
{
mixin(traceEnterAndExit!(__FUNCTION__));
auto node = new AttributedDeclaration;
node.attribute = parseAttribute();
switch (current.type)
{
case TokenType.colon:
advance();
break;
default:
node.declaration = parseDeclaration();
break;
}
auto node = new AttributeDeclaration;
node.attribute = attribute is null ? parseAttribute() : attribute;
expect(TokenType.colon);
return node;
}
@ -859,8 +813,6 @@ alias core.sys.posix.stdio.fileno fileno;
{
mixin(traceEnterAndExit!(__FUNCTION__));
auto node = new AutoDeclaration;
node.storageClass = parseStorageClass();
if (node.storageClass is null) return null;
do
{
auto ident = expect(TokenType.identifier);
@ -1464,7 +1416,7 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
auto dec = parseDeclaration();
if (dec is null) return null;
node.trueDeclarations ~= dec;
node.trueDeclaration = dec;
if(currentIs(TokenType.else_))
advance();
@ -1473,7 +1425,7 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
auto elseDec = parseDeclaration();
if (elseDec is null) return null;
node.falseDeclarations ~= elseDec;
node.falseDeclaration = elseDec;
return node;
}
@ -1520,8 +1472,7 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
* Parses a Constructor
*
* $(GRAMMAR $(RULEDEF constructor):
* $(LITERAL 'this') $(RULE templateParameters) $(RULE parameters) $(RULE memberFunctionAttribute)* $(RULE constraint)? $(RULE functionBody)
* | $(LITERAL 'this') $(RULE parameters) $(RULE memberFunctionAttribute)* ($(RULE functionBody) | $(LITERAL ';'))
* $(LITERAL 'this') $(RULE templateParameters) $(RULE parameters) $(RULE memberFunctionAttribute)* $(RULE constraint)? ($(RULE functionBody) | $(LITERAL ';'))
* ;)
*/
Constructor parseConstructor()
@ -1544,9 +1495,7 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
if (isTemplate && currentIs(TokenType.if_))
node.constraint = parseConstraint();
if (isTemplate)
node.functionBody = parseFunctionBody();
else if (currentIs(TokenType.semicolon))
if (currentIs(TokenType.semicolon))
advance();
else
node.functionBody = parseFunctionBody();
@ -1640,9 +1589,11 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
* Parses a Declaration
*
* $(GRAMMAR $(RULEDEF declaration):
* $(RULE attribute)* $(declaration2)
* ;
* $(RULEDEF declaration2):
* $(RULE aliasDeclaration)
* | $(RULE aliasThisDeclaration)
* | $(RULE attributedDeclaration)
* | $(RULE classDeclaration)
* | $(RULE conditionalDeclaration)
* | $(RULE constructor)
@ -1664,6 +1615,7 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
* | $(RULE unionDeclaration)
* | $(RULE unittest)
* | $(RULE variableDeclaration)
* | $(RULE attributeDeclaration)
* | $(LITERAL '{') $(RULE declaration)+ $(LITERAL '}')
* ;)
*/
@ -1671,6 +1623,23 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
{
mixin(traceEnterAndExit!(__FUNCTION__));
auto node = new Declaration;
do
{
if (!isAttribute())
break;
auto attr = parseAttribute();
if (attr is null)
{
error("attribute is null");
break;
}
if (currentIs(TokenType.colon))
node.attributeDeclaration = parseAttributeDeclaration(attr);
else
node.attributes ~= attr;
} while (true);
with (TokenType) switch (current.type)
{
case semicolon:
@ -1704,34 +1673,7 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
node.destructor = parseDestructor();
break;
case enum_:
if (peekIsOneOf(TokenType.lBrace, TokenType.colon))
node.enumDeclaration = parseEnumDeclaration();
else if (!peekIs(TokenType.identifier))
goto storageClass;
else
{
auto b = setBookmark();
advance();
assert (current.type == identifier);
if (peekIs(TokenType.assign))
{
trace("** 'enum identifier =' ");
goToBookmark(b);
node.variableDeclaration = parseVariableDeclaration();
}
else if (peekIsOneOf(TokenType.lBrace, TokenType.colon, TokenType.semicolon))
{
trace("** 'enum identifier { : ;' ");
goToBookmark(b);
node.enumDeclaration = parseEnumDeclaration();
}
else
{
trace("** something else");
goToBookmark(b);
goto storageClass;
}
}
node.enumDeclaration = parseEnumDeclaration();
break;
case import_:
node.importDeclaration = parseImportDeclaration();
@ -1753,22 +1695,20 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
node.sharedStaticConstructor = parseSharedStaticConstructor();
else if (startsWith(shared_, static_, tilde))
node.sharedStaticDestructor = parseSharedStaticDestructor();
else if (peekIs(lParen))
goto type;
else
node.attributedDeclaration = parseAttributedDeclaration();
goto type;
break;
case static_:
if (startsWith(static_, this_))
if (peekIs(this_))
node.staticConstructor = parseStaticConstructor();
else if (startsWith(static_, tilde))
else if (peekIs(tilde))
node.staticDestructor = parseStaticDestructor();
else if (startsWith(static_, if_))
else if (peekIs(if_))
node.conditionalDeclaration = parseConditionalDeclaration();
else if (startsWith(static_, assert_))
else if (peekIs(assert_))
node.staticAssertDeclaration = parseStaticAssertDeclaration();
else
node.attributedDeclaration = parseAttributedDeclaration();
goto type;
break;
case struct_:
node.structDeclaration = parseStructDeclaration();
@ -1782,9 +1722,26 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
case unittest_:
node.unittest_ = parseUnittest();
break;
case typeof_:
case bool_: .. case wchar_:
case identifier:
if (node.attributes.length > 0
&& node.attributes[$ - 1].storageClass !is null)
{
if (peekIs(assign))
node.variableDeclaration = parseVariableDeclaration(null, true);
else if (peekIs(lParen))
node.functionDeclaration = parseFunctionDeclaration(null, true);
else
goto type;
}
else
goto type;
break;
case const_:
case immutable_:
case inout_:
case scope_:
case typeof_:
mixin (BASIC_TYPE_CASE_RANGE);
type:
Type type = parseType();
if (!currentIs(identifier))
@ -1811,53 +1768,6 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
case debug_:
node.conditionalDeclaration = parseConditionalDeclaration();
break;
case auto_:
if (startsWith(auto_, ref_, identifier, lParen)
|| startsWith(auto_, identifier, lParen))
node.functionDeclaration = parseFunctionDeclaration();
else
goto storageClass;
break;
case ref_:
node.functionDeclaration = parseFunctionDeclaration();
break;
case const_:
if (startsWith(const_, identifier, assign))
node.variableDeclaration = parseVariableDeclaration();
else
goto typeConstructor;
break;
case immutable_:
if (startsWith(immutable_, identifier, assign))
node.variableDeclaration = parseVariableDeclaration();
else
goto typeConstructor;
break;
case inout_:
typeConstructor:
if (peekIs(TokenType.lParen))
goto type;
else
goto case;
case at:
case align_:
case deprecated_:
case private_:
case package_:
case protected_:
case public_:
case export_:
case extern_:
case final_:
case synchronized_:
case override_:
case abstract_:
case gshared:
case pure_:
case nothrow_:
storageClass:
node.attributedDeclaration = parseAttributedDeclaration();
break;
default:
error("Declaration expected");
advance();
@ -2017,7 +1927,7 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
* Parses a Destructor
*
* $(GRAMMAR $(RULEDEF destructor):
* $(LITERAL '~') $(LITERAL 'this') $(LITERAL '$(LPAREN)') $(LITERAL '$(RPAREN)') $(RULE functionBody)
* $(LITERAL '~') $(LITERAL 'this') $(LITERAL '$(LPAREN)') $(LITERAL '$(RPAREN)') ($(RULE functionBody) | $(LITERAL ';'))
* ;)
*/
Destructor parseDestructor()
@ -2028,7 +1938,10 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
if (expect(TokenType.this_) is null) return null;
if (expect(TokenType.lParen) is null) return null;
if (expect(TokenType.rParen) is null) return null;
node.functionBody = parseFunctionBody();
if (currentIs(TokenType.semicolon))
advance();
else
node.functionBody = parseFunctionBody();
return node;
}
@ -2497,47 +2410,23 @@ body {} // six
* Parses a FunctionDeclaration
*
* $(GRAMMAR $(RULEDEF functionDeclaration):
* $(RULE memberFunctionAttribute)* ($(RULE type) | $(LITERAL 'auto') $(LITERAL 'ref')? | $(LITERAL 'ref') $(LITERAL 'auto')?) $(LITERAL Identifier) $(RULE templateParameters) $(RULE parameters) $(RULE memberFunctionAttribute)* $(RULE constraint)? $(RULE functionBody)
* | $(RULE memberFunctionAttribute)* ($(RULE type) | $(LITERAL 'auto') $(LITERAL 'ref')? | $(LITERAL 'ref') $(LITERAL 'auto')?) $(LITERAL Identifier) $(RULE parameters) $(RULE memberFunctionAttribute)* ($(RULE functionBody) | $(LITERAL ';'))
* ($(RULE storageClass) | $(RULE _type)) $(LITERAL Identifier) $(RULE templateParameters) $(RULE parameters) $(RULE memberFunctionAttribute)* $(RULE constraint)? ($(RULE functionBody) | $(LITERAL ';'))
* ;)
*/
FunctionDeclaration parseFunctionDeclaration(Type type = null)
FunctionDeclaration parseFunctionDeclaration(Type type = null, bool isAuto = false)
{
mixin(traceEnterAndExit!(__FUNCTION__));
auto node = new FunctionDeclaration;
if (isAuto)
goto functionName;
while(moreTokens() && currentIsMemberFunctionAttribute())
node.memberFunctionAttributes ~= parseMemberFunctionAttribute();
with (TokenType) switch (current.type)
{
case auto_:
advance();
node.hasAuto = true;
if (currentIs(ref_))
{
node.hasRef = true;
advance();
}
break;
case ref_:
advance();
node.hasRef = true;
if (currentIs(auto_))
{
node.hasAuto = true;
advance();
break;
}
else if (startsWith(identifier, lParen))
break;
else
goto default;
default:
node.returnType = type is null ? parseType() : type;
break;
}
node.returnType = type is null ? parseType() : type;
functionName:
auto ident = expect(TokenType.identifier);
if (ident is null) return null;
@ -2549,6 +2438,7 @@ body {} // six
return null;
}
assert (currentIs(TokenType.lParen));
auto p = peekPastParens();
bool isTemplate = p !is null && p.type == TokenType.lParen;
@ -2563,9 +2453,7 @@ body {} // six
if (isTemplate && currentIs(TokenType.if_))
node.constraint = parseConstraint();
if (isTemplate)
node.functionBody = parseFunctionBody();
else if (currentIs(TokenType.semicolon))
if (currentIs(TokenType.semicolon))
advance();
else
node.functionBody = parseFunctionBody();
@ -3159,7 +3047,7 @@ invariant() foo();
* Parses an IsExpression
*
* $(GRAMMAR $(RULEDEF isExpression):
* $(LITERAL'is') $(LITERAL '$(LPAREN)') ($(RULE type) $(LITERAL Identifier)? (($(LITERAL ':') | $(LITERAL '==')) $(RULE typeSpecialization) ($(LITERAL ',') $(RULE templateParameterList))?)?)) $(LITERAL '$(RPAREN)')
* $(LITERAL'is') $(LITERAL '$(LPAREN)') ($(RULE type) $(LITERAL Identifier)? (($(LITERAL ':') | $(LITERAL '==')) $(RULE typeSpecialization) ($(LITERAL ',') $(RULE templateParameterList))?)?) $(LITERAL '$(RPAREN)')
* ;)
*/
IsExpression parseIsExpression()
@ -3851,6 +3739,7 @@ invariant() foo();
goto end;
if (currentIs(TokenType.vararg))
{
advance();
node.hasVarargs = true;
goto end;
}
@ -3909,7 +3798,7 @@ q{(int a, ...)
* Parses a Postblit
*
* $(GRAMMAR $(RULEDEF parameters):
* $(LITERAL 'this') $(LITERAL '$(LPAREN)') $(LITERAL 'this') $(LITERAL '$(RPAREN)') $(RULE functionBody)
* $(LITERAL 'this') $(LITERAL '$(LPAREN)') $(LITERAL 'this') $(LITERAL '$(RPAREN)') ($(RULE functionBody) | $(LITERAL ';'))
* ;)
*/
Postblit parsePostblit()
@ -3919,7 +3808,10 @@ q{(int a, ...)
expect(TokenType.lParen);
expect(TokenType.this_);
expect(TokenType.rParen);
node.functionBody = parseFunctionBody();
if (currentIs(TokenType.semicolon))
advance();
else
node.functionBody = parseFunctionBody();
return node;
}
@ -4467,18 +4359,19 @@ q{(int a, ...)
/**
* Parses an StorageClass
*
* $(GRAMMAR $(RULE storageClass):
* $(GRAMMAR $(RULEDEF storageClass):
* $(RULE atAttribute)
* | $(RULE typeConstructor)
* | $(RULE deprecated)
* | $(LITERAL 'abstract')
* | $(LITERAL 'auto')
* | $(LITERAL 'deprecated')
* | $(LITERAL 'enum')
* | $(LITERAL 'extern')
* | $(LITERAL 'final')
* | $(LITERAL 'nothrow')
* | $(LITERAL 'override')
* | $(LITERAL 'pure')
* | $(LITERAL 'ref')
* | $(LITERAL '___gshared')
* | $(LITERAL 'scope')
* | $(LITERAL 'static')
@ -4494,23 +4387,26 @@ q{(int a, ...)
node.atAttribute = parseAtAttribute();
if (node.atAttribute is null) return null;
break;
case deprecated_:
node.deprecated_ = parseDeprecated();
break;
case const_:
case immutable_:
case inout_:
case shared_:
case abstract_:
case auto_:
case deprecated_:
case enum_:
case extern_:
case final_:
case nothrow_:
case override_:
case pure_:
case ref_:
case gshared:
case scope_:
case static_:
case synchronized_:
case const_:
case immutable_:
case inout_:
case shared_:
node.token = advance();
break;
default:
@ -4564,7 +4460,7 @@ q{(int a, ...)
* Parses a StructDeclaration
*
* $(GRAMMAR $(RULEDEF structDeclaration):
* $(LITERAL 'struct') $(LITERAL Identifier) ($(RULE templateParameters) $(RULE constraint)? $(RULE structBody) | ($(RULE structBody) | $(LITERAL ';')))
* $(LITERAL 'struct') $(LITERAL Identifier)? ($(RULE templateParameters) $(RULE constraint)? $(RULE structBody) | ($(RULE structBody) | $(LITERAL ';')))
* ;)
*/
StructDeclaration parseStructDeclaration()
@ -4572,9 +4468,11 @@ q{(int a, ...)
mixin(traceEnterAndExit!(__FUNCTION__));
auto node = new StructDeclaration;
expect(TokenType.struct_);
auto ident = expect(TokenType.identifier);
if (ident is null) return null;
node.name = *ident;
if (currentIs(TokenType.identifier))
{
node.name = advance();
}
if (currentIs(TokenType.lParen))
{
node.templateParameters = parseTemplateParameters();
@ -4796,7 +4694,8 @@ q{(int a, ...)
{
mixin(traceEnterAndExit!(__FUNCTION__));
auto node = new TemplateArgument;
if (isType())
if (isBasicType(current.type) || !isExpression())
{
if ((node.type = parseType()) is null) return null;
}
@ -5708,14 +5607,11 @@ q{doStuff(5)}c;
* | $(RULE autoDeclaration)
* ;)
*/
VariableDeclaration parseVariableDeclaration(Type type = null)
VariableDeclaration parseVariableDeclaration(Type type = null, bool isAuto = false)
{
mixin (traceEnterAndExit!(__FUNCTION__));
auto node = new VariableDeclaration;
with (TokenType) if (currentIsOneOf(const_, immutable_, inout_, shared_,
abstract_, auto_, deprecated_, enum_, extern_, final_, nothrow_,
override_, pure_, gshared, scope_, static_, synchronized_)
&& !(peekIs(lParen)))
if (isAuto)
{
node.autoDeclaration = parseAutoDeclaration();
return node;
@ -5975,6 +5871,58 @@ private:
return parseType() !is null;
}
bool isAttribute()
{
if (!moreTokens()) return false;
with (TokenType) switch (current.type)
{
case const_:
case immutable_:
case inout_:
return !peekIs(TokenType.lParen);
case static_:
return !peekIsOneOf(assert_, this_, if_, tilde);
case shared_:
return !(startsWith(shared_, static_, this_)
|| startsWith(shared_, static_, tilde)
|| peekIs(TokenType.lParen));
case enum_:
if (peekIsOneOf(lBrace, colon, semicolon))
return false;
else if (peekIs(TokenType.identifier))
{
auto b = setBookmark();
scope(exit) goToBookmark(b);
advance();
if (peekIsOneOf(lBrace, colon, semicolon))
return false;
return true;
}
return true;
case deprecated_:
case private_:
case package_:
case protected_:
case public_:
case export_:
case final_:
case synchronized_:
case override_:
case abstract_:
case auto_:
case scope_:
case gshared:
case pure_:
case nothrow_:
case at:
case ref_:
case extern_:
return true;
default:
return false;
}
}
bool currentIsMemberFunctionAttribute() const
{
switch (current.type)
@ -6118,21 +6066,19 @@ private:
}
const(Token)* peekPast(alias O, alias C)()
in
{
assert (tokens[index].type == O);
}
body
{
if (index >= tokens.length)
return null;
int depth = 1;
auto i = index;
++i;
while (i < tokens.length)
{
if (i >= tokens.length)
return null;
if (tokens[i] == O)
{
++depth;
++i;
}
else if (tokens[i] == C)
{
--depth;
@ -6140,7 +6086,8 @@ private:
if (depth <= 0)
break;
}
++i;
else
++i;
}
return depth == 0 ? &tokens[i] : null;
}
@ -6270,8 +6217,8 @@ private:
template traceEnterAndExit(string fun)
{
enum traceEnterAndExit = `version (verbose) trace(">> ` ~ fun ~ ` ");`
~ `version (verbose) scope(exit) trace("<< ` ~ fun ~ ` ");`;
enum traceEnterAndExit = `version (verbose) trace(">>> ` ~ fun ~ ` ");`
~ `version (verbose) scope(exit) trace("<<< ` ~ fun ~ ` ");`;
}
version (verbose)