Skip to content

[TSP] Adding source file, namespace, scalar, operation, and references.#371

Open
glecaros wants to merge 6 commits intoalloy-framework:feature/typespecfrom
glecaros:feature/typespec-dev
Open

[TSP] Adding source file, namespace, scalar, operation, and references.#371
glecaros wants to merge 6 commits intoalloy-framework:feature/typespecfrom
glecaros:feature/typespec-dev

Conversation

@glecaros
Copy link

@glecaros glecaros commented Mar 1, 2026

This pull request introduces a suite of new TypeSpec component implementations and comprehensive tests for namespace, operation, name, and reference handling. It also improves developer tooling and workflow with formatting and devcontainer enhancements. The most important changes are grouped below:

New Component Implementations

  • Added core TypeSpec components for namespace, operation declarations, source files, and template parameters in src/components/. These enable structured rendering and context propagation for TypeSpec constructs. [1] [2] [3] [4] [5]
  • Implemented a Name component for rendering declaration names with context validation.
  • Implemented a Reference component for resolving and rendering type references, including proper symbol emission and fallback for unresolved references.

Comprehensive Test Coverage

  • Added extensive test suites for Namespace, OperationDeclaration, Name, and Reference components to verify correct rendering, context handling, error cases, and reference resolution across files and directories. [1] [2] [3] [4]

Developer Tooling & Workflow

  • Added a format script using Prettier to package.json for consistent code formatting.
  • Enhanced devcontainer configuration to include the Copilot CLI feature for improved developer experience.

glecaros and others added 6 commits February 3, 2026 05:34
Adding namespace and source file components.
* Implementing references.

* adding copilot cli to dev container.

* adjust names after refactor.

* Adding operation and template parameters.

* Added support for template parameter references.

* rever extend-expect workaround

* format

export type Optional<T> = T | undefined;

export function joinPath(...parts: string[]) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use pathe for this, there's a dep in core for it already.

relative?: boolean;
}

export function NamespaceName(props: NamespaceNameProps) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need doc comments on these components.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be marked internal also.

children: Children;
}

export function NamespaceScopeComponent(props: NamespaceScopeProps) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docs, internal

</SourceFile>
</Output>,
).toRenderTo({
"main.tsp": d`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you don't need d when using toRenderTo.

expect(
<Output>
<SourceFile path="main.tsp">
<Namespace name="File.Level">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Putting dots in the name isn't good here because it means separate symbols for a namespace named "File.Level" and "Level" (as a member of File). It's just a test but good to note that this usage should morally be disallowed.

<group>
(
{props.parameters && props.parameters.length > 0 && (
<Indent nobreak>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think probably you can just use the intrinsic here for a bit more simplicity?

(
{props.parameters && props.parameters.length > 0 && (
<Indent nobreak>
<For each={props.parameters} joiner={", "}>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use comma softline instead of this joiner and you'll get better formatting when operations are too long (add test to validate this) and won't need the softline within the block.


export function Reference(props: ReferenceProps) {
const { refkey } = props;
const symbol = ref(refkey);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably should make ref just return a ref (strong regrets on this naming convention lol)

const usings = computed(() => scope.usings);
return (
<CoreSourceFile path={props.path} filetype="typespec">
<List joiner={<hbr />} ender={<hbr />}>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hardline ender

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works below also.

import { SourceFileScope } from "../scopes/source-file.js";
import { NamespaceSymbol } from "../symbols/index.js";

export function createGlobalNamespace(parent: SourceFileScope | ProgramScope) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can eliminate the notion of "program scope", global namespace is a typespec concept and should be sufficient here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants