<commit_before>/*
   Copyright 2016 <NAME>, LLC

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

import ast
import source

extension Parser {
    /*
    - [x] enum-declaration → attributes/opt/ access-level-modifier/opt/ union-style-enum
    - [x] enum-declaration → attributes/opt/ access-level-modifier/opt/ raw-value-style-enum
    - [x] union-style-enum → `indirect`/opt/ `enum` enum-name generic-parameter-clause/opt/ type-inheritance-clause/opt/ `{` union-style-enum-members/opt/ `}`
    - [x] union-style-enum-members → union-style-enum-member union-style-enum-members/opt/
    - [_] union-style-enum-member → declaration | union-style-enum-case-clause
    - [x] union-style-enum-case-clause → attributes/opt/ `indirect`/opt/ `case` union-style-enum-case-list
    - [x] union-style-enum-case-list → union-style-enum-case | union-style-enum-case `,` union-style-enum-case-list
    - [x] union-style-enum-case → enum-case-name tuple-type/opt/
    - [x] enum-name → identifier
    - [x] enum-case-name → identifier
    - [x] raw-value-style-enum → `enum` enum-name generic-parameter-clause/opt/ type-inheritance-clause `{` raw-value-style-enum-members `}`
    - [x] raw-value-style-enum-members → raw-value-style-enum-member raw-value-style-enum-members/opt/
    - [_] raw-value-style-enum-member → declaration | raw-value-style-enum-case-clause
    - [x] raw-value-style-enum-case-clause → attributes/opt/ `case` raw-value-style-enum-case-list
    - [x] raw-value-style-enum-case-list → raw-value-style-enum-case | raw-value-style-enum-case `,` raw-value-style-enum-case-list
    - [x] raw-value-style-enum-case → enum-case-name raw-value-assignment/opt/
    - [x] raw-value-assignment → `=` raw-value-literal
    - [_] raw-value-literal → numeric-literal | static-string-literal | boolean-literal
    - [_] error handling
    */
    func parseEnumDeclaration(
        attributes attributes: [Attribute],
        declarationModifiers: [String],
        accessLevelModifier: AccessLevel,
        startLocation: SourceLocation) throws {
        skipWhitespaces()

        var containsMissingSeparatorError = false

        guard let enumName = readIdentifier(includeContextualKeywords: true) else {
            throw ParserError.MissingIdentifier
        }
        skipWhitespaces()

        let genericParameterClause = try? parseGenericParameterClause()

        let typeInheritanceClause = try parseTypeInheritanceClause()
        let (containsClassRequirement, typeInheritance) = refineTypeInheritanceClause(typeInheritanceClause)

        if let token = currentToken, case let .Punctuator(type) = token where type == .LeftBrace {
            skipWhitespaces()

            var enumCases = [EnumCaseDelcaration]()

            var caseAttributes = parseAttributes()
            var caseModifiers = parseDeclarationModifiers()
            while let token = currentToken, case let .Keyword(keywordName, _) = token where keywordName == "case" {
                skipWhitespaces()
                let enumCaseDecl = try parseEnumCaseDeclaration(attributes: caseAttributes, caseModifiers: caseModifiers)
                enumCases.append(enumCaseDecl)

                try unshiftToken()
                while let token = currentToken where token.isWhitespace() {
                    try unshiftToken()
                }
                do {
                    try ensureStatementSeparator(stopAtRightBrace: true)
                }
                catch _ {
                    containsMissingSeparatorError = true // just to delay throw this
                } // TODO: ^ this block of code needs to be re-considered

                if let token = currentToken, case let .Punctuator(punctuatorType) = token where punctuatorType == .RightBrace {
                    break
                }

                skipWhitespaces(treatSemiAsWhitespace: true)

                caseAttributes = parseAttributes()
                caseModifiers = parseDeclarationModifiers()
            }

            if let token = currentToken, case let .Punctuator(type) = token where type == .RightBrace {
                // TODO: too nested
                var enumDeclAccessLevel = accessLevelModifier
                switch accessLevelModifier {
                case .PublicSet, .InternalSet, .PrivateSet:
                    enumDeclAccessLevel = .Default
                default: ()
                }
                let enumDecl = EnumDeclaration(
                    name: enumName,
                    genericParameter: genericParameterClause,
                    cases: enumCases,
                    attributes: attributes,
                    modifiers: declarationModifiers,
                    accessLevel: enumDeclAccessLevel,
                    typeInheritance: typeInheritance)
                if let currentRange = currentRange ?? consumedTokens.last?.1 {
                    enumDecl.sourceRange = SourceRange(start: startLocation, end: currentRange.end)
                }
                topLevelCode.append(enumDecl)
                switch accessLevelModifier {
                case .PublicSet, .InternalSet, .PrivateSet:
                    throw ParserError.InvalidModifierToDeclaration(accessLevelModifier.errorDescription)
                default: ()<commit_msg>We already check current token exists, so current range must exist<commit_after>/*
   Copyright 2016 <NAME>, LLC

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

import ast
import source

extension Parser {
    /*
    - [x] enum-declaration → attributes/opt/ access-level-modifier/opt/ union-style-enum
    - [x] enum-declaration → attributes/opt/ access-level-modifier/opt/ raw-value-style-enum
    - [x] union-style-enum → `indirect`/opt/ `enum` enum-name generic-parameter-clause/opt/ type-inheritance-clause/opt/ `{` union-style-enum-members/opt/ `}`
    - [x] union-style-enum-members → union-style-enum-member union-style-enum-members/opt/
    - [_] union-style-enum-member → declaration | union-style-enum-case-clause
    - [x] union-style-enum-case-clause → attributes/opt/ `indirect`/opt/ `case` union-style-enum-case-list
    - [x] union-style-enum-case-list → union-style-enum-case | union-style-enum-case `,` union-style-enum-case-list
    - [x] union-style-enum-case → enum-case-name tuple-type/opt/
    - [x] enum-name → identifier
    - [x] enum-case-name → identifier
    - [x] raw-value-style-enum → `enum` enum-name generic-parameter-clause/opt/ type-inheritance-clause `{` raw-value-style-enum-members `}`
    - [x] raw-value-style-enum-members → raw-value-style-enum-member raw-value-style-enum-members/opt/
    - [_] raw-value-style-enum-member → declaration | raw-value-style-enum-case-clause
    - [x] raw-value-style-enum-case-clause → attributes/opt/ `case` raw-value-style-enum-case-list
    - [x] raw-value-style-enum-case-list → raw-value-style-enum-case | raw-value-style-enum-case `,` raw-value-style-enum-case-list
    - [x] raw-value-style-enum-case → enum-case-name raw-value-assignment/opt/
    - [x] raw-value-assignment → `=` raw-value-literal
    - [_] raw-value-literal → numeric-literal | static-string-literal | boolean-literal
    - [_] error handling
    */
    func parseEnumDeclaration(
        attributes attributes: [Attribute],
        declarationModifiers: [String],
        accessLevelModifier: AccessLevel,
        startLocation: SourceLocation) throws {
        skipWhitespaces()

        var containsMissingSeparatorError = false

        guard let enumName = readIdentifier(includeContextualKeywords: true) else {
            throw ParserError.MissingIdentifier
        }
        skipWhitespaces()

        let genericParameterClause = try? parseGenericParameterClause()

        let typeInheritanceClause = try parseTypeInheritanceClause()
        let (containsClassRequirement, typeInheritance) = refineTypeInheritanceClause(typeInheritanceClause)

        if let token = currentToken, case let .Punctuator(type) = token where type == .LeftBrace {
            skipWhitespaces()

            var enumCases = [EnumCaseDelcaration]()

            var caseAttributes = parseAttributes()
            var caseModifiers = parseDeclarationModifiers()
            while let token = currentToken, case let .Keyword(keywordName, _) = token where keywordName == "case" {
                skipWhitespaces()
                let enumCaseDecl = try parseEnumCaseDeclaration(attributes: caseAttributes, caseModifiers: caseModifiers)
                enumCases.append(enumCaseDecl)

                try unshiftToken()
                while let token = currentToken where token.isWhitespace() {
                    try unshiftToken()
                }
                do {
                    try ensureStatementSeparator(stopAtRightBrace: true)
                }
                catch _ {
                    containsMissingSeparatorError = true // just to delay throw this
                } // TODO: ^ this block of code needs to be re-considered

                if let token = currentToken, case let .Punctuator(punctuatorType) = token where punctuatorType == .RightBrace {
                    break
                }

                skipWhitespaces(treatSemiAsWhitespace: true)

                caseAttributes = parseAttributes()
                caseModifiers = parseDeclarationModifiers()
            }

            if let token = currentToken, case let .Punctuator(type) = token where type == .RightBrace {
                // TODO: too nested
                var enumDeclAccessLevel = accessLevelModifier
                switch accessLevelModifier {
                case .PublicSet, .InternalSet, .PrivateSet:
                    enumDeclAccessLevel = .Default
                default: ()
                }
                let enumDecl = EnumDeclaration(
                    name: enumName,
                    genericParameter: genericParameterClause,
                    cases: enumCases,
                    attributes: attributes,
                    modifiers: declarationModifiers,
                    accessLevel: enumDeclAccessLevel,
                    typeInheritance: typeInheritance)
                if let currentRange = currentRange {
                    enumDecl.sourceRange = SourceRange(start: startLocation, end: currentRange.end)
                }
                topLevelCode.append(enumDecl)
                switch accessLevelModifier {
                case .PublicSet, .InternalSet, .PrivateSet:
                    throw ParserError.InvalidModifierToDeclaration(accessLevelModifier.errorDescription)
                default: ()
{'fraction_non_alphanumeric': 0.0928182525278714, 'fraction_numerical': 0.0014691902169216143, 'mean_word_length': 2.2260942291608585, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7577564', 'n_tokens_mistral': 3135, 'n_tokens_neox': 3023, 'n_words': 769}