Skip to content

Commit

Permalink
Consistent self types (#6867)
Browse files Browse the repository at this point in the history
close #6800

Update the `executionContext/expressionUpdates` notification and send the list of not applied arguments in addition to the method pointer.

# Important Notes
IDE is updated to support the new API.
  • Loading branch information
4e6 authored May 31, 2023
1 parent 65958cb commit ed3f9b3
Show file tree
Hide file tree
Showing 24 changed files with 1,281 additions and 288 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ fn test_computed_value_update() {
let update = &expression_updates.updates.first().unwrap();
assert_eq!(update.expression_id, id);
assert_eq!(update.typename.as_deref(), Some(typename));
assert!(update.method_pointer.is_none());
assert!(update.method_call.is_none());
assert!(update.from_cache);
assert!(matches!(update.payload, ExpressionUpdatePayload::Value { warnings: None }))
}
Expand Down
20 changes: 15 additions & 5 deletions app/gui/controller/engine-protocol/src/language_server/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ pub struct ExpressionUpdate {
pub expression_id: ExpressionId,
#[serde(rename = "type")] // To avoid collision with the `type` keyword.
pub typename: Option<String>,
pub method_pointer: Option<MethodPointer>,
pub method_call: Option<MethodCall>,
pub profiling_info: Vec<ProfilingInfo>,
pub from_cache: bool,
pub payload: ExpressionUpdatePayload,
Expand Down Expand Up @@ -740,6 +740,16 @@ pub struct MethodPointer {
pub name: String,
}

/// A representation of a method call.
#[derive(Hash, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct MethodCall {
/// The method pointer of a call.
pub method_pointer: MethodPointer,
/// Indexes of arguments that have not been applied to this method.
pub not_applied_arguments: Vec<usize>,
}

/// Used for entering a method. The first item on the execution context stack should always be
/// an `ExplicitCall`.
#[derive(Hash, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
Expand Down Expand Up @@ -1226,7 +1236,7 @@ pub mod test {
ExpressionUpdate {
expression_id: id,
typename: Some(typename.into()),
method_pointer: None,
method_call: None,
profiling_info: default(),
from_cache: false,
payload: ExpressionUpdatePayload::Value { warnings: None },
Expand All @@ -1242,7 +1252,7 @@ pub mod test {
ExpressionUpdate {
expression_id: id,
typename: None,
method_pointer: Some(method_pointer),
method_call: Some(MethodCall { method_pointer, not_applied_arguments: vec![] }),
profiling_info: default(),
from_cache: false,
payload: ExpressionUpdatePayload::Value { warnings: None },
Expand All @@ -1256,7 +1266,7 @@ pub mod test {
ExpressionUpdate {
expression_id: id,
typename: None,
method_pointer: None,
method_call: None,
profiling_info: default(),
from_cache: false,
payload: ExpressionUpdatePayload::DataflowError { trace },
Expand All @@ -1274,7 +1284,7 @@ pub mod test {
ExpressionUpdate {
expression_id: id,
typename: None,
method_pointer: None,
method_call: None,
profiling_info: default(),
from_cache: false,
payload: ExpressionUpdatePayload::Panic { trace, message },
Expand Down
2 changes: 1 addition & 1 deletion app/gui/src/model/execution_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ impl From<ExpressionUpdate> for ComputedValueInfo {
fn from(update: ExpressionUpdate) -> Self {
ComputedValueInfo {
typename: update.typename.map(ImString::new),
method_call: update.method_pointer,
method_call: update.method_call.map(|mc| mc.method_pointer),
payload: update.payload,
}
}
Expand Down
5 changes: 4 additions & 1 deletion app/gui/src/model/project/synchronized.rs
Original file line number Diff line number Diff line change
Expand Up @@ -950,7 +950,10 @@ mod test {
// Context now has the information about type.
let value_info = value_registry.get(&expression_id).unwrap();
assert_eq!(value_info.typename, value_update.typename.clone().map(ImString::new));
assert_eq!(value_info.method_call, value_update.method_pointer);
assert_eq!(
value_info.method_call,
value_update.method_call.clone().map(|mc| mc.method_pointer)
);
}


Expand Down
19 changes: 17 additions & 2 deletions docs/language-server/protocol-language-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ transport formats, please look [here](./protocol-architecture).
- [`ExpressionId`](#expressionid)
- [`ContextId`](#contextid)
- [`StackItem`](#stackitem)
- [`MethodCall`](#methodcall)
- [`MethodPointer`](#methodpointer)
- [`ProfilingInfo`](#profilinginfo)
- [`ExpressionUpdate`](#expressionupdate)
Expand Down Expand Up @@ -271,6 +272,20 @@ interface LocalCall {
}
```

### `MethodCall`

A representation of a method call.

```typescript
interface MethodCall {
/** The method pointer of a call. */
methodPointer: MethodPointer;

/** Indexes of arguments that have not been applied to this method. */
notAppliedArguments: number[];
}
```

### `MethodPointer`

Points to a method definition.
Expand Down Expand Up @@ -331,9 +346,9 @@ interface ExpressionUpdate {
type?: String;

/**
* The updated pointer to the method call.
* The updated method call info.
*/
methodPointer?: MethodPointer;
methodCall?: MethodCall;

/**
* Profiling information about the expression.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ final class ContextEventsListener(
ContextRegistryProtocol.ExpressionUpdate(
update.expressionId,
update.expressionType,
update.methodCall.map(toProtocolMethodPointer),
update.methodCall.map(toProtocolMethodCall),
update.profilingInfo.map(toProtocolProfilingInfo),
update.fromCache,
toProtocolPayload(update.payload)
Expand Down Expand Up @@ -248,8 +248,20 @@ final class ContextEventsListener(
ProfilingInfo.ExecutionTime(t)
}

/** Convert the runtime method call to the context registry protocol
* representation.
*
* @param methodCall the method call
* @return the registry protocol representation of the method call
*/
private def toProtocolMethodCall(methodCall: Api.MethodCall): MethodCall =
MethodCall(
toProtocolMethodPointer(methodCall.methodPointer),
methodCall.notAppliedArguments
)

/** Convert the runtime method pointer to the context registry protocol
* representation
* representation.
*
* @param methodPointer the method pointer
* @return the registry protocol representation of the method pointer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,15 +176,15 @@ object ContextRegistryProtocol {
*
* @param expressionId the id of updated expression
* @param `type` the updated type of expression
* @param methodPointer the updated method pointer
* @param methodCall the updated method call
* @param profilingInfo profiling information about the expression
* @param fromCache whether or not the expression's value came from the cache
* @param payload an extra information about the computed value
*/
case class ExpressionUpdate(
expressionId: UUID,
`type`: Option[String],
methodPointer: Option[MethodPointer],
methodCall: Option[MethodCall],
profilingInfo: Vector[ProfilingInfo],
fromCache: Boolean,
payload: ExpressionUpdate.Payload
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.enso.languageserver.runtime

import org.enso.polyglot.runtime.Runtime.Api

/** A representation of a method call.
*
* @param methodPointer the method pointer of a call
* @param notAppliedArguments indexes of arguments that have not been applied
* to this method
*/
case class MethodCall(
methodPointer: MethodPointer,
notAppliedArguments: Vector[Int]
) {

/** Convert this method call to the corresponding [[Api]] message. */
def toApi: Api.MethodCall =
Api.MethodCall(methodPointer.toApi, notAppliedArguments)
}

/** An object pointing to a method definition.
*
* @param module the module of the method file
* @param definedOnType method type
* @param name method name
*/
case class MethodPointer(module: String, definedOnType: String, name: String) {

/** Convert this method pointer to the corresponding [[Api]] message. */
def toApi: Api.MethodPointer =
Api.MethodPointer(module, definedOnType, name)
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,14 @@ class ContextEventsListenerSpec
Suggestions.method.selfType,
Suggestions.method.name
)
val methodCall = Api.MethodCall(methodPointer)
listener ! Api.ExpressionUpdates(
contextId,
Set(
Api.ExpressionUpdate(
Suggestions.method.externalId.get,
Some(Suggestions.method.returnType),
Some(methodPointer),
Some(methodCall),
Vector(),
false,
true,
Expand All @@ -79,7 +80,7 @@ class ContextEventsListenerSpec
ContextRegistryProtocol.ExpressionUpdate(
Suggestions.method.externalId.get,
Some(Suggestions.method.returnType),
Some(toProtocolMethodPointer(methodPointer)),
Some(toProtocolMethodCall(methodCall)),
Vector(),
false,
ContextRegistryProtocol.ExpressionUpdate.Payload.Value(None)
Expand Down Expand Up @@ -477,6 +478,12 @@ class ContextEventsListenerSpec
}
}

def toProtocolMethodCall(methodCall: Api.MethodCall): MethodCall =
MethodCall(
toProtocolMethodPointer(methodCall.methodPointer),
methodCall.notAppliedArguments
)

def toProtocolMethodPointer(methodPointer: Api.MethodPointer): MethodPointer =
MethodPointer(
methodPointer.module,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -307,14 +307,34 @@ object Runtime {
*/
sealed trait Error extends ApiResponse

/** A representation of a pointer to a method definition.
*/
/** A representation of a pointer to a method definition. */
case class MethodPointer(
module: String,
definedOnType: String,
name: String
)

/** A representation of a method call.
*
* @param methodPointer the method pointer of a call
* @param notAppliedArguments indexes of arguments that have not been applied
* to this method
*/
case class MethodCall(
methodPointer: MethodPointer,
notAppliedArguments: Vector[Int]
)
object MethodCall {

/** Create a method call with all the arguments applied.
*
* @param methodPointer the method pointer of a call
* @return a new [[MethodCall]].
*/
def apply(methodPointer: MethodPointer): MethodCall =
MethodCall(methodPointer, Vector())
}

/** A representation of an executable position in code.
*/
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
Expand Down Expand Up @@ -362,7 +382,7 @@ object Runtime {
*
* @param expressionId the expression id
* @param expressionType the type of expression
* @param methodCall the pointer to a method definition
* @param methodCall the underlying method call of this expression
* @param profilingInfo profiling information about the execution of this
* expression
* @param fromCache whether or not the value for this expression came
Expand All @@ -374,7 +394,7 @@ object Runtime {
case class ExpressionUpdate(
expressionId: ExpressionId,
expressionType: Option[String],
methodCall: Option[MethodPointer],
methodCall: Option[MethodCall],
profilingInfo: Vector[ProfilingInfo],
fromCache: Boolean,
typeChanged: Boolean,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -308,8 +308,7 @@ private FunctionCallInfo functionCallInfoById(UUID nodeId) {

@CompilerDirectives.TruffleBoundary
private void onFunctionReturn(UUID nodeId, FunctionCallInstrumentationNode.FunctionCall result, EventContext context) throws ThreadDeath {
calls.put(
nodeId, new FunctionCallInfo(result));
calls.put(nodeId, new FunctionCallInfo(result));
functionCallCallback.accept(new ExpressionCall(nodeId, result));
// Return cached value after capturing the enterable function call in `functionCallCallback`
Object cachedResult = cache.get(nodeId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@
services = NodeCountingTestInstrument.class)
public class NodeCountingTestInstrument extends TruffleInstrument {
public static final String INSTRUMENT_ID = "node-count-test";
private Map<Node, Node> all = new ConcurrentHashMap<>();
private final Map<Node, Node> all = new ConcurrentHashMap<>();
private Map<Class, List<Node>> counter = new ConcurrentHashMap<>();

private Map<UUID, FunctionCallInfo> calls = new ConcurrentHashMap<>();
private final Map<UUID, FunctionCallInfo> calls = new ConcurrentHashMap<>();
private Env env;

@Override
Expand Down Expand Up @@ -107,7 +107,7 @@ public ExecutionEventNode create(EventContext context) {
}
}

private class NodeWrapper extends ExecutionEventNode {
private static class NodeWrapper extends ExecutionEventNode {

private final EventContext context;

Expand All @@ -134,7 +134,7 @@ private void onFunctionReturn(FunctionCallInstrumentationNode node, FunctionCall

}

public class FunctionCallInfo {
public static class FunctionCallInfo {

private final QualifiedName moduleName;
private final QualifiedName typeName;
Expand Down
Loading

0 comments on commit ed3f9b3

Please sign in to comment.