Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preprocessor directives proposal #3670

Closed
tinganho opened this issue Jun 29, 2015 · 5 comments
Closed

Preprocessor directives proposal #3670

tinganho opened this issue Jun 29, 2015 · 5 comments
Labels
Duplicate An existing issue was already created Suggestion An idea for TypeScript

Comments

@tinganho
Copy link
Contributor

This proposal is based on C# spec for preprocessor directives. https://msdn.microsoft.com/en-us/library/aa691099(v=vs.71).aspx

Problem

Some JS applications are used in multiple platforms. I.e. Cordova/Phonegap for mobile platforms, isomorphic applications for server-side and client-side rendered applications. And those platforms are hosting different set of API:s. We use import statements to import and use a host's API. A developer must guard one platform's API from an another.

Before ES6 modules one could guard an import using if statements:

if (IOS_PLATFORM) {
   var http = require('./http-ios');
}

ES6 modules prohibits conditional imports, because the import statements must be a file-level statement. So we can't do:

if (IOS_PLATFORM) {
   import {something} from './something';
}

Solution

We can solve the above problem with preprocessor directives. And here is one example of the problem above solved with a preprocessor directives:

#if IOS_PLATFORM
import {http} from './http';
#endif

Proposed directives:

define directive

#define {VARIABLE} [{VALUE}]

The define directive defines a global flag or global variable. When a value is specified it is regarded as a preprocessor variable.

flow directives

#if
#elif
#else
#endif

It must exist at least one #if and at maximum one #else directive per control-flow statement. A directive must be closed with an #endif directive. You can also nest preprocessor control-flow statements in each other. In addition to hosting TS code, a control-flow statement's body can also host #define and #error directive that defines additional behaviour for the preprocessor.

Each control-flow branch is scoped from other sibling branches. So the below example will yield an access undefined error:

#if branch1
var test = "string";
#elif branch2
test.length; // error
#endif
test.length; // no error

preprocessor operators:

==
!=
&&
||

These should work as comparison operators in TS and JS along with parens ().

error directive

#error {MESSAGE}

The error directive is to help guiding developers to set right set of flags and values. In some cases two disjoint branches aren't supposed to be joined. An example is given below:

#if IOS_PLATFORM && ANDROID_PLATFORM
    #error "Cannot set two platform flags"
#endif

Or when a preprocessor variable is set to an invalid value:

#if PLATFORM == windows
    #error "Cannot set platform preprocessor variable to windows."
#endif
@mhegazy
Copy link
Contributor

mhegazy commented Jun 29, 2015

duplicate of #449?

@RichiCoder1
Copy link

Arguably a very specific sub-topic.

@tinganho
Copy link
Contributor Author

@mhegazy that one needed a proposal so I came with one proposal.

@danquirk danquirk added the Suggestion An idea for TypeScript label Jul 8, 2015
@yortus
Copy link
Contributor

yortus commented Sep 8, 2015

Working implementation for part of this proposal over at #4691

@mhegazy
Copy link
Contributor

mhegazy commented Dec 9, 2015

looks like #4691 has more details now. closing in favor of #4691.

@mhegazy mhegazy closed this as completed Dec 9, 2015
@mhegazy mhegazy added the Duplicate An existing issue was already created label Dec 9, 2015
@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate An existing issue was already created Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

5 participants