Skip to content

Commit

Permalink
Merged with main
Browse files Browse the repository at this point in the history
  • Loading branch information
Your Name committed Aug 31, 2024
2 parents 9779181 + b33bc87 commit aa6af0e
Show file tree
Hide file tree
Showing 241 changed files with 9,162 additions and 5,280 deletions.
4 changes: 0 additions & 4 deletions packages/components/src/components/CodeEditor/fields.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ export type CodemirrorReactProps = {
showGutter: boolean;
lineWrapping: boolean;
project: SqProject;
sourceId: string;
height: string | number | null;
renderImportTooltip:
| ((params: { project: SqProject; importId: string }) => ReactNode)
Expand All @@ -29,7 +28,6 @@ const defaultReactProps: CodemirrorReactProps = {
showGutter: false,
lineWrapping: true,
project: new SqProject(),
sourceId: "fake",
onChange: () => {},
onSubmit: null,
height: null,
Expand Down Expand Up @@ -62,7 +60,6 @@ export const projectFacet = makeReactPropFacet("project");
export const heightFacet = makeReactPropFacet("height");
export const onChangeFacet = makeReactPropFacet("onChange");
export const onSubmitFacet = makeReactPropFacet("onSubmit");
export const sourceIdFacet = makeReactPropFacet("sourceId");
export const renderImportTooltipFacet = makeReactPropFacet(
"renderImportTooltip"
);
Expand Down Expand Up @@ -120,7 +117,6 @@ export function useReactPropsField(
defineFacet(projectFacet, "project"),
defineFacet(showGutterFacet, "showGutter"),
defineFacet(simulationFacet, "simulation"),
defineFacet(sourceIdFacet, "sourceId"),
defineFacet(renderImportTooltipFacet, "renderImportTooltip"),
],
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,7 @@ function* getMarkerSubData(
}
break;
case "Block": {
const lastNode = ast.statements.at(-1);
if (lastNode) {
yield* getMarkerSubData(lastNode, path);
}
yield* getMarkerSubData(ast.result, path);
break;
}
}
Expand All @@ -59,35 +56,32 @@ function* getMarkerData(ast: ASTNode): Generator<MarkerDatum, void> {
}

nextStatement: for (const statement of ast.statements) {
if (
statement.kind === "DefunStatement" ||
statement.kind === "LetStatement"
) {
for (const decorator of statement.decorators) {
if (decorator.name.value === "hide") {
break nextStatement;
}
}
const name = statement.variable.value;
if (ast.symbols[name] !== statement) {
break; // skip, probably redefined later
for (const decorator of statement.decorators) {
if (decorator.name.value === "hide") {
break nextStatement;
}
const path = new SqValuePath({
root: "bindings",
edges: [SqValuePathEdge.fromKey(name)],
});
yield { ast: statement.variable, path };
yield* getMarkerSubData(statement.value, path);
break;
} else {
// end expression
const path = new SqValuePath({
root: "result",
edges: [],
});
yield { ast: statement, path };
yield* getMarkerSubData(statement, path);
}
const name = statement.variable.value;
if (ast.symbols[name] !== statement) {
break; // skip, probably redefined later
}
const path = new SqValuePath({
root: "bindings",
edges: [SqValuePathEdge.fromKey(name)],
});
yield { ast: statement.variable, path };
yield* getMarkerSubData(statement.value, path);
break;
}

// end expression
if (ast.result) {
const path = new SqValuePath({
root: "result",
edges: [],
});
yield { ast: ast.result, path };
yield* getMarkerSubData(ast.result, path);
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/components/src/components/CodeEditor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export type CodeEditorProps = {
onFocusByPath?: (path: SqValuePath) => void;
height?: number | string;
lineWrapping?: boolean;
sourceId: string;
sourceId: string; // TODO - remove this, it's not very useful since source ids in the new SqProject are not unique
fontSize?: number;
showGutter?: boolean;
project: SqProject;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ LambdaParameter {
}

LambdaArgs {
() | LambdaParameter ("," LambdaParameter)*
"" | LambdaParameter ("," LambdaParameter)*
}

Decorator {
Expand Down Expand Up @@ -83,7 +83,15 @@ expressionWithoutParens[@isGroup="Expression"] {
>
"}"
}
| Lambda { "{" ArgsOpen { "|" } LambdaArgs "|" blockContent "}" }
| Lambda {
"{"
(
ArgsOpen { "|" } LambdaArgs "|"
| "||" // special case - '||' would be parsed as a LogicOp token without this rule
)
blockContent
"}"
}
| Identifier { identifier }
| AccessExpr { expression !deref "." Field { identifier } }
| Call { expression ~callOrDeclaration !call "(" commaSep<Argument { expression }> ")" }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { FC } from "react";

import { Type } from "@quri/squiggle-lang";

export const ShowType: FC<{ type: Type }> = ({ type }) => {
return (
// TODO - traverse type recursively, with colors and indentation
<div className="max-w-80 font-mono text-xs text-slate-600">
{type.toString()}
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { EditorView } from "@codemirror/view";
import { FC } from "react";

import { Type } from "@quri/squiggle-lang";

import { ShowType } from "./ShowType.js";
import { TooltipBox } from "./TooltipBox.js";

export const TypeTooltip: FC<{ type: Type; view: EditorView }> = ({
type,
view,
}) => {
return (
<TooltipBox view={view}>
<div className="px-4 py-1">
<ShowType type={type} />
</div>
</TooltipBox>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,26 @@ import { FC } from "react";

import { SqValue } from "@quri/squiggle-lang";

import { valueHasContext } from "../../../lib/utility.js";
import { SqValueWithContext, valueHasContext } from "../../../lib/utility.js";
import { SquiggleValueChart } from "../../SquiggleViewer/SquiggleValueChart.js";
import {
InnerViewerProvider,
useViewerContext,
} from "../../SquiggleViewer/ViewerProvider.js";
import { ShowType } from "./ShowType.js";
import { TooltipBox } from "./TooltipBox.js";

const ValueAstType: FC<{ value: SqValueWithContext }> = ({ value }) => {
const ast = value.context.valueAst;
if (ast.isStatement()) {
return <ShowType type={ast.variable.type} />;
} else if (ast.isExpression()) {
return <ShowType type={ast.type} />;
} else {
return null;
}
};

export const ValueTooltip: FC<{ value: SqValue; view: EditorView }> = ({
value,
view,
Expand All @@ -21,6 +33,7 @@ export const ValueTooltip: FC<{ value: SqValue; view: EditorView }> = ({
return (
<TooltipBox view={view}>
<div className="px-4 py-1">
<ValueAstType value={value} />
{/* Force a standalone ephemeral ViewerProvider, so that we won't sync up collapsed state with the top-level viewer */}
<InnerViewerProvider
partialPlaygroundSettings={globalSettings}
Expand Down
49 changes: 39 additions & 10 deletions packages/components/src/components/CodeEditor/tooltips/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { ReactNode } from "react";

import { getFunctionDocumentation } from "@quri/squiggle-lang";

import { mainHeadName } from "../../../lib/hooks/useSimulator.js";
import {
projectFacet,
renderImportTooltipFacet,
Expand All @@ -13,6 +14,7 @@ import {
import { reactAsDom } from "../utils.js";
import { HoverTooltip } from "./HoverTooltip.js";
import { TooltipBox } from "./TooltipBox.js";
import { TypeTooltip } from "./TypeTooltip.js";
import { ValueTooltip } from "./ValueTooltip.js";

function nodeTooltip(syntaxNode: SyntaxNode, reactNode: ReactNode) {
Expand Down Expand Up @@ -58,6 +60,30 @@ export function tooltipsExtension() {
return nodeTooltip(node, <HoverTooltip hover={hover} view={view} />);
};

const createTypeTooltip = (node: SyntaxNode) => {
// TODO - pass head name through facet
if (!project.hasHead(mainHeadName)) {
return null;
}
const module = project.getHead(mainHeadName);
const astR = module.typedAst();
if (!astR.ok) {
return null;
}

const ast = astR.value;
const astNode = ast.findDescendantByLocation(node.from, node.to);

if (astNode?.isExpression() || astNode?.kind === "IdentifierDefinition") {
return nodeTooltip(
node,
<TypeTooltip type={astNode.type} view={view} />
);
} else {
return null;
}
};

switch (cursor.name) {
case "String": {
// Is this an import?
Expand All @@ -75,19 +101,24 @@ export function tooltipsExtension() {
}
break;
}
case "Identifier":
case "Identifier": {
if (getText(cursor.node).match(/^[A-Z]/)) {
// TODO - expand the namespace to the identifier, or just show the namespace documentation
return null;
}
// TODO - check that the identifier is not overwritten by a local variable
return createBuiltinTooltip(cursor.node);
return (
createBuiltinTooltip(cursor.node) ?? createTypeTooltip(cursor.node)
);
}
case "Field":
// `Namespace.function`; go up to fully identified name.
// Either `Namespace.function` (fake namespaced builtin) or `foo.bar` (real field access)
if (!cursor.parent()) {
return null;
}
return createBuiltinTooltip(cursor.node);
return (
createBuiltinTooltip(cursor.node) ?? createTypeTooltip(cursor.node)
);
case "VariableName": {
const node = cursor.node;

Expand All @@ -107,12 +138,11 @@ export function tooltipsExtension() {

return nodeTooltip(node, <ValueTooltip value={value} view={view} />);
} else if (cursor.type.is("Statement")) {
// Ascend through decorated statements.
while (cursor.type.is("Statement") && cursor.parent());

// Is this a top-level variable?
// Ascend to the parent scope; is this a top-level variable?
cursor.parent();
if (!cursor.type.is("Program")) {
return null;
// Not a top-level variable, but we can still show its type.
return createTypeTooltip(node);
}

const value = output.bindings.get(name);
Expand All @@ -126,7 +156,6 @@ export function tooltipsExtension() {
}

if (
// Note that `valueAst` can't be "DecoratedStatement", we skip those in `SqValueContext` and AST symbols
(valueAst.kind === "LetStatement" ||
valueAst.kind === "DefunStatement") &&
// If these don't match then variable was probably shadowed by a later statement and we can't show its value.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ export function useSquiggleEditorExtensions(
showGutter: params.showGutter ?? false,
lineWrapping: params.lineWrapping ?? true,
project: params.project,
sourceId: params.sourceId,
height: params.height ?? null,
onChange: params.onChange,
onSubmit: params.onSubmit ?? null,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { memo } from "react";

import { result, SqError, SqValue } from "@quri/squiggle-lang";
import { result, SqErrorList, SqValue } from "@quri/squiggle-lang";

import { valueHasContext } from "../../lib/utility.js";
import { PlaygroundSettings } from "../PlaygroundSettings.js";
import { SquiggleValueChart } from "./SquiggleValueChart.js";

export type SqValueResult = result<SqValue, SqError>;
export type SqValueResult = result<SqValue, SqErrorList>;

// Unlike ValueViewer/ValueWithContextViewer, this just renders the raw widget, or displays an error.
export const SquiggleValueResultChart = memo(function ValueResultViewer({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { forwardRef, lazy } from "react";

import { SqModuleOutput, SqProject } from "@quri/squiggle-lang";

import { SquiggleErrorAlert } from "../../index.js";
import {
mainHeadName,
renderedHeadName,
Expand All @@ -20,6 +19,7 @@ import {
ViewerProvider,
} from "../SquiggleViewer/ViewerProvider.js";
import { ErrorBoundary } from "../ui/ErrorBoundary.js";
import { SquiggleErrorListAlert } from "../ui/SquiggleErrorListAlert.js";
import { Overlay } from "./Overlay.js";

const ProjectStateViewer = lazy(() =>
Expand Down Expand Up @@ -65,7 +65,7 @@ export const ViewerBody = forwardRef<SquiggleViewerHandle, Props>(
}

if (!outputResult.ok) {
return <SquiggleErrorAlert error={outputResult.value} />;
return <SquiggleErrorListAlert errorList={outputResult.value} />;
}

const sqOutput = outputResult.value;
Expand Down
11 changes: 5 additions & 6 deletions packages/components/src/components/ui/FnDocumentation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,18 @@ const StyleDefinition: FC<{ fullName: string; def: FnDefinition }> = ({
fullName,
def,
}) => {
const isOptional = (t) => (t.isOptional === undefined ? false : t.isOptional);
const primaryColor = "text-slate-900";
const secondaryColor = "text-slate-400";
const inputs = def.inputs.map((t, index) => (
const inputs = def.signature.inputs.map((t, index) => (
<span key={index}>
<span className={primaryColor}>{t.display()}</span>
{isOptional(t) ? <span className={primaryColor}>?</span> : ""}
{index !== def.inputs.length - 1 && (
<span className={primaryColor}>{t.type.toString()}</span>
{t.optional ? <span className={primaryColor}>?</span> : ""}
{index !== def.signature.inputs.length - 1 && (
<span className={secondaryColor}>, </span>
)}
</span>
));
const output = def.output.display();
const output = def.signature.output.toString();
return (
<div>
<span className="text-slate-500">{fullName}</span>
Expand Down
Loading

0 comments on commit aa6af0e

Please sign in to comment.