Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Python-like import syntax #598

Merged
merged 24 commits into from
Oct 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
fb1ae54
test: adjust grammar tests
lars-reimann Oct 2, 2023
1446e32
feat: update the grammar
lars-reimann Oct 2, 2023
fc97066
fix: build errors
lars-reimann Oct 2, 2023
929fc41
fix: validation tests
lars-reimann Oct 2, 2023
cbf7e59
fix: formatter tests
lars-reimann Oct 2, 2023
5298423
build: update dependencies
lars-reimann Oct 2, 2023
5162967
test: fix scoping tests
lars-reimann Oct 2, 2023
9d12376
refactor: imported declaration is now a cross-reference
lars-reimann Oct 2, 2023
a3642cc
fix: don't validate package name if it contains syntax errors
lars-reimann Oct 2, 2023
eeeab45
test: add resources to test scoping of imported declarations
lars-reimann Oct 2, 2023
dc6be43
feat: don't put modules into the index
lars-reimann Oct 2, 2023
687be53
feat: initialize custom service to access declarations by package
lars-reimann Oct 2, 2023
6d71887
refactor: remove unnecessary check
lars-reimann Oct 2, 2023
d78a5a2
style: format file
lars-reimann Oct 2, 2023
ab938ee
feat: first implementation of package manager
lars-reimann Oct 2, 2023
9a74b32
refactor: use the package manager to find declarations in same packag…
lars-reimann Oct 2, 2023
99fdc83
refactor: use the package manager to find imported declarations
lars-reimann Oct 2, 2023
65c166d
refactor: remove unneeded code
lars-reimann Oct 2, 2023
927289e
test: fix some issues in the test resources
lars-reimann Oct 2, 2023
67e2017
fix: last bugs in the new scope provider implementation
lars-reimann Oct 2, 2023
f5db76b
test: ignore some lines for coverage
lars-reimann Oct 2, 2023
e75a7ef
test: add unit tests for package manager
lars-reimann Oct 2, 2023
281fdee
docs: adjust the documentation
lars-reimann Oct 2, 2023
7912312
style: apply automated linter fixes
megalinter-bot Oct 2, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 26 additions & 10 deletions docs/language/common/imports.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,56 +9,72 @@ Safe-DS has two kinds of imports, namely a _qualified import_, which imports a s
A _qualified import_ makes a single declaration available. Here is an example that imports the [class][classes] `DecisionTree` in the [package][packages] `safeds.model.regression`:

```txt
import safeds.model.regression.DecisionTree
from safeds.model.regression import DecisionTree
```

The syntax consists of the following parts:

- The keyword `import`
- The _qualified name_ of the declaration to import (here `safeds.model.regression.DecisionTree`). The qualified name can be obtained by concatenating the name of the [package][packages] that contains the declaration (i.e. `safeds.model.regression`) with the name of the declaration (i.e. `DecisionTree`). The two parts are separated by a dot.
- The keyword `from`.
- The name of the [package][packages] that contains the declaration (here `safeds.model.regression`).
- The keyword `import`.
- The name of the declaration (i.e. `DecisionTree`).

Once the declaration is imported, we can refer to it by its _simple name_. This is the last segment of the qualified name, which is the name of the declaration. Here is, for example, a [call][calls] to the constructor of the `DecisionTree` class:
Once the declaration is imported, we can refer to it by its name. Here is, for example, a [call][calls] to the constructor of the `DecisionTree` class:

```txt
DecisionTree()
```

Multiple declarations can be imported from the same package in a single import statement by separating them with commas:

```txt
from safeds.model.regression import DecisionTree, RandomForest
```

### Qualified Imports with Alias

Sometimes the name of the imported declaration can conflict with other declarations that are imported or that are contained in the importing file. To counter this, declarations can be imported under an alias:

```txt
import safeds.model.regression.DecisionTree as StdlibDecisionTree
from safeds.model.regression import DecisionTree as StdlibDecisionTree
```

Let us take apart the syntax:

- The keyword `from`.
- The name of the [package][packages] that contains the declaration (here `safeds.model.regression`).
- The keyword `import`.
- The _qualified name_ of the declaration to import (here `safeds.model.regression.DecisionTree`). The qualified name can be obtained by concatenating the name of the [package][packages] that contains the declaration (i.e. `safeds.model.regression`) with the name of the declaration (i.e. `DecisionTree`). The two parts are separated by a dot.
- The name of the declaration (i.e. `DecisionTree`).
- The keyword `as`.
- The alias to use (here `StdlibDecisionTree`). This can be any combination of upper- and lowercase letters, underscores, and numbers, as long as it does not start with a number.

Afterwards, the declaration can **only** be accessed using the alias. The simple name cannot be used anymore. The next example shows how to create a new instance of the class now by invoking its constructor:
Afterwards, the declaration can **only** be accessed using the alias. The next example shows how to create a new instance of the class now by invoking its constructor:

```txt
StdlibDecisionTree()
```

Multiple declarations can be imported with or without an alias in a single import statement by separating them with commas:

```txt
from safeds.model.regression import DecisionTree as StdlibDecisionTree, RandomForest
```

## Wildcard Imports

We can also import all declarations in a [package][packages] with a single import. While this saves some typing, it also increases the likelihood of name conflicts and can make it harder for readers of the code to determine where a declaration comes from. Therefore, this should be used with caution.

Nevertheless, let us look at an example, which imports all declarations from the [package][packages] `safeds.model.regression`:

```txt
import safeds.model.regression.*
from safeds.model.regression import *
```

Here is the breakdown of the syntax:

- The keyword `import`.
- The keyword `from`.
- The name of the [package][packages] to import (here `safeds.model.regression`).
- A dot.
- The keyword `import`.
- A star.

Afterwards, we can again access declarations by their simple name, such as the [class][classes] `DecisionTree`:
Expand Down
2 changes: 1 addition & 1 deletion docs/language/common/packages.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ Here is a breakdown of this:
```txt
// Safe-DS

import safeds.model.regression.DecisionTree
from safeds.model.regression import DecisionTree
```

It is important to note that the `@PythonModule` annotation only affects the one Safe-DS file that contains it rather than the entire Safe-DS package. This allows different Safe-DS files in the same package to point to different [Python modules][python-modules].
Expand Down
Loading