Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/Kampfkarren/selene
Browse files Browse the repository at this point in the history
  • Loading branch information
chriscerie committed Nov 11, 2023
2 parents a0d53df + 6e88708 commit 98176b5
Show file tree
Hide file tree
Showing 28 changed files with 366 additions and 391 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Run tests (selene, all features)
run: cargo test -- --nocapture
run: cargo test --release -- --nocapture
working-directory: selene
- name: Run tests (selene, no features)
run: cargo test --no-default-features -- --nocapture
run: cargo test --release --no-default-features -- --nocapture
working-directory: selene
- name: Run tests (selene-lib, all features)
run: cargo test
run: cargo test --release
working-directory: selene-lib
- name: Run tests (selene-lib, no features)
run: cargo test --no-default-features
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Added new [`mixed_table` lint](https://kampfkarren.github.io/selene/lints/mixed_table.html), which will warn against mixed tables.
- Added `bit32.byteswap` to Luau standard library
- Added `buffer` library to Luau standard library
- Added `SharedTable` to Roblox standard library

### Changed
- Updated internal parser, which includes floor division (`//`), more correct parsing of string interpolation with double braces, and better parsing of `\z` escapes.

### Fixed
- `string.pack` and `string.unpack` now have proper function signatures in the Lua 5.3 standard library.
Expand Down
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[workspace]

members = ["selene", "selene-lib"]
resolver = "2"

[workspace.package]
version = "0.25.0"
Expand All @@ -11,8 +11,8 @@ license = "MPL-2.0"
repository = "https://github.com/Kampfkarren/selene"

[workspace.dependencies]
full_moon = "0.18.0"
full_moon = "0.19.0"
toml = "0.7.2"

# Do not update this without confirming profiling uses the same version of tracy-client as selene
profiling = "1.0.7"
profiling = "1.0.7"
45 changes: 45 additions & 0 deletions selene-lib/default_std/roblox_base.yml
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,51 @@ globals:
require:
args:
- type: number
SharedTable.clear:
args:
- type:
display: SharedTable
SharedTable.clone:
args:
- type:
display: SharedTable
- required: false
type: bool
must_use: true
SharedTable.cloneAndFreeze:
args:
- type:
display: SharedTable
- required: false
type: bool
must_use: true
SharedTable.increment:
args:
- type:
display: SharedTable
- type: any
- type: number
SharedTable.isFrozen:
args:
- type:
display: SharedTable
must_use: true
SharedTable.new:
args:
- required: false
type: table
must_use: true
SharedTable.size:
args:
- type:
display: SharedTable
must_use: true
SharedTable.update:
args:
- type:
display: SharedTable
- type: any
- type: function
settings:
args: []
shared:
Expand Down
26 changes: 14 additions & 12 deletions selene-lib/src/ast_util/extract_static_token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,23 @@ pub fn extract_static_token(expression: &ast::Expression) -> Option<&TokenRefere
deny(non_exhaustive_omitted_patterns)
)]
match expression {
ast::Expression::BinaryOperator { .. } | ast::Expression::UnaryOperator { .. } => None,

ast::Expression::Parentheses { expression, .. } => extract_static_token(expression),

#[cfg_attr(
feature = "force_exhaustive_checks",
allow(non_exhaustive_omitted_patterns)
)]
ast::Expression::Value { value, .. } => match &**value {
ast::Value::Number(token) => Some(token),
ast::Value::String(token) => Some(token),
ast::Value::Symbol(token) => Some(token),
ast::Expression::Number(token)
| ast::Expression::String(token)
| ast::Expression::Symbol(token) => Some(token),

ast::Expression::BinaryOperator { .. }
| ast::Expression::UnaryOperator { .. }
| ast::Expression::Function(_)
| ast::Expression::FunctionCall(_)
| ast::Expression::TableConstructor(_)
| ast::Expression::Var(_) => None,

_ => None,
},
#[cfg(feature = "roblox")]
ast::Expression::IfExpression(_)
| ast::Expression::InterpolatedString(_)
| ast::Expression::TypeAssertion { .. } => None,

_ => None,
}
Expand Down
19 changes: 3 additions & 16 deletions selene-lib/src/ast_util/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@ pub fn first_code(ast: &Ast) -> Option<(Position, Position)> {

pub fn is_vararg(expression: &ast::Expression) -> bool {
if_chain::if_chain! {
if let ast::Expression::Value { value, .. } = expression;
if let ast::Value::Symbol(token) = &**value;
if let ast::Expression::Symbol(token) = expression;
if let tokenizer::TokenType::Symbol {
symbol: tokenizer::Symbol::Ellipse,
} = token.token().token_type();
Expand All @@ -63,21 +62,9 @@ pub fn is_vararg(expression: &ast::Expression) -> bool {
}
}

pub fn is_function_call(expression: &ast::Expression) -> bool {
if let ast::Expression::Value { value, .. } = expression {
if let ast::Value::FunctionCall(_) = &**value {
return true;
}
}

false
}

pub fn expression_to_ident(expression: &ast::Expression) -> Option<&TokenReference> {
if let ast::Expression::Value { value, .. } = expression {
if let ast::Value::Var(ast::Var::Name(name)) = &**value {
return Some(name);
}
if let ast::Expression::Var(ast::Var::Name(name)) = expression {
return Some(name);
}

None
Expand Down
18 changes: 7 additions & 11 deletions selene-lib/src/ast_util/name_paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,15 @@ pub fn name_path_from_prefix_suffix<'a, S: Iterator<Item = &'a ast::Suffix>>(
}

pub fn name_path(expression: &ast::Expression) -> Option<Vec<String>> {
if let ast::Expression::Value { value, .. } = expression {
if let ast::Value::Var(var) = &**value {
match var {
ast::Var::Expression(expression) => {
name_path_from_prefix_suffix(expression.prefix(), expression.suffixes())
}
if let ast::Expression::Var(var) = expression {
match var {
ast::Var::Expression(expression) => {
name_path_from_prefix_suffix(expression.prefix(), expression.suffixes())
}

ast::Var::Name(name) => Some(vec![name.to_string()]),
ast::Var::Name(name) => Some(vec![name.to_string()]),

_ => None,
}
} else {
None
_ => None,
}
} else {
None
Expand Down
100 changes: 48 additions & 52 deletions selene-lib/src/ast_util/scopes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,9 +201,9 @@ fn get_name_path_from_call(call: &ast::FunctionCall) -> Option<Vec<String>> {
let mut all_suffixes = Vec::new();

let mut path = match call.prefix() {
ast::Prefix::Expression(ast::Expression::Value { value, .. }) => match &**value {
ast::Value::Var(ast::Var::Name(name)) => vec![name.token().to_string()],
ast::Value::Var(ast::Var::Expression(var_expression)) => {
ast::Prefix::Expression(expression) => match &**expression {
ast::Expression::Var(ast::Var::Name(name)) => vec![name.token().to_string()],
ast::Expression::Var(ast::Var::Expression(var_expression)) => {
let mut path = Vec::new();

let name = if let ast::Prefix::Name(name) = var_expression.prefix() {
Expand All @@ -220,7 +220,6 @@ fn get_name_path_from_call(call: &ast::FunctionCall) -> Option<Vec<String>> {
}
_ => return None,
},
ast::Prefix::Expression(_) => return None,
ast::Prefix::Name(name) => vec![name.token().to_string()],
_ => return None,
};
Expand Down Expand Up @@ -259,12 +258,10 @@ fn get_name_path_from_call(call: &ast::FunctionCall) -> Option<Vec<String>> {
}

fn get_assigned_value(expression: &ast::Expression) -> Option<AssignedValue> {
if let ast::Expression::Value { value, .. } = expression {
if let ast::Value::TableConstructor(table_constructor) = &**value {
return Some(AssignedValue::StaticTable {
has_fields: !table_constructor.fields().is_empty(),
});
}
if let ast::Expression::TableConstructor(table_constructor) = expression {
return Some(AssignedValue::StaticTable {
has_fields: !table_constructor.fields().is_empty(),
});
}

None
Expand Down Expand Up @@ -342,62 +339,61 @@ impl ScopeVisitor {
self.read_expression(rhs);
}

ast::Expression::Value { value, .. } => match &**value {
ast::Value::Function((name, _)) => {
self.read_name(name);
}

ast::Value::FunctionCall(call) => {
self.read_prefix(call.prefix());
for suffix in call.suffixes() {
self.read_suffix(suffix);
}
}
ast::Expression::Function((name, _)) => {
self.read_name(name);
}

ast::Value::TableConstructor(table) => {
self.read_table_constructor(table);
ast::Expression::FunctionCall(call) => {
self.read_prefix(call.prefix());
for suffix in call.suffixes() {
self.read_suffix(suffix);
}
}

ast::Value::ParenthesesExpression(expression) => self.read_expression(expression),
ast::Expression::TableConstructor(table) => {
self.read_table_constructor(table);
}

ast::Value::Symbol(symbol) => {
if *symbol.token_type()
== (TokenType::Symbol {
symbol: Symbol::Ellipse,
})
{
self.read_name(symbol);
}
ast::Expression::Symbol(symbol) => {
if *symbol.token_type()
== (TokenType::Symbol {
symbol: Symbol::Ellipse,
})
{
self.read_name(symbol);
}
}

ast::Value::Var(var) => self.read_var(var),
ast::Expression::Var(var) => self.read_var(var),

#[cfg(feature = "roblox")]
ast::Value::IfExpression(if_expression) => {
self.read_expression(if_expression.condition());
self.read_expression(if_expression.if_expression());
#[cfg(feature = "roblox")]
ast::Expression::IfExpression(if_expression) => {
self.read_expression(if_expression.condition());
self.read_expression(if_expression.if_expression());

if let Some(else_if_expressions) = if_expression.else_if_expressions() {
for else_if_expression in else_if_expressions {
self.read_expression(else_if_expression.condition());
self.read_expression(else_if_expression.expression());
}
if let Some(else_if_expressions) = if_expression.else_if_expressions() {
for else_if_expression in else_if_expressions {
self.read_expression(else_if_expression.condition());
self.read_expression(else_if_expression.expression());
}

self.read_expression(if_expression.else_expression());
}

#[cfg(feature = "roblox")]
ast::Value::InterpolatedString(interpolated_string) => {
for expression in interpolated_string.expressions() {
self.read_expression(expression);
}
self.read_expression(if_expression.else_expression());
}

#[cfg(feature = "roblox")]
ast::Expression::InterpolatedString(interpolated_string) => {
for expression in interpolated_string.expressions() {
self.read_expression(expression);
}
}

ast::Value::Number(_) | ast::Value::String(_) => {}
#[cfg(feature = "roblox")]
ast::Expression::TypeAssertion { expression, .. } => {
self.read_expression(expression);
}

_ => {}
},
ast::Expression::Number(_) | ast::Expression::String(_) => {}

_ => {}
}
Expand Down
Loading

0 comments on commit 98176b5

Please sign in to comment.