Skip to content

Commit

Permalink
Merge pull request #42912 from lochana-chathura/semIntegration/error
Browse files Browse the repository at this point in the history
 Integrate error semtype into compiler
  • Loading branch information
lochana-chathura authored Jul 16, 2024
2 parents 55b3511 + 58f41b3 commit ffaac5c
Show file tree
Hide file tree
Showing 30 changed files with 146 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public ErrorTypeSymbol build() {
symTable.rootPkgSymbol.pkgID, symTable.errorType, symTable.rootPkgSymbol, symTable.builtinPos,
COMPILED_SOURCE);

BErrorType errorType = new BErrorType(errorTSymbol, getBType(typeParam));
BErrorType errorType = new BErrorType(symTable.typeEnv(), errorTSymbol, getBType(typeParam));
errorTSymbol.type = errorType;
ErrorTypeSymbol errorTypeSymbol = (ErrorTypeSymbol) typesFactory.getTypeDescriptor(errorType);
this.typeParam = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1583,7 +1583,7 @@ public BType readType(int cpI) throws IOException {
errorSymbol = new BErrorTypeSymbol(SymTag.ERROR, Flags.PUBLIC, Names.EMPTY,
env.pkgSymbol.pkgID, null, env.pkgSymbol, symTable.builtinPos, COMPILED_SOURCE);
}
BErrorType errorType = new BErrorType(errorSymbol);
BErrorType errorType = new BErrorType(symTable.typeEnv(), errorSymbol);
addShapeCP(errorType, cpI);
compositeStack.push(errorType);
String errorName = getStringCPEntryValue(inputStream);
Expand Down Expand Up @@ -2023,6 +2023,7 @@ private RecAtom readRecAtom() throws IOException {
case LIST_ATOM -> offsets.listOffset();
case FUNCTION_ATOM -> offsets.functionOffset();
case MAPPING_ATOM -> offsets.mappingOffset();
case DISTINCT_ATOM -> (-offsets.distinctOffset());
case XML_ATOM -> 0;
case CELL_ATOM -> throw new IllegalStateException("Cell atom cannot be recursive");
};
Expand Down Expand Up @@ -2232,15 +2233,17 @@ private BType getEffectiveImmutableType(BType type, PackageID pkgID, BSymbol own
null, names);
}

private record AtomOffsets(int atomOffset, int listOffset, int functionOffset, int mappingOffset) {
private record AtomOffsets(int atomOffset, int listOffset, int functionOffset, int mappingOffset,
int distinctOffset) {

static AtomOffsets from(Env env) {
PredefinedTypeEnv predefinedTypeEnv = PredefinedTypeEnv.getInstance();
int recAtomOffset = predefinedTypeEnv.reservedRecAtomCount();
return new AtomOffsets(env.atomCount(),
env.recListAtomCount() - recAtomOffset,
env.recFunctionAtomCount(),
env.recMappingAtomCount() - recAtomOffset);
env.recMappingAtomCount() - recAtomOffset,
env.distinctAtomCount());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -699,7 +699,8 @@ private void writeInlinedRecAtom(RecAtom recAtom) {
case LIST_ATOM -> typeEnv.listAtom(typeEnv.listAtomType(recAtom));
case FUNCTION_ATOM -> typeEnv.functionAtom(typeEnv.functionAtomType(recAtom));
case MAPPING_ATOM -> typeEnv.mappingAtom(typeEnv.mappingAtomType(recAtom));
case XML_ATOM -> throw new IllegalStateException("Should not happen. Handled before reaching here");
case XML_ATOM, DISTINCT_ATOM ->
throw new IllegalStateException("Should not happen. Handled before reaching here");
case CELL_ATOM -> throw new IllegalStateException("Cell atom cannot be recursive");
};
writeTypeAtom(typeAtom);
Expand All @@ -710,7 +711,8 @@ private boolean shouldInline(RecAtom recAtom) {
// RecAtoms. But when we deserialize the nodes we need to get the actual BDD node somehow. Currently, we
// "inline" the actual node first time we see it in the tree. Exceptions to this rule are predefined rec atoms
// which are unique and every environment has the same atoms and XML atoms
if (predefinedTypeEnv.isPredefinedRecAtom(recAtom.index) || recAtom.kind() == Atom.Kind.XML_ATOM) {
if (predefinedTypeEnv.isPredefinedRecAtom(recAtom.index) || recAtom.kind() == Atom.Kind.XML_ATOM ||
recAtom.kind() == Atom.Kind.DISTINCT_ATOM) {
return false;
}
return !visitedAtoms.contains(recAtom.getIdentifier());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9866,7 +9866,7 @@ private BType getStructuredBindingPatternType(BLangVariable bindingPatternVariab
TypeDefBuilderHelper.createTypeDefinitionForTSymbol(detailType, detailType.tsymbol,
recordTypeNode, env);
}
BErrorType errorType = new BErrorType(errorTypeSymbol, detailType);
BErrorType errorType = new BErrorType(symTable.typeEnv(), errorTypeSymbol, detailType);
errorTypeSymbol.type = errorType;

TypeDefBuilderHelper.createTypeDefinitionForTSymbol(errorType, errorTypeSymbol,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ public static SemType semTypeComponent(BType t) {
case TypeTags.FUTURE:
case TypeTags.TYPEDESC:
case TypeTags.STREAM:
case TypeTags.ERROR:
return t.semType();
default:
if (isFullSemType(t.tag)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1734,7 +1734,7 @@ public void visit(BLangErrorVariable varNode, AnalyzerData data) {
// reason must be a const of subtype of string.
// then we match the error with this specific reason.
if (!varNode.reasonVarPrefixAvailable && varNode.getBType() == null) {
BErrorType errorType = new BErrorType(varNode.getBType().tsymbol, null);
BErrorType errorType = new BErrorType(symTable.typeEnv(), varNode.getBType().tsymbol, null);

if (Types.getImpliedType(varNode.getBType()).tag == TypeTags.UNION) {
Set<BType> members = types.expandAndGetMemberTypesRecursive(varNode.getBType());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1973,7 +1973,7 @@ private BErrorType getDistinctErrorType(BLangTypeDefinition typeDefinition, BErr
if (definedErrorType.tsymbol != typeDefSymbol) {
BTypeSymbol typeSymbol = new BTypeSymbol(SymTag.TYPE_DEF, typeDefSymbol.flags, typeDefSymbol.name,
typeDefSymbol.pkgID, null, typeDefSymbol.owner, typeDefSymbol.pos, typeDefSymbol.origin);
BErrorType bErrorType = new BErrorType(typeSymbol);
BErrorType bErrorType = new BErrorType(symTable.typeEnv(), typeSymbol);
typeSymbol.type = bErrorType;
bErrorType.detailType = definedErrorType.detailType;
typeDefSymbol.type = bErrorType;
Expand Down Expand Up @@ -3282,7 +3282,7 @@ boolean validateErrorVariable(BLangErrorVariable errorVariable, SymbolEnv env) {
BType errorDetailType = detailType.size() > 1
? BUnionType.create(symTable.typeEnv(), null, detailType)
: detailType.iterator().next();
errorType = new BErrorType(null, errorDetailType);
errorType = new BErrorType(symTable.typeEnv(), null, errorDetailType);
} else {
errorType = possibleTypes.get(0);
}
Expand Down Expand Up @@ -3331,7 +3331,7 @@ boolean validateErrorVariable(BLangErrorVariable errorVariable, SymbolEnv env) {
env.enclPkg.packageID, symTable.errorType,
env.scope.owner, errorVariable.pos, SOURCE);
// TODO: detail type need to be a union representing all details of members of `errorType`
errorVariable.setBType(new BErrorType(errorTypeSymbol, symTable.detailType));
errorVariable.setBType(new BErrorType(symTable.typeEnv(), errorTypeSymbol, symTable.detailType));
return validateErrorVariable(errorVariable, env);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1076,7 +1076,7 @@ public void bootstrapCloneableType() {
PackageID.VALUE, symTable.cloneableType, symTable.langValueModuleSymbol,
symTable.builtinPos, BUILTIN);
symTable.detailType = new BMapType(symTable.typeEnv(), TypeTags.MAP, symTable.cloneableType, null);
symTable.errorType = new BErrorType(null, symTable.detailType);
symTable.errorType = new BErrorType(symTable.typeEnv(), null, symTable.detailType);
symTable.errorType.tsymbol = new BErrorTypeSymbol(SymTag.ERROR, Flags.PUBLIC, Names.ERROR,
symTable.rootPkgSymbol.pkgID, symTable.errorType, symTable.rootPkgSymbol, symTable.builtinPos
, BUILTIN);
Expand Down Expand Up @@ -1497,7 +1497,7 @@ public BType transform(BLangErrorType errorTypeNode, AnalyzerData data) {
symbolEnter.defineSymbol(errorTypeNode.pos, errorTypeSymbol, data.env);
}

BErrorType errorType = new BErrorType(errorTypeSymbol, detailType);
BErrorType errorType = new BErrorType(symTable.typeEnv(), errorTypeSymbol, detailType);
errorType.addFlags(errorTypeSymbol.flags);
errorTypeSymbol.type = errorType;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3398,7 +3398,7 @@ public void visit(BLangErrorVarRef varRefExpr, AnalyzerData data) {
BType errorDetailType = errorRefRestFieldType == symTable.anydataOrReadonly
? symTable.errorType.detailType
: new BMapType(symTable.typeEnv(), TypeTags.MAP, errorRefRestFieldType, null, Flags.PUBLIC);
data.resultType = new BErrorType(symTable.errorType.tsymbol, errorDetailType);
data.resultType = new BErrorType(symTable.typeEnv(), symTable.errorType.tsymbol, errorDetailType);
}

private void checkIndirectErrorVarRef(BLangErrorVarRef varRefExpr, AnalyzerData data) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1166,7 +1166,7 @@ private BType getMatchingErrorBoundType(BErrorType expType, SymbolEnv env, HashS
null, null, symTable.builtinPos, VIRTUAL);
typeSymbol.isTypeParamResolved = true;
typeSymbol.typeParamTSymbol = expType.tsymbol;
BErrorType errorType = new BErrorType(typeSymbol, detailType);
BErrorType errorType = new BErrorType(symTable.typeEnv(), typeSymbol, detailType);
typeSymbol.type = errorType;
return errorType;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1265,7 +1265,7 @@ private BType resolveTypeDesc(BLangErrorType td, ResolverData data) {
}

if (td.detailType == null) {
BType errorType = new BErrorType(null, symTable.detailType);
BType errorType = new BErrorType(symTable.typeEnv(), null, symTable.detailType);
errorType.tsymbol = new BErrorTypeSymbol(SymTag.ERROR, Flags.PUBLIC, Names.ERROR,
symTable.rootPkgSymbol.pkgID, errorType, symTable.rootPkgSymbol, symTable.builtinPos, BUILTIN);
return errorType;
Expand All @@ -1274,7 +1274,7 @@ private BType resolveTypeDesc(BLangErrorType td, ResolverData data) {
// Define user define error type.
BErrorTypeSymbol errorTypeSymbol = Symbols.createErrorSymbol(Flags.asMask(td.flagSet),
Names.EMPTY, data.env.enclPkg.packageID, null, data.env.scope.owner, td.pos, BUILTIN);
BErrorType errorType = new BErrorType(errorTypeSymbol, symTable.empty);
BErrorType errorType = new BErrorType(symTable.typeEnv(), errorTypeSymbol, symTable.empty);
td.setBType(errorType);
resolvingTypes.push(errorType);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5393,7 +5393,7 @@ public BErrorType createErrorType(BType detailType, long flags, SymbolEnv env) {
env.enclPkg.symbol.pkgID, null,
env.scope.owner, symTable.builtinPos, VIRTUAL);
errorTypeSymbol.scope = new Scope(errorTypeSymbol);
BErrorType errorType = new BErrorType(errorTypeSymbol, detailType);
BErrorType errorType = new BErrorType(symTable.typeEnv(), errorTypeSymbol, detailType);
errorType.addFlags(errorTypeSymbol.flags);
errorTypeSymbol.type = errorType;
errorType.typeIdSet = BTypeIdSet.emptySet();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
import org.ballerinalang.model.types.TypeKind;
import org.wso2.ballerinalang.compiler.diagnostic.BLangDiagnosticLocation;
import org.wso2.ballerinalang.compiler.semantics.analyzer.Types;
import org.wso2.ballerinalang.compiler.semantics.model.symbols.BConstructorSymbol;
import org.wso2.ballerinalang.compiler.semantics.model.symbols.BErrorTypeSymbol;
import org.wso2.ballerinalang.compiler.semantics.model.symbols.BInvokableTypeSymbol;
import org.wso2.ballerinalang.compiler.semantics.model.symbols.BOperatorSymbol;
Expand Down Expand Up @@ -143,14 +142,11 @@ public class SymbolTable {
public final BIntersectionType anyAndReadonly;
public BUnionType anyAndReadonlyOrError;

public final BType errorIntersectionType = new BErrorType(null, null);

public final BType semanticError = new BType(TypeTags.SEMANTIC_ERROR, null);
public final BType nullSet = new BType(TypeTags.NULL_SET, null);
public final BType invokableType;
public final BType empty = new BType(TypeTags.EMPTY, null);

public BConstructorSymbol errorConstructor;
public BUnionType anyOrErrorType;
public BUnionType pureType;
public BUnionType errorOrNilType;
Expand Down Expand Up @@ -1189,7 +1185,7 @@ private void defineCloneableCyclicTypeAndDependentTypes() {
cloneableType, rootPkgSymbol, builtinPos, BUILTIN);

detailType = new BMapType(typeEnv(), TypeTags.MAP, cloneableType, null);
errorType = new BErrorType(null, detailType);
errorType = new BErrorType(typeEnv(), null, detailType);
errorType.tsymbol = new BErrorTypeSymbol(SymTag.ERROR, Flags.PUBLIC, Names.ERROR,
rootPkgSymbol.pkgID, errorType, rootPkgSymbol, builtinPos, BUILTIN);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@

import static io.ballerina.types.CellAtomicType.CellMutability.CELL_MUT_LIMITED;
import static io.ballerina.types.CellAtomicType.CellMutability.CELL_MUT_NONE;
import static io.ballerina.types.PredefinedType.ANY;
import static io.ballerina.types.PredefinedType.NEVER;
import static io.ballerina.types.PredefinedType.VAL;

/**
* @since 0.94
Expand Down Expand Up @@ -159,7 +159,7 @@ public SemType semType() {
}
ld = new ListDefinition();
if (hasTypeHoles()) {
return ld.defineListTypeWrapped(env, ANY);
return ld.defineListTypeWrapped(env, VAL);
}
SemType elementTypeSemType = eType.semType();
if (elementTypeSemType == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,14 @@
*/
package org.wso2.ballerinalang.compiler.semantics.model.types;

import io.ballerina.types.Env;
import io.ballerina.types.PredefinedType;
import io.ballerina.types.SemType;
import io.ballerina.types.SemTypes;
import org.ballerinalang.model.types.ErrorType;
import org.wso2.ballerinalang.compiler.semantics.model.TypeVisitor;
import org.wso2.ballerinalang.compiler.semantics.model.symbols.BTypeSymbol;
import org.wso2.ballerinalang.compiler.semantics.model.symbols.Symbols;
import org.wso2.ballerinalang.compiler.util.TypeTags;
import org.wso2.ballerinalang.util.Flags;

Expand All @@ -36,15 +41,20 @@ public class BErrorType extends BType implements ErrorType {
private static final String ERROR = "error<";
private static final String CLOSE_ERROR = ">";

public BErrorType(BTypeSymbol tSymbol, BType detailType) {
public final Env env;
public int distinctId = -1;

public BErrorType(Env env, BTypeSymbol tSymbol, BType detailType) {
super(TypeTags.ERROR, tSymbol, Flags.READONLY);
this.detailType = detailType;
this.typeIdSet = BTypeIdSet.emptySet();
this.env = env;
}

public BErrorType(BTypeSymbol tSymbol) {
public BErrorType(Env env, BTypeSymbol tSymbol) {
super(TypeTags.ERROR, tSymbol, Flags.READONLY);
this.typeIdSet = BTypeIdSet.emptySet();
this.env = env;
}

@Override
Expand All @@ -70,4 +80,25 @@ public String toString() {
}
return ERROR + detailType + CLOSE_ERROR;
}

@Override
public SemType semType() {
SemType err;
if (detailType == null || detailType.semType() == null) {
// semtype will be null for semantic error
err = PredefinedType.ERROR;
} else {
SemType detail = detailType.semType();
err = SemTypes.errorDetail(detail);
}

if (Symbols.isFlagOn(this.getFlags(), Flags.DISTINCT)) {
// this is to avoid creating a new ID every time calling this method
if (distinctId == -1) {
distinctId = env.distinctAtomCountGetAndIncrement();
}
err = SemTypes.intersect(SemTypes.errorDistinct(distinctId), err);
}
return err;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@

import static io.ballerina.types.CellAtomicType.CellMutability.CELL_MUT_LIMITED;
import static io.ballerina.types.CellAtomicType.CellMutability.CELL_MUT_NONE;
import static io.ballerina.types.PredefinedType.ANY;
import static io.ballerina.types.PredefinedType.NEVER;
import static io.ballerina.types.PredefinedType.VAL;

/**
* @since 0.94
Expand Down Expand Up @@ -108,7 +108,7 @@ public SemType semType() {
}
md = new MappingDefinition();
if (hasTypeHoles()) {
return md.defineMappingTypeWrapped(env, List.of(), ANY);
return md.defineMappingTypeWrapped(env, List.of(), VAL);
}
SemType elementTypeSemType = constraint.semType();
if (elementTypeSemType == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@

import static io.ballerina.types.CellAtomicType.CellMutability.CELL_MUT_LIMITED;
import static io.ballerina.types.CellAtomicType.CellMutability.CELL_MUT_NONE;
import static io.ballerina.types.PredefinedType.ANY;
import static io.ballerina.types.PredefinedType.NEVER;
import static io.ballerina.types.PredefinedType.VAL;

/**
* {@code BRecordType} represents record type in Ballerina.
Expand Down Expand Up @@ -155,7 +155,7 @@ public SemType semType() {
}
md = new MappingDefinition();
if (hasTypeHoles()) {
return md.defineMappingTypeWrapped(env, List.of(), ANY);
return md.defineMappingTypeWrapped(env, List.of(), VAL);
}

List<Field> semFields = new ArrayList<>(this.fields.size());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@

import static io.ballerina.types.CellAtomicType.CellMutability.CELL_MUT_LIMITED;
import static io.ballerina.types.CellAtomicType.CellMutability.CELL_MUT_NONE;
import static io.ballerina.types.PredefinedType.ANY;
import static io.ballerina.types.PredefinedType.NEVER;
import static io.ballerina.types.PredefinedType.VAL;

/**
* {@code {@link BTupleType }} represents the tuple type.
Expand Down Expand Up @@ -272,7 +272,7 @@ public SemType semType() {
}
ld = new ListDefinition();
if (hasTypeHoles()) {
return ld.defineListTypeWrapped(env, ANY);
return ld.defineListTypeWrapped(env, VAL);
}
boolean isReadonly = Symbols.isFlagOn(getFlags(), Flags.READONLY);
CellAtomicType.CellMutability mut = isReadonly ? CELL_MUT_NONE : CELL_MUT_LIMITED;
Expand Down
3 changes: 3 additions & 0 deletions semtypes/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ dependencies {
}

test {
// Add additional system property to distinguish tests requiring all basic types
systemProperty "ballerina.semtype.all.types.test", "true"

useTestNG() {
suites 'src/test/resources/testng.xml'
}
Expand Down
3 changes: 2 additions & 1 deletion semtypes/src/main/java/io/ballerina/types/Atom.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ enum Kind {
FUNCTION_ATOM,
MAPPING_ATOM,
CELL_ATOM,
XML_ATOM
XML_ATOM,
DISTINCT_ATOM
}
}
10 changes: 10 additions & 0 deletions semtypes/src/main/java/io/ballerina/types/Core.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@
*/
public final class Core {

private static final boolean SEM_ALL_TEST =
Boolean.parseBoolean(System.getProperty("ballerina.semtype.all.types.test"));

public static CellAtomicType cellAtomType(Atom atom) {
return (CellAtomicType) ((TypeAtom) atom).atomicType();
}
Expand Down Expand Up @@ -321,6 +324,13 @@ public static boolean isNever(SemType t) {
}

public static boolean isEmpty(Context cx, SemType t) {
// TODO: remove this intersect once all types are implemented.
// The predefined readonly and other atoms contain types that are not yet implemented.
// This is a temporary workaround to remove the unimplemented portion of the type.
if (!SEM_ALL_TEST) {
t = intersect(t, PredefinedType.IMPLEMENTED_TYPES);
}

if (t instanceof BasicTypeBitSet b) {
return b.bitset == 0;
} else {
Expand Down
Loading

0 comments on commit ffaac5c

Please sign in to comment.