Skip to content

Assertion error with if-else-if inside class #5444

Closed

Description

@jeffreymorlan

Type-checking the following (broken) program:

class C {
    if (a) {}
    else if (0) {}
}

results in an assertion error:

Error: Debug Failure. False expression: 
    at Object.assert (/home/jeffrey/TypeScript-1.6.2/lib/tsc.js:724:23)
    at reportImplementationExpectedError (/home/jeffrey/TypeScript-1.6.2/lib/tsc.js:18530:38)
    at checkFunctionOrConstructorSymbol (/home/jeffrey/TypeScript-1.6.2/lib/tsc.js:18580:25)
    at checkFunctionLikeDeclaration (/home/jeffrey/TypeScript-1.6.2/lib/tsc.js:18943:21)
    at checkMethodDeclaration (/home/jeffrey/TypeScript-1.6.2/lib/tsc.js:18251:13)
    at checkSourceElement (/home/jeffrey/TypeScript-1.6.2/lib/tsc.js:20413:28)
    at Object.forEach (/home/jeffrey/TypeScript-1.6.2/lib/tsc.js:90:30)
    at checkClassDeclaration (/home/jeffrey/TypeScript-1.6.2/lib/tsc.js:19663:16)
    at checkSourceElement (/home/jeffrey/TypeScript-1.6.2/lib/tsc.js:20477:28)
    at Object.forEach (/home/jeffrey/TypeScript-1.6.2/lib/tsc.js:90:30)

Activity

  1. mhegazy commented on Oct 29, 2015

    @mhegazy
    Contributor

    A PR would be appreciated.

  2. added this to the milestone on Oct 29, 2015
  3. jeffreymorlan commented on Oct 31, 2015

    @jeffreymorlan
    ContributorAuthor

    I don't know what the right fix to this is, but here's my analysis:

    • The "if"s are getting parsed as MethodDeclarations. The first method node's .end is less than the second method node's .pos because of the intervening erroneous "else", which does not become a node.

    • checkFunctionOrConstructSymbol loops over declarations of a symbol. If declarations are not "consecutive", it calls reportImplementationExpectedError on the earlier one:

      else if (!isExportSymbolInsideModule && previousDeclaration && previousDeclaration.parent === node.parent && previousDeclaration.end !== node.pos) {
          reportImplementationExpectedError(previousDeclaration);
      }
    • reportImplementationExpectedError assumes that its node and its next sibling (found by ts.forEachChild) must be for different symbols (and thus differ in some way: kind, name, or static-ness). Because if they were for the same symbol, those would be "consecutive" declarations and not an error.

    The problem is the two different definitions of what makes nodes "consecutive". Is it node.pos === prev.end, or being next in the ts.forEachChild iteration? cFOCS uses the former definition, while rIEE uses the latter. And with the current parser, they are not the same.

  4. mhegazy commented on Nov 7, 2015

    @mhegazy
    Contributor
  5. jeffreymorlan commented on Nov 8, 2015

    @jeffreymorlan
    ContributorAuthor

    I've realized it would be inefficient for checkFunctionOrConstructorSymbol to walk the tree since it has to check for consecutiveness on every function/method overload, whether error or not, and having to scan the list of children for each means checking a class becomes potentially O(n²). So it's reportImplementationExpectedError that needs to change. PR

  6. added a commit that references this issue on Nov 28, 2015
  7. DanielRosenwasser commented on Nov 28, 2015

    @DanielRosenwasser
    Member
  8. modified the milestones: TypeScript 1.8, on Nov 30, 2015
  9. locked and limited conversation to collaborators on Jun 19, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugA bug in TypeScriptFixedA PR has been merged for this issueHelp WantedYou can do this

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions