implements PR-05.0.4
This commit is contained in:
parent
0149b85e7d
commit
19f293d8ea
@ -15,14 +15,19 @@ import p.studio.compiler.pbs.semantics.PbsFlowSemanticsValidator;
|
|||||||
import p.studio.compiler.pbs.semantics.PbsSemanticsErrors;
|
import p.studio.compiler.pbs.semantics.PbsSemanticsErrors;
|
||||||
import p.studio.compiler.source.diagnostics.DiagnosticSink;
|
import p.studio.compiler.source.diagnostics.DiagnosticSink;
|
||||||
import p.studio.compiler.source.diagnostics.DiagnosticPhase;
|
import p.studio.compiler.source.diagnostics.DiagnosticPhase;
|
||||||
|
import p.studio.compiler.source.identifiers.CallableShapeId;
|
||||||
import p.studio.compiler.source.identifiers.CallableId;
|
import p.studio.compiler.source.identifiers.CallableId;
|
||||||
import p.studio.compiler.source.identifiers.FileId;
|
import p.studio.compiler.source.identifiers.FileId;
|
||||||
import p.studio.compiler.source.identifiers.IntrinsicId;
|
import p.studio.compiler.source.identifiers.IntrinsicId;
|
||||||
|
import p.studio.compiler.source.identifiers.NameId;
|
||||||
|
import p.studio.compiler.source.identifiers.TypeSurfaceId;
|
||||||
|
import p.studio.compiler.source.tables.CallableShapeTable;
|
||||||
import p.studio.compiler.source.tables.CallableSignatureRef;
|
import p.studio.compiler.source.tables.CallableSignatureRef;
|
||||||
import p.studio.compiler.source.tables.CallableTable;
|
import p.studio.compiler.source.tables.CallableTable;
|
||||||
import p.studio.compiler.source.tables.IntrinsicReference;
|
import p.studio.compiler.source.tables.IntrinsicReference;
|
||||||
import p.studio.compiler.source.tables.IntrinsicTable;
|
import p.studio.compiler.source.tables.IntrinsicTable;
|
||||||
import p.studio.compiler.source.tables.NameTable;
|
import p.studio.compiler.source.tables.NameTable;
|
||||||
|
import p.studio.compiler.source.tables.TypeSurfaceTable;
|
||||||
import p.studio.utilities.structures.ReadOnlyList;
|
import p.studio.utilities.structures.ReadOnlyList;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -144,7 +149,7 @@ public final class PbsFrontendCompiler {
|
|||||||
final var loweringErrorBaseline = diagnostics.errorCount();
|
final var loweringErrorBaseline = diagnostics.errorCount();
|
||||||
final var executableLowering = sourceKind == SourceKind.SDK_INTERFACE
|
final var executableLowering = sourceKind == SourceKind.SDK_INTERFACE
|
||||||
? new ExecutableLoweringResult(ReadOnlyList.empty(), ReadOnlyList.empty(), ReadOnlyList.empty())
|
? new ExecutableLoweringResult(ReadOnlyList.empty(), ReadOnlyList.empty(), ReadOnlyList.empty())
|
||||||
: lowerExecutableFunctions(fileId, ast, moduleKey, reservedMetadata, diagnostics);
|
: lowerExecutableFunctions(fileId, ast, moduleKey, reservedMetadata, effectiveNameTable, diagnostics);
|
||||||
if (diagnostics.errorCount() > loweringErrorBaseline) {
|
if (diagnostics.errorCount() > loweringErrorBaseline) {
|
||||||
return IRBackendFile.empty(fileId);
|
return IRBackendFile.empty(fileId);
|
||||||
}
|
}
|
||||||
@ -175,6 +180,7 @@ public final class PbsFrontendCompiler {
|
|||||||
final PbsAst.File ast,
|
final PbsAst.File ast,
|
||||||
final String moduleKey,
|
final String moduleKey,
|
||||||
final IRReservedMetadata reservedMetadata,
|
final IRReservedMetadata reservedMetadata,
|
||||||
|
final NameTable nameTable,
|
||||||
final DiagnosticSink diagnostics) {
|
final DiagnosticSink diagnostics) {
|
||||||
final var normalizedModuleKey = moduleKey == null ? "" : moduleKey;
|
final var normalizedModuleKey = moduleKey == null ? "" : moduleKey;
|
||||||
final var hostByMethodName = new HashMap<String, IRReservedMetadata.HostMethodBinding>();
|
final var hostByMethodName = new HashMap<String, IRReservedMetadata.HostMethodBinding>();
|
||||||
@ -188,19 +194,24 @@ public final class PbsFrontendCompiler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
final var callableIdTable = new CallableTable();
|
final var callableIdTable = new CallableTable();
|
||||||
final var callableIdsByNameAndArity = new HashMap<String, List<CallableId>>();
|
final var callableIdsByNameAndArity = new HashMap<CallableResolutionKey, List<CallableId>>();
|
||||||
final var callableIdByDeclaration = new HashMap<PbsAst.FunctionDecl, CallableId>();
|
final var callableIdByDeclaration = new HashMap<PbsAst.FunctionDecl, CallableId>();
|
||||||
final var returnSlotsByCallableId = new HashMap<CallableId, Integer>();
|
final var returnSlotsByCallableId = new HashMap<CallableId, Integer>();
|
||||||
final var intrinsicIdTable = new IntrinsicTable();
|
final var intrinsicIdTable = new IntrinsicTable();
|
||||||
|
final var typeSurfaceTable = new TypeSurfaceTable();
|
||||||
|
final var callableShapeTable = new CallableShapeTable();
|
||||||
for (final var declaredFn : ast.functions()) {
|
for (final var declaredFn : ast.functions()) {
|
||||||
|
final var callableShapeId = callableShapeId(declaredFn, typeSurfaceTable, callableShapeTable);
|
||||||
final var callableId = callableIdTable.register(
|
final var callableId = callableIdTable.register(
|
||||||
normalizedModuleKey,
|
normalizedModuleKey,
|
||||||
declaredFn.name(),
|
declaredFn.name(),
|
||||||
declaredFn.parameters().size(),
|
declaredFn.parameters().size(),
|
||||||
callableShapeKey(declaredFn));
|
callableShapeSurface(callableShapeId, typeSurfaceTable, callableShapeTable));
|
||||||
callableIdByDeclaration.put(declaredFn, callableId);
|
callableIdByDeclaration.put(declaredFn, callableId);
|
||||||
callableIdsByNameAndArity
|
callableIdsByNameAndArity
|
||||||
.computeIfAbsent(callableArityKey(declaredFn.name(), declaredFn.parameters().size()), ignored -> new ArrayList<>())
|
.computeIfAbsent(
|
||||||
|
new CallableResolutionKey(nameTable.register(declaredFn.name()), declaredFn.parameters().size()),
|
||||||
|
ignored -> new ArrayList<>())
|
||||||
.add(callableId);
|
.add(callableId);
|
||||||
final var retSlots = returnSlotsFor(declaredFn);
|
final var retSlots = returnSlotsFor(declaredFn);
|
||||||
returnSlotsByCallableId.put(callableId, retSlots);
|
returnSlotsByCallableId.put(callableId, retSlots);
|
||||||
@ -261,7 +272,8 @@ public final class PbsFrontendCompiler {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
final var candidateCallableIds = callableIdsByNameAndArity.get(callableArityKey(calleeName, callExpr.arguments().size()));
|
final var candidateCallableIds = callableIdsByNameAndArity.get(
|
||||||
|
new CallableResolutionKey(nameTable.register(calleeName), callExpr.arguments().size()));
|
||||||
if (candidateCallableIds == null || candidateCallableIds.isEmpty()) {
|
if (candidateCallableIds == null || candidateCallableIds.isEmpty()) {
|
||||||
diagnostics.error(
|
diagnostics.error(
|
||||||
DiagnosticPhase.STATIC_SEMANTICS,
|
DiagnosticPhase.STATIC_SEMANTICS,
|
||||||
@ -354,38 +366,51 @@ public final class PbsFrontendCompiler {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private String callableArityKey(
|
private CallableShapeId callableShapeId(
|
||||||
final String callableName,
|
final PbsAst.FunctionDecl functionDecl,
|
||||||
final int arity) {
|
final TypeSurfaceTable typeSurfaceTable,
|
||||||
return callableName + "#" + arity;
|
final CallableShapeTable callableShapeTable) {
|
||||||
|
final var parameterSurfaceIds = new ArrayList<TypeSurfaceId>(functionDecl.parameters().size());
|
||||||
|
for (final var parameter : functionDecl.parameters()) {
|
||||||
|
parameterSurfaceIds.add(typeSurfaceTable.register(typeSurfaceKey(parameter.typeRef())));
|
||||||
|
}
|
||||||
|
final var outputSurfaceId = typeSurfaceTable.register(outputShapeSurface(
|
||||||
|
functionDecl.returnKind(),
|
||||||
|
functionDecl.returnType(),
|
||||||
|
functionDecl.resultErrorType()));
|
||||||
|
return callableShapeTable.register(ReadOnlyList.wrap(parameterSurfaceIds), outputSurfaceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String callableShapeKey(final PbsAst.FunctionDecl functionDecl) {
|
private String callableShapeSurface(
|
||||||
|
final CallableShapeId callableShapeId,
|
||||||
|
final TypeSurfaceTable typeSurfaceTable,
|
||||||
|
final CallableShapeTable callableShapeTable) {
|
||||||
|
final var shape = callableShapeTable.get(callableShapeId);
|
||||||
final var builder = new StringBuilder();
|
final var builder = new StringBuilder();
|
||||||
builder.append('(');
|
builder.append('(');
|
||||||
for (var i = 0; i < functionDecl.parameters().size(); i++) {
|
for (var i = 0; i < shape.parameterTypeSurfaces().size(); i++) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
builder.append(',');
|
builder.append(',');
|
||||||
}
|
}
|
||||||
builder.append(typeKey(functionDecl.parameters().get(i).typeRef()));
|
builder.append(typeSurfaceTable.get(shape.parameterTypeSurfaces().get(i)).surface());
|
||||||
}
|
}
|
||||||
builder.append(")->");
|
builder.append(")->");
|
||||||
builder.append(outputShapeKey(functionDecl.returnKind(), functionDecl.returnType(), functionDecl.resultErrorType()));
|
builder.append(typeSurfaceTable.get(shape.outputTypeSurface()).surface());
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String outputShapeKey(
|
private String outputShapeSurface(
|
||||||
final PbsAst.ReturnKind returnKind,
|
final PbsAst.ReturnKind returnKind,
|
||||||
final PbsAst.TypeRef returnType,
|
final PbsAst.TypeRef returnType,
|
||||||
final PbsAst.TypeRef resultErrorType) {
|
final PbsAst.TypeRef resultErrorType) {
|
||||||
return switch (returnKind) {
|
return switch (returnKind) {
|
||||||
case INFERRED_UNIT, EXPLICIT_UNIT -> "unit";
|
case INFERRED_UNIT, EXPLICIT_UNIT -> "unit";
|
||||||
case PLAIN -> typeKey(returnType);
|
case PLAIN -> typeSurfaceKey(returnType);
|
||||||
case RESULT -> "result<" + typeKey(resultErrorType) + ">" + typeKey(returnType);
|
case RESULT -> "result<" + typeSurfaceKey(resultErrorType) + ">" + typeSurfaceKey(returnType);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private String typeKey(final PbsAst.TypeRef typeRef) {
|
private String typeSurfaceKey(final PbsAst.TypeRef typeRef) {
|
||||||
final var unwrapped = unwrapGroup(typeRef);
|
final var unwrapped = unwrapGroup(typeRef);
|
||||||
if (unwrapped == null) {
|
if (unwrapped == null) {
|
||||||
return "unit";
|
return "unit";
|
||||||
@ -393,11 +418,11 @@ public final class PbsFrontendCompiler {
|
|||||||
return switch (unwrapped.kind()) {
|
return switch (unwrapped.kind()) {
|
||||||
case SIMPLE -> "simple:" + unwrapped.name();
|
case SIMPLE -> "simple:" + unwrapped.name();
|
||||||
case SELF -> "self";
|
case SELF -> "self";
|
||||||
case OPTIONAL -> "optional(" + typeKey(unwrapped.inner()) + ")";
|
case OPTIONAL -> "optional(" + typeSurfaceKey(unwrapped.inner()) + ")";
|
||||||
case UNIT -> "unit";
|
case UNIT -> "unit";
|
||||||
case GROUP -> typeKey(unwrapped.inner());
|
case GROUP -> typeSurfaceKey(unwrapped.inner());
|
||||||
case NAMED_TUPLE -> "tuple(" + unwrapped.fields().stream()
|
case NAMED_TUPLE -> "tuple(" + unwrapped.fields().stream()
|
||||||
.map(field -> typeKey(field.typeRef()))
|
.map(field -> typeSurfaceKey(field.typeRef()))
|
||||||
.reduce((left, right) -> left + "," + right)
|
.reduce((left, right) -> left + "," + right)
|
||||||
.orElse("") + ")";
|
.orElse("") + ")";
|
||||||
case ERROR -> "error";
|
case ERROR -> "error";
|
||||||
@ -681,6 +706,11 @@ public final class PbsFrontendCompiler {
|
|||||||
ReadOnlyList<IntrinsicReference> intrinsicPool) {
|
ReadOnlyList<IntrinsicReference> intrinsicPool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private record CallableResolutionKey(
|
||||||
|
NameId callableNameId,
|
||||||
|
int arity) {
|
||||||
|
}
|
||||||
|
|
||||||
private static final class ExecutableLoweringAnalysisException extends RuntimeException {
|
private static final class ExecutableLoweringAnalysisException extends RuntimeException {
|
||||||
private ExecutableLoweringAnalysisException(final String message) {
|
private ExecutableLoweringAnalysisException(final String message) {
|
||||||
super(message);
|
super(message);
|
||||||
|
|||||||
@ -6,8 +6,12 @@ import p.studio.compiler.source.diagnostics.DiagnosticSink;
|
|||||||
import p.studio.compiler.source.diagnostics.RelatedSpan;
|
import p.studio.compiler.source.diagnostics.RelatedSpan;
|
||||||
import p.studio.compiler.source.diagnostics.Severity;
|
import p.studio.compiler.source.diagnostics.Severity;
|
||||||
import p.studio.compiler.source.identifiers.FileId;
|
import p.studio.compiler.source.identifiers.FileId;
|
||||||
|
import p.studio.compiler.source.identifiers.CallableShapeId;
|
||||||
import p.studio.compiler.source.identifiers.NameId;
|
import p.studio.compiler.source.identifiers.NameId;
|
||||||
|
import p.studio.compiler.source.identifiers.TypeSurfaceId;
|
||||||
|
import p.studio.compiler.source.tables.CallableShapeTable;
|
||||||
import p.studio.compiler.source.tables.NameTable;
|
import p.studio.compiler.source.tables.NameTable;
|
||||||
|
import p.studio.compiler.source.tables.TypeSurfaceTable;
|
||||||
import p.studio.utilities.structures.ReadOnlyList;
|
import p.studio.utilities.structures.ReadOnlyList;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -29,10 +33,11 @@ public final class PbsModuleVisibilityValidator {
|
|||||||
final ReadOnlyList<ModuleUnit> modules,
|
final ReadOnlyList<ModuleUnit> modules,
|
||||||
final NameTable nameTable,
|
final NameTable nameTable,
|
||||||
final DiagnosticSink diagnostics) {
|
final DiagnosticSink diagnostics) {
|
||||||
|
final var signatureInterning = new SignatureInterning(new TypeSurfaceTable(), new CallableShapeTable());
|
||||||
final var exportsByModule = new HashMap<ModuleRefKey, ModuleExports>();
|
final var exportsByModule = new HashMap<ModuleRefKey, ModuleExports>();
|
||||||
|
|
||||||
for (final var module : modules) {
|
for (final var module : modules) {
|
||||||
final var exports = validateModule(module, nameTable, diagnostics);
|
final var exports = validateModule(module, nameTable, signatureInterning, diagnostics);
|
||||||
exportsByModule.put(toModuleRef(module.coordinates()), exports);
|
exportsByModule.put(toModuleRef(module.coordinates()), exports);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,6 +49,7 @@ public final class PbsModuleVisibilityValidator {
|
|||||||
private ModuleExports validateModule(
|
private ModuleExports validateModule(
|
||||||
final ModuleUnit module,
|
final ModuleUnit module,
|
||||||
final NameTable nameTable,
|
final NameTable nameTable,
|
||||||
|
final SignatureInterning signatureInterning,
|
||||||
final DiagnosticSink diagnostics) {
|
final DiagnosticSink diagnostics) {
|
||||||
final var exports = new ModuleExports();
|
final var exports = new ModuleExports();
|
||||||
|
|
||||||
@ -79,7 +85,7 @@ public final class PbsModuleVisibilityValidator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final var barrel = module.barrelFiles().getFirst();
|
final var barrel = module.barrelFiles().getFirst();
|
||||||
final var declarations = collectDeclarations(module, nameTable);
|
final var declarations = collectDeclarations(module, nameTable, signatureInterning);
|
||||||
exports.declaredNameIds.addAll(declarations.declaredNameIds);
|
exports.declaredNameIds.addAll(declarations.declaredNameIds);
|
||||||
final Map<NonFunctionSymbolKey, Span> seenNonFunctionEntries = new HashMap<>();
|
final Map<NonFunctionSymbolKey, Span> seenNonFunctionEntries = new HashMap<>();
|
||||||
final Map<FunctionSymbolKey, Span> seenFunctionEntries = new HashMap<>();
|
final Map<FunctionSymbolKey, Span> seenFunctionEntries = new HashMap<>();
|
||||||
@ -92,7 +98,8 @@ public final class PbsModuleVisibilityValidator {
|
|||||||
functionItem.returnKind(),
|
functionItem.returnKind(),
|
||||||
functionItem.returnType(),
|
functionItem.returnType(),
|
||||||
functionItem.resultErrorType(),
|
functionItem.resultErrorType(),
|
||||||
nameTable);
|
nameTable,
|
||||||
|
signatureInterning);
|
||||||
final var firstFunctionEntry = seenFunctionEntries.putIfAbsent(functionKey, functionItem.span());
|
final var firstFunctionEntry = seenFunctionEntries.putIfAbsent(functionKey, functionItem.span());
|
||||||
if (firstFunctionEntry != null) {
|
if (firstFunctionEntry != null) {
|
||||||
p.studio.compiler.source.diagnostics.Diagnostics.error(diagnostics,
|
p.studio.compiler.source.diagnostics.Diagnostics.error(diagnostics,
|
||||||
@ -231,7 +238,8 @@ public final class PbsModuleVisibilityValidator {
|
|||||||
|
|
||||||
private ModuleDeclarations collectDeclarations(
|
private ModuleDeclarations collectDeclarations(
|
||||||
final ModuleUnit module,
|
final ModuleUnit module,
|
||||||
final NameTable nameTable) {
|
final NameTable nameTable,
|
||||||
|
final SignatureInterning signatureInterning) {
|
||||||
final var declarations = new ModuleDeclarations();
|
final var declarations = new ModuleDeclarations();
|
||||||
|
|
||||||
for (final var sourceFile : module.sourceFiles()) {
|
for (final var sourceFile : module.sourceFiles()) {
|
||||||
@ -243,7 +251,8 @@ public final class PbsModuleVisibilityValidator {
|
|||||||
functionDecl.returnKind(),
|
functionDecl.returnKind(),
|
||||||
functionDecl.returnType(),
|
functionDecl.returnType(),
|
||||||
functionDecl.resultErrorType(),
|
functionDecl.resultErrorType(),
|
||||||
nameTable);
|
nameTable,
|
||||||
|
signatureInterning);
|
||||||
declarations.functionsBySignature
|
declarations.functionsBySignature
|
||||||
.computeIfAbsent(key, ignored -> new ArrayList<>())
|
.computeIfAbsent(key, ignored -> new ArrayList<>())
|
||||||
.add(functionDecl.span());
|
.add(functionDecl.span());
|
||||||
@ -295,37 +304,37 @@ public final class PbsModuleVisibilityValidator {
|
|||||||
final PbsAst.ReturnKind returnKind,
|
final PbsAst.ReturnKind returnKind,
|
||||||
final PbsAst.TypeRef returnType,
|
final PbsAst.TypeRef returnType,
|
||||||
final PbsAst.TypeRef resultErrorType,
|
final PbsAst.TypeRef resultErrorType,
|
||||||
final NameTable nameTable) {
|
final NameTable nameTable,
|
||||||
final var signatureSurface = signatureSurfaceKey(parameterTypes, returnKind, returnType, resultErrorType);
|
final SignatureInterning signatureInterning) {
|
||||||
return new FunctionSymbolKey(nameTable.register(name), signatureSurface);
|
return new FunctionSymbolKey(
|
||||||
|
nameTable.register(name),
|
||||||
|
callableShapeId(parameterTypes, returnKind, returnType, resultErrorType, signatureInterning));
|
||||||
}
|
}
|
||||||
|
|
||||||
private String signatureSurfaceKey(
|
private CallableShapeId callableShapeId(
|
||||||
final List<PbsAst.TypeRef> parameterTypes,
|
final List<PbsAst.TypeRef> parameterTypes,
|
||||||
|
final PbsAst.ReturnKind returnKind,
|
||||||
|
final PbsAst.TypeRef returnType,
|
||||||
|
final PbsAst.TypeRef resultErrorType,
|
||||||
|
final SignatureInterning signatureInterning) {
|
||||||
|
final var parameterSurfaceIds = new ArrayList<TypeSurfaceId>(parameterTypes.size());
|
||||||
|
for (final var parameterType : parameterTypes) {
|
||||||
|
parameterSurfaceIds.add(signatureInterning.typeSurfaces().register(typeSurfaceKey(parameterType)));
|
||||||
|
}
|
||||||
|
final var outputSurfaceId = signatureInterning.typeSurfaces().register(outputSurfaceKey(returnKind, returnType, resultErrorType));
|
||||||
|
return signatureInterning.callableShapes().register(ReadOnlyList.wrap(parameterSurfaceIds), outputSurfaceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String outputSurfaceKey(
|
||||||
final PbsAst.ReturnKind returnKind,
|
final PbsAst.ReturnKind returnKind,
|
||||||
final PbsAst.TypeRef returnType,
|
final PbsAst.TypeRef returnType,
|
||||||
final PbsAst.TypeRef resultErrorType) {
|
final PbsAst.TypeRef resultErrorType) {
|
||||||
final var builder = new StringBuilder();
|
return switch (returnKind) {
|
||||||
builder.append('(');
|
case INFERRED_UNIT -> "infer_unit";
|
||||||
for (int i = 0; i < parameterTypes.size(); i++) {
|
case EXPLICIT_UNIT -> "unit";
|
||||||
if (i > 0) {
|
case PLAIN -> typeSurfaceKey(returnType);
|
||||||
builder.append(',');
|
case RESULT -> "result<" + typeSurfaceKey(resultErrorType) + ">" + typeSurfaceKey(returnType);
|
||||||
}
|
};
|
||||||
builder.append(typeSurfaceKey(parameterTypes.get(i)));
|
|
||||||
}
|
|
||||||
builder.append(")->");
|
|
||||||
|
|
||||||
switch (returnKind) {
|
|
||||||
case INFERRED_UNIT -> builder.append("infer_unit");
|
|
||||||
case EXPLICIT_UNIT -> builder.append("unit");
|
|
||||||
case PLAIN -> builder.append(typeSurfaceKey(returnType));
|
|
||||||
case RESULT -> builder.append("result<")
|
|
||||||
.append(typeSurfaceKey(resultErrorType))
|
|
||||||
.append('>')
|
|
||||||
.append(typeSurfaceKey(returnType));
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String typeSurfaceKey(final PbsAst.TypeRef typeRef) {
|
private String typeSurfaceKey(final PbsAst.TypeRef typeRef) {
|
||||||
@ -489,7 +498,12 @@ public final class PbsModuleVisibilityValidator {
|
|||||||
|
|
||||||
private record FunctionSymbolKey(
|
private record FunctionSymbolKey(
|
||||||
NameId nameId,
|
NameId nameId,
|
||||||
String signatureSurface) {
|
CallableShapeId callableShapeId) {
|
||||||
|
}
|
||||||
|
|
||||||
|
private record SignatureInterning(
|
||||||
|
TypeSurfaceTable typeSurfaces,
|
||||||
|
CallableShapeTable callableShapes) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class ModuleDeclarations {
|
private static final class ModuleDeclarations {
|
||||||
|
|||||||
@ -0,0 +1,7 @@
|
|||||||
|
package p.studio.compiler.source.identifiers;
|
||||||
|
|
||||||
|
public class CallableShapeId extends SourceIdentifier {
|
||||||
|
public CallableShapeId(final int id) {
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
package p.studio.compiler.source.identifiers;
|
||||||
|
|
||||||
|
public class TypeSurfaceId extends SourceIdentifier {
|
||||||
|
public TypeSurfaceId(final int id) {
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
package p.studio.compiler.source.tables;
|
||||||
|
|
||||||
|
import p.studio.compiler.source.identifiers.TypeSurfaceId;
|
||||||
|
import p.studio.utilities.structures.ReadOnlyList;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public record CallableShapeRef(
|
||||||
|
ReadOnlyList<TypeSurfaceId> parameterTypeSurfaces,
|
||||||
|
TypeSurfaceId outputTypeSurface) {
|
||||||
|
public CallableShapeRef {
|
||||||
|
parameterTypeSurfaces = parameterTypeSurfaces == null ? ReadOnlyList.empty() : parameterTypeSurfaces;
|
||||||
|
outputTypeSurface = Objects.requireNonNull(outputTypeSurface, "outputTypeSurface");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
package p.studio.compiler.source.tables;
|
||||||
|
|
||||||
|
import p.studio.compiler.source.identifiers.CallableShapeId;
|
||||||
|
import p.studio.compiler.source.identifiers.TypeSurfaceId;
|
||||||
|
import p.studio.utilities.structures.ReadOnlyList;
|
||||||
|
|
||||||
|
public class CallableShapeTable extends InternTable<CallableShapeId, CallableShapeRef> {
|
||||||
|
|
||||||
|
public CallableShapeTable() {
|
||||||
|
super(CallableShapeId::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CallableShapeId register(
|
||||||
|
final ReadOnlyList<TypeSurfaceId> parameterTypeSurfaces,
|
||||||
|
final TypeSurfaceId outputTypeSurface) {
|
||||||
|
return register(new CallableShapeRef(parameterTypeSurfaces, outputTypeSurface));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
package p.studio.compiler.source.tables;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public record TypeSurfaceRef(
|
||||||
|
String surface) {
|
||||||
|
public TypeSurfaceRef {
|
||||||
|
surface = Objects.requireNonNull(surface, "surface");
|
||||||
|
if (surface.isBlank()) {
|
||||||
|
throw new IllegalArgumentException("surface must not be blank");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
package p.studio.compiler.source.tables;
|
||||||
|
|
||||||
|
import p.studio.compiler.source.identifiers.TypeSurfaceId;
|
||||||
|
|
||||||
|
public class TypeSurfaceTable extends InternTable<TypeSurfaceId, TypeSurfaceRef> {
|
||||||
|
|
||||||
|
public TypeSurfaceTable() {
|
||||||
|
super(TypeSurfaceId::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypeSurfaceId register(final String surface) {
|
||||||
|
return register(new TypeSurfaceRef(surface));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
package p.studio.compiler.source.tables;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import p.studio.utilities.structures.ReadOnlyList;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
class CallableShapeTableTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldInternEqualShapesToSameIdentifier() {
|
||||||
|
final var surfaces = new TypeSurfaceTable();
|
||||||
|
final var shapes = new CallableShapeTable();
|
||||||
|
|
||||||
|
final var intType = surfaces.register("simple:int");
|
||||||
|
final var unitType = surfaces.register("unit");
|
||||||
|
final var first = shapes.register(ReadOnlyList.from(intType, intType), unitType);
|
||||||
|
final var second = shapes.register(ReadOnlyList.from(intType, intType), unitType);
|
||||||
|
final var third = shapes.register(ReadOnlyList.from(intType), unitType);
|
||||||
|
|
||||||
|
assertEquals(first, second);
|
||||||
|
assertEquals(2, shapes.size());
|
||||||
|
assertEquals(1, shapes.get(third).parameterTypeSurfaces().size());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
package p.studio.compiler.source.tables;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
|
class TypeSurfaceTableTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldInternEqualSurfacesToSameIdentifier() {
|
||||||
|
final var table = new TypeSurfaceTable();
|
||||||
|
|
||||||
|
final var first = table.register("simple:int");
|
||||||
|
final var second = table.register("simple:int");
|
||||||
|
final var third = table.register("result<error>simple:int");
|
||||||
|
|
||||||
|
assertEquals(first, second);
|
||||||
|
assertEquals(2, table.size());
|
||||||
|
assertEquals("result<error>simple:int", table.get(third).surface());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldRejectInvalidSurfaceContract() {
|
||||||
|
assertThrows(IllegalArgumentException.class, () -> new TypeSurfaceRef(""));
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user