From 480e4c29b231a9cd632f5fcfe0ec82f823eb071f Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Mon, 7 Dec 2020 20:54:04 -0700 Subject: [PATCH] Workaround for complexType parsing --- kiss/src/kiss/Helpers.hx | 50 +++++++------------------- kiss/src/test/cases/BasicTestCase.hx | 4 +++ kiss/src/test/cases/BasicTestCase.kiss | 14 +++++++- 3 files changed, 30 insertions(+), 38 deletions(-) diff --git a/kiss/src/kiss/Helpers.hx b/kiss/src/kiss/Helpers.hx index eb5804a1..e071336c 100644 --- a/kiss/src/kiss/Helpers.hx +++ b/kiss/src/kiss/Helpers.hx @@ -35,47 +35,23 @@ class Helpers { } public static function parseTypePath(path:String, from:ReaderExp):TypePath { - // TODO function types with generic argument types are broken - var genericParts = path.split("<"); - var typeParams:Array = null; - if (genericParts.length > 1) { - typeParams = [ - for (typeParam in genericParts[1].substr(0, genericParts[1].length - 1).split(",")) { - TPType(parseComplexType(typeParam, from)); - } - ]; - } - - var parts:List = genericParts[0].trim().split("."); - var uppercaseParts:List = parts.map(startsWithUpperCase); - for (isUpcase in uppercaseParts.slice(0, -2)) { - if (isUpcase) { - throw CompileError.fromExp(from, 'Type path $path should only have capitalized type and subtype'); - } - } - var lastIsCap = uppercaseParts[-1]; - var penultIsCap = uppercaseParts[-2]; - - return if (penultIsCap && lastIsCap) { - { - sub: parts[-1], - name: parts[-2], - pack: parts.slice(0, -2), - params: typeParams - }; - } else if (lastIsCap) { - { - name: parts[-1], - pack: parts.slice(0, -1), - params: typeParams - }; - } else { - throw CompileError.fromExp(from, 'Type path $path should end with a capitalized type'); + return switch (parseComplexType(path, from)) { + case TPath(path): + path; + default: + throw CompileError.fromExp(from, 'Haxe could not parse a type path from $path'); }; } public static function parseComplexType(path:String, from:ReaderExp):ComplexType { - return TPath(parseTypePath(path, from)); + // Trick Haxe into parsing it for us: + var typeCheckExpr = Context.parse('(thing : $path)', Context.currentPos()); + return switch (typeCheckExpr.expr) { + case EParenthesis({pos: _, expr: ECheckType(_, complexType)}): + complexType; + default: + throw CompileError.fromExp(from, 'Haxe could not parse a complex type from $path, parsed ${typeCheckExpr.expr}'); + }; } // TODO generic type parameter declarations diff --git a/kiss/src/test/cases/BasicTestCase.hx b/kiss/src/test/cases/BasicTestCase.hx index 2bf55280..379e326f 100644 --- a/kiss/src/test/cases/BasicTestCase.hx +++ b/kiss/src/test/cases/BasicTestCase.hx @@ -254,6 +254,10 @@ class BasicTestCase extends Test { function testRest() { _testRest(); } + + function testTypeParsing() { + _testTypeParsing(); + } } class BasicObject { diff --git a/kiss/src/test/cases/BasicTestCase.kiss b/kiss/src/test/cases/BasicTestCase.kiss index d7e75837..b83d87c1 100644 --- a/kiss/src/test/cases/BasicTestCase.kiss +++ b/kiss/src/test/cases/BasicTestCase.kiss @@ -370,4 +370,16 @@ (Assert.equals 15 (last myList))) (defun _testRest [] - (Assert.equals (.toString [2 3 4]) (.toString (rest [1 2 3 4])))) \ No newline at end of file + (Assert.equals (.toString [2 3 4]) (.toString (rest [1 2 3 4])))) + +(defun doSomething [:Int->Int func] + (func 5)) + +(defun itsAMonster [:Null>>> monsterArg] "but it still compiles") + +(defun _testTypeParsing [] + // Do stuff with functions that take complex type parameters, mostly just to check if it compiles + (Assert.equals 5 (doSomething (lambda [i] i))) + (Assert.equals 7 (doSomething (lambda [i] (+ i 2)))) + // Pass null to the really crazy one because I'm lazy: + (Assert.equals "but it still compiles" (itsAMonster null))) \ No newline at end of file