Skip to content

Commit

Permalink
fix: cannot use datetime or regex as a type annotation (#7001)
Browse files Browse the repository at this point in the history
## Checklist
fixes #6376 

Please pay attention that `std.Regex` and `std.Datetime` cannot be used by types now (similarly how `std.Json` can't be used as a type, if it's a bug let me know and I'll open an issue @Chriscbr )

- [ ] Title matches [Winglang's style guide](https://www.winglang.io/contributing/start-here/pull_requests#how-are-pull-request-titles-formatted)
- [ ] Description explains motivation and solution
- [ ] Tests added (always)
- [ ] Docs updated (only required for features)
- [ ] Added `pr/e2e-full` label if this feature requires end-to-end testing

*By submitting this pull request, I confirm that my contribution is made under the terms of the [Wing Cloud Contribution License](https://github.com/winglang/wing/blob/main/CONTRIBUTION_LICENSE.md)*.
  • Loading branch information
tsuf239 authored Aug 6, 2024
1 parent b72cfa8 commit 36e6b27
Show file tree
Hide file tree
Showing 23 changed files with 464 additions and 20 deletions.
45 changes: 45 additions & 0 deletions examples/tests/valid/std_type_annotation.test.w
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
bring expect;
let then: datetime = datetime.utcNow();
let now: datetime = then;


let isOlderOrEqual = inflight (x: datetime, y: datetime) => {
return y.timestampMs >= x.timestampMs;
};

test "datetime is a valid type" {
let later: datetime = datetime.fromComponents({
day: now.dayOfMonth,
hour: now.hours,
year: now.year + 1,
min: now.min,
month: now.month,
ms: now.ms,
sec: now.sec,
tz: now.timezone
});

expect.ok(isOlderOrEqual(then, now));
expect.ok(isOlderOrEqual(now, later));
}


let decimal: regex = regex.compile("^[0-9]*$");

let testString = inflight (re: regex, s: str) => {
return re.test(s);
};

test "regex is valid type" {
let binary: regex = regex.compile("^[0-1]*$");
expect.equal(testString(decimal, "24"), true);
expect.equal(testString(decimal, "340523"), true);
expect.equal(testString(decimal, "a23"), false);

expect.equal(testString(binary, "01101"), true);
expect.equal(testString(binary, "0"), true);
expect.equal(testString(binary, "120010"), false);
}



33 changes: 23 additions & 10 deletions libs/tree-sitter-wing/grammar.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,12 +235,7 @@ module.exports = grammar({

field_modifiers: ($) =>
repeat1(
choice(
$.access_modifier,
$.static,
$.phase_specifier,
$.reassignable
)
choice($.access_modifier, $.static, $.phase_specifier, $.reassignable)
),

class_field: ($) =>
Expand Down Expand Up @@ -338,7 +333,12 @@ module.exports = grammar({
),

else_if_block: ($) =>
seq("else", "if", field("condition", $.expression), field("block", $.block)),
seq(
"else",
"if",
field("condition", $.expression),
field("block", $.block)
),

try_catch_statement: ($) =>
seq(
Expand Down Expand Up @@ -531,7 +531,16 @@ module.exports = grammar({
parameter_type_list: ($) => seq("(", commaSep($._type), ")"),

builtin_type: ($) =>
choice("num", "bool", "any", "str", "void", "duration"),
choice(
"num",
"bool",
"any",
"str",
"void",
"duration",
"datetime",
"regex"
),

initializer: ($) =>
seq(
Expand Down Expand Up @@ -695,7 +704,8 @@ module.exports = grammar({
),

map_literal_member: ($) => seq($.expression, "=>", $.expression),
struct_literal_member: ($) => choice($.identifier, seq($.identifier, ":", $.expression)),
struct_literal_member: ($) =>
choice($.identifier, seq($.identifier, ":", $.expression)),
structured_access_expression: ($) =>
prec.right(
PREC.STRUCTURED_ACCESS,
Expand All @@ -714,7 +724,10 @@ module.exports = grammar({
json_map_literal: ($) =>
braced(commaSep(field("member", $.json_literal_member))),
json_literal_member: ($) =>
choice($.identifier, seq(choice($.identifier, $.string), ":", $.expression)),
choice(
$.identifier,
seq(choice($.identifier, $.string), ":", $.expression)
),
json_container_type: ($) => $._json_types,

_json_types: ($) => choice("Json", "MutJson"),
Expand Down
8 changes: 8 additions & 0 deletions libs/tree-sitter-wing/src/grammar.json

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

4 changes: 4 additions & 0 deletions libs/wingc/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ pub enum TypeAnnotationKind {
String,
Bool,
Duration,
Datetime,
Regex,
Void,
Json,
MutJson,
Expand Down Expand Up @@ -203,6 +205,8 @@ impl Display for TypeAnnotationKind {
TypeAnnotationKind::String => write!(f, "str"),
TypeAnnotationKind::Bool => write!(f, "bool"),
TypeAnnotationKind::Duration => write!(f, "duration"),
TypeAnnotationKind::Datetime => write!(f, "datetime"),
TypeAnnotationKind::Regex => write!(f, "regex"),
TypeAnnotationKind::Void => write!(f, "void"),
TypeAnnotationKind::Json => write!(f, "Json"),
TypeAnnotationKind::MutJson => write!(f, "MutJson"),
Expand Down
4 changes: 4 additions & 0 deletions libs/wingc/src/docs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ impl Documented for TypeRef {
| Type::Number
| Type::String
| Type::Duration
| Type::Datetime
| Type::Regex
| Type::Boolean
| Type::Void
| Type::Json(_)
Expand Down Expand Up @@ -190,6 +192,8 @@ impl Documented for TypeRef {
| Type::Number
| Type::String
| Type::Duration
| Type::Datetime
| Type::Regex
| Type::Boolean
| Type::Void
| Type::Json(_)
Expand Down
26 changes: 25 additions & 1 deletion libs/wingc/src/dtsify/extern_dtsify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ use crate::{
files::{remove_file, update_file, FilesError},
jsify::codemaker::CodeMaker,
type_check::*,
WINGSDK_ASSEMBLY_NAME, WINGSDK_DURATION,
WINGSDK_ASSEMBLY_NAME, WINGSDK_DATETIME, WINGSDK_DURATION, WINGSDK_REGEX,
};

const DURATION_FQN: &str = formatcp!("{WINGSDK_ASSEMBLY_NAME}.{WINGSDK_DURATION}");
const DATETIME_FQN: &str = formatcp!("{WINGSDK_ASSEMBLY_NAME}.{WINGSDK_DATETIME}");
const REGEX_FQN: &str = formatcp!("{WINGSDK_ASSEMBLY_NAME}.{WINGSDK_REGEX}");

/// Generates a self-contained .d.ts file for a given extern file.
pub struct ExternDTSifier<'a> {
Expand Down Expand Up @@ -134,6 +136,28 @@ impl<'a> ExternDTSifier<'a> {
.unwrap();
self.dtsify_type(duration_type, false)
}
Type::Datetime => {
let datetime_type = self
.types
.libraries
.lookup_nested_str(DATETIME_FQN, None)
.unwrap()
.0
.as_type()
.unwrap();
self.dtsify_type(datetime_type, false)
}
Type::Regex => {
let regex_type = self
.types
.libraries
.lookup_nested_str(REGEX_FQN, None)
.unwrap()
.0
.as_type()
.unwrap();
self.dtsify_type(regex_type, false)
}
Type::Optional(t) => format!("({}) | undefined", self.dtsify_type(*t, is_inflight)),
Type::Array(t) => format!("(readonly ({})[])", self.dtsify_type(*t, is_inflight)),
Type::MutArray(t) => format!("({})[]", self.dtsify_type(*t, is_inflight)),
Expand Down
2 changes: 2 additions & 0 deletions libs/wingc/src/dtsify/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,8 @@ impl<'a> DTSifier<'a> {
TypeAnnotationKind::Json => format!("Readonly<{TYPE_INTERNAL_NAMESPACE}.Json>"),
TypeAnnotationKind::MutJson => format!("{TYPE_INTERNAL_NAMESPACE}.Json"),
TypeAnnotationKind::Duration => format!("{TYPE_STD}.Duration"),
TypeAnnotationKind::Datetime => format!("{TYPE_STD}.Datetime"),
TypeAnnotationKind::Regex => format!("{TYPE_STD}.Regex"),
TypeAnnotationKind::Optional(t) => {
format!("({}) | undefined", self.dtsify_type_annotation(&t, ignore_phase))
}
Expand Down
2 changes: 2 additions & 0 deletions libs/wingc/src/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,8 @@ where
TypeAnnotationKind::String => TypeAnnotationKind::String,
TypeAnnotationKind::Bool => TypeAnnotationKind::Bool,
TypeAnnotationKind::Duration => TypeAnnotationKind::Duration,
TypeAnnotationKind::Datetime => TypeAnnotationKind::Datetime,
TypeAnnotationKind::Regex => TypeAnnotationKind::Regex,
TypeAnnotationKind::Void => TypeAnnotationKind::Void,
TypeAnnotationKind::Json => TypeAnnotationKind::Json,
TypeAnnotationKind::MutJson => TypeAnnotationKind::MutJson,
Expand Down
2 changes: 2 additions & 0 deletions libs/wingc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ const WINGSDK_BRINGABLE_MODULES: [&'static str; 10] = [

const WINGSDK_GENERIC: &'static str = "std.T1";
const WINGSDK_DURATION: &'static str = "std.Duration";
const WINGSDK_DATETIME: &'static str = "std.Datetime";
const WINGSDK_REGEX: &'static str = "std.Regex";
const WINGSDK_MAP: &'static str = "std.Map";
const WINGSDK_MUT_MAP: &'static str = "std.MutMap";
const WINGSDK_ARRAY: &'static str = "std.Array";
Expand Down
2 changes: 2 additions & 0 deletions libs/wingc/src/lsp/completions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1124,6 +1124,8 @@ fn format_symbol_kind_as_completion(name: &str, symbol_kind: &SymbolKind) -> Opt
| Type::String
| Type::Stringable
| Type::Duration
| Type::Datetime
| Type::Regex
| Type::Boolean
| Type::Void
| Type::Json(_)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ source: libs/wingc/src/lsp/completions.rs
kind: 22
documentation:
kind: markdown
value: "```wing\nstruct ObjectMetadata {\n contentType?: str;\n lastModified: Datetime;\n size: num;\n}\n```\n---\nMetadata of a bucket object."
value: "```wing\nstruct ObjectMetadata {\n contentType?: str;\n lastModified: datetime;\n size: num;\n}\n```\n---\nMetadata of a bucket object."
sortText: hh|ObjectMetadata
- label: OnDeployProps
kind: 22
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ source: libs/wingc/src/lsp/completions.rs
kind: 22
documentation:
kind: markdown
value: "```wing\nstruct ObjectMetadata {\n contentType?: str;\n lastModified: Datetime;\n size: num;\n}\n```\n---\nMetadata of a bucket object."
value: "```wing\nstruct ObjectMetadata {\n contentType?: str;\n lastModified: datetime;\n size: num;\n}\n```\n---\nMetadata of a bucket object."
sortText: hh|ObjectMetadata
- label: OnDeployProps
kind: 22
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ source: libs/wingc/src/lsp/completions.rs
kind: 22
documentation:
kind: markdown
value: "```wing\nstruct ObjectMetadata {\n contentType?: str;\n lastModified: Datetime;\n size: num;\n}\n```\n---\nMetadata of a bucket object."
value: "```wing\nstruct ObjectMetadata {\n contentType?: str;\n lastModified: datetime;\n size: num;\n}\n```\n---\nMetadata of a bucket object."
sortText: hh|ObjectMetadata
- label: OnDeployProps
kind: 22
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ source: libs/wingc/src/lsp/completions.rs
kind: 22
documentation:
kind: markdown
value: "```wing\nstruct ObjectMetadata {\n contentType?: str;\n lastModified: Datetime;\n size: num;\n}\n```\n---\nMetadata of a bucket object."
value: "```wing\nstruct ObjectMetadata {\n contentType?: str;\n lastModified: datetime;\n size: num;\n}\n```\n---\nMetadata of a bucket object."
sortText: hh|ObjectMetadata
- label: OnDeployProps
kind: 22
Expand Down
2 changes: 2 additions & 0 deletions libs/wingc/src/lsp/symbol_locator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ impl<'a> SymbolLocator<'a> {
| Type::Number
| Type::String
| Type::Duration
| Type::Datetime
| Type::Regex
| Type::Boolean => {
if let Some((std_type, ..)) = self.types.get_std_class(&type_) {
if let Some(t) = std_type.as_type_ref() {
Expand Down
10 changes: 10 additions & 0 deletions libs/wingc/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ static RESERVED_WORDS: phf::Set<&'static str> = phf_set! {
"num",
"str",
"duration",
"datetime",
"regex",
"bool",
"Json",
"MutJson",
Expand Down Expand Up @@ -1981,6 +1983,14 @@ impl<'s> Parser<'s> {
kind: TypeAnnotationKind::Duration,
span,
}),
"datetime" => Ok(TypeAnnotation {
kind: TypeAnnotationKind::Datetime,
span,
}),
"regex" => Ok(TypeAnnotation {
kind: TypeAnnotationKind::Regex,
span,
}),
"void" => Ok(TypeAnnotation {
kind: TypeAnnotationKind::Void,
span,
Expand Down
Loading

0 comments on commit 36e6b27

Please sign in to comment.