Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,4 @@ os:
sudo: false # use the new container-based Travis infrastructure

script:
- chmod u+x ./build.sh
- ./build.sh RunTests
36 changes: 36 additions & 0 deletions FSharp.TypeProviders.StarterPack.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.24720.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.TypeProviders.StarterPack", "src\FSharp.TypeProviders.StarterPack.fsproj", "{6EBFDE55-9687-40A9-8C1A-6E204ECB117F}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{B3B9D21D-D7A9-4DB8-B7D2-A3F414990881}"
ProjectSection(SolutionItems) = preProject
examples\ErasedWithConstructor.fsx = examples\ErasedWithConstructor.fsx
examples\ErasedWithConstructor.Tests.fsx = examples\ErasedWithConstructor.Tests.fsx
examples\StaticProperty.fsx = examples\StaticProperty.fsx
examples\StaticProperty.Tests.fsx = examples\StaticProperty.Tests.fsx
EndProjectSection
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.TypeProviders.StarterPack.Tests", "tests\FSharp.TypeProviders.StarterPack.Tests.fsproj", "{5EF9FF95-1C75-458A-983A-168E43945913}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6EBFDE55-9687-40A9-8C1A-6E204ECB117F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6EBFDE55-9687-40A9-8C1A-6E204ECB117F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6EBFDE55-9687-40A9-8C1A-6E204ECB117F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6EBFDE55-9687-40A9-8C1A-6E204ECB117F}.Release|Any CPU.Build.0 = Release|Any CPU
{5EF9FF95-1C75-458A-983A-168E43945913}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5EF9FF95-1C75-458A-983A-168E43945913}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5EF9FF95-1C75-458A-983A-168E43945913}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5EF9FF95-1C75-458A-983A-168E43945913}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
91 changes: 75 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,89 @@

# F# Type Provider Starter Pack [![NuGet Status](http://img.shields.io/nuget/v/FSharp.TypeProviders.StarterPack.svg?style=flat)](https://www.nuget.org/packages/FSharp.TypeProviders.StarterPack/)

The F# Type Provider Starter Pack is two things: a code only NuGet package with the code
files you'll need to get you started in type provider creation, and a repository of tutorials
that will (hopefully, over time) answer all your questions about how to build type providers,
best practices and general hints and tips.
The F# Type Provider Starter Pack is two things:

This package is still currently pre-release, and actively seeking contributions towards documentation
1. The ``ProvidedTypes.fs`` API files you need to author type providers

2. Documentation and samples on type provider creation

This package is actively seeking contributions. We are aiming for documentation
(the plan is a GitHub page setup similar to [FSharp.Data](http://fsharp.github.io/FSharp.Data)) with
examples of all the most common features of Type Providers that people will want to use (basic erased type
generation, parameterized providers, full generated types, seperating design and runtime how's and why's, etc).
It will also become the main place for improvements and additions to the ProvidedTypes code.

Once it has reached an acceptable standard of documentation/helpfulness ownership will be transferred to the
F# Foundation.

## Build status

### Windows (.net)

[![Build status](https://ci.appveyor.com/api/projects/status/y1c6gs2r0ihog1re)](https://ci.appveyor.com/project/mavnn/fsharp-typeproviders-starterpack)
[![Build status (Windows)](https://ci.appveyor.com/api/projects/status/y1c6gs2r0ihog1re)](https://ci.appveyor.com/project/mavnn/fsharp-typeproviders-starterpack) [![Build Status (MacOS, mono)](https://travis-ci.org/fsprojects/FSharp.TypeProviders.StarterPack.svg?branch=master)](https://travis-ci.org/fsprojects/FSharp.TypeProviders.StarterPack)

### MacOS (mono)
## The ProvidedTypes API - Adding the Files

[![Build Status](https://travis-ci.org/fsprojects/FSharp.TypeProviders.StarterPack.svg?branch=master)](https://travis-ci.org/fsprojects/FSharp.TypeProviders.StarterPack)
Building a type provider nearly always starts with adding these files to your project:

## Documentation
ProvidedTypes.fsi
ProvidedTypes.fs

Building a type provider nearly always starts with adding the `ProvidedTypes.fs` and `ProvidedTypes.fsi`. The
[Starter Pack NuGet package](https://www.nuget.org/packages/FSharp.TypeProviders.StarterPack) contains both these files as well as a set of debugging helpers, and when you install
The [Starter Pack NuGet package](https://www.nuget.org/packages/FSharp.TypeProviders.StarterPack) contains both these files as well as a set of debugging helpers, and when you install
it, it should add them all to your F# project. It's probably best not to modify the files after adding them as
upgrades to the package will ask to replace the previous versions - either submit changes back to this project
or shadow the relevant functions in a seperate file.

If using Paket, you can also add code files by direct GitHub references.


## The ProvidedTypes API - Cross-Targeting Type Providers

Type providers may be used in projects that generate portable code or target other .NET Frameworks than
that being used by the F# compiler. To convert an erasing
type provider to a cross-targeting erasing type provider, add the following source files to your project:

AssemblyReader.fs
AssemblyReaderReflection.fs
ProvidedTypesContext.fs

Then add

let ctxt = ProvidedTypesContext.Create(config)

to your code and always create proided entities using this ``ctxt`` object:

let myType = ctxt.ProvidedTypeDefinition(asm, ns, "MyType", typeof<obj>)

This is shown in the example below.

## The ProvidedTypes API - A Basic Type Provider

Here is a basic erasing type provider using the Provided Types API:

open ProviderImplementation
open ProviderImplementation.ProvidedTypes
open Microsoft.FSharp.Core.CompilerServices
open System.Reflection

[<TypeProvider>]
type BasicProvider (config : TypeProviderConfig) as this =
inherit TypeProviderForNamespaces ()

let ns = "StaticProperty.Provided"
let asm = Assembly.GetExecutingAssembly()
let ctxt = ProvidedTypesContext.Create(config)

let createTypes () =
let myType = ctxt.ProvidedTypeDefinition(asm, ns, "MyType", typeof<obj>)
let myProp = ctxt.ProvidedProperty("MyProperty", typeof<string>, IsStatic = true, getterCode = (fun args -> <@@ "Hello world" @@>))
myType.AddMember(myProp)
[myType]

do
this.AddNamespace(ns, createTypes())

[<assembly:TypeProviderAssembly>]
do ()

## Resources

For advice on how to get started building a type provider, check out:

- [Type Providers from the ground up](http://blog.mavnn.co.uk/type-providers-from-the-ground-up/)
Expand All @@ -50,7 +101,14 @@ For advice on how to get started building a type provider, check out:

## Building

- This repository contains no compiled code.
Use

build.sh RunTests

or

build.cmd RunTests


## Library license

Expand All @@ -63,5 +121,6 @@ The library is available under Apache 2.0. For more information see the [License

- [@mavnn](https://github.com/mavnn)
- [@ovatsus](https://github.com/ovatsus)
- [@dsyme](https://github.com/dsyme)

The default maintainer account for projects under "fsprojects" is [@fsprojectsgit](https://github.com/fsprojectsgit) - F# Community Project Incubation Space (repo management)
2 changes: 2 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@

#### 2.0.0 - 02/02/2016
* Updates for cross-targeting of type providers

#### 1.1.3 - July 30 2014
* Remove folders
Expand Down
64 changes: 36 additions & 28 deletions build.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ let release =
File.ReadLines "RELEASE_NOTES.md"
|> ReleaseNotesHelper.parseReleaseNotes

let PullRequest =
let pullRequest =
match getBuildParamOrDefault "APPVEYOR_PULL_REQUEST_NUMBER" "" with
| "" ->
trace "Master build detected"
Expand All @@ -48,7 +48,7 @@ let buildNumber =
int (getBuildParamOrDefault "APPVEYOR_BUILD_VERSION" "0")

let version =
match PullRequest with
match pullRequest with
| None ->
sprintf "%s.%d" release.AssemblyVersion buildNumber
| Some num ->
Expand All @@ -61,26 +61,36 @@ let exampleDir = "examples"
let testDir = "test"
let nunitDir = "packages/NUnit/lib/net45"

let sources =
[srcDir @@ "ProvidedTypes.fsi"
srcDir @@ "ProvidedTypes.fs"
srcDir @@ "AssemblyReader.fs"
srcDir @@ "AssemblyReaderReflection.fs"
srcDir @@ "ProvidedTypesContext.fs"
srcDir @@ "ProvidedTypesTesting.fs" ]


// --------------------------------------------------------------------------------------
// Clean build results

Target "Clean" (fun _ ->
CleanDirs [outputPath; workingDir;testDir]
)

let pt = [srcDir @@ "ProvidedTypes.fsi";srcDir @@ "ProvidedTypes.fs"]

// --------------------------------------------------------------------------------------
// Compile ProvidedTypes as a smoke test
Target "Compile" (fun _ ->
Fsc id pt
Fsc id sources
!! "FSharp.TypeProviders.StarterPack.sln"
|> MSBuildRelease "" "Build"
|> ignore
)

type ExampleWithTests = {
Name : string
ProviderSourceFiles : string list
TestSourceFiles : string list
}
type ExampleWithTests =
{ Name : string
ProviderSourceFiles : string list
TestSourceFiles : string list }


// --------------------------------------------------------------------------------------
// Compile example providers and accompanying test dlls
Expand All @@ -91,12 +101,15 @@ Target "Examples" (fun _ ->
{ Name = "ErasedWithConstructor"; ProviderSourceFiles = ["ErasedWithConstructor.fsx"]; TestSourceFiles = ["ErasedWithConstructor.Tests.fsx"]}
]

if not (Directory.Exists testDir) then
Directory.CreateDirectory testDir |> ignore

let testNunitDll = testDir @@ "nunit.framework.dll"

do
if File.Exists testNunitDll then
File.Delete testNunitDll
File.Copy (nunitDir @@ "nunit.framework.dll", testNunitDll)
if File.Exists testNunitDll then
File.Delete testNunitDll

File.Copy (nunitDir @@ "nunit.framework.dll", testNunitDll)

let fromExampleDir filenames =
filenames
Expand All @@ -107,7 +120,7 @@ Target "Examples" (fun _ ->
// Compile type provider
let output = testDir @@ example.Name + ".dll"
let setOpts = fun def -> { def with Output = output; FscTarget = FscTarget.Library }
Fsc setOpts (List.concat [pt;fromExampleDir example.ProviderSourceFiles])
Fsc setOpts (List.concat [sources;fromExampleDir example.ProviderSourceFiles])

// Compile test dll
let setTestOpts = fun def ->
Expand All @@ -120,6 +133,8 @@ Target "Examples" (fun _ ->
)

Target "RunTests" (fun _ ->
!! ("tests/bin/Release/FSharp.TypeProviders.StarterPack.Tests.dll")
|> NUnit3 id
!! (testDir @@ "*.Tests.dll")
|> NUnit3 id
)
Expand All @@ -128,8 +143,7 @@ Target "RunTests" (fun _ ->
// Build a NuGet package

Target "NuGet" (fun _ ->
[srcDir @@ "ProvidedTypes.fsi"] |> CopyTo (workingDir @@ "content")
[srcDir @@ "ProvidedTypes.fs"; "./src/DebugProvidedTypes.fs"] |> CopyTo (workingDir @@ "content")
sources |> CopyTo (workingDir @@ "content")

NuGet (fun p ->
{ p with
Expand All @@ -144,26 +158,20 @@ Target "NuGet" (fun _ ->
WorkingDir = workingDir
AccessKey = getBuildParamOrDefault "nugetkey" ""
Publish = hasBuildParam "nugetkey"
Files = [workingDir, None, None]
Files = [(workingDir, None, None)]
Dependencies = [] })
"nuget/FSharp.TypeProviders.StarterPack.nuspec"
)

// --------------------------------------------------------------------------------------
// Help

Target "Help" (fun _ ->
printfn ""
printfn " Please specify the target by calling 'build <Target>'"
printfn ""
printfn " * NuGet (creates package only, doesn't publish unless api key provided)"
printfn " * Compile (attempts to compile ProvidedTypes.fs)"
printfn "")

"Clean"
==> "Compile"
==> "NuGet"

"Compile"
==> "Examples"
==> "RunTests"
==> "NuGet"

RunTargetOrDefault "Help"
RunTargetOrDefault "RunTests"
4 changes: 4 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ then
packages/FAKE/tools/FAKE.exe $@ --fsiargs -d:MONO build.fsx
else
# use mono

which mono
find /usr/lib/mono

mono .paket/paket.bootstrapper.exe
exit_code=$?
if [ $exit_code -ne 0 ]; then
Expand Down
19 changes: 9 additions & 10 deletions examples/ErasedWithConstructor.fsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#if INTERACTIVE
#load "../src/ProvidedTypes.fsi"
#load "../src/ProvidedTypes.fs"
#load "../src/ProvidedTypes.fsi" "../src/ProvidedTypes.fs" "../src/AssemblyReader.fs" "../src/AssemblyReaderReflection.fs" "../src/ProvidedTypesContext.fs"
#endif

open ProviderImplementation
open ProviderImplementation.ProvidedTypes
open Microsoft.FSharp.Core.CompilerServices
open System.Reflection
Expand All @@ -13,20 +13,18 @@ type BasicProvider (config : TypeProviderConfig) as this =

let ns = "ErasedWithConstructor.Provided"
let asm = Assembly.GetExecutingAssembly()
let ctxt = ProvidedTypesContext.Create(config)

let createTypes () =
let myType = ProvidedTypeDefinition(asm, ns, "MyType", Some typeof<obj>)
let myType = ctxt.ProvidedTypeDefinition(asm, ns, "MyType", Some typeof<obj>)

let ctor = ProvidedConstructor([], InvokeCode = fun args -> <@@ "My internal state" :> obj @@>)
let ctor = ctxt.ProvidedConstructor([], invokeCode = fun args -> <@@ "My internal state" :> obj @@>)
myType.AddMember(ctor)

let ctor2 = ProvidedConstructor(
[ProvidedParameter("InnerState", typeof<string>)],
InvokeCode = fun args -> <@@ (%%(args.[0]):string) :> obj @@>)
let ctor2 = ctxt.ProvidedConstructor([ctxt.ProvidedParameter("InnerState", typeof<string>)], invokeCode = fun args -> <@@ (%%(args.[0]):string) :> obj @@>)
myType.AddMember(ctor2)

let innerState = ProvidedProperty("InnerState", typeof<string>,
GetterCode = fun args -> <@@ (%%(args.[0]) :> obj) :?> string @@>)
let innerState = ctxt.ProvidedProperty("InnerState", typeof<string>, getterCode = fun args -> <@@ (%%(args.[0]) :> obj) :?> string @@>)
myType.AddMember(innerState)

[myType]
Expand All @@ -35,4 +33,5 @@ type BasicProvider (config : TypeProviderConfig) as this =
this.AddNamespace(ns, createTypes())

[<assembly:TypeProviderAssembly>]
do ()
do ()

Loading