Skip to content
This repository has been archived by the owner on Mar 25, 2021. It is now read-only.

Support disallowing namespaces (noNamespace). #1133

Merged
merged 1 commit into from
Apr 26, 2016

Conversation

mprobst
Copy link
Contributor

@mprobst mprobst commented Apr 15, 2016

This allows code bases to outlaw pre-ES6 modules and namespaces. It's often
still useful to declare namespaces when interacting with non-TypeScript code, so
this has an option to allow "declare namespace" style usage.

}
}

class NullWalker extends Lint.RuleWalker {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we give this class a more meaningful name, like NoNamespaceWalker?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@jkillian
Copy link
Contributor

Thanks @mprobst, I like this rule! Makes sense to me to have this rule as more TS codebases will want to enforce ES6 module usage over namespaces.

Left you a few tweaks to make, and then we should be able to merge this. Looks like the rule also needs a rebase, a previously merged PR must've created a conflict

@mprobst
Copy link
Contributor Author

mprobst commented Apr 19, 2016

Thanks for the review! Please take another look.

@mprobst
Copy link
Contributor Author

mprobst commented Apr 19, 2016

So, in the mean time I found the no-internal-module rule (no idea how I didn't notice that before). I think it might make sense to unify the two configuration settings - no-namespace is sort of a natural extension of no-internal-module, and the code should share the logic around global augmentations and nested declarations.

I've added that as a separate commit as it makes the configuration a bit harder to understand. Let me know what you think.

@jkillian
Copy link
Contributor

It's a tough call. In my mind:

no-internal-module encourages the use of the namespace keyword instead of the outdated module keyword where appropriate

no-namespace encourages people to stop using namespaces all together and instead organize their code with ES6 modules.

They're definitely about similar syntaxic elements, but the goals of the two are somewhat different. I'm unsure here about what's best.

@mprobst
Copy link
Contributor Author

mprobst commented Apr 19, 2016

I agree, it's a bit tricky, and I presume it might also be nicer to have just one option going forward (no-namespace). I could also refactor the code so we only have one shared implementation, but still two different options.

How do we resolve? Get a third opinion?

@jkillian
Copy link
Contributor

@adidahiya any thoughts?

@mprobst
Copy link
Contributor Author

mprobst commented Apr 20, 2016

@alexeagle knows his way around static analysis tools and might venture an opinion?

@alexeagle
Copy link
Contributor

I think tslint lacks a curated default set of checks, in which case things that have been deprecated by the language (no-internal-module) should be enabled by default and users don't think about it (unless they need to disable it). If that were the case, the answer would clearly be to make a new, separate no-namespace rule.

In my opinion, the convenience of no-namespace implying no-internal-module is not worth the complexity of understanding the configuration. Are there any other options that currently flip other options? Users are expected to study a long list of rules and decide what to opt-in to, so follow that model.

@jkillian
Copy link
Contributor

Makes sense to me. We should be sure that no-namespace doesn't conflict with no-internal-module though: that is, it shouldn't be possible to get into a position where one of the two rules will always error.

An example of this would be if you had a rule that required explicit typedefs and had a rule that required implicit typedefs. It would be impossible to declare a variable and satisfy both of these rules.

I think we'll be fine here, as no-namespace is just more strict that no-internal-module which shouldn't lead to conflicts. Let's keep it as a separate no-namespace rule if you're in agreement @mprobst

@mprobst mprobst force-pushed the namespace branch 3 times, most recently from 899827a to 068e7e1 Compare April 22, 2016 01:15
@mprobst
Copy link
Contributor Author

mprobst commented Apr 22, 2016

Agreed, sounds good to me. Please take another look; I've "unmerged" the code, and now just share the implementation of isNestedDeclaration across the two lint rules.

@mprobst
Copy link
Contributor Author

mprobst commented Apr 25, 2016

Friendly ping :-)

@@ -44,7 +44,7 @@ class NoInternalModuleWalker extends Lint.RuleWalker {
}
}

function isNestedDeclaration(node: ts.ModuleDeclaration) {
export function isNestedDeclaration(node: ts.ModuleDeclaration) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you instead move this function to src/language/utils and rename it isNestedModuleDeclaration? Then we avoid any chance of circular dependencies and keep shared code in a separate location

@jkillian
Copy link
Contributor

Sorry for the delay! Can you make the one change listed above and also rebase off the latest develop? (The rebase will help make sure that CI passes)

This allows code bases to outlaw pre-ES6 modules and namespaces. It's often
still useful to declare namespaces when interacting with non-TypeScript code, so
this has an option to allow "declare namespace" style usage.
@mprobst
Copy link
Contributor Author

mprobst commented Apr 26, 2016

No worries! Refactored and rebased, PTAL.

@jkillian jkillian merged commit cdb56c3 into palantir:master Apr 26, 2016
@jkillian
Copy link
Contributor

Looks great, thank you!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants