Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions crates/graph-core/src/extraction/facts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,8 @@ fn module_parts_for_path(path: &str) -> Vec<String> {
let without_extension = path
.strip_suffix(".py")
.or_else(|| path.strip_suffix(".pyi"))
.or_else(|| path.strip_suffix(".mts"))
.or_else(|| path.strip_suffix(".cts"))
.or_else(|| path.strip_suffix(".ts"))
.or_else(|| path.strip_suffix(".tsx"))
.or_else(|| path.strip_suffix(".js"))
Expand Down
28 changes: 26 additions & 2 deletions crates/graph-core/src/extraction/facts/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ use crate::protocol::{GraphFactEdge, GraphFactNode};
use oxc_ast::ast::{
Argument, BindingPattern, CallExpression, Class, ExportAllDeclaration,
ExportDefaultDeclaration, ExportDefaultDeclarationKind, ExportNamedDeclaration, Expression,
Function, ImportDeclaration, ImportDeclarationSpecifier, ModuleExportName, NewExpression,
TSInterfaceDeclaration, TSTypeAliasDeclaration, TSTypeName, VariableDeclaration,
Function, ImportDeclaration, ImportDeclarationSpecifier, ImportExpression, ModuleExportName,
NewExpression, TSImportType, TSInterfaceDeclaration, TSTypeAliasDeclaration, TSTypeName,
VariableDeclaration,
};
use oxc_ast_visit::{walk, Visit};
use oxc_syntax::scope::ScopeFlags;
Expand Down Expand Up @@ -317,6 +318,24 @@ impl<'a> Visit<'a> for FileFactCollector {
});
}

fn visit_import_expression(&mut self, import: &ImportExpression<'a>) {
if let Expression::StringLiteral(source) = &import.source {
self.imports.push(ImportFact {
specifier: source.value.to_string(),
bindings: Vec::new(),
});
}
walk::walk_import_expression(self, import);
}

fn visit_ts_import_type(&mut self, import: &TSImportType<'a>) {
self.imports.push(ImportFact {
specifier: import.source.value.to_string(),
bindings: Vec::new(),
});
walk::walk_ts_import_type(self, import);
}

fn visit_export_named_declaration(&mut self, export: &ExportNamedDeclaration<'a>) {
let source = export
.source
Expand Down Expand Up @@ -530,6 +549,7 @@ impl<'a> Visit<'a> for FileFactCollector {

fn visit_ts_type_alias_declaration(&mut self, declaration: &TSTypeAliasDeclaration<'a>) {
self.add_declaration("type", "Type", declaration.id.name.as_ref());
walk::walk_ts_type_alias_declaration(self, declaration);
}

fn visit_ts_interface_declaration(&mut self, declaration: &TSInterfaceDeclaration<'a>) {
Expand All @@ -543,10 +563,14 @@ impl<'a> Visit<'a> for FileFactCollector {
});
}
}
walk::walk_ts_interface_declaration(self, declaration);
}

fn visit_variable_declaration(&mut self, declaration: &VariableDeclaration<'a>) {
for declarator in &declaration.declarations {
if let Some(type_annotation) = &declarator.type_annotation {
self.visit_ts_type_annotation(type_annotation);
}
if let Some(name) = binding_name(&declarator.id) {
if self.current_context.is_none() {
let Some(init) = declarator.init.as_ref() else {
Expand Down
9 changes: 5 additions & 4 deletions crates/graph-core/src/extraction/language.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub enum SourceLanguage {
impl SourceLanguage {
pub fn from_path(path: &Path) -> Option<Self> {
match path.extension().and_then(|extension| extension.to_str()) {
Some("ts") => Some(Self::TypeScript),
Some("ts") | Some("mts") | Some("cts") => Some(Self::TypeScript),
Some("tsx") => Some(Self::TypeScriptJsx),
Some("js") => Some(Self::JavaScript),
Some("jsx") => Some(Self::JavaScriptJsx),
Expand All @@ -38,9 +38,10 @@ impl SourceLanguage {
pub fn unsupported_source_extension(path: &Path) -> Option<String> {
let extension = path.extension()?.to_str()?;
match extension {
"mjs" | "cjs" | "mts" | "cts" | "vue" | "svelte" | "go" | "java" | "rb" | "php"
| "swift" | "kt" | "kts" | "scala" | "lua" | "cs" | "c" | "cc" | "cpp" | "h"
| "hpp" => Some(extension.to_string()),
"mjs" | "cjs" | "vue" | "svelte" | "go" | "java" | "rb" | "php" | "swift" | "kt"
| "kts" | "scala" | "lua" | "cs" | "c" | "cc" | "cpp" | "h" | "hpp" => {
Some(extension.to_string())
}
_ => None,
}
}
Expand Down
51 changes: 43 additions & 8 deletions crates/graph-core/src/extraction/tsconfig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -355,16 +355,51 @@ fn resolve_candidate(
}

fn resolution_candidates(path: &str) -> Vec<String> {
let mut candidates = vec![path.to_string()];
if Path::new(path).extension().is_none() {
for extension in [".ts", ".tsx", ".js", ".jsx"] {
candidates.push(format!("{path}{extension}"));
}
for extension in ["ts", "tsx", "js", "jsx"] {
candidates.push(format!("{path}/index.{extension}"));
let extension = Path::new(path).extension().and_then(|value| value.to_str());
match extension {
Some("js") => vec![
replace_extension(path, "ts"),
replace_extension(path, "tsx"),
replace_extension(path, "d.ts"),
path.to_string(),
replace_extension(path, "jsx"),
],
Some("jsx") => vec![
replace_extension(path, "tsx"),
replace_extension(path, "ts"),
replace_extension(path, "d.ts"),
path.to_string(),
replace_extension(path, "js"),
],
Some("mjs") => vec![
replace_extension(path, "mts"),
replace_extension(path, "d.mts"),
path.to_string(),
],
Some("cjs") => vec![
replace_extension(path, "cts"),
replace_extension(path, "d.cts"),
path.to_string(),
],
Some(_) => vec![path.to_string()],
None => {
let mut candidates = vec![path.to_string()];
for extension in ["ts", "tsx", "mts", "cts", "js", "jsx", "d.ts"] {
candidates.push(format!("{path}.{extension}"));
}
for extension in ["ts", "tsx", "mts", "cts", "js", "jsx", "d.ts"] {
candidates.push(format!("{path}/index.{extension}"));
}
candidates
}
}
candidates
}

fn replace_extension(path: &str, extension: &str) -> String {
Path::new(path)
.with_extension(extension)
.to_string_lossy()
.replace('\\', "/")
}

fn normalize_relative(path: &Path) -> Result<String, ()> {
Expand Down
12 changes: 12 additions & 0 deletions packages/contracts/schemas/opcore-contracts.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -3326,6 +3326,18 @@
"failureMessage": {
"type": "string",
"minLength": 1
},
"cwd": {
"type": "string",
"minLength": 1
},
"configFile": {
"type": "string",
"minLength": 1
},
"source": {
"type": "string",
"minLength": 1
}
}
}
Expand Down
8 changes: 8 additions & 0 deletions packages/contracts/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1256,6 +1256,9 @@ export interface ValidationAdapterToolchainStatus {
command?: string;
version?: string;
failureMessage?: string;
cwd?: string;
configFile?: string;
source?: string;
}

export interface ValidationAdapterDegradedCheckStatus {
Expand Down Expand Up @@ -6619,6 +6622,11 @@ function validateValidationAdapterToolchainStatus(status: ValidationAdapterToolc
if (status.failureMessage !== undefined) {
validateNonEmptyString(status.failureMessage, "Validation adapter toolchain status failureMessage");
}
if (status.cwd !== undefined) validateNonEmptyString(status.cwd, "Validation adapter toolchain status cwd");
if (status.configFile !== undefined) {
validateNonEmptyString(status.configFile, "Validation adapter toolchain status configFile");
}
if (status.source !== undefined) validateNonEmptyString(status.source, "Validation adapter toolchain status source");
return status;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
{
"schemaVersion": 1,
"fixture": "source-extraction-node-next",
"fileNodeIds": [
"file:src/alias-consumer.ts",
"file:src/alias/value.ts",
"file:src/common-dep.cts",
"file:src/common.cts",
"file:src/dep.ts",
"file:src/dynamic-target.ts",
"file:src/dynamic.ts",
"file:src/import-type.ts",
"file:src/main.ts",
"file:src/module-dep.mts",
"file:src/module.mts",
"file:src/nonliteral.ts",
"file:src/types.ts"
],
"moduleEdgeTriples": [
[
"DEPENDS_ON",
"file:src/alias-consumer.ts",
"file:src/alias/value.ts"
],
[
"DEPENDS_ON",
"file:src/common.cts",
"file:src/common-dep.cts"
],
[
"DEPENDS_ON",
"file:src/dynamic.ts",
"file:src/dynamic-target.ts"
],
[
"DEPENDS_ON",
"file:src/import-type.ts",
"file:src/types.ts"
],
[
"DEPENDS_ON",
"file:src/main.ts",
"file:src/dep.ts"
],
[
"DEPENDS_ON",
"file:src/module.mts",
"file:src/module-dep.mts"
],
[
"IMPORTS_FROM",
"file:src/alias-consumer.ts",
"file:src/alias/value.ts"
],
[
"IMPORTS_FROM",
"file:src/common.cts",
"file:src/common-dep.cts"
],
[
"IMPORTS_FROM",
"file:src/dynamic.ts",
"file:src/dynamic-target.ts"
],
[
"IMPORTS_FROM",
"file:src/import-type.ts",
"file:src/types.ts"
],
[
"IMPORTS_FROM",
"file:src/main.ts",
"file:src/dep.ts"
],
[
"IMPORTS_FROM",
"file:src/module.mts",
"file:src/module-dep.mts"
]
],
"diagnostics": []
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { aliasValue } from "@fixture/value.js";

export const consumedAlias = aliasValue;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const aliasValue = "alias";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const commonDependency = "common";
3 changes: 3 additions & 0 deletions packages/fixtures/source-extraction/node-next/src/common.cts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { commonDependency } from "./common-dep.cjs";

export const commonValue = commonDependency;
1 change: 1 addition & 0 deletions packages/fixtures/source-extraction/node-next/src/dep.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const dependency = "typescript";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const dynamicValue = "dynamic";
3 changes: 3 additions & 0 deletions packages/fixtures/source-extraction/node-next/src/dynamic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export async function loadDynamic() {
return import("./dynamic-target.js");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type ImportedShape = import("./types.js").Shape;
3 changes: 3 additions & 0 deletions packages/fixtures/source-extraction/node-next/src/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { dependency } from "./dep.js";

export const mainValue = dependency;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const moduleDependency = "module";
3 changes: 3 additions & 0 deletions packages/fixtures/source-extraction/node-next/src/module.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { moduleDependency } from "./module-dep.mjs";

export const moduleValue = moduleDependency;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export async function loadFrom(specifier: string) {
return import(specifier);
}
3 changes: 3 additions & 0 deletions packages/fixtures/source-extraction/node-next/src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export interface Shape {
value: string;
}
12 changes: 12 additions & 0 deletions packages/fixtures/source-extraction/node-next/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"compilerOptions": {
"baseUrl": ".",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"paths": {
"@fixture/*": ["src/alias/*"]
},
"target": "ES2022"
},
"include": ["src/**/*"]
}
2 changes: 1 addition & 1 deletion packages/opcore-graph-core-linux-x64/metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
"targetPlatform": "linux-x64",
"binaryPath": "opcore-graph-core",
"checksumPath": "opcore-graph-core.sha256",
"checksumSha256": "70cb6d213d74594f337a67522c879b77767872dc4601063686f1abe70886127b",
"checksumSha256": "c3a771435a7a8172a9e5f0bb20b0d111453efc70901e95308094664f77e7bdf1",
"buildProfile": "release"
}
Binary file modified packages/opcore-graph-core-linux-x64/opcore-graph-core
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1 +1 @@
70cb6d213d74594f337a67522c879b77767872dc4601063686f1abe70886127b opcore-graph-core
c3a771435a7a8172a9e5f0bb20b0d111453efc70901e95308094664f77e7bdf1 opcore-graph-core
2 changes: 1 addition & 1 deletion packages/opcore/src/advanced/validation-composition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export function createDefaultValidationStatusPayload(options: {
const graphMode = options.graphMode ?? "optional";
return createValidationStatusPayload({
checks: validationChecksForRepoPolicy(options.repoRoot),
adapters: [createRustValidationAdapterStatus(), createPythonValidationAdapterStatus()],
adapters: [createRustValidationAdapterStatus(), createPythonValidationAdapterStatus({ repoRoot: options.repoRoot })],
graphMode,
graphStatus: cliGraphStatus({ repoRoot: options.repoRoot }, graphMode)
});
Expand Down
Loading
Loading