Granica zewnętrzna: extern
extern deklaruje granicę z kodem dostarczanym poza Junexis. Należy rozróżnić
sygnaturę zadania, nazwę typu zewnętrznego oraz nazwany kontrakt integracji.
Ich poprawne sprawdzenie nie dowodzi obecności ani wykonania implementacji natywnej.
Składnia zadania i typu
externDeclaration
: EXTERN TASK IDENTIFIER
(LPAREN parameterList? RPAREN)?
platformAnnotation*
communicationSignature?
SEMICOLON?
;
externTypeDeclaration
: EXTERN TYPE IDENTIFIER platformAnnotation+ SEMICOLON?
;
E01 — extern task
extern task zawiera nazwę, opcjonalną listę parametrów w nawiasach,
zero lub więcej adnotacji platformy oraz opcjonalną sygnaturę wyniku.
Średnik jest opcjonalny. Nawiasy można pominąć; nie ma ciała instrukcji Junexis.
extern task Read() @server {} jest błędem parsera.
Parametry i wynik podlegają kontroli typów. Sama zgodność typów nie określa
mapowania reprezentacji w pamięci, skutków ubocznych ani sposobu zgłaszania błędów.
Gramatyka nie wymaga platformy przy extern task; próba bez platformy przechodzi
check. Nie jest to dowód wyboru domyślnego wykonawcy.
E02 — extern type
extern type wymaga nazwy oraz co najmniej jednej adnotacji platformy.
Nie deklaruje pól ani ich układu. Nie należy utożsamiać go ze strukturą Junexis
o dowolnie dostępnych polach, z serializowalną wiadomością ani ze wspólnym ABI
wszystkich generatorów. Deklaracja z @server przechodzi sprawdzanie;
deklaracja bez platformy jest błędem składni.
Składnia kontraktu
externContractDeclaration
: EXTERN anyIdentifier anyIdentifier externContractBody
;
externContractBody
: LBRACE externContractMember* RBRACE
;
externContractMember
: externFunctionMember
| externFileMember
| externLanguageMember
| externTargetMember
;
externFunctionMember
: FN IDENTIFIER LPAREN parameterList? RPAREN (ARROW typeReference)? SEMICOLON?
;
externTargetMember
: IDENTIFIER platformTarget SEMICOLON?
;
externLanguageMember
: IDENTIFIER IDENTIFIER SEMICOLON?
;
externFileMember
: IDENTIFIER STRING_LITERAL SEMICOLON?
;
E03 — deklaracja granicy
Postać extern rodzaj Nazwa { ... } jest odrębna od pojedynczego extern task.
Na przykład extern telemetry Sensor opisuje nazwaną granicę, a nie tworzy
automatycznie zadania Sensor. Ciało może być puste.
Funkcja kontraktu ma listę parametrów i opcjonalny wynik, lecz nie ma ciała.
Zwyczajowe wpisy to:
extern telemetry Sensor {
target server
language go
file "user/server/sensor.go"
fn read(value: Int) -> Int
}
target nie jest tu adnotacją z @. Wartością jest platformTarget.
Język jest identyfikatorem, a ścieżka pliku literałem tekstowym.
E04 — ograniczenie rozpoznawania pól kontraktu
Reguły członków posługują się ogólnym IDENTIFIER w miejscu klucza wpisu.
AstBuilder wybiera znaczenie według rozpoznanej postaci członka; nie sprawdza,
czy pierwszy identyfikator jest dokładnie słowem target, language albo file.
Próba extern telemetry Sensor { mystery go } przechodzi check.
Nie stanowi to kontraktu dowolnych rozszerzeń metadanych.
Kolejne rozpoznane wpisy target, języka lub pliku zastępują poprzednią wartość
w AST. Powtórzone language go language rust przechodzi sprawdzanie.
Nie opisujemy tego jako zalecanej składni ani reguły rozstrzygania konfiguracji;
brakuje diagnostyk nieznanych kluczy i powtórzeń.
Wiązanie funkcji z extern task
E05 — konwencja nazwy
SemanticAnalyzer.ValidateExternContractBindings dla funkcji read w kontrakcie
Sensor szuka zadania zewnętrznego Sensor_read.
extern task Sensor_read(value: Int) @server -> Int
Brak takiej deklaracji albo znalezienie zwykłego tasku zamiast extern task
prowadzi do ostrzeżenia W0030, a nie błędu. Sama funkcja kontraktu nie zastępuje
w tej kontroli deklaracji zadania zewnętrznego.
Nazwy są wyszukiwane w tablicy symboli; nie jest to sprawdzenie symbolu w pliku Go,
C++ ani TypeScript.
E06 — zgodność sygnatury
Jeżeli odpowiadające extern task istnieje, kontrola sprawdza:
- obecność platformy wskazanej przez target kontraktu, jeżeli target podano;
- liczbę parametrów i zgodność ich typów według pozycji;
- zgodność wyniku, w tym jego braku.
Niezgodność powoduje błąd E0031. Platforma jest porównywana bez rozróżniania
wielkości liter. Zadanie może mieć dodatkowe adnotacje: ta kontrola wymaga
obecności oczekiwanej, nie wyłączności jednej platformy.
Nazwy parametrów nie są w tym porównaniu wymagane jako identyczne.
fn read(value: Int) oraz extern task Sensor_read(other: Int) przeszły próbę
bez diagnostyk. To zgodność pozycyjnych typów, nie mapowanie argumentów po nazwach
między dowolnymi językami hosta.
Sprawdzone przykłady
Pary są sprawdzane przez rzeczywiste CLI w osobnych projektach. Nie dołączają implementacji natywnej i nie są testami działania integracji.
Przykład poprawny
extern task ReadTemperature() @embedded -> Float
task Source() @embedded -> chan<Float> {
send ReadTemperature()
}
Kontrola: przykład przyjęty przez check. Nie jest to test wykonania.
Przykład błędny
extern task ReadTemperature(value Float) @embedded -> Float
Powód: Parametr extern task również wymaga dwukropka przed typem.
Kontrola: przykład odrzucony przez check; kody: P0001.
Pełny zakres weryfikacji przykładów.
Przykład: Zgodność sygnatury kontraktu
Poprawny zapis
extern telemetry Sensor { target server language go file "missing.go" fn read(value: Int) -> Int }
extern task Sensor_read(value: Int) @server -> Int
Kontrola: przykład przyjęty przez check. Nie jest to test wykonania.
Błędny zapis
extern telemetry Sensor { target server language go file "missing.go" fn read(value: Int) -> Int }
extern task Sensor_read(value: Text) @server -> Int
Powód: Typ parametru extern task nie odpowiada typowi funkcji kontraktu.
Kontrola: przykład odrzucony przez check; kody: E0031.
Pełny zakres weryfikacji przykładów.
Przykład: Platforma wiązania
Poprawny zapis
extern telemetry Sensor { target server language go file "missing.go" fn read(value: Int) -> Int }
extern task Sensor_read(value: Int) @server -> Int
Kontrola: przykład przyjęty przez check. Nie jest to test wykonania.
Błędny zapis
extern telemetry Sensor { target server language go file "missing.go" fn read(value: Int) -> Int }
extern task Sensor_read(value: Int) @report -> Int
Powód: Extern task nie ma platformy server wymaganej przez kontrakt.
Kontrola: przykład odrzucony przez check; kody: E0031.
Pełny zakres weryfikacji przykładów.
Przykład: Typ zewnętrzny wymaga platformy
Poprawny zapis
extern type Handle @server
Kontrola: przykład przyjęty przez check. Nie jest to test wykonania.
Błędny zapis
extern type Handle
Powód: extern type wymaga co najmniej jednej adnotacji platformy.
Kontrola: przykład odrzucony przez check; kody: P0001.
Pełny zakres weryfikacji przykładów.
Przykład: Deklaracja bez ciała
Poprawny zapis
extern task Read -> Int
Kontrola: przykład przyjęty przez check. Nie jest to test wykonania.
Błędny zapis
extern task Read() @server {}
Powód: extern task deklaruje sygnaturę, a nie ciało instrukcji Junexis.
Kontrola: przykład odrzucony przez check; kody: P0001.
Pełny zakres weryfikacji przykładów.
Generowanie a dostarczenie implementacji
ExternContractManifestGenerator zapisuje kontrakty do manifestu
externs/junexis.externs.toml danego targetu: rodzaj, nazwę, target, język,
ścieżkę pliku i sygnatury. Wybiera kontrakty bez targetu albo zgodne z targetem
manifestu. Obecność manifestu nie potwierdza dostępności pliku i funkcji.
Generator Go ma ścieżkę emitującą zastępczą funkcję, która przy wywołaniu kończy
się panic z komunikatem Junexis extern is not bound. Wygenerowanie takiej
funkcji nie oznacza realizacji zadania. Nie rozszerzamy tego zachowania Go na
wszystkie generatory.
Repozytorium ma polecenie extern scaffold i testy tworzenia szkieletu Go,
pominięcia istniejącego pliku oraz trybu bez zapisu. Szkielet nadal wymaga
implementacji. To narzędzie przygotowawcze, nie dowód poprawności integracji.
Pliki wskazane przez autora są oddzielone od plików należących do generatora.
Rodzaj extern storage ma dodatkowe ścieżki manifestów i kontraktów storage.
Nie jest równoważny deklaracji logicznych encji, query i mutation w
storage, ani sam w sobie nie otwiera połączenia z bazą.
Nie przenosimy gwarancji szczególnego kontraktu storage na dowolny rodzaj extern.
Wyniki prób granicznych
| Próba | Wynik check | Granica dowodu |
|---|---|---|
| Zgodne typy i platforma Sensor_read | przyjęte | Sprawdzenie deklaracji Junexis, nie implementacji natywnej. |
| Brak Sensor_read dla funkcji kontraktu | przyjęte, W0030 |
Brak wiązania nie blokuje tej próby. |
| Inna nazwa parametru przy zgodnym typie | przyjęte bez diagnostyk | Zgodność typów sprawdzana pozycyjnie. |
| Niezgodny typ parametru | odrzucone, E0031 |
Kontrola sygnatury jest aktywna. |
| Brak wymaganej platformy | odrzucone, E0031 |
Kontrola targetu kontraktu jest aktywna. |
file "missing.go" w zgodnym kontrakcie |
przyjęte bez diagnostyk | check nie potwierdził istnienia implementacji w tym pliku. |
| Pusty kontrakt | przyjęte | Nie ustanawia zachowania integracji. |
| Nieznany klucz lub powtórzone language | przyjęte | Brak pełnej walidacji wpisów. |
Jawne luki i granice kontraktu
- Walidacja nazw kluczy, ich powtórzeń, wymaganych pól oraz zgodności języka z targetem.
- Pełne sprawdzenie istnienia pliku, symbolu natywnego i zgodności jego rzeczywistej sygnatury z deklaracją Junexis na wszystkich targetach.
- Wspólny kontrakt reprezentacji typów i wartości, własności pamięci, czasu życia uchwytów i zasad zwalniania zasobów.
- Mapowanie błędów, wyjątków/panic, anulowania i limitów czasu na poziom Junexis.
- Reguły współbieżnego wywoływania, bezpieczeństwa wątkowego i efektów zewnętrznych.
- Serializacja i przesyłanie uchwytów między procesami lub urządzeniami.
Są to właściwości wymagające osobnych kontraktów i dowodów. Sam token extern,
poprawna sygnatura czy manifest ich nie zapewniają.
Podstawa w repozytorium
grammar/JunexisLang.g4: reguły przytoczone powyżej.compiler/JunexisLang.Compiler.Core/Parsing/AstBuilder.cs:VisitExternContractDeclaration, odczyt i zastępowanie pól kontraktu.compiler/JunexisLang.Compiler.Core/Semantics/SemanticAnalyzer.cs:ValidateExternContractBindingsiValidateExternBindingSignature.compiler/JunexisLang.Compiler.CodeGen/ExternContractManifestGenerator.csiGoCodeGenerator.cs: manifest i zastępcze funkcje.compiler/JunexisLang.Compiler.Tests/Semantics/SemanticAnalyzerTests.cs: testy typów, duplikatów i zgodności kontraktów.compiler/JunexisLang.Compiler.CodeGen.Tests/CodeGeneratorExternContractTests.cs: testy tekstu artefaktów; nie są próbami wykonania kodu natywnego.compiler/JunexisLang.Compiler.CLI.Tests/ExternScaffoldCommandTests.cs: odrębne testy przygotowania plików implementacji.