Skip to content

Commit d5ad06f

Browse files
authored
Merge pull request #6 from intel/add-code
Initial add of code from the non-public-source repo
2 parents 1daf3b4 + 2214344 commit d5ad06f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+33841
-28
lines changed

.github/dependabot.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: Cargo
4+
directory: "/"
5+
schedule:
6+
interval: "daily"

.github/workflows/binaries.yml

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
name: Build Binaries
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
binary_name:
7+
description: "Expected name of binary"
8+
required: false
9+
type: string
10+
default: "dls"
11+
output_binary_name:
12+
description: "Name of uploaded binary artifact"
13+
type: string
14+
default: "dls"
15+
log-dir:
16+
description: "Folder to put cargo logs in"
17+
required: false
18+
type: string
19+
os:
20+
description: "Machine to run on"
21+
required: true
22+
type: string
23+
env:
24+
CARGO_TERM_COLOR: always
25+
jobs:
26+
build:
27+
runs-on: ${{ inputs.os }}
28+
steps:
29+
- uses: actions/checkout@v4
30+
- name: versions
31+
run: |
32+
rustup --version
33+
cargo --version
34+
rustc --version
35+
- name: Prepare log dir
36+
run: mkdir -p ${{ inputs.log-dir }}
37+
- name: Build
38+
shell: bash
39+
run: cargo build --release --verbose 2>&1 | tee -a ${{ inputs.log-dir }}/build.log
40+
- name: Test
41+
shell: bash
42+
run: |
43+
set -o pipefail
44+
cargo test --verbose 2>&1 | tee -a ${{ inputs.log-dir }}/test.log
45+
- name: Clippy
46+
shell: bash
47+
if: ${{ success() || failure() }}
48+
run: |
49+
set -o pipefail
50+
rustup component add clippy
51+
cargo clippy --version
52+
cargo clippy --all-targets -- --deny warnings 2>&1 | tee -a ${{ inputs.log-dir }}/clippy.log
53+
- name: Upload logs
54+
if: ${{ success() || failure() }}
55+
uses: actions/upload-artifact@v4
56+
with:
57+
name: cargo-logs
58+
overwrite: true
59+
path: ${{ inputs.log-dir }}
60+
if-no-files-found: error
61+
- name: Upload binary
62+
if: ${{ success() || failure() }}
63+
uses: actions/upload-artifact@v4
64+
with:
65+
name: ${{ inputs.output_binary_name }}
66+
overwrite: true
67+
path: target/release/${{ inputs.binary_name }}
68+
if-no-files-found: error

.github/workflows/rust.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: Archive Binary
2+
3+
on:
4+
push:
5+
branches: [ "main" ]
6+
pull_request:
7+
branches: [ "main" ]
8+
schedule:
9+
- cron: "0 0 * * *"
10+
jobs:
11+
build-package:
12+
strategy:
13+
matrix:
14+
os:
15+
- ubuntu-latest
16+
- windows-latest
17+
include:
18+
- os: ubuntu-latest
19+
binary: dls
20+
- os: windows-latest
21+
binary: dls.exe
22+
uses: ./.github/workflows/binaries.yml
23+
with:
24+
binary_name: ${{ matrix.binary }}
25+
output_binary_name: dml-server-${{ matrix.os }}
26+
log-dir: ${{ matrix.binary }}-logs
27+
os: ${{ matrix.os }}
28+
check-package:
29+
uses: ./.github/workflows/scans.yml
30+
with:
31+
os: ubuntu-latest
32+
log-dir: checking-logs
33+
merge-package:
34+
runs-on:
35+
- ubuntu-latest
36+
needs: build-package
37+
steps:
38+
- name: Merge Artifacts
39+
uses: actions/upload-artifact/merge@v4
40+
with:
41+
name: dml-server
42+
pattern: dml-server-*

.github/workflows/scans.yml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: Cargo Check
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
os:
7+
description: "Machine to run on"
8+
required: true
9+
type: string
10+
log-dir:
11+
description: "Folder to put cargo logs in"
12+
required: false
13+
type: string
14+
15+
env:
16+
CARGO_TERM_COLOR: always
17+
jobs:
18+
audit:
19+
runs-on: ${{ inputs.os }}
20+
steps:
21+
- uses: actions/checkout@v4
22+
- name: versions
23+
run: |
24+
rustup --version
25+
cargo --version
26+
rustc --version
27+
- name: Prepare log dir
28+
run: mkdir -p ${{ inputs.log-dir }}
29+
- name: Audit Deny
30+
shell: bash
31+
if: ${{ success() || failure() }}
32+
run: |
33+
cargo install cargo-deny
34+
cargo deny --version
35+
set -o pipefail
36+
cargo deny check 2>&1 | tee -a ${{ inputs.log-dir }}/deny-log
37+
- name: Audit Outdated
38+
shell: bash
39+
if: ${{ success() || failure() }}
40+
run: |
41+
cargo install cargo-outdated
42+
cargo outdated --version
43+
set -o pipefail
44+
cargo outdated --exit-code 1 2>&1 | tee -a ${{ inputs.log-dir }}/outdated-log
45+
- name: Upload logs
46+
if: ${{ success() || failure() }}
47+
uses: actions/upload-artifact@v4
48+
with:
49+
name: cargo-scan-logs
50+
overwrite: true
51+
path: ${{ inputs.log-dir }}

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<!--
2+
© 2024 Intel Corporation
3+
SPDX-License-Identifier: Apache-2.0 and MIT
4+
-->
5+
# Change Log
6+
7+
## 1.0.0
8+
- Initial open-source release

CONTRIBUTING.md

Lines changed: 150 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
### License
44

5-
<PROJECT NAME> is licensed under the terms in [LICENSE]<link to license file in repo>. By contributing to the project, you agree to the license and copyright terms therein and release your contribution under these terms.
5+
DML Language Server is dual-licensed under the terms in [APACHE 2.0](./LICENSE-APACHE) and [MIT](./LICENSE-MIT). By contributing to the project, you agree to the license and copyright terms therein and release your contribution under these terms.
66

77
### Sign your work
88

@@ -55,3 +55,152 @@ Use your real name (sorry, no pseudonyms or anonymous contributions.)
5555

5656
If you set your `user.name` and `user.email` git configs, you can sign your
5757
commit automatically with `git commit -s`.
58+
59+
## How-To
60+
61+
This section provides information for developers who want to contribute to the
62+
DLS or run it in a heavily customised configuration.
63+
64+
Testing, reporting issues, writing documentation, writing tests,
65+
writing code, and implementing clients are all extremely valuable.
66+
67+
To get help with this, either leave an issue on the repo or contact the primary
68+
developer directly.
69+
70+
If you want to implement DLS support in an editor, see [clients.md](clients.md).
71+
72+
## Building
73+
74+
```
75+
git clone https://github.com/intel/dml-language-server.git
76+
cd dml-language-server
77+
cargo build --release
78+
```
79+
80+
## Running and testing
81+
82+
There are three main ways to run the DLS, you can run it directly with:
83+
84+
```
85+
cargo run --bin dls
86+
```
87+
Which starts up the DLS in a server-mode, so its of narrow applicability unless
88+
you are planning on directly sending LSP communication into it. By passing the
89+
'--cli' option you start up the server in command-line mode, see [CLI](#cli).
90+
91+
You can run the Direct-File-Analysis (DFA) binary with:
92+
```
93+
cargo run --bin dfa [options ...] <dls-binary> [files ...]
94+
```
95+
This will analyze the specified 'files' using the 'dls-binary' server binary
96+
as-if they had been opened in a language client, this is usefull to quickly
97+
test and debug initial file analysis and error reporting without advanced
98+
client-interaction.
99+
100+
Most commonly, you'll use an IDE plugin to invoke the DLS binary for you
101+
(see [README.md](README.md) for details).
102+
103+
Test the crate using `cargo test`.
104+
105+
Testing is unfortunately minimal. There is support for some regression tests,
106+
but not many actual tests exists yet. There is significant work to do
107+
before we have a comprehensive testing story.
108+
109+
### <a id="cli"></a>CLI
110+
111+
You can run DLS in the command line mode which is useful for debugging and
112+
testing, especially to narrow down a bug to either the DLS or a client.
113+
114+
You need to run it with the
115+
`--cli` flag, e.g., `cargo run --bin dls -- --cli`. This should initialize the
116+
DLS and then give you a `>` prompt.
117+
Look for the final message that will signal the end of the
118+
initialization phase which will look something like:
119+
```
120+
{"jsonrpc":"2.0","method":"window/showMessage","params":{"message": "DML Language Server Started", "type": 3}}
121+
```
122+
123+
Type `help` (or just `h`) to see the [commands available][CLI_COMMANDS]. Note
124+
that the [positions][LSP_POSITION] in the requests and the responses are
125+
_zero-based_ (contrary to what you'll normally see in the IDE line numbers).
126+
127+
[LSP_POSITION]: https://github.com/Microsoft/language-server-protocol/blob/gh-pages/specification.md#position
128+
129+
[CLI_COMMANDS]: dls/src/cmd.rs#L508-L542
130+
131+
## Implementation overview
132+
133+
The idea behind the DLS is to grant fast and mostly-accurate feedback for DML
134+
development, of either specific devices or DML common-code. Due to complexities
135+
in the DML language, and the high level of customization available when running
136+
DMLC, this information will not be perfectly accurate or holistic at all times.
137+
However the goal is to give a best-effort analysis that minimizes noisy
138+
incorrect feedback and maximizes the amount of valuable info a developer can
139+
extract, as well as providing basic standard-issue IDE functionality.
140+
141+
### Analysis
142+
143+
The DLS tracks changes to files, and keeps the changed file in memory (i.e., the
144+
DLS does not need the IDE to save a file before providing data). These changed
145+
files are tracked by the 'Virtual File System'.
146+
147+
Analysis is divided into two phases.
148+
- The 'isolated' analysis analyses each
149+
DML file individually, and does parsing and some post-parse processing. This
150+
analysis perform syntactic analysis and is enough to report basic syntax errors,
151+
- The 'device' analysis analyses from the perspective of a particular DML file with
152+
a device declaration, pulling in information from the various isolated
153+
analysises. This analysis performs semantic analysis, and is what
154+
powers reference-matching, object resolution, etc.
155+
156+
Isolated analysis is started as soon as the user opens or changes a file
157+
(although this can be configured in the settings to be only on save).
158+
In addition the DLS will use information about import paths and workspaces to
159+
try to resolve file imports, and recursively analyse any file imported from
160+
an opened one. See the section on [include paths](#include-paths) for more
161+
information on them. Device analysis is started as soon as it is determined that
162+
it could be, or needs to be re-done. Commonly this is when an isolated analysis
163+
involved in the import tree of a device-file is updated, if all files that the
164+
device depends on have had an isolated analysis done. There are corner-case
165+
exceptions to this (allowing for a partially correct device analysis when an
166+
imported file is missing) but for simplicity that is not described here.
167+
168+
### Communicating with IDEs
169+
170+
The DLS communicates with IDEs via
171+
the [Language Server protocol](https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md).
172+
173+
The LS protocol uses JSON sent over stdin/stdout. The JSON is rather dynamic -
174+
we can't make structs to easily map to many of the protocol objects. The client
175+
sends commands and notifications to the DLS. Commands must get a reply,
176+
notifications do not. Usually the structure of the reply is dictated by the
177+
protocol spec. The DLS can also send notifications to the client. So for a long
178+
running task (such as a build), the DLS will reply quickly to acknowledge the
179+
request, then send a message later with the result of the task.
180+
181+
Associating requests with replies is done using an id which must be handled by
182+
the DLS.
183+
184+
### Extensions to the Language Server Protocol
185+
186+
The DLS uses some custom extensions to the Language Server Protocol.
187+
These are all sent from the DLS to an LSP client and are only used to
188+
improve the user experience by showing progress indicators.
189+
190+
* `window/progress`: notification, `title: "Analysing", value: WorkDoneProgressBegin`. Sent when the first analysis starts
191+
* ... standard LSP `publishDiagnostics`
192+
* `window/progress`: notification, `title: "Analysing", value: WorkDoneProgressEnd`. Sent when the last analysis finishes
193+
194+
### <a id="include-paths"></a>Include Paths
195+
In order to support fairly generic and complicating import configurations, the
196+
DLS uses a context-aware methodology in order to resolve import paths.
197+
198+
Sidenote: be aware that due to past DMLC 1.2/1.4 interoperability functionality,
199+
the DLS will correctly search the "./" and "./1.4/" of every path it searches.
200+
201+
When importing a file "A.dml" from some file "B", the DLS will search, in no
202+
particular order:
203+
- The folder of B
204+
- The root folder of the workspace
205+
- All other workspace roots
206+
- Every include path specified by the [DML Compile commands](README.md#dml-compile-commands) under the related module

COPYRIGHT

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Source code is a modified version of the code available at
2+
https://github.com/rust-lang/rls, which is licensed under Apache 2.0
3+
and MIT.
4+
5+
This code is similarly dual-licensed under Apache 2.0 and MIT,
6+
see the corresponding license files for more information.

0 commit comments

Comments
 (0)