Skip to content

Commit

Permalink
deploy: e73cccc
Browse files Browse the repository at this point in the history
  • Loading branch information
chriscerie committed Feb 24, 2024
1 parent dd4e232 commit 71f1676
Show file tree
Hide file tree
Showing 26 changed files with 257 additions and 257 deletions.
56 changes: 28 additions & 28 deletions archive/std_v1.html
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ <h2 id="examples"><a class="header" href="#examples">Examples</a></h2>
<h2 id="selene"><a class="header" href="#selene">[selene]</a></h2>
<p>Anything under the key <code>[selene]</code> is used for meta information. The following paths are accepted:</p>
<p><code>[selene.base]</code> - Used for specifying what standard library to be based off of. Currently only accepts built in standard libraries, meaning <code>lua51</code> or <code>lua52</code>.</p>
<p><code>[selene.name]</code> - Used for specifying the name of the standard library. Used internally for cases such as only giving Roblox lints if the standard library is named <code>&quot;roblox&quot;</code>.</p>
<p><code>[selene.name]</code> - Used for specifying the name of the standard library. Used internally for cases such as only giving Roblox lints if the standard library is named <code>"roblox"</code>.</p>
<p><code>[selene.structs]</code> - Used for declaring <a href="#structs">structs</a>.</p>
<h2 id="globals"><a class="header" href="#globals">[globals]</a></h2>
<p>This is where the magic happens. The <code>globals</code> field is a dictionary where the keys are the globals you want to define. The value you give tells selene what the value can be, do, and provide.</p>
Expand All @@ -203,36 +203,36 @@ <h2 id="any"><a class="header" href="#any">Any</a></h2>
<h2 id="functions"><a class="header" href="#functions">Functions</a></h2>
<p>Example:</p>
<pre><code class="language-toml">[[tonumber.args]]
type = &quot;any&quot;
type = "any"

[[tonumber.args]]
type = &quot;number&quot;
type = "number"
required = false
</code></pre>
<p>A field is a function if it contains an <code>args</code> and/or <code>method</code> field.</p>
<p>If <code>method</code> is specified as <code>true</code> and the function is inside a table, then it will require the function be called in the form of <code>Table:FunctionName()</code>, instead of <code>Table.FunctionName()</code>.</p>
<p><code>args</code> is an array of arguments, in order of how they're used in the function. An argument is in the form of:</p>
<pre><code>required?: false | true | string;
type: &quot;any&quot; | &quot;bool&quot; | &quot;function&quot; | &quot;nil&quot;
| &quot;number&quot; | &quot;string&quot; | &quot;table&quot; | &quot;...&quot;
| string[] | { &quot;display&quot;: string }
type: "any" | "bool" | "function" | "nil"
| "number" | "string" | "table" | "..."
| string[] | { "display": string }
</code></pre>
<h2 id="required"><a class="header" href="#required">&quot;required&quot;</a></h2>
<h2 id="required"><a class="header" href="#required">"required"</a></h2>
<ul>
<li><code>true</code> - The default, this argument is required.</li>
<li><code>false</code> - This argument is optional.</li>
<li>A string - This argument is required, and not using it will give this as the reason why.</li>
</ul>
<h2 id="argument-types"><a class="header" href="#argument-types">Argument types</a></h2>
<ul>
<li><code>&quot;any&quot;</code> - Allows any value.</li>
<li><code>&quot;bool&quot;</code>, <code>&quot;function&quot;</code>, <code>&quot;nil&quot;</code>, <code>&quot;number&quot;</code>, <code>&quot;string&quot;</code>, <code>&quot;table&quot;</code> - Expects a value of the respective type.</li>
<li><code>&quot;...&quot;</code> - Allows any number of variables after this one. If <code>required</code> is true (it is by default), then this will lint if no additional arguments are given. It is incorrect to have this in the middle.</li>
<li>Constant list of strings - Will check if the value provided is one of the strings in the list. For example, <code>collectgarbage</code> only takes one of a few exact string arguments--doing <code>collectgarbage(&quot;count&quot;)</code> will work, but <code>collectgarbage(&quot;whoops&quot;)</code> won't.</li>
<li><code>{ &quot;display&quot;: string }</code> - Used when no constant could possibly be correct. If a constant is used, selene will tell the user that an argument of the type (display) is required. For an example, the Roblox method <code>Color3.toHSV</code> expects a <code>Color3</code> object--no constant inside it could be correct, so this is defined as:</li>
<li><code>"any"</code> - Allows any value.</li>
<li><code>"bool"</code>, <code>"function"</code>, <code>"nil"</code>, <code>"number"</code>, <code>"string"</code>, <code>"table"</code> - Expects a value of the respective type.</li>
<li><code>"..."</code> - Allows any number of variables after this one. If <code>required</code> is true (it is by default), then this will lint if no additional arguments are given. It is incorrect to have this in the middle.</li>
<li>Constant list of strings - Will check if the value provided is one of the strings in the list. For example, <code>collectgarbage</code> only takes one of a few exact string arguments--doing <code>collectgarbage("count")</code> will work, but <code>collectgarbage("whoops")</code> won't.</li>
<li><code>{ "display": string }</code> - Used when no constant could possibly be correct. If a constant is used, selene will tell the user that an argument of the type (display) is required. For an example, the Roblox method <code>Color3.toHSV</code> expects a <code>Color3</code> object--no constant inside it could be correct, so this is defined as:</li>
</ul>
<pre><code class="language-toml">[[Color3.toHSV.args]]
type = { display = &quot;Color3&quot; }
type = { display = "Color3" }
</code></pre>
<h2 id="properties"><a class="header" href="#properties">Properties</a></h2>
<p>Example:</p>
Expand All @@ -243,19 +243,19 @@ <h2 id="properties"><a class="header" href="#properties">Properties</a></h2>
<p>The same goes for <code>_G</code>, which is defined as:</p>
<pre><code class="language-toml">[_G]
property = true
writable = &quot;new-fields&quot;
writable = "new-fields"
</code></pre>
<p><code>writable</code> is an optional field that tells selene how the property can be mutated and used:</p>
<ul>
<li><code>&quot;new-fields&quot;</code> - New fields can be added and set, but variable itself cannot be redefined. In the case of _G, it means that <code>_G = &quot;foo&quot;</code> is linted against.</li>
<li><code>&quot;overridden&quot;</code> - New fields can't be added, but entire variable can be overridden. In the case of Roblox's <code>Instance.Name</code>, it means we can do <code>Instance.Name = &quot;Hello&quot;</code>, but not <code>Instance.Name.Call()</code>.</li>
<li><code>&quot;full&quot;</code> - New fields can be added and entire variable can be overridden.</li>
<li><code>"new-fields"</code> - New fields can be added and set, but variable itself cannot be redefined. In the case of _G, it means that <code>_G = "foo"</code> is linted against.</li>
<li><code>"overridden"</code> - New fields can't be added, but entire variable can be overridden. In the case of Roblox's <code>Instance.Name</code>, it means we can do <code>Instance.Name = "Hello"</code>, but not <code>Instance.Name.Call()</code>.</li>
<li><code>"full"</code> - New fields can be added and entire variable can be overridden.</li>
</ul>
<p>If <code>writable</code> is not specified, selene will assume it can neither have new fields associated with it nor can be overridden.</p>
<h2 id="struct"><a class="header" href="#struct">Struct</a></h2>
<p>Example:</p>
<pre><code class="language-toml">[game]
struct = &quot;DataModel&quot;
struct = "DataModel"
</code></pre>
<p>Specifies that the field is an instance of a <a href="#structs">struct</a>. The value is the name of the struct.</p>
<h2 id="table"><a class="header" href="#table">Table</a></h2>
Expand All @@ -280,32 +280,32 @@ <h2 id="structs"><a class="header" href="#structs">Structs</a></h2>
method = true

[[selene.structs.Event.Connect.args]]
type = &quot;function&quot;
type = "function"
</code></pre>
<p>From there, it can define:</p>
<pre><code class="language-toml">[workspace.Changed]
struct = &quot;Event&quot;
struct = "Event"
</code></pre>
<p>...and selene will know that <code>workspace.Changed:Connect(callback)</code> is valid, but <code>workspace.Changed:RandomNameHere()</code> is not.</p>
<h2 id="wildcards"><a class="header" href="#wildcards">Wildcards</a></h2>
<p>Fields can specify requirements if a field is referenced that is not explicitly named. For example, in Roblox, instances can have arbitrary fields of other instances (<code>workspace.Baseplate</code> indexes an instance named Baseplate inside <code>workspace</code>, but <code>Baseplate</code> is nowhere in the Roblox API).</p>
<p>We can specify this behavior by using the special <code>&quot;*&quot;</code> field.</p>
<pre><code class="language-toml">[workspace.&quot;*&quot;]
struct = &quot;Instance&quot;
<p>We can specify this behavior by using the special <code>"*"</code> field.</p>
<pre><code class="language-toml">[workspace."*"]
struct = "Instance"
</code></pre>
<p>This will tell selene &quot;any field accessed from <code>workspace</code> that doesn't exist must be an Instance <a href="#structs">struct</a>&quot;.</p>
<p>This will tell selene "any field accessed from <code>workspace</code> that doesn't exist must be an Instance <a href="#structs">struct</a>".</p>
<p>Wildcards can even be used in succession. For example, consider the following:</p>
<pre><code class="language-toml">[script.Name]
property = true
writable = &quot;overridden&quot;
writable = "overridden"

[script.&quot;*&quot;.&quot;*&quot;]
[script."*"."*"]
property = true
writable = &quot;full&quot;
writable = "full"
</code></pre>
<p>Ignoring the wildcard, so far this means:</p>
<ul>
<li><code>script.Name = &quot;Hello&quot;</code> <em>will</em> work.</li>
<li><code>script.Name = "Hello"</code> <em>will</em> work.</li>
<li><code>script = nil</code> <em>will not</em> work, because the writability of <code>script</code> is not specified.</li>
<li><code>script.Name.UhOh</code> <em>will not</em> work, because <code>script.Name</code> does not have fields.</li>
</ul>
Expand Down
4 changes: 2 additions & 2 deletions cli/usage.html
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ <h1 id="cli-usage"><a class="header" href="#cli-usage">CLI Usage</a></h1>
--no-exclude Ignore excludes defined in config
-h, --help Prints help information
-n, --no-summary Suppress summary information
-q, --quiet Display only the necessary information. Equivalent to --display-style=&quot;quiet&quot;
-q, --quiet Display only the necessary information. Equivalent to --display-style="quiet"
-V, --version Prints version information

OPTIONS:
Expand Down Expand Up @@ -239,7 +239,7 @@ <h2 id="advanced-options"><a class="header" href="#advanced-options">Advanced op
<p><strong>--num-threads</strong> <em>num-threads</em></p>
<p>Specifies the number of threads for selene to use. Defaults to however many cores your CPU has. If you type <code>selene --help</code>, you can see this number because it will show as the default for you.</p>
<p><strong>--pattern</strong> <em>pattern</em></p>
<p>A <a href="https://en.wikipedia.org/wiki/Glob_(programming)">glob</a> to match what files selene should check for. For example, if you only wanted to check files that end with <code>.spec.lua</code>, you would input <code>--pattern **/*.spec.lua</code>. Defaults to <code>**/*.lua</code>, meaning &quot;any lua file&quot;, or <code>**/*.lua</code> and <code>**/*.luau</code> with the roblox feature flag, meaning &quot;any lua/luau file&quot;.</p>
<p>A <a href="https://en.wikipedia.org/wiki/Glob_(programming)">glob</a> to match what files selene should check for. For example, if you only wanted to check files that end with <code>.spec.lua</code>, you would input <code>--pattern **/*.spec.lua</code>. Defaults to <code>**/*.lua</code>, meaning "any lua file", or <code>**/*.lua</code> and <code>**/*.luau</code> with the roblox feature flag, meaning "any lua/luau file".</p>

</main>

Expand Down
10 changes: 5 additions & 5 deletions contributing.html
Original file line number Diff line number Diff line change
Expand Up @@ -257,17 +257,17 @@ <h3 id="writing-tests"><a class="header" href="#writing-tests">Writing tests</a>
fn test_cool_lint() {
test_lint(
CoolLint::new(()).unwrap(),
&quot;cool_lint&quot;,
&quot;cool_lint&quot;,
"cool_lint",
"cool_lint",
);
}
}
</code></pre>
<p>Let's discuss what this code means, assuming you're familiar with <a href="https://doc.rust-lang.org/book/ch11-00-testing.html">the way tests are written and performed in Rust</a>.</p>
<p>The <code>test_lint</code> function is the easiest way to test that a lint works. It'll search the source code we made before, run selene on it (only your lint), and check its results with the existing <code>[filename].stderr</code> file, or create one if it does not yet exist.</p>
<p>The first argument is the lint object to use. <code>CoolLint::new(())</code> just means &quot;create <code>CoolLint</code> with a configuration of <code>()</code>&quot;. If your lint specifies a configuration, this will instead be something such as <code>CoolLintConfig::default()</code> or whatever you're specifically testing.</p>
<p>The first argument is the lint object to use. <code>CoolLint::new(())</code> just means "create <code>CoolLint</code> with a configuration of <code>()</code>". If your lint specifies a configuration, this will instead be something such as <code>CoolLintConfig::default()</code> or whatever you're specifically testing.</p>
<p>The <code>.unwrap()</code> is just because <code>CoolLint::new</code> returns a <code>Result</code>. If you want to test configuration errors, you can avoid <code>test_lint</code> altogether and just test <code>CoolLint::new(...).is_err()</code> directly.</p>
<p>The first <code>&quot;cool_lint&quot;</code> is the name of the folder we created. The second <code>&quot;cool_lint&quot;</code> is the name of the <em>Lua file</em> we created.</p>
<p>The first <code>"cool_lint"</code> is the name of the folder we created. The second <code>"cool_lint"</code> is the name of the <em>Lua file</em> we created.</p>
<p>Now, just run <code>cargo test</code>, and a <code>.stderr</code> file will be automatically generated! You can manipulate it however you see fit as well as modifying your lint, and so long as the file is there, selene will make sure that its accurate.</p>
<p>Optionally, you can add a <code>.std.toml</code> with the same name as the test next to the lua file, where you can specify a custom <a href="./usage/std.html">standard library</a> to use. If you do not, the Lua 5.1 standard library will be used.</p>
<h3 id="documenting-it"><a class="header" href="#documenting-it">Documenting it</a></h3>
Expand Down Expand Up @@ -298,7 +298,7 @@ <h3 id="documenting-it"><a class="header" href="#documenting-it">Documenting it<
## Remarks
If there's anything else a user should know when using this lint, write it here.
</code></pre>
<p>This isn't a strict format, and you can mess with it as appropriate. For example, <code>standard_library</code> does not have a &quot;Why this is bad&quot; section as not only is it a very encompassing lint, but it should be fairly obvious. Many lints don't specify a &quot;...should be written as...&quot; as it is either something with various potential fixes (such as <a href="./lints/global_usage.html"><code>global_usage</code></a>) or because the &quot;good code&quot; is just removing parts entirely (such as <a href="./lints/unbalanced_assignments.html"><code>unbalanced_assignments</code></a>).</p>
<p>This isn't a strict format, and you can mess with it as appropriate. For example, <code>standard_library</code> does not have a "Why this is bad" section as not only is it a very encompassing lint, but it should be fairly obvious. Many lints don't specify a "...should be written as..." as it is either something with various potential fixes (such as <a href="./lints/global_usage.html"><code>global_usage</code></a>) or because the "good code" is just removing parts entirely (such as <a href="./lints/unbalanced_assignments.html"><code>unbalanced_assignments</code></a>).</p>

</main>

Expand Down
2 changes: 1 addition & 1 deletion lints/constant_table_comparison.html
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ <h2 id="what-it-does"><a class="header" href="#what-it-does">What it does</a></h
<h2 id="why-this-is-bad"><a class="header" href="#why-this-is-bad">Why this is bad</a></h2>
<p>This will always fail.</p>
<h2 id="example"><a class="header" href="#example">Example</a></h2>
<pre><code class="language-lua">if x == { &quot;a&quot;, &quot;b&quot;, &quot;c&quot; } then
<pre><code class="language-lua">if x == { "a", "b", "c" } then
</code></pre>
<p>...will never pass.</p>
<pre><code class="language-lua">if x == {} then
Expand Down
2 changes: 1 addition & 1 deletion lints/deprecated.html
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ <h2 id="what-it-does"><a class="header" href="#what-it-does">What it does</a></h
<h2 id="why-this-is-bad"><a class="header" href="#why-this-is-bad">Why this is bad</a></h2>
<p>Deprecated fields may not be getting any support, or even face the possibility of being removed.</p>
<h2 id="configuration"><a class="header" href="#configuration">Configuration</a></h2>
<p><code>allow</code> - A list of patterns where the deprecated lint will not throw. For instance, <code>[&quot;table.getn&quot;]</code> will allow you to use <code>table.getn</code>, even though it is deprecated. This supports wildcards, so <code>table.*</code> will allow both <code>table.getn</code> and <code>table.foreach</code>.</p>
<p><code>allow</code> - A list of patterns where the deprecated lint will not throw. For instance, <code>["table.getn"]</code> will allow you to use <code>table.getn</code>, even though it is deprecated. This supports wildcards, so <code>table.*</code> will allow both <code>table.getn</code> and <code>table.foreach</code>.</p>
<h2 id="example"><a class="header" href="#example">Example</a></h2>
<pre><code class="language-lua">local count = table.getn(x)
</code></pre>
Expand Down
16 changes: 8 additions & 8 deletions lints/duplicate_keys.html
Original file line number Diff line number Diff line change
Expand Up @@ -182,23 +182,23 @@ <h2 id="example"><a class="header" href="#example">Example</a></h2>
<pre><code class="language-lua">local foo = {
a = 1,
b = 5,
[&quot;a&quot;] = 3, -- duplicate definition
["a"] = 3, -- duplicate definition
c = 3,
b = 1, -- duplicate definition
}

local bar = {
&quot;foo&quot;,
&quot;bar&quot;,
[1524] = &quot;hello&quot;,
&quot;baz&quot;,
&quot;foobar&quot;,
[2] = &quot;goodbye&quot;, -- duplicate to `bar` which has key `2`
"foo",
"bar",
[1524] = "hello",
"baz",
"foobar",
[2] = "goodbye", -- duplicate to `bar` which has key `2`
}
</code></pre>
<h2 id="remarks"><a class="header" href="#remarks">Remarks</a></h2>
<p>Only handles keys which constant string/number literals or named (such as <code>{ a = true }</code>).
Array-like values are also handled, where <code>{&quot;foo&quot;}</code> is implicitly handled as <code>{ [1] = &quot;foo&quot; }</code>.</p>
Array-like values are also handled, where <code>{"foo"}</code> is implicitly handled as <code>{ [1] = "foo" }</code>.</p>

</main>

Expand Down
Loading

0 comments on commit 71f1676

Please sign in to comment.