From a32abae782da0f74799efc4bfa94f870382d4f9a Mon Sep 17 00:00:00 2001 From: wingbot <109207340+monadabot@users.noreply.github.com> Date: Fri, 15 Sep 2023 22:03:18 +0300 Subject: [PATCH] feat(docs): update docs (#609) feat(docs): update docs Updates the Wing docs. See details in [workflow run]. [Workflow Run]: https://github.com/winglang/docsite/actions/runs/6201818673 ------ *Automatically created via the "update-docs" workflow* --- .../version-latest/03-language-reference.md | 119 ++++++++++++++---- .../version-latest/07-examples/08-classes.md | 16 +-- 2 files changed, 100 insertions(+), 35 deletions(-) diff --git a/versioned_docs/version-latest/03-language-reference.md b/versioned_docs/version-latest/03-language-reference.md index 2330fc6f7..223e6ba3b 100644 --- a/versioned_docs/version-latest/03-language-reference.md +++ b/versioned_docs/version-latest/03-language-reference.md @@ -654,7 +654,73 @@ Static class fields are not supported yet, see https://github.com/winglang/wing/ --- -### 1.5 Reassignability +### 1.5 Access Modifiers (member visibility) + +Class members, by default, can only be accessed from within the implementation code of the same class (private). +Inner classes or closures can access private members of their containing class. +```TS +class Foo { + private_field: num; // This is private by default + + init() {this.private_field = 1;} + + method() { + log(this.private_field); // We can access `private_field` since we're in Foo + + class InnerFoo { + method(f: Foo) { + log(f.private_field); // We can access `private_field` since we're in Foo + } + } + } +} +``` +Accessing class members of a super class can be done by adding the the `protected` access modifier. +```TS +class Foo { + protected protected_method() {}; // This is a `protected` method +} + +class Bar extends Foo { + method() { + this.protected_method(); // We can access `protected_method` from a subclass + } +} +``` +The `pub` access modifier makes the class member accessible from anywhere. +Interface members are always public. +Implementing interface members in a class requires explicitly flagging them as `pub`. +```TS +interface FooInterface { + interface_method(): void; // Interface definitions are always implicitly `pub` +} + +class Foo impl FooInterface { + pub public_method() {} // This can be accessed from outside of the class implemenetation + pub interface_method() {} // This must be explicitly defined as `pub` since it's an interface implementation +} +let f = new Foo(); +f.public_method(); // We can call this method from outside the class - it's public +``` + +Access modifier rules apply for both fields and methods of a class. +Struct fields are always public and do not have access modifiers. + +#### 1.5.1 Method overriding and access modifiers +Private methods cannot be overriden. +Overriding a method of a parent class requires the parent class's method to be either `pub` or `protected`. +The overriding method can have either the same access modifier as the original method or a more permissive one. +You cannot "decrease" the access level down the inheritence hierarchy, only "increase" it. +In practice this means: +* `protected` methods can be overidden by either a `protected` or a `pub` method. +* `pub` methods can be overriden by a `pub` method. + +Note that method overriding only applies to instance methods. `static` methods are not treated as part of the inheritence hierarcy. + +[`▲ top`][top] + +--- +### 1.6 Reassignability Re-assignment to variables that are defined with `let` is not allowed in Wing. @@ -700,7 +766,7 @@ let f = (arg1: num, var arg2: num) => { --- -### 1.6 Optionality +### 1.7 Optionality Nullity is a primary source of bugs in software. Being able to guarantee that a value will never be null makes it easier to write safe code without constantly having to take nullity into account. @@ -723,9 +789,9 @@ Here's a quick summary of how optionality works in Wing: * The keyword `nil` can be used in assignment scenarios to indicate that an optional doesn't have a value. It cannot be used to test if an optional has a value or not. -#### 1.6.1 Declaration +#### 1.7.1 Declaration -##### 1.6.1.1 Struct fields +##### 1.7.1.1 Struct fields One of the more common use cases for optionals is to use them in struct declarations. @@ -746,7 +812,7 @@ assert(david.address? == false); assert(jonathan.address? == true); ``` -##### 1.6.1.2 Variables +##### 1.7.1.2 Variables Use `T?` to indicate that a variable is optional. To initialize it without a value use `= nil`. @@ -764,7 +830,7 @@ x = nil; assert(x? == false); ``` -##### 1.6.1.3 Class fields +##### 1.7.1.3 Class fields Similarly to struct fields, fields of classes can be also defined as optional using `T?`: @@ -784,7 +850,7 @@ class Foo { } ``` -##### 1.6.1.4 Function arguments +##### 1.7.1.4 Function arguments In the following example, the argument `by` is optional, so it is possible to call `increment()` without supplying a value for `by`: @@ -826,7 +892,7 @@ f(myRequired: "hello"); f(myOptional: 12, myRequired: "dang"); ``` -##### 1.6.1.5 Function return types +##### 1.7.1.5 Function return types If a function returns an optional type, use the `return nil;` statement to indicate that the value is not defined. @@ -852,7 +918,7 @@ if let name = tryParseName("Neo Matrix") { } ``` -#### 1.6.2 Testing using `x?` +#### 1.7.2 Testing using `x?` To test if an optional has a value or not, you can either use `x == nil` or `x != nil` or the special syntax `x?`. @@ -883,7 +949,7 @@ if myPerson.address == nil { } ``` -#### 1.6.3 Unwrapping using `if let` +#### 1.7.3 Unwrapping using `if let` The `if let` statement (or `if let var` for a reassignable variable) can be used to test if an optional is defined and *unwrap* it into a non-optional variable defined inside the block: @@ -899,7 +965,7 @@ if let address = myPerson.address { > multiple conditions, or unwrapping multiple optionals. This is something we might consider in the > future. -#### 1.6.4 Unwrapping or default value using `??` +#### 1.7.4 Unwrapping or default value using `??` The `??` operator can be used to unwrap or provide a default value. This returns a value of `T` that can safely be used. @@ -908,7 +974,7 @@ can safely be used. let address: str = myPerson.address ?? "Planet Earth"; ``` -#### 1.6.5 Optional chaining using `?.` +#### 1.7.5 Optional chaining using `?.` The `?.` syntax can be used for optional chaining. Optional chaining returns a value of type `T?` which must be unwrapped in order to be used. @@ -925,7 +991,7 @@ if let ip = ipAddress { --- -#### 1.6.6 Roadmap +#### 1.7.6 Roadmap The following features are not yet implemented, but we are planning to add them in the future: @@ -944,7 +1010,7 @@ The following features are not yet implemented, but we are planning to add them * Support `??` for different types if they have a common ancestor (and also think of interfaces). See https://github.com/winglang/wing/issues/2103 to track. -### 1.7 Type Inference +### 1.8 Type Inference Type can optionally be put between name and the equal sign, using a colon. Partial type inference is allowed while using the `?` keyword immediately after @@ -972,7 +1038,7 @@ Type annotations are required for method arguments and their return value but op --- -### 1.8 Error Handling +### 1.9 Error Handling Exceptions and `try/catch/finally` are the error mechanism. Mechanics directly translate to JavaScript. You can create a new exception with a `throw` call. @@ -997,7 +1063,7 @@ In the presence of `catch` the variable holding the exception (`e` in the exampl --- -### 1.9 Recommended Formatting +### 1.10 Recommended Formatting Wing recommends the following formatting and naming conventions: @@ -1013,7 +1079,7 @@ Wing recommends the following formatting and naming conventions: --- -### 1.10 Memory Management +### 1.11 Memory Management There is no implicit memory de-allocation function, dynamic memory is managed by Wing and is garbage collected (relying on JSII target GC for the meantime). @@ -1022,7 +1088,7 @@ Wing and is garbage collected (relying on JSII target GC for the meantime). --- -### 1.11 Execution Model +### 1.12 Execution Model Execution model currently is delegated to the JSII target. This means if you are targeting JSII with Node, Wing will use the event based loop that Node offers. @@ -1043,7 +1109,7 @@ case of CDK for Terraform target. --- -### 1.12 Asynchronous Model +### 1.13 Asynchronous Model Wing builds upon the asynchronous model of JavaScript currently and expands upon it with new keywords and concepts. The `async` keyword of JavaScript is replaced @@ -1056,17 +1122,17 @@ Main concepts to understand: Contrary to JavaScript, any call to an async function is implicitly awaited in Wing. -#### 1.12.1 Roadmap +#### 1.13.1 Roadmap The following features are not yet implemented, but we are planning to add them in the future: * `await`/`defer` statements - see https://github.com/winglang/wing/issues/116 to track. * Promise function type - see https://github.com/winglang/wing/issues/1004 to track. -### 1.13 Roadmap +### 1.14 Roadmap -Access modifiers (`private`/`public`/`internal`/`protected`) are not yet implemented. -See https://github.com/winglang/wing/issues/108 to track. +* Module type visibility (exports/`pub` types) is not implemented yet - see https://github.com/winglang/wing/issues/130 to track. +* `internal` access modifier is not yet implemented - see https://github.com/winglang/wing/issues/4156 to track. ## 2. Statements @@ -1310,7 +1376,7 @@ class Bar { this.z = new Foo(); this.log(); // OK to call here } - public log() { + pub log() { log("${this.y}"); } } @@ -1331,7 +1397,7 @@ their "strict" mode. class Foo { x: num; init() { this.x = 0; } - public method() { } + pub method() { } } class Boo extends Foo { init() { @@ -1349,7 +1415,7 @@ Classes can implement interfaces iff the interfaces do not contain `inflight`. class Foo { x: num; init() { this.x = 0; } - public method() { } + pub method() { } } class Boo extends Foo { init() { super(); this.x = 10; } @@ -1372,7 +1438,6 @@ In methods if return type is missing, `: void` is assumed. The following features are not yet implemented, but we are planning to add them in the future: * Overloading class methods (including `init`) - see https://github.com/winglang/wing/issues/3123 to track. -* Overriding class methods - see https://github.com/winglang/wing/issues/1124 to track. * Using the `final` keyword to stop the inheritance chain - see https://github.com/winglang/wing/issues/460 to track. [`▲ top`][top] diff --git a/versioned_docs/version-latest/07-examples/08-classes.md b/versioned_docs/version-latest/07-examples/08-classes.md index 60691e4b9..cb78702f4 100644 --- a/versioned_docs/version-latest/07-examples/08-classes.md +++ b/versioned_docs/version-latest/07-examples/08-classes.md @@ -28,7 +28,7 @@ class Foo { log("at inflight init"); } - inflight doStuff() { + pub inflight doStuff() { // all code is async and runs on the cloud log("field3[0]='${this.field3.at(0)}'"); util.sleep(1s); @@ -55,7 +55,7 @@ interface IProfile { } inflight class WingPerson impl IProfile { - inflight name(): str { + pub inflight name(): str { return "Fairy Wing"; } } @@ -84,10 +84,10 @@ class BucketBasedKeyValueStore impl IKVStore { init() { this.bucket = new cloud.Bucket(); } - inflight get(key: str): Json { + pub inflight get(key: str): Json { return this.bucket.getJson(key); } - inflight set(key: str, value: Json): void { + pub inflight set(key: str, value: Json): void { this.bucket.putJson(key, value); } } @@ -108,10 +108,10 @@ class BucketBasedKeyValueStore impl IKVStore { init() { this.bucket = new cloud.Bucket(); } - inflight get(key: str): Json { + pub inflight get(key: str): Json { return this.bucket.getJson(key); } - inflight set(key: str, value: Json): void { + pub inflight set(key: str, value: Json): void { this.bucket.putJson(key, value); } } @@ -127,10 +127,10 @@ class TableBasedKeyValueStore impl IKVStore { } ); } - inflight get(key: str): Json { + pub inflight get(key: str): Json { return this.table.get(key); } - inflight set(key: str, value: Json): str { + pub inflight set(key: str, value: Json): str { this.table.insert(key, value); } }