Skip to content

Dot versus Colon 2 - #111

Merged
Perryvw merged 4 commits into
masterfrom
feature/dot-calls
Jun 6, 2018
Merged

Dot versus Colon 2#111
Perryvw merged 4 commits into
masterfrom
feature/dot-calls

Conversation

@Perryvw

@Perryvw Perryvw commented Jun 3, 2018

Copy link
Copy Markdown
Member

Counter proposal to #109 and #108

@Perryvw
Perryvw requested a review from lolleko June 3, 2018 15:03

@lolleko lolleko left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good but we should resolve the discussion in #108 before merging.

@dmarcuse

dmarcuse commented Jun 3, 2018

Copy link
Copy Markdown
Contributor

Here's a few issues I've found:

  • Static methods are called using colon syntax (fix here)
  • Using union types and shared members (e.g, declare const test: TypeLiteralA | TypeLiteralB; test.sharedMethod()) uses colon syntax, although this can be prevented using a type guard or cast, so it's not a huge problem.
  • Similarly, using intersection types (e.g. declare const aPlus: A & { something(): void }; aPlus.hello() results in colon syntax, although this can only be fixed with a cast - type guards don't help.
    • This happens even if you explicitly declare the type separately (e.g. declare type APlus = A & { something(): void }; declare const aPlus: APlus; aPlus.hello())
    • This is one reason that I wanted to be able to use interfaces, to properly handle extending the behavior. In Improve dot vs colon method invocations #109, methods inherited from a parent class/interface will properly behave with !DotMethod unless overridden (in which case you can use !DotMethod if desired)
  • There's likely related issues with other advanced types, although I haven't tested them

Sorry if I seem overly critical, I just like to cover the edge cases 😛

@Perryvw

Perryvw commented Jun 3, 2018

Copy link
Copy Markdown
Member Author

I actually remembered why we use : for static methods: when using this in a static method it usually refers to the class itself. If we look at what happens in lua this is perfectly preserved by using the : syntax and adding a 'self' parameter.

These other ones indeed seem like issues and I will have a look at how to resolve those when I have time.

@dmarcuse

dmarcuse commented Jun 3, 2018

Copy link
Copy Markdown
Contributor

Hmm, that does make sense for static, although there are again cases where APIs expect to be called using dot syntax, which complicates things.

@Perryvw Perryvw changed the title call functions on object literals with a dot Dot versus Colon 2 Jun 4, 2018
@Perryvw

Perryvw commented Jun 4, 2018

Copy link
Copy Markdown
Member Author

@apemanzilla @lolleko tried to solve by transpiling lambda properties with . and methods with :. Have a look

@dmarcuse dmarcuse left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this looks pretty good: here's the results of my testing.

  • Classes and interfaces are working, including inheritance (might want to add to the test)
  • Simple type literals are working (also might want to add to the test)
  • Intersections and unions (and likely other advanced types) are not working, but with classes/interfaces and inheritance this can typically be worked around and would probably require a lot of effort to fix anyways

Comment thread src/Transpiler.ts Outdated
}

if (expType.symbol && (expType.symbol.flags & ts.SymbolFlags.Namespace)) {
const expType2 = this.checker.getTypeAtLocation(node.expression);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be worth renaming expType and expType2 to something more descriptive - such as containerType and functionType respectively.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed

Comment thread src/Transpiler.ts Outdated
}

if (expType.symbol && (expType.symbol.flags & ts.SymbolFlags.Namespace)) {
const expType2 = this.checker.getTypeAtLocation(node.expression);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed

interfaceInstance.colonMethod();
interfaceInstance.dotMethod();
TestNameSpace.dotMethod();
TestNameSpace.dotMethod2();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure how much sense it makes but maybe add some functional tests too. Probably not that important.

@dmarcuse

dmarcuse commented Jun 6, 2018

Copy link
Copy Markdown
Contributor

Is there anything still holding this back?

@dmarcuse

dmarcuse commented Jun 6, 2018

Copy link
Copy Markdown
Contributor

Found another minor edge case. If you have an instance of an interface extending from two interfaces defining the same method as an arrow function and regular function, it will use the first parent interface to determine the function type. I can't think of any cases where this really matters, though.

declare interface A2 {
    method: () => void;
}

declare interface B2 {
    method(): void;
}

declare interface Thing extends B2, A2 {} // swapping B2 and A2 here changes transpilation

declare const thing: Thing;

thing.method();

@Perryvw

Perryvw commented Jun 6, 2018

Copy link
Copy Markdown
Member Author

@apemanzilla I will merge this once I added some functional tests and had a quick look if there is any easy way to deal with union types.

@Perryvw
Perryvw merged commit 6da78c5 into master Jun 6, 2018
@dmarcuse

dmarcuse commented Jun 6, 2018

Copy link
Copy Markdown
Contributor

Thank you!

@lolleko
lolleko deleted the feature/dot-calls branch June 12, 2018 11:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants