Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop' into wip/jtulach/Startu…
Browse files Browse the repository at this point in the history
…pWithImport
  • Loading branch information
JaroslavTulach committed Aug 28, 2024
2 parents f4a29a1 + 27f7d14 commit 183ca7a
Show file tree
Hide file tree
Showing 38 changed files with 651 additions and 215 deletions.
20 changes: 18 additions & 2 deletions app/gui2/e2e/collapsingAndEntering.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { expect } from './customExpect'
import { mockCollapsedFunctionInfo } from './expressionUpdates'
import { CONTROL_KEY } from './keyboard'
import * as locate from './locate'
import { mockSuggestion } from './suggestionUpdates'

const MAIN_FILE_NODES = 12

Expand Down Expand Up @@ -81,9 +82,24 @@ test('Collapsing nodes', async ({ page }) => {

await page.getByLabel('Group Selected Components').click()
await expect(locate.graphNode(page)).toHaveCount(initialNodesCount - 2)
const collapsedNode = locate.graphNodeByBinding(page, 'prod')
await expect(collapsedNode.locator('.WidgetToken')).toHaveText(['Main', '.', 'collapsed', 'five'])
await mockCollapsedFunctionInfo(page, 'prod', 'collapsed')
await mockSuggestion(page, {
type: 'method',
module: 'local.Mock_Project',
name: 'collapsed',
isStatic: true,
aliases: [],
arguments: [{ name: 'five', reprType: 'Any', isSuspended: false, hasDefault: false }],
selfType: 'local.Mock_Project',
returnType: 'Standard.Base.Any.Any',
documentation: [],
annotations: [],
})
const collapsedNode = locate.graphNodeByBinding(page, 'prod')
await expect(collapsedNode.locator('.WidgetFunctionName')).toExist()
await expect(collapsedNode.locator('.WidgetFunctionName .WidgetToken')).toHaveText(['Main', '.'])
await expect(collapsedNode.locator('.WidgetFunctionName input')).toHaveValue('collapsed')
await expect(collapsedNode.locator('.WidgetTopLevelArgument')).toHaveText('five')

await locate.graphNodeIcon(collapsedNode).dblclick()
await actions.ensureNoCircularMenusVisibleDueToHovering(page)
Expand Down
7 changes: 7 additions & 0 deletions app/gui2/e2e/suggestionUpdates.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { Page } from '@playwright/test'
import * as lsTypes from 'ydoc-shared/languageServerTypes/suggestions'

/** Add an entry to the suggestion database. */
export async function mockSuggestion(page: Page, update: lsTypes.SuggestionEntry) {
await page.evaluate(({ update }) => (window as any)._mockSuggestion(update), { update })
}
3 changes: 3 additions & 0 deletions app/gui2/src/components/GraphEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import type { RequiredImport } from '@/stores/graph/imports'
import { useProjectStore } from '@/stores/project'
import { provideSuggestionDbStore } from '@/stores/suggestionDatabase'
import { suggestionDocumentationUrl, type Typename } from '@/stores/suggestionDatabase/entry'
import { applyUpdates } from '@/stores/suggestionDatabase/lsUpdate'
import { provideVisualizationStore } from '@/stores/visualization'
import { bail } from '@/util/assert'
import type { AstId } from '@/util/ast/abstract'
Expand All @@ -71,6 +72,7 @@ import {
type ComponentInstance,
} from 'vue'
import { encodeMethodPointer } from 'ydoc-shared/languageServerTypes'
import * as lsTypes from 'ydoc-shared/languageServerTypes/suggestions'
import * as iterable from 'ydoc-shared/util/data/iterable'
import { isDevMode } from 'ydoc-shared/util/detect'
Expand All @@ -84,6 +86,7 @@ const widgetRegistry = provideWidgetRegistry(graphStore.db)
const _visualizationStore = provideVisualizationStore(projectStore)
const visible = injectVisibility()
provideFullscreenContext(rootNode)
;(window as any)._mockSuggestion = suggestionDb.mockSuggestion
onMounted(() => {
widgetRegistry.loadWidgets(Object.entries(builtinWidgets))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@ const targetMaybePort = computed(() => {
if (!ptr) return input
const definition = graph.getMethodAst(ptr)
if (!definition.ok) return input
input[FunctionName] = {
editableName: definition.value.name.externalId,
if (input.value instanceof Ast.PropertyAccess || input.value instanceof Ast.Ident) {
input[FunctionName] = {
editableName: definition.value.name.externalId,
}
}
return input
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,10 @@ const innerInput = computed(() => {
const callInfo = methodCallInfo.value
if (callInfo) {
input[CallInfo] = callInfo
const definition = graph.getMethodAst(callInfo.methodCall.methodPointer)
if (definition.ok) input[FunctionName] = { editableName: definition.value.name.externalId }
if (input.value instanceof Ast.PropertyAccess || input.value instanceof Ast.Ident) {
const definition = graph.getMethodAst(callInfo.methodCall.methodPointer)
if (definition.ok) input[FunctionName] = { editableName: definition.value.name.externalId }
}
}
return input
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export const FunctionName: unique symbol = Symbol.for('WidgetInput:FunctionName'
declare module '@/providers/widgetRegistry' {
export interface WidgetInput {
[FunctionName]?: {
/** Id of expression which is accepted by Lanugage Server's
/** Id of expression which is accepted by Language Server's
* [`refactoring/renameSymbol` method](https://github.com/enso-org/enso/blob/develop/docs/language-server/protocol-language-server.md#refactoringrenamesymbol)
*/
editableName: ExpressionId
Expand All @@ -63,7 +63,7 @@ declare module '@/providers/widgetRegistry' {
function isFunctionName(
input: WidgetInput,
): input is WidgetInput & { value: Ast.Ast; [FunctionName]: { editableName: ExpressionId } } {
return WidgetInput.isToken(input) && FunctionName in input
return WidgetInput.isAst(input) && FunctionName in input
}
export const widgetDefinition = defineWidget(
Expand All @@ -82,7 +82,7 @@ export const widgetDefinition = defineWidget(
<NodeWidget v-if="operator" :input="WidgetInput.FromAst(operator)" />
<AutoSizedInput
v-model="displayedName"
class="FunctionName"
class="FunctionName widgetApplyPadding"
@change="newNameAccepted"
@pointerdown.stop
@click.stop
Expand Down
19 changes: 18 additions & 1 deletion app/gui2/src/stores/suggestionDatabase/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
import { markRaw, proxyRefs, ref, type Ref } from 'vue'
import { LanguageServer } from 'ydoc-shared/languageServer'
import type { MethodPointer } from 'ydoc-shared/languageServerTypes'
import * as lsTypes from 'ydoc-shared/languageServerTypes/suggestions'
import { exponentialBackoff } from 'ydoc-shared/util/net'

export class SuggestionDb extends ReactiveDb<SuggestionId, SuggestionEntry> {
Expand Down Expand Up @@ -154,6 +155,22 @@ export const { provideFn: provideSuggestionDbStore, injectFn: useSuggestionDbSto
const entries = new SuggestionDb()
const groups = ref<Group[]>([])

/** Add an entry to the suggestion database. */
function mockSuggestion(entry: lsTypes.SuggestionEntry) {
const id = Math.max(...entries.nameToId.reverse.keys()) + 1
applyUpdates(
entries,
[
{
type: 'Add',
id,
suggestion: entry,
},
],
groups.value,
)
}

const _synchronizer = new Synchronizer(projectStore, entries, groups)
return proxyRefs({ entries: markRaw(entries), groups, _synchronizer })
return proxyRefs({ entries: markRaw(entries), groups, _synchronizer, mockSuggestion })
})
8 changes: 7 additions & 1 deletion app/gui2/src/util/ast/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ export function primaryApplicationSubject(
// Require at least one property access.
if (accessChain.length === 0) return
// The leftmost element must be an identifier or a placeholder.
if (!(subject instanceof Ast.Ident || subject instanceof Ast.Wildcard)) return
if (
!(
(subject instanceof Ast.Ident && !subject.isTypeOrConstructor()) ||
subject instanceof Ast.Wildcard
)
)
return
return { subject: subject.id, accessChain: accessChain.map((ast) => ast.id) }
}
4 changes: 4 additions & 0 deletions app/ydoc-shared/src/ast/tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2224,6 +2224,10 @@ export class Ident extends Ast {
return this.module.getToken(this.fields.get('token').node) as IdentifierToken
}

isTypeOrConstructor(): boolean {
return /^[A-Z]/.test(this.token.code())
}

static concrete(module: MutableModule, token: NodeChild<Token>) {
const base = module.baseObject('Ident')
const fields = composeFieldData(base, { token })
Expand Down
21 changes: 17 additions & 4 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -2872,7 +2872,7 @@ lazy val `std-benchmarks` = (project in file("std-bits/benchmarks"))
.settings(
frgaalJavaCompilerSetting,
annotationProcSetting,
libraryDependencies ++= GraalVM.modules ++ GraalVM.langsPkgs ++ Seq(
libraryDependencies ++= GraalVM.modules ++ GraalVM.langsPkgs ++ GraalVM.toolsPkgs ++ Seq(
"org.openjdk.jmh" % "jmh-core" % jmhVersion,
"org.openjdk.jmh" % "jmh-generator-annprocess" % jmhVersion,
"org.graalvm.polyglot" % "polyglot" % graalMavenPackagesVersion,
Expand All @@ -2895,14 +2895,23 @@ lazy val `std-benchmarks` = (project in file("std-bits/benchmarks"))
"-J-Dpolyglotimpl.DisableClassPathIsolation=true",
"-J-Dpolyglot.engine.WarnInterpreterOnly=false"
),
moduleDependencies := {
componentModulesIds.value ++ Seq(
modulePath := {
val allRuntimeMods = componentModulesPaths.value
val otherModIds = Seq(
"org.slf4j" % "slf4j-nop" % slf4jVersion
)
val requiredMods = JPMSUtils.filterModulesFromUpdate(
(Compile / update).value,
otherModIds,
streams.value.log,
shouldContainAll = true
)
allRuntimeMods ++ requiredMods
},
addModules := {
val runtimeModuleName = (`runtime-fat-jar` / javaModuleName).value
Seq(runtimeModuleName)
val arrowModName = (`runtime-language-arrow` / javaModuleName).value
Seq(runtimeModuleName, arrowModName)
},
addExports := {
Map("org.slf4j.nop/org.slf4j.nop" -> Seq("org.slf4j"))
Expand Down Expand Up @@ -2937,6 +2946,10 @@ lazy val `std-benchmarks` = (project in file("std-bits/benchmarks"))
)
.dependsOn(`bench-processor`)
.dependsOn(`runtime-fat-jar`)
.dependsOn(`ydoc-server`)
.dependsOn(`runtime-language-arrow`)
.dependsOn(`syntax-rust-definition`)
.dependsOn(`profiling-utils`)
.dependsOn(`std-table` % "provided")
.dependsOn(`std-base` % "provided")
.dependsOn(`benchmark-java-helpers` % "provided")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import Standard.Database.Connection.SSL_Mode.SSL_Mode
import Standard.Database.Internal.Connection.Entity_Naming_Properties.Entity_Naming_Properties
import Standard.Database.Internal.JDBC_Connection
import Standard.Database.Internal.Postgres.Pgpass
from Standard.Database.Internal.Postgres.Postgres_Connection import get_encoding_name, parse_postgres_encoding
from Standard.Database.Internal.Postgres.Helpers import get_encoding_name, parse_postgres_encoding

import project.AWS_Credential.AWS_Credential
import project.Database.Redshift.Internal.Redshift_Dialect
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import project.Connection.Connection_Options.Connection_Options
import project.Connection.Credentials.Credentials
import project.Connection.SSL_Mode.SSL_Mode
import project.Internal.Postgres.Pgpass
import project.Internal.Postgres.Postgres_Connection.Postgres_Connection
import project.Connection.Postgres_Connection.Postgres_Connection
import project.Internal.Postgres.Postgres_Data_Link_Setup.Postgres_Data_Link_Setup

polyglot java import org.postgresql.Driver
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
from Standard.Base import all
import Standard.Base.Errors.Encoding_Error.Encoding_Error
import Standard.Base.Errors.Illegal_Argument.Illegal_Argument
import Standard.Base.Errors.Illegal_State.Illegal_State
import Standard.Base.Metadata.Display
from Standard.Base.Metadata.Choice import Option
from Standard.Base.Metadata.Widget import Single_Choice
Expand All @@ -22,7 +19,8 @@ import project.SQL_Query.SQL_Query
import project.SQL_Statement.SQL_Statement
import project.SQL_Type.SQL_Type
from project.Connection.Connection import make_schema_selector, make_structure_creator, make_table_name_selector, make_table_types_selector
from project.Errors import SQL_Error, Table_Already_Exists, Table_Not_Found, Unsupported_Database_Encoding
from project.Errors import SQL_Error, Table_Already_Exists, Table_Not_Found
from project.Internal.Postgres.Helpers import get_encoding_name, parse_postgres_encoding
from project.Internal.Upload.Helpers.Default_Arguments import first_column_name_in_structure

type Postgres_Connection
Expand Down Expand Up @@ -305,43 +303,3 @@ type Postgres_Connection
to_js_object : JS_Object
to_js_object self =
JS_Object.from_pairs [["type", "Postgres_Connection"], ["links", self.connection.tables.at "Name" . to_vector], ["get_child_node_action", "query"]]

## PRIVATE
get_encoding_name : JDBC_Connection.JDBC_Connection -> Text
get_encoding_name jdbc_connection =
server_encoding = JDBC_Connection.get_pragma_value jdbc_connection "SHOW server_encoding"
if server_encoding != "SQL_ASCII" then server_encoding else
JDBC_Connection.get_pragma_value jdbc_connection "SHOW client_encoding"

## PRIVATE
Translates names of encodings from https://www.postgresql.org/docs/current/multibyte.html#CHARSET-TABLE
into their Java counterparts.
parse_postgres_encoding : Text -> Encoding
parse_postgres_encoding encoding_name =
resolved_by_jvm = Encoding.from_name encoding_name
# If the JVM did not resolve the encoding immediately, we try a few workarounds.
resolved_by_jvm.catch Illegal_Argument _->
fallback = case encoding_name of
"EUC_JIS_2004" ->
## Currently, I was unable to find a JVM supported encoding for
JIS X 0213-2004, so I'm falling back to the closest one and
adding a warning.
warning = Unsupported_Database_Encoding.Warning "The database is using the JIS X 0213-2004 encoding, which is currently not supported in Enso. Falling back to JIS X 0212. Column/table names may not be mapped correctly if they contain unsupported characters."
Warning.attach warning (Encoding.from_name "JIS_X0212-1990")
"KOI8R" -> Encoding.from_name "KOI8-R"
"KOI8U" -> Encoding.from_name "KOI8-U"
"LATIN7" -> Encoding.from_name "ISO-8859-13"
"SHIFT_JIS_2004" ->
## Same issue as with EUC_JIS_2004.
warning = Unsupported_Database_Encoding.Warning "The database is using the Shift JIS 2004 encoding, which is currently not supported in Enso. Falling back to older Shift JIS. Column/table names may not be mapped correctly if they contain unsupported characters."
Warning.attach warning (Encoding.from_name "SJIS")
"UHC" -> Encoding.from_name "Windows949"
_ ->
if encoding_name.starts_with "ISO_" then Encoding.from_name (encoding_name.replace "_" "-") else
if encoding_name.starts_with "WIN" then Encoding.from_name (encoding_name.replace "WIN" "CP") else
resolved_by_jvm

# If the workaround failed, we fallback to UTF-8 and log a warning.
fallback.catch Any _->
warning = Unsupported_Database_Encoding.Warning "The database is using an encoding ("+encoding_name.to_display_text+") that is currently not supported by Enso. Falling back to UTF-8. Column/table names may not be mapped correctly if they contain unsupported characters."
Warning.attach warning Encoding.utf_8
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from Standard.Base import all

import project.Connection.Connection_Options.Connection_Options
import project.Internal.SQLite.SQLite_Connection.SQLite_Connection
import project.Connection.SQLite_Connection.SQLite_Connection

type SQLite
## Connect to a SQLite DB File.
Expand Down
Loading

0 comments on commit 183ca7a

Please sign in to comment.