Coder Social home page Coder Social logo

resolve's Introduction

resolve

An abstract type to help filter and select fields based on type signatures, naming schemes and metadata usage using regular expressions.

Why tho?

Resolve is more useful for when dealing with user provided types during macro generation. If using resolve in other macros, it is recommended to use the be.resolve.macros.Resolver methods directly.

Type Support

Classes and Abstracts are supported, currently. There are two ways of searching, either static or instance fields, with some exceptions for Abstracts.

Searching Statics
  • var r:Resolve<Int->Int> = SomeClass;
Searching Instances
  • var i:SomeClass = new SomeClass();
    var r:Resolve<Int->Int> = i;
Filtering against names
  • var r:Resolve<Int->Int, ~/add(ition|able)?/> = /*Search against instance or static expression*/.
Filtering against metadata

Notice the open and close brackets () are escaped.

  • var r:Resolve<Int->Int, ~/@:op\([\w\d\s]+\+[\w\d\s]+\)/> = /*Search against instance or static expression*/.
Filtering against names & metadata
  • Resolve<$type, $name, $meta>
    • $type is always position 0.
    • If both EReg's are supplied:
      • Names is always position 1.
      • Metas is always position 2.
    • If either EReg is omitted, Resolve will:
      • Check for @ character, if it exists, it assumes its a meta regular expression.
      • Otherwise it defaults to a name regular expression.
  • var r:Resolve<Int->Int, ~/add(ition|able)?/, ~/@:op\([\w\d\s]+\+[\w\d\s]+\)/> = /*Search against instance or static expression*/.
Abstract Support

Abstracts are compile time only types, with many features which can result in complex usage. Pairing them with macros make this more difficult. ๐Ÿ”ฅ๐Ÿฒ

To access Abstract features like @:to, @:from, @:op(_) etc, the metadata filter needs to match the respective metadata for that feature.

Types API

Resolve

abstract Resolve<T:Function, @:const R:EReg, @:const M:EReg> {
    static function coerce<In, Out>(expr:ExprOf<In>):ExprOf<Out>;
    static function resolve<Int, Out:Function>(expr:ExprOf<Class<Int>>):ExprOf<Out>;
}
Resolve.coerce
import be.types.Resolve.coerce;

class Main {
    public static function main() {
        var input = '2018-11-15';
        var aInt:Int = coerce( input );
        var aFloat:Float = coerce( input );
        var aDate:Date = coerce( input );
        var aFake:Fake = coerce( input );

        trace( 
            aInt    /*2018*/, 
            aFloat  /*2018*/, 
            aDate   /*Novemeber 15th 2018*/, 
            aFake   /* {name:"2018-11-15"} */
        );
    }

}

class Fake {
    var name:String;
    public function new(v:String) name = v;
    public static function mkFake(v:String):Fake return new Fake(v);
}
Resolve.resolve

Using resolve(<expr>) can help prevent auto-completion issues.

import be.types.Resolve;
import be.types.Resolve.resolve;

class Main {
    public static function main() {
        var input = '999';
        var r:Resolve<String->Int, ~/int/i> = resolve(Std);
        // `r` is already resolved, so gets passed as `Std.parseInt`.
        trace( asInt(r, input) );       // trace(999);
        // Resolves to `Std.parseInt`.
        trace( asInt(Std, input) );     // trace(999);
        // Resolves to `Fake.parseInt`.
        trace( asInt(Fake, input) );    // trace(1000);
        // Functions that unify pass right through.
        trace( asInt(_ -> 1, '125') );  // trace(1);
    }

    static inline function asInt(r:Resolve<String->Int, ~/int/i, ~//i, v:String):Int return r(v);
}

public class Fake {
    static function parseInt(v:String):Int return 1000;
    static function parseFloat(v:String):Float return 0.0;
    static function falseSig(v:String):Int return throw 'This is skipped due to the `~/int/i` regular expression';
}

Resolve

Resolve is a @:genericBuild macro which redirects to either a ResolveMethod or ResolveProperty or ResolveFunctions type.

  • Resolve only requires the type signature.
  • How does Resolve decide if a regular expression passed in is a metadata filter or not?
    • It checks for the existence of the @ character, which isn't a valid ident character in Haxelang.
import be.types.Resolve;
import be.types.Resolve.resolve;

class Main {
    public static function main() {
        var input = '999';
        trace( asInt(Std, input) );             // trace(999);
        trace( asInt(resolve(Fake), input) );   // trace(1000);
        // Functions that unify pass right through.
        trace( asInt(_ -> 1, '125') );  // trace(1);
    }

    // `Resolve<String-Int>` returns the `ResolveMethod<String->Int, ~//, ~//>` type.
    static function asInt(r:Resolve<String->Int>, v:String):Int return r(v);
}

public class Fake {
    static function parseFloat(v:String):Float return 0.0;
    static function parseInt(v:String):Int return 1000;
}

โš  be.resolve.macros.Resolver

Take a look at the source of be.types.ResolveFunctions on how to get started.

class Resolver {
    public static function determineTask(expr:Expr, input:Type, output:Type, ?debug:Bool):ResolveTask;
    public static function findMethod(signature:Type, module:Type, statics:Bool, pos:Position, ?fieldEReg:EReg, ?metaEReg:EReg, ?debug:Bool):Outcome<Array<{name:String, type:Type}>, Error>;
    public static function convertValue(input:Type, output:Type, value:Expr, ?debug:Bool):Outcome<Expr, Error>;
    public static function handleTask(task:ResolveTask, ?debug:Bool):Expr;
}

Defines

  • -D resolve-verbose - Paired with -debug will have the build macros print a lot of trace statements.

resolve's People

Contributors

skial avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar

resolve's Issues

Spread method

Look into supporting a spread macro method, that works only on objects (@:structInit, class?) and arrays, by expanding the object/array onto function args.

Rename lib & types to Resolve

  • ResolveProperty
  • Resolve -> ResolveMethod
  • Pick -> Resolve
  • Library name from coerce -> resolve
  • Update readme.
  • Update library defines.

The method coerce is distinct from resolve in that it doesnt wrap the result in a typedef to detect already processed types & that it doesnt depend on the output type being a Resolve<T> type.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.